86 typename Hash = DefaultHash<Key>,
91 typename IsEqual = DefaultEquality<Key>,
123 int64_t occupied_and_removed_slots_;
144#define LOAD_FACTOR 1, 2
145 LoadFactor max_load_factor_ = LoadFactor(
LOAD_FACTOR);
157#define SET_SLOT_PROBING_BEGIN(HASH, R_SLOT) \
158 SLOT_PROBING_BEGIN (ProbingStrategy, HASH, slot_mask_, SLOT_INDEX) \
159 auto &R_SLOT = slots_[SLOT_INDEX];
160#define SET_SLOT_PROBING_END() SLOT_PROBING_END()
168 Set(Allocator allocator = {})
noexcept
170 occupied_and_removed_slots_(0),
193 Set(
Set &&other)
noexcept(std::is_nothrow_move_constructible_v<SlotArray>)
197 if constexpr (std::is_nothrow_move_constructible_v<SlotArray>) {
198 slots_ = std::move(other.slots_);
202 slots_ = std::move(other.slots_);
205 other.noexcept_reset();
209 removed_slots_ = other.removed_slots_;
210 occupied_and_removed_slots_ = other.occupied_and_removed_slots_;
211 usable_slots_ = other.usable_slots_;
212 slot_mask_ = other.slot_mask_;
213 hash_ = std::move(other.hash_);
214 is_equal_ = std::move(other.is_equal_);
215 other.noexcept_reset();
235 this->add_new__impl(key, hash_(key));
239 this->add_new__impl(std::move(key), hash_(key));
254 return this->
add_as(std::move(key));
256 template<
typename ForwardKey>
bool add_as(ForwardKey &&key)
258 return this->add__impl(std::forward<ForwardKey>(key), hash_(key));
270 for (
const Key &key : keys) {
281 for (
const Key &key : keys) {
295 template<
typename ForwardKey>
bool contains_as(
const ForwardKey &key)
const
297 return this->contains__impl(key, hash_(key));
310 return this->lookup_key__impl(key, hash_(key));
321 template<
typename ForwardKey>
324 const Key *
ptr = this->lookup_key_ptr__impl(key, hash_(key));
325 if (
ptr ==
nullptr) {
341 return this->lookup_key_ptr__impl(key, hash_(key));
358 return this->lookup_key_or_add__impl(std::forward<ForwardKey>(key), hash_(key));
370 template<
typename ForwardKey>
bool remove_as(
const ForwardKey &key)
372 return this->remove__impl(key, hash_(key));
384 this->remove_contained__impl(key, hash_(key));
411 : slots_(slots), total_slots_(total_slots), current_slot_(
current_slot)
417 while (++current_slot_ < total_slots_) {
418 if (slots_[current_slot_].is_occupied()) {
429 return copied_iterator;
434 return *slots_[current_slot_].key();
439 return slots_[current_slot_].key();
446 return a.current_slot_ !=
b.current_slot_;
457 return slots_[current_slot_];
464 if (slots_[i].is_occupied()) {
484 Slot &slot =
const_cast<Slot &
>(it.current_slot());
499 for (Slot &slot : slots_) {
500 if (slot.is_occupied()) {
501 const Key &key = *slot.key();
502 if (predicate(key)) {
508 return prev_size - this->
size();
526 return this->count_collisions__impl(key, hash_(key));
534 for (Slot &slot : slots_) {
540 occupied_and_removed_slots_ = 0;
548 std::destroy_at(
this);
558 this->realloc_and_reinsert(this->
size());
566 return occupied_and_removed_slots_ - removed_slots_;
574 return occupied_and_removed_slots_ == removed_slots_;
582 return slots_.
size();
590 return removed_slots_;
607 return sizeof(Slot) * slots_.
size();
616 if (usable_slots_ < n) {
617 this->realloc_and_reinsert(n);
627 if (a.size() >
b.size()) {
631 for (
const Key &key : a) {
632 if (
b.contains(key)) {
649 if (a.size() !=
b.size()) {
652 for (
const Key &key : a) {
653 if (!
b.contains(key)) {
668 int64_t total_slots, usable_slots;
677 if (this->
size() == 0) {
682 this->noexcept_reset();
686 occupied_and_removed_slots_ = 0;
687 usable_slots_ = usable_slots;
688 slot_mask_ = new_slot_mask;
693 SlotArray new_slots(total_slots);
696 for (Slot &slot : slots_) {
697 if (slot.is_occupied()) {
698 this->add_after_grow(slot, new_slots, new_slot_mask);
702 slots_ = std::move(new_slots);
705 this->noexcept_reset();
709 occupied_and_removed_slots_ -= removed_slots_;
710 usable_slots_ = usable_slots;
712 slot_mask_ = new_slot_mask;
715 void add_after_grow(Slot &old_slot, SlotArray &new_slots,
const uint64_t new_slot_mask)
720 Slot &slot = new_slots[slot_index];
721 if (slot.is_empty()) {
722 slot.occupy(std::move(*old_slot.key()),
hash);
733 void noexcept_reset() noexcept
735 Allocator allocator = slots_.
allocator();
737 new (
this)
Set(NoExceptConstructor(), allocator);
740 template<
typename ForwardKey>
741 bool contains__impl(
const ForwardKey &key,
const uint64_t hash)
const
744 if (slot.is_empty()) {
747 if (slot.contains(key, is_equal_,
hash)) {
754 template<
typename ForwardKey>
755 const Key &lookup_key__impl(
const ForwardKey &key,
const uint64_t hash)
const
760 if (slot.contains(key, is_equal_,
hash)) {
767 template<
typename ForwardKey>
768 const Key *lookup_key_ptr__impl(
const ForwardKey &key,
const uint64_t hash)
const
771 if (slot.contains(key, is_equal_,
hash)) {
774 if (slot.is_empty()) {
781 template<
typename ForwardKey>
void add_new__impl(ForwardKey &&key,
const uint64_t hash)
785 this->ensure_can_add();
788 if (slot.is_empty()) {
789 slot.occupy(std::forward<ForwardKey>(key),
hash);
791 occupied_and_removed_slots_++;
798 template<
typename ForwardKey>
bool add__impl(ForwardKey &&key,
const uint64_t hash)
800 this->ensure_can_add();
803 if (slot.is_empty()) {
804 slot.occupy(std::forward<ForwardKey>(key),
hash);
806 occupied_and_removed_slots_++;
809 if (slot.contains(key, is_equal_,
hash)) {
816 template<
typename ForwardKey>
bool remove__impl(
const ForwardKey &key,
const uint64_t hash)
819 if (slot.contains(key, is_equal_,
hash)) {
824 if (slot.is_empty()) {
831 template<
typename ForwardKey>
832 void remove_contained__impl(
const ForwardKey &key,
const uint64_t hash)
837 if (slot.contains(key, is_equal_,
hash)) {
846 template<
typename ForwardKey>
847 const Key &lookup_key_or_add__impl(ForwardKey &&key,
const uint64_t hash)
849 this->ensure_can_add();
852 if (slot.contains(key, is_equal_,
hash)) {
855 if (slot.is_empty()) {
856 slot.occupy(std::forward<ForwardKey>(key),
hash);
858 occupied_and_removed_slots_++;
865 template<
typename ForwardKey>
871 if (slot.contains(key, is_equal_,
hash)) {
874 if (slot.is_empty()) {
882 void ensure_can_add()
884 if (occupied_and_removed_slots_ >= usable_slots_) {
885 this->realloc_and_reinsert(this->
size() + 1);
886 BLI_assert(occupied_and_removed_slots_ < usable_slots_);
895template<
typename Key,
898 typename Hash = DefaultHash<Key>,
899 typename IsEqual = DefaultEquality<Key>,
#define SLOT_PROBING_BEGIN(PROBING_STRATEGY, HASH, MASK, R_SLOT_INDEX)
#define SLOT_PROBING_END()
#define SET_SLOT_PROBING_END()
#define SET_SLOT_PROBING_BEGIN(HASH, R_SLOT)
#define BLI_NO_UNIQUE_ADDRESS
static int64_t inline_buffer_capacity()
void reinitialize(const int64_t new_size)
void print(const char *name) const
static constexpr int64_t compute_total_slots(int64_t min_usable_slots, uint8_t numerator, uint8_t denominator)
void compute_total_and_usable_slots(int64_t min_total_slots, int64_t min_usable_slots, int64_t *r_total_slots, int64_t *r_usable_slots) const
std::ptrdiff_t difference_type
friend bool operator!=(const Iterator &a, const Iterator &b)
const Key * operator->() const
std::forward_iterator_tag iterator_category
const Key & operator*() const
const Slot & current_slot() const
friend bool operator==(const Iterator &a, const Iterator &b)
Iterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
Set(NoExceptConstructor, Allocator allocator={}) noexcept
const Key & lookup_key_or_add_as(ForwardKey &&key)
void remove(const Iterator &it)
int64_t size_per_element() const
const Key & lookup_key_default(const Key &key, const Key &default_value) const
bool remove_as(const ForwardKey &key)
Set(const std::initializer_list< Key > &values)
int64_t size_in_bytes() const
Set(const Set &other)=default
const Key & lookup_key_or_add(const Key &key)
void add_multiple_new(Span< Key > keys)
const Key & lookup_key(const Key &key) const
void print_stats(const char *name) const
static bool Disjoint(const Set &a, const Set &b)
const Key & lookup_key_as(const ForwardKey &key) const
bool add_as(ForwardKey &&key)
int64_t removed_amount() const
bool contains_as(const ForwardKey &key) const
void reserve(const int64_t n)
const Key & lookup_key_default_as(const ForwardKey &key, const Key &default_key) const
Set(Span< Key > values, Allocator allocator={})
void remove_contained(const Key &key)
friend bool operator!=(const Set &a, const Set &b)
bool contains(const Key &key) const
static bool Intersects(const Set &a, const Set &b)
int64_t count_collisions(const Key &key) const
friend bool operator==(const Set &a, const Set &b)
Set & operator=(const Set &other)
Set & operator=(Set &&other)
void add_multiple(Span< Key > keys)
const Key * lookup_key_ptr_as(const ForwardKey &key) const
Set(Set &&other) noexcept(std::is_nothrow_move_constructible_v< SlotArray >)
void add_new(const Key &key)
const Key & lookup_key_or_add(Key &&key)
Set(Allocator allocator={}) noexcept
int64_t remove_if(Predicate &&predicate)
void remove_contained_as(const ForwardKey &key)
const Key * lookup_key_ptr(const Key &key) const
bool remove(const Key &key)
local_group_size(16, 16) .push_constant(Type b
Container & copy_assign_container(Container &dst, const Container &src)
Container & move_assign_container(Container &dst, Container &&src) noexcept(std::is_nothrow_move_constructible_v< Container >)
constexpr int64_t default_inline_buffer_capacity(size_t element_size)
PythonProbingStrategy<> DefaultProbingStrategy
unsigned __int64 uint64_t
SimpleSetSlot< Key > type