Blender  V3.3
BLI_set.hh
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #pragma once
4 
58 #include <unordered_set>
59 
60 #include "BLI_array.hh"
61 #include "BLI_hash.hh"
62 #include "BLI_hash_tables.hh"
64 #include "BLI_set_slots.hh"
65 
66 namespace blender {
67 
68 template<
72  typename Key,
78  int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(Key)),
82  typename ProbingStrategy = DefaultProbingStrategy,
87  typename Hash = DefaultHash<Key>,
92  typename IsEqual = DefaultEquality,
101  typename Slot = typename DefaultSetSlot<Key>::type,
106  typename Allocator = GuardedAllocator>
107 class Set {
108  public:
109  class Iterator;
110  using value_type = Key;
111  using pointer = Key *;
112  using const_pointer = const Key *;
113  using reference = Key &;
114  using const_reference = const Key &;
117 
118  private:
123  int64_t removed_slots_;
124  int64_t occupied_and_removed_slots_;
125 
130  int64_t usable_slots_;
131 
136  uint64_t slot_mask_;
137 
139  BLI_NO_UNIQUE_ADDRESS Hash hash_;
140 
142  BLI_NO_UNIQUE_ADDRESS IsEqual is_equal_;
143 
145 #define LOAD_FACTOR 1, 2
146  LoadFactor max_load_factor_ = LoadFactor(LOAD_FACTOR);
147  using SlotArray =
148  Array<Slot, LoadFactor::compute_total_slots(InlineBufferCapacity, LOAD_FACTOR), Allocator>;
149 #undef LOAD_FACTOR
150 
155  SlotArray slots_;
156 
158 #define SET_SLOT_PROBING_BEGIN(HASH, R_SLOT) \
159  SLOT_PROBING_BEGIN (ProbingStrategy, HASH, slot_mask_, SLOT_INDEX) \
160  auto &R_SLOT = slots_[SLOT_INDEX];
161 #define SET_SLOT_PROBING_END() SLOT_PROBING_END()
162 
163  public:
169  Set(Allocator allocator = {}) noexcept
170  : removed_slots_(0),
171  occupied_and_removed_slots_(0),
172  usable_slots_(0),
173  slot_mask_(0),
174  slots_(1, allocator)
175  {
176  }
177 
178  Set(NoExceptConstructor, Allocator allocator = {}) noexcept : Set(allocator)
179  {
180  }
181 
182  Set(Span<Key> values, Allocator allocator = {}) : Set(NoExceptConstructor(), allocator)
183  {
184  this->add_multiple(values);
185  }
186 
190  Set(const std::initializer_list<Key> &values) : Set(Span<Key>(values))
191  {
192  }
193 
194  ~Set() = default;
195 
196  Set(const Set &other) = default;
197 
198  Set(Set &&other) noexcept(std::is_nothrow_move_constructible_v<SlotArray>)
199  : Set(NoExceptConstructor(), other.slots_.allocator())
200 
201  {
202  if constexpr (std::is_nothrow_move_constructible_v<SlotArray>) {
203  slots_ = std::move(other.slots_);
204  }
205  else {
206  try {
207  slots_ = std::move(other.slots_);
208  }
209  catch (...) {
210  other.noexcept_reset();
211  throw;
212  }
213  }
214  removed_slots_ = other.removed_slots_;
215  occupied_and_removed_slots_ = other.occupied_and_removed_slots_;
216  usable_slots_ = other.usable_slots_;
217  slot_mask_ = other.slot_mask_;
218  hash_ = std::move(other.hash_);
219  is_equal_ = std::move(other.is_equal_);
220  other.noexcept_reset();
221  }
222 
223  Set &operator=(const Set &other)
224  {
225  return copy_assign_container(*this, other);
226  }
227 
228  Set &operator=(Set &&other)
229  {
230  return move_assign_container(*this, std::move(other));
231  }
232 
238  void add_new(const Key &key)
239  {
240  this->add_new__impl(key, hash_(key));
241  }
242  void add_new(Key &&key)
243  {
244  this->add_new__impl(std::move(key), hash_(key));
245  }
246 
253  bool add(const Key &key)
254  {
255  return this->add_as(key);
256  }
257  bool add(Key &&key)
258  {
259  return this->add_as(std::move(key));
260  }
261  template<typename ForwardKey> bool add_as(ForwardKey &&key)
262  {
263  return this->add__impl(std::forward<ForwardKey>(key), hash_(key));
264  }
265 
274  {
275  for (const Key &key : keys) {
276  this->add(key);
277  }
278  }
279 
285  {
286  for (const Key &key : keys) {
287  this->add_new(key);
288  }
289  }
290 
296  bool contains(const Key &key) const
297  {
298  return this->contains_as(key);
299  }
300  template<typename ForwardKey> bool contains_as(const ForwardKey &key) const
301  {
302  return this->contains__impl(key, hash_(key));
303  }
304 
309  const Key &lookup_key(const Key &key) const
310  {
311  return this->lookup_key_as(key);
312  }
313  template<typename ForwardKey> const Key &lookup_key_as(const ForwardKey &key) const
314  {
315  return this->lookup_key__impl(key, hash_(key));
316  }
317 
322  const Key &lookup_key_default(const Key &key, const Key &default_value) const
323  {
324  return this->lookup_key_default_as(key, default_value);
325  }
326  template<typename ForwardKey>
327  const Key &lookup_key_default_as(const ForwardKey &key, const Key &default_key) const
328  {
329  const Key *ptr = this->lookup_key_ptr__impl(key, hash_(key));
330  if (ptr == nullptr) {
331  return default_key;
332  }
333  return *ptr;
334  }
335 
340  const Key *lookup_key_ptr(const Key &key) const
341  {
342  return this->lookup_key_ptr_as(key);
343  }
344  template<typename ForwardKey> const Key *lookup_key_ptr_as(const ForwardKey &key) const
345  {
346  return this->lookup_key_ptr__impl(key, hash_(key));
347  }
348 
353  const Key &lookup_key_or_add(const Key &key)
354  {
355  return this->lookup_key_or_add_as(key);
356  }
357  const Key &lookup_key_or_add(Key &&key)
358  {
359  return this->lookup_key_or_add_as(std::move(key));
360  }
361  template<typename ForwardKey> const Key &lookup_key_or_add_as(ForwardKey &&key)
362  {
363  return this->lookup_key_or_add__impl(std::forward<ForwardKey>(key), hash_(key));
364  }
365 
371  bool remove(const Key &key)
372  {
373  return this->remove_as(key);
374  }
375  template<typename ForwardKey> bool remove_as(const ForwardKey &key)
376  {
377  return this->remove__impl(key, hash_(key));
378  }
379 
383  void remove_contained(const Key &key)
384  {
385  this->remove_contained_as(key);
386  }
387  template<typename ForwardKey> void remove_contained_as(const ForwardKey &key)
388  {
389  this->remove_contained__impl(key, hash_(key));
390  }
391 
399  class Iterator {
400  public:
401  using iterator_category = std::forward_iterator_tag;
402  using value_type = Key;
403  using pointer = const Key *;
404  using reference = const Key &;
405  using difference_type = std::ptrdiff_t;
406 
407  private:
408  const Slot *slots_;
409  int64_t total_slots_;
410  int64_t current_slot_;
411 
412  friend Set;
413 
414  public:
415  Iterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
416  : slots_(slots), total_slots_(total_slots), current_slot_(current_slot)
417  {
418  }
419 
421  {
422  while (++current_slot_ < total_slots_) {
423  if (slots_[current_slot_].is_occupied()) {
424  break;
425  }
426  }
427  return *this;
428  }
429 
430  Iterator operator++(int) const
431  {
432  Iterator copied_iterator = *this;
433  ++copied_iterator;
434  return copied_iterator;
435  }
436 
437  const Key &operator*() const
438  {
439  return *slots_[current_slot_].key();
440  }
441 
442  const Key *operator->() const
443  {
444  return slots_[current_slot_].key();
445  }
446 
447  friend bool operator!=(const Iterator &a, const Iterator &b)
448  {
449  BLI_assert(a.slots_ == b.slots_);
450  BLI_assert(a.total_slots_ == b.total_slots_);
451  return a.current_slot_ != b.current_slot_;
452  }
453 
454  friend bool operator==(const Iterator &a, const Iterator &b)
455  {
456  return !(a != b);
457  }
458 
459  protected:
460  const Slot &current_slot() const
461  {
462  return slots_[current_slot_];
463  }
464  };
465 
466  Iterator begin() const
467  {
468  for (int64_t i = 0; i < slots_.size(); i++) {
469  if (slots_[i].is_occupied()) {
470  return Iterator(slots_.data(), slots_.size(), i);
471  }
472  }
473  return this->end();
474  }
475 
476  Iterator end() const
477  {
478  return Iterator(slots_.data(), slots_.size(), slots_.size());
479  }
480 
486  void remove(const Iterator &it)
487  {
488  /* The const cast is valid because this method itself is not const. */
489  Slot &slot = const_cast<Slot &>(it.current_slot());
490  BLI_assert(slot.is_occupied());
491  slot.remove();
492  removed_slots_++;
493  }
494 
498  void print_stats(StringRef name = "") const
499  {
500  HashTableStats stats(*this, *this);
501  stats.print(name);
502  }
503 
508  int64_t count_collisions(const Key &key) const
509  {
510  return this->count_collisions__impl(key, hash_(key));
511  }
512 
516  void clear()
517  {
518  for (Slot &slot : slots_) {
519  slot.~Slot();
520  new (&slot) Slot();
521  }
522 
523  removed_slots_ = 0;
524  occupied_and_removed_slots_ = 0;
525  }
526 
531  void rehash()
532  {
533  this->realloc_and_reinsert(this->size());
534  }
535 
539  int64_t size() const
540  {
541  return occupied_and_removed_slots_ - removed_slots_;
542  }
543 
547  bool is_empty() const
548  {
549  return occupied_and_removed_slots_ == removed_slots_;
550  }
551 
556  {
557  return slots_.size();
558  }
559 
564  {
565  return removed_slots_;
566  }
567 
572  {
573  return sizeof(Slot);
574  }
575 
581  {
582  return sizeof(Slot) * slots_.size();
583  }
584 
589  void reserve(const int64_t n)
590  {
591  if (usable_slots_ < n) {
592  this->realloc_and_reinsert(n);
593  }
594  }
595 
599  static bool Intersects(const Set &a, const Set &b)
600  {
601  /* Make sure we iterate over the shorter set. */
602  if (a.size() > b.size()) {
603  return Intersects(b, a);
604  }
605 
606  for (const Key &key : a) {
607  if (b.contains(key)) {
608  return true;
609  }
610  }
611  return false;
612  }
613 
617  static bool Disjoint(const Set &a, const Set &b)
618  {
619  return !Intersects(a, b);
620  }
621 
622  private:
623  BLI_NOINLINE void realloc_and_reinsert(const int64_t min_usable_slots)
624  {
625  int64_t total_slots, usable_slots;
626  max_load_factor_.compute_total_and_usable_slots(
627  SlotArray::inline_buffer_capacity(), min_usable_slots, &total_slots, &usable_slots);
628  BLI_assert(total_slots >= 1);
629  const uint64_t new_slot_mask = static_cast<uint64_t>(total_slots) - 1;
630 
634  if (this->size() == 0) {
635  try {
636  slots_.reinitialize(total_slots);
637  }
638  catch (...) {
639  this->noexcept_reset();
640  throw;
641  }
642  removed_slots_ = 0;
643  occupied_and_removed_slots_ = 0;
644  usable_slots_ = usable_slots;
645  slot_mask_ = new_slot_mask;
646  return;
647  }
648 
649  /* The grown array that we insert the keys into. */
650  SlotArray new_slots(total_slots);
651 
652  try {
653  for (Slot &slot : slots_) {
654  if (slot.is_occupied()) {
655  this->add_after_grow(slot, new_slots, new_slot_mask);
656  slot.remove();
657  }
658  }
659  slots_ = std::move(new_slots);
660  }
661  catch (...) {
662  this->noexcept_reset();
663  throw;
664  }
665 
666  occupied_and_removed_slots_ -= removed_slots_;
667  usable_slots_ = usable_slots;
668  removed_slots_ = 0;
669  slot_mask_ = new_slot_mask;
670  }
671 
672  void add_after_grow(Slot &old_slot, SlotArray &new_slots, const uint64_t new_slot_mask)
673  {
674  const uint64_t hash = old_slot.get_hash(Hash());
675 
676  SLOT_PROBING_BEGIN (ProbingStrategy, hash, new_slot_mask, slot_index) {
677  Slot &slot = new_slots[slot_index];
678  if (slot.is_empty()) {
679  slot.occupy(std::move(*old_slot.key()), hash);
680  return;
681  }
682  }
684  }
685 
690  void noexcept_reset() noexcept
691  {
692  Allocator allocator = slots_.allocator();
693  this->~Set();
694  new (this) Set(NoExceptConstructor(), allocator);
695  }
696 
697  template<typename ForwardKey>
698  bool contains__impl(const ForwardKey &key, const uint64_t hash) const
699  {
700  SET_SLOT_PROBING_BEGIN (hash, slot) {
701  if (slot.is_empty()) {
702  return false;
703  }
704  if (slot.contains(key, is_equal_, hash)) {
705  return true;
706  }
707  }
709  }
710 
711  template<typename ForwardKey>
712  const Key &lookup_key__impl(const ForwardKey &key, const uint64_t hash) const
713  {
714  BLI_assert(this->contains_as(key));
715 
716  SET_SLOT_PROBING_BEGIN (hash, slot) {
717  if (slot.contains(key, is_equal_, hash)) {
718  return *slot.key();
719  }
720  }
722  }
723 
724  template<typename ForwardKey>
725  const Key *lookup_key_ptr__impl(const ForwardKey &key, const uint64_t hash) const
726  {
727  SET_SLOT_PROBING_BEGIN (hash, slot) {
728  if (slot.contains(key, is_equal_, hash)) {
729  return slot.key();
730  }
731  if (slot.is_empty()) {
732  return nullptr;
733  }
734  }
736  }
737 
738  template<typename ForwardKey> void add_new__impl(ForwardKey &&key, const uint64_t hash)
739  {
740  BLI_assert(!this->contains_as(key));
741 
742  this->ensure_can_add();
743 
744  SET_SLOT_PROBING_BEGIN (hash, slot) {
745  if (slot.is_empty()) {
746  slot.occupy(std::forward<ForwardKey>(key), hash);
747  occupied_and_removed_slots_++;
748  return;
749  }
750  }
752  }
753 
754  template<typename ForwardKey> bool add__impl(ForwardKey &&key, const uint64_t hash)
755  {
756  this->ensure_can_add();
757 
758  SET_SLOT_PROBING_BEGIN (hash, slot) {
759  if (slot.is_empty()) {
760  slot.occupy(std::forward<ForwardKey>(key), hash);
761  occupied_and_removed_slots_++;
762  return true;
763  }
764  if (slot.contains(key, is_equal_, hash)) {
765  return false;
766  }
767  }
769  }
770 
771  template<typename ForwardKey> bool remove__impl(const ForwardKey &key, const uint64_t hash)
772  {
773  SET_SLOT_PROBING_BEGIN (hash, slot) {
774  if (slot.contains(key, is_equal_, hash)) {
775  slot.remove();
776  removed_slots_++;
777  return true;
778  }
779  if (slot.is_empty()) {
780  return false;
781  }
782  }
784  }
785 
786  template<typename ForwardKey>
787  void remove_contained__impl(const ForwardKey &key, const uint64_t hash)
788  {
789  BLI_assert(this->contains_as(key));
790 
791  SET_SLOT_PROBING_BEGIN (hash, slot) {
792  if (slot.contains(key, is_equal_, hash)) {
793  slot.remove();
794  removed_slots_++;
795  return;
796  }
797  }
799  }
800 
801  template<typename ForwardKey>
802  const Key &lookup_key_or_add__impl(ForwardKey &&key, const uint64_t hash)
803  {
804  this->ensure_can_add();
805 
806  SET_SLOT_PROBING_BEGIN (hash, slot) {
807  if (slot.contains(key, is_equal_, hash)) {
808  return *slot.key();
809  }
810  if (slot.is_empty()) {
811  slot.occupy(std::forward<ForwardKey>(key), hash);
812  occupied_and_removed_slots_++;
813  return *slot.key();
814  }
815  }
817  }
818 
819  template<typename ForwardKey>
820  int64_t count_collisions__impl(const ForwardKey &key, const uint64_t hash) const
821  {
822  int64_t collisions = 0;
823 
824  SET_SLOT_PROBING_BEGIN (hash, slot) {
825  if (slot.contains(key, is_equal_, hash)) {
826  return collisions;
827  }
828  if (slot.is_empty()) {
829  return collisions;
830  }
831  collisions++;
832  }
834  }
835 
836  void ensure_can_add()
837  {
838  if (occupied_and_removed_slots_ >= usable_slots_) {
839  this->realloc_and_reinsert(this->size() + 1);
840  BLI_assert(occupied_and_removed_slots_ < usable_slots_);
841  }
842  }
843 };
844 
849 template<typename Key> class StdUnorderedSetWrapper {
850  private:
851  using SetType = std::unordered_set<Key, blender::DefaultHash<Key>>;
852  SetType set_;
853 
854  public:
855  int64_t size() const
856  {
857  return static_cast<int64_t>(set_.size());
858  }
859 
860  bool is_empty() const
861  {
862  return set_.empty();
863  }
864 
865  void reserve(int64_t n)
866  {
867  set_.reserve(n);
868  }
869 
870  void add_new(const Key &key)
871  {
872  set_.insert(key);
873  }
874  void add_new(Key &&key)
875  {
876  set_.insert(std::move(key));
877  }
878 
879  bool add(const Key &key)
880  {
881  return set_.insert(key).second;
882  }
883  bool add(Key &&key)
884  {
885  return set_.insert(std::move(key)).second;
886  }
887 
889  {
890  for (const Key &key : keys) {
891  set_.insert(key);
892  }
893  }
894 
895  bool contains(const Key &key) const
896  {
897  return set_.find(key) != set_.end();
898  }
899 
900  bool remove(const Key &key)
901  {
902  return (bool)set_.erase(key);
903  }
904 
905  void remove_contained(const Key &key)
906  {
907  return set_.erase(key);
908  }
909 
910  void clear()
911  {
912  set_.clear();
913  }
914 
915  typename SetType::iterator begin() const
916  {
917  return set_.begin();
918  }
919 
920  typename SetType::iterator end() const
921  {
922  return set_.end();
923  }
924 };
925 
930 template<typename Key,
931  int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(Key)),
932  typename ProbingStrategy = DefaultProbingStrategy,
933  typename Hash = DefaultHash<Key>,
934  typename IsEqual = DefaultEquality,
935  typename Slot = typename DefaultSetSlot<Key>::type>
937 
938 } // namespace blender
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_NOINLINE
#define SLOT_PROBING_BEGIN(PROBING_STRATEGY, HASH, MASK, R_SLOT_INDEX)
#define SLOT_PROBING_END()
#define SET_SLOT_PROBING_END()
Definition: BLI_set.hh:161
#define SET_SLOT_PROBING_BEGIN(HASH, R_SLOT)
Definition: BLI_set.hh:158
#define LOAD_FACTOR
Definition: BLI_set.hh:145
#define BLI_NO_UNIQUE_ADDRESS
struct Key Key
static int64_t inline_buffer_capacity()
Definition: BLI_array.hh:378
void print(StringRef name="")
static constexpr int64_t compute_total_slots(int64_t min_usable_slots, uint8_t numerator, uint8_t denominator)
std::ptrdiff_t difference_type
Definition: BLI_set.hh:405
friend bool operator!=(const Iterator &a, const Iterator &b)
Definition: BLI_set.hh:447
Iterator & operator++()
Definition: BLI_set.hh:420
const Key * operator->() const
Definition: BLI_set.hh:442
const Key & operator*() const
Definition: BLI_set.hh:437
std::forward_iterator_tag iterator_category
Definition: BLI_set.hh:401
friend bool operator==(const Iterator &a, const Iterator &b)
Definition: BLI_set.hh:454
Iterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
Definition: BLI_set.hh:415
const Slot & current_slot() const
Definition: BLI_set.hh:460
Iterator operator++(int) const
Definition: BLI_set.hh:430
Set(NoExceptConstructor, Allocator allocator={}) noexcept
Definition: BLI_set.hh:178
void remove(const Iterator &it)
Definition: BLI_set.hh:486
const Key & lookup_key_or_add(Key &&key)
Definition: BLI_set.hh:357
int64_t size_per_element() const
Definition: BLI_set.hh:571
const Key & lookup_key_default_as(const ForwardKey &key, const Key &default_key) const
Definition: BLI_set.hh:327
bool remove_as(const ForwardKey &key)
Definition: BLI_set.hh:375
Set(const std::initializer_list< Key > &values)
Definition: BLI_set.hh:190
Set & operator=(const Set &other)
Definition: BLI_set.hh:223
int64_t size_in_bytes() const
Definition: BLI_set.hh:580
Set & operator=(Set &&other)
Definition: BLI_set.hh:228
~Set()=default
Set(const Set &other)=default
Iterator begin() const
Definition: BLI_set.hh:466
void add_multiple_new(Span< Key > keys)
Definition: BLI_set.hh:284
const Key * lookup_key_ptr(const Key &key) const
Definition: BLI_set.hh:340
int64_t size_type
Definition: BLI_set.hh:116
static bool Disjoint(const Set &a, const Set &b)
Definition: BLI_set.hh:617
bool add(Key &&key)
Definition: BLI_set.hh:257
const Key & lookup_key(const Key &key) const
Definition: BLI_set.hh:309
int64_t size() const
Definition: BLI_set.hh:539
bool add_as(ForwardKey &&key)
Definition: BLI_set.hh:261
int64_t removed_amount() const
Definition: BLI_set.hh:563
bool contains_as(const ForwardKey &key) const
Definition: BLI_set.hh:300
void reserve(const int64_t n)
Definition: BLI_set.hh:589
const Key * lookup_key_ptr_as(const ForwardKey &key) const
Definition: BLI_set.hh:344
Iterator end() const
Definition: BLI_set.hh:476
Set(Span< Key > values, Allocator allocator={})
Definition: BLI_set.hh:182
void remove_contained(const Key &key)
Definition: BLI_set.hh:383
bool contains(const Key &key) const
Definition: BLI_set.hh:296
static bool Intersects(const Set &a, const Set &b)
Definition: BLI_set.hh:599
int64_t capacity() const
Definition: BLI_set.hh:555
const Key & lookup_key_or_add_as(ForwardKey &&key)
Definition: BLI_set.hh:361
const Key & lookup_key_or_add(const Key &key)
Definition: BLI_set.hh:353
int64_t count_collisions(const Key &key) const
Definition: BLI_set.hh:508
bool add(const Key &key)
Definition: BLI_set.hh:253
bool is_empty() const
Definition: BLI_set.hh:547
void add_multiple(Span< Key > keys)
Definition: BLI_set.hh:273
Set(Set &&other) noexcept(std::is_nothrow_move_constructible_v< SlotArray >)
Definition: BLI_set.hh:198
void add_new(const Key &key)
Definition: BLI_set.hh:238
Set(Allocator allocator={}) noexcept
Definition: BLI_set.hh:169
void clear()
Definition: BLI_set.hh:516
void remove_contained_as(const ForwardKey &key)
Definition: BLI_set.hh:387
void print_stats(StringRef name="") const
Definition: BLI_set.hh:498
const Key & lookup_key_default(const Key &key, const Key &default_value) const
Definition: BLI_set.hh:322
bool remove(const Key &key)
Definition: BLI_set.hh:371
const Key & lookup_key_as(const ForwardKey &key) const
Definition: BLI_set.hh:313
void rehash()
Definition: BLI_set.hh:531
void add_new(Key &&key)
Definition: BLI_set.hh:242
bool add(const Key &key)
Definition: BLI_set.hh:879
bool remove(const Key &key)
Definition: BLI_set.hh:900
bool contains(const Key &key) const
Definition: BLI_set.hh:895
void remove_contained(const Key &key)
Definition: BLI_set.hh:905
SetType::iterator begin() const
Definition: BLI_set.hh:915
void add_multiple(Span< Key > keys)
Definition: BLI_set.hh:888
void add_new(const Key &key)
Definition: BLI_set.hh:870
SetType::iterator end() const
Definition: BLI_set.hh:920
static unsigned a[3]
Definition: RandGen.cpp:78
Container & move_assign_container(Container &dst, Container &&src) noexcept(std::is_nothrow_move_constructible_v< Container >)
Container & copy_assign_container(Container &dst, const Container &src)
PythonProbingStrategy<> DefaultProbingStrategy
constexpr int64_t default_inline_buffer_capacity(size_t element_size)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
#define hash
Definition: noise.c:153
__int64 int64_t
Definition: stdint.h:89
unsigned __int64 uint64_t
Definition: stdint.h:90
SimpleSetSlot< Key > type
PointerRNA * ptr
Definition: wm_files.c:3480