Blender  V3.3
BLI_set_slots.hh
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #pragma once
4 
20 #include "BLI_memory_utils.hh"
21 #include "BLI_string_ref.hh"
22 
23 namespace blender {
24 
30 template<typename Key> class SimpleSetSlot {
31  private:
32  enum State : uint8_t {
33  Empty = 0,
34  Occupied = 1,
35  Removed = 2,
36  };
37 
38  State state_;
39  TypedBuffer<Key> key_buffer_;
40 
41  public:
46  {
47  state_ = Empty;
48  }
49 
54  {
55  if (state_ == Occupied) {
56  key_buffer_.ref().~Key();
57  }
58  }
59 
65  {
66  state_ = other.state_;
67  if (other.state_ == Occupied) {
68  new (&key_buffer_) Key(*other.key_buffer_);
69  }
70  }
71 
77  SimpleSetSlot(SimpleSetSlot &&other) noexcept(std::is_nothrow_move_constructible_v<Key>)
78  {
79  state_ = other.state_;
80  if (other.state_ == Occupied) {
81  new (&key_buffer_) Key(std::move(*other.key_buffer_));
82  }
83  }
84 
88  Key *key()
89  {
90  return key_buffer_;
91  }
92 
96  const Key *key() const
97  {
98  return key_buffer_;
99  }
100 
104  bool is_occupied() const
105  {
106  return state_ == Occupied;
107  }
108 
112  bool is_empty() const
113  {
114  return state_ == Empty;
115  }
116 
121  template<typename Hash> uint64_t get_hash(const Hash &hash) const
122  {
123  BLI_assert(this->is_occupied());
124  return hash(*key_buffer_);
125  }
126 
131  template<typename ForwardKey, typename IsEqual>
132  bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t UNUSED(hash)) const
133  {
134  if (state_ == Occupied) {
135  return is_equal(key, *key_buffer_);
136  }
137  return false;
138  }
139 
144  template<typename ForwardKey> void occupy(ForwardKey &&key, uint64_t UNUSED(hash))
145  {
146  BLI_assert(!this->is_occupied());
147  new (&key_buffer_) Key(std::forward<ForwardKey>(key));
148  state_ = Occupied;
149  }
150 
154  void remove()
155  {
156  BLI_assert(this->is_occupied());
157  key_buffer_.ref().~Key();
158  state_ = Removed;
159  }
160 };
161 
166 template<typename Key> class HashedSetSlot {
167  private:
168  enum State : uint8_t {
169  Empty = 0,
170  Occupied = 1,
171  Removed = 2,
172  };
173 
174  uint64_t hash_;
175  State state_;
176  TypedBuffer<Key> key_buffer_;
177 
178  public:
180  {
181  state_ = Empty;
182  }
183 
185  {
186  if (state_ == Occupied) {
187  key_buffer_.ref().~Key();
188  }
189  }
190 
192  {
193  state_ = other.state_;
194  if (other.state_ == Occupied) {
195  hash_ = other.hash_;
196  new (&key_buffer_) Key(*other.key_buffer_);
197  }
198  }
199 
200  HashedSetSlot(HashedSetSlot &&other) noexcept(std::is_nothrow_move_constructible_v<Key>)
201  {
202  state_ = other.state_;
203  if (other.state_ == Occupied) {
204  hash_ = other.hash_;
205  new (&key_buffer_) Key(std::move(*other.key_buffer_));
206  }
207  }
208 
209  Key *key()
210  {
211  return key_buffer_;
212  }
213 
214  const Key *key() const
215  {
216  return key_buffer_;
217  }
218 
219  bool is_occupied() const
220  {
221  return state_ == Occupied;
222  }
223 
224  bool is_empty() const
225  {
226  return state_ == Empty;
227  }
228 
229  template<typename Hash> uint64_t get_hash(const Hash &UNUSED(hash)) const
230  {
231  BLI_assert(this->is_occupied());
232  return hash_;
233  }
234 
235  template<typename ForwardKey, typename IsEqual>
236  bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint64_t hash) const
237  {
238  /* `hash_` might be uninitialized here, but that is ok. */
239  if (hash_ == hash) {
240  if (state_ == Occupied) {
241  return is_equal(key, *key_buffer_);
242  }
243  }
244  return false;
245  }
246 
247  template<typename ForwardKey> void occupy(ForwardKey &&key, const uint64_t hash)
248  {
249  BLI_assert(!this->is_occupied());
250  new (&key_buffer_) Key(std::forward<ForwardKey>(key));
251  state_ = Occupied;
252  hash_ = hash;
253  }
254 
255  void remove()
256  {
257  BLI_assert(this->is_occupied());
258  key_buffer_.ref().~Key();
259  state_ = Removed;
260  }
261 };
262 
271 template<typename Key, typename KeyInfo> class IntrusiveSetSlot {
272  private:
273  Key key_ = KeyInfo::get_empty();
274 
275  public:
276  IntrusiveSetSlot() = default;
277  ~IntrusiveSetSlot() = default;
278  IntrusiveSetSlot(const IntrusiveSetSlot &other) = default;
279  IntrusiveSetSlot(IntrusiveSetSlot &&other) noexcept(std::is_nothrow_move_constructible_v<Key>) =
280  default;
281 
282  Key *key()
283  {
284  return &key_;
285  }
286 
287  const Key *key() const
288  {
289  return &key_;
290  }
291 
292  bool is_occupied() const
293  {
294  return KeyInfo::is_not_empty_or_removed(key_);
295  }
296 
297  bool is_empty() const
298  {
299  return KeyInfo::is_empty(key_);
300  }
301 
302  template<typename Hash> uint64_t get_hash(const Hash &hash) const
303  {
304  BLI_assert(this->is_occupied());
305  return hash(key_);
306  }
307 
308  template<typename ForwardKey, typename IsEqual>
309  bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint64_t UNUSED(hash)) const
310  {
311  BLI_assert(KeyInfo::is_not_empty_or_removed(key));
312  return is_equal(key_, key);
313  }
314 
315  template<typename ForwardKey> void occupy(ForwardKey &&key, const uint64_t UNUSED(hash))
316  {
317  BLI_assert(!this->is_occupied());
318  BLI_assert(KeyInfo::is_not_empty_or_removed(key));
319  key_ = std::forward<ForwardKey>(key);
320  }
321 
322  void remove()
323  {
324  BLI_assert(this->is_occupied());
325  KeyInfo::remove(key_);
326  }
327 };
328 
333 template<typename Int, Int EmptyValue, Int RemovedValue>
335 
336 template<typename Key> struct DefaultSetSlot;
337 
341 template<typename Key> struct DefaultSetSlot {
343 };
344 
349 template<> struct DefaultSetSlot<std::string> {
351 };
352 template<> struct DefaultSetSlot<StringRef> {
354 };
355 template<> struct DefaultSetSlot<StringRefNull> {
357 };
358 
363 template<typename Key> struct DefaultSetSlot<Key *> {
365 };
366 
367 } // namespace blender
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define UNUSED(x)
struct Key Key
HashedSetSlot(HashedSetSlot &&other) noexcept(std::is_nothrow_move_constructible_v< Key >)
uint64_t get_hash(const Hash &UNUSED(hash)) const
bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint64_t hash) const
void occupy(ForwardKey &&key, const uint64_t hash)
const Key * key() const
HashedSetSlot(const HashedSetSlot &other)
uint64_t get_hash(const Hash &hash) const
IntrusiveSetSlot(IntrusiveSetSlot &&other) noexcept(std::is_nothrow_move_constructible_v< Key >)=default
const Key * key() const
void occupy(ForwardKey &&key, const uint64_t UNUSED(hash))
IntrusiveSetSlot(const IntrusiveSetSlot &other)=default
bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint64_t UNUSED(hash)) const
bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t UNUSED(hash)) const
SimpleSetSlot(SimpleSetSlot &&other) noexcept(std::is_nothrow_move_constructible_v< Key >)
uint64_t get_hash(const Hash &hash) const
SimpleSetSlot(const SimpleSetSlot &other)
void occupy(ForwardKey &&key, uint64_t UNUSED(hash))
const Key * key() const
bool remove(void *owner, const AttributeIDRef &attribute_id)
#define hash
Definition: noise.c:153
unsigned char uint8_t
Definition: stdint.h:78
unsigned __int64 uint64_t
Definition: stdint.h:90