Blender  V2.93
BLI_set_slots.hh
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #pragma once
18 
34 #include "BLI_memory_utils.hh"
35 #include "BLI_string_ref.hh"
36 
37 namespace blender {
38 
44 template<typename Key> class SimpleSetSlot {
45  private:
46  enum State : uint8_t {
47  Empty = 0,
48  Occupied = 1,
49  Removed = 2,
50  };
51 
52  State state_;
53  TypedBuffer<Key> key_buffer_;
54 
55  public:
60  {
61  state_ = Empty;
62  }
63 
68  {
69  if (state_ == Occupied) {
70  key_buffer_.ref().~Key();
71  }
72  }
73 
79  {
80  state_ = other.state_;
81  if (other.state_ == Occupied) {
82  new (&key_buffer_) Key(*other.key_buffer_);
83  }
84  }
85 
91  SimpleSetSlot(SimpleSetSlot &&other) noexcept(std::is_nothrow_move_constructible_v<Key>)
92  {
93  state_ = other.state_;
94  if (other.state_ == Occupied) {
95  new (&key_buffer_) Key(std::move(*other.key_buffer_));
96  }
97  }
98 
102  Key *key()
103  {
104  return key_buffer_;
105  }
106 
110  const Key *key() const
111  {
112  return key_buffer_;
113  }
114 
118  bool is_occupied() const
119  {
120  return state_ == Occupied;
121  }
122 
126  bool is_empty() const
127  {
128  return state_ == Empty;
129  }
130 
135  template<typename Hash> uint64_t get_hash(const Hash &hash) const
136  {
137  BLI_assert(this->is_occupied());
138  return hash(*key_buffer_);
139  }
140 
145  template<typename ForwardKey, typename IsEqual>
146  bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t UNUSED(hash)) const
147  {
148  if (state_ == Occupied) {
149  return is_equal(key, *key_buffer_);
150  }
151  return false;
152  }
153 
158  template<typename ForwardKey> void occupy(ForwardKey &&key, uint64_t UNUSED(hash))
159  {
160  BLI_assert(!this->is_occupied());
161  new (&key_buffer_) Key(std::forward<ForwardKey>(key));
162  state_ = Occupied;
163  }
164 
168  void remove()
169  {
170  BLI_assert(this->is_occupied());
171  key_buffer_.ref().~Key();
172  state_ = Removed;
173  }
174 };
175 
180 template<typename Key> class HashedSetSlot {
181  private:
182  enum State : uint8_t {
183  Empty = 0,
184  Occupied = 1,
185  Removed = 2,
186  };
187 
188  uint64_t hash_;
189  State state_;
190  TypedBuffer<Key> key_buffer_;
191 
192  public:
194  {
195  state_ = Empty;
196  }
197 
199  {
200  if (state_ == Occupied) {
201  key_buffer_.ref().~Key();
202  }
203  }
204 
206  {
207  state_ = other.state_;
208  if (other.state_ == Occupied) {
209  hash_ = other.hash_;
210  new (&key_buffer_) Key(*other.key_buffer_);
211  }
212  }
213 
214  HashedSetSlot(HashedSetSlot &&other) noexcept(std::is_nothrow_move_constructible_v<Key>)
215  {
216  state_ = other.state_;
217  if (other.state_ == Occupied) {
218  hash_ = other.hash_;
219  new (&key_buffer_) Key(std::move(*other.key_buffer_));
220  }
221  }
222 
223  Key *key()
224  {
225  return key_buffer_;
226  }
227 
228  const Key *key() const
229  {
230  return key_buffer_;
231  }
232 
233  bool is_occupied() const
234  {
235  return state_ == Occupied;
236  }
237 
238  bool is_empty() const
239  {
240  return state_ == Empty;
241  }
242 
243  template<typename Hash> uint64_t get_hash(const Hash &UNUSED(hash)) const
244  {
245  BLI_assert(this->is_occupied());
246  return hash_;
247  }
248 
249  template<typename ForwardKey, typename IsEqual>
250  bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint64_t hash) const
251  {
252  /* hash_ might be uninitialized here, but that is ok. */
253  if (hash_ == hash) {
254  if (state_ == Occupied) {
255  return is_equal(key, *key_buffer_);
256  }
257  }
258  return false;
259  }
260 
261  template<typename ForwardKey> void occupy(ForwardKey &&key, const uint64_t hash)
262  {
263  BLI_assert(!this->is_occupied());
264  new (&key_buffer_) Key(std::forward<ForwardKey>(key));
265  state_ = Occupied;
266  hash_ = hash;
267  }
268 
269  void remove()
270  {
271  BLI_assert(this->is_occupied());
272  key_buffer_.ref().~Key();
273  state_ = Removed;
274  }
275 };
276 
285 template<typename Key, typename KeyInfo> class IntrusiveSetSlot {
286  private:
287  Key key_ = KeyInfo::get_empty();
288 
289  public:
290  IntrusiveSetSlot() = default;
291  ~IntrusiveSetSlot() = default;
292  IntrusiveSetSlot(const IntrusiveSetSlot &other) = default;
293  IntrusiveSetSlot(IntrusiveSetSlot &&other) noexcept(std::is_nothrow_move_constructible_v<Key>) =
294  default;
295 
296  Key *key()
297  {
298  return &key_;
299  }
300 
301  const Key *key() const
302  {
303  return &key_;
304  }
305 
306  bool is_occupied() const
307  {
308  return KeyInfo::is_not_empty_or_removed(key_);
309  }
310 
311  bool is_empty() const
312  {
313  return KeyInfo::is_empty(key_);
314  }
315 
316  template<typename Hash> uint64_t get_hash(const Hash &hash) const
317  {
318  BLI_assert(this->is_occupied());
319  return hash(key_);
320  }
321 
322  template<typename ForwardKey, typename IsEqual>
323  bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint64_t UNUSED(hash)) const
324  {
325  BLI_assert(KeyInfo::is_not_empty_or_removed(key));
326  return is_equal(key_, key);
327  }
328 
329  template<typename ForwardKey> void occupy(ForwardKey &&key, const uint64_t UNUSED(hash))
330  {
331  BLI_assert(!this->is_occupied());
332  BLI_assert(KeyInfo::is_not_empty_or_removed(key));
333  key_ = std::forward<ForwardKey>(key);
334  }
335 
336  void remove()
337  {
338  BLI_assert(this->is_occupied());
339  KeyInfo::remove(key_);
340  }
341 };
342 
347 template<typename Int, Int EmptyValue, Int RemovedValue>
349 
350 template<typename Key> struct DefaultSetSlot;
351 
355 template<typename Key> struct DefaultSetSlot {
357 };
358 
363 template<> struct DefaultSetSlot<std::string> {
365 };
366 template<> struct DefaultSetSlot<StringRef> {
368 };
369 template<> struct DefaultSetSlot<StringRefNull> {
371 };
372 
377 template<typename Key> struct DefaultSetSlot<Key *> {
379 };
380 
381 } // namespace blender
#define BLI_assert(a)
Definition: BLI_assert.h:58
#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
#define hash
Definition: noise.c:169
unsigned char uint8_t
Definition: stdint.h:81
unsigned __int64 uint64_t
Definition: stdint.h:93