123 int64_t occupied_and_removed_slots_;
144#define LOAD_FACTOR 1, 2
145 static constexpr 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));
277 return this->add_overwrite__impl(std::forward<ForwardKey>(key), hash_(key));
289 for (
const Key &key : keys) {
300 for (
const Key &key : keys) {
314 template<
typename ForwardKey>
bool contains_as(
const ForwardKey &key)
const
316 return this->contains__impl(key, hash_(key));
329 return this->lookup_key__impl(key, hash_(key));
340 template<
typename ForwardKey>
343 const Key *
ptr = this->lookup_key_ptr__impl(key, hash_(key));
344 if (
ptr ==
nullptr) {
360 return this->lookup_key_ptr__impl(key, hash_(key));
377 return this->lookup_key_or_add__impl(std::forward<ForwardKey>(key), hash_(key));
389 template<
typename ForwardKey>
bool remove_as(
const ForwardKey &key)
391 return this->remove__impl(key, hash_(key));
403 this->remove_contained__impl(key, hash_(key));
430 : slots_(slots), total_slots_(total_slots), current_slot_(
current_slot)
436 while (++current_slot_ < total_slots_) {
437 if (slots_[current_slot_].is_occupied()) {
448 return copied_iterator;
453 return *slots_[current_slot_].key();
458 return slots_[current_slot_].key();
465 return a.current_slot_ !=
b.current_slot_;
476 return slots_[current_slot_];
483 if (slots_[
i].is_occupied()) {
484 return Iterator(slots_.data(), slots_.size(),
i);
492 return Iterator(slots_.data(), slots_.size(), slots_.size());
503 Slot &slot =
const_cast<Slot &
>(it.current_slot());
518 for (Slot &slot : slots_) {
519 if (slot.is_occupied()) {
520 const Key &key = *slot.key();
521 if (predicate(key)) {
527 return prev_size - this->
size();
545 return this->count_collisions__impl(key, hash_(key));
553 std::destroy_at(
this);
566 for (Slot &slot : slots_) {
572 occupied_and_removed_slots_ = 0;
581 this->realloc_and_reinsert(this->
size());
589 return occupied_and_removed_slots_ - removed_slots_;
597 return occupied_and_removed_slots_ == removed_slots_;
605 return slots_.size();
613 return removed_slots_;
630 return sizeof(Slot) * slots_.size();
639 if (usable_slots_ < n) {
640 this->realloc_and_reinsert(n);
650 if (a.
size() >
b.size()) {
654 for (
const Key &key : a) {
655 if (
b.contains(key)) {
672 if (a.
size() !=
b.size()) {
675 for (
const Key &key : a) {
676 if (!
b.contains(key)) {
691 int64_t total_slots, usable_slots;
700 if (this->
size() == 0) {
705 this->noexcept_reset();
709 occupied_and_removed_slots_ = 0;
710 usable_slots_ = usable_slots;
711 slot_mask_ = new_slot_mask;
716 SlotArray new_slots(total_slots);
719 for (Slot &slot : slots_) {
720 if (slot.is_occupied()) {
721 this->add_after_grow(slot, new_slots, new_slot_mask);
725 slots_ = std::move(new_slots);
728 this->noexcept_reset();
732 occupied_and_removed_slots_ -= removed_slots_;
733 usable_slots_ = usable_slots;
735 slot_mask_ = new_slot_mask;
738 void add_after_grow(Slot &old_slot, SlotArray &new_slots,
const uint64_t new_slot_mask)
743 Slot &slot = new_slots[slot_index];
744 if (slot.is_empty()) {
745 slot.occupy(std::move(*old_slot.key()),
hash);
756 void noexcept_reset() noexcept
758 Allocator allocator = slots_.allocator();
760 new (
this)
Set(NoExceptConstructor(), allocator);
763 template<
typename ForwardKey>
764 bool contains__impl(
const ForwardKey &key,
const uint64_t hash)
const
767 if (slot.is_empty()) {
770 if (slot.contains(key, is_equal_,
hash)) {
777 template<
typename ForwardKey>
778 const Key &lookup_key__impl(
const ForwardKey &key,
const uint64_t hash)
const
783 if (slot.contains(key, is_equal_,
hash)) {
790 template<
typename ForwardKey>
791 const Key *lookup_key_ptr__impl(
const ForwardKey &key,
const uint64_t hash)
const
794 if (slot.contains(key, is_equal_,
hash)) {
797 if (slot.is_empty()) {
804 template<
typename ForwardKey>
void add_new__impl(ForwardKey &&key,
const uint64_t hash)
808 this->ensure_can_add();
811 if (slot.is_empty()) {
812 slot.occupy(std::forward<ForwardKey>(key),
hash);
814 occupied_and_removed_slots_++;
821 template<
typename ForwardKey>
bool add__impl(ForwardKey &&key,
const uint64_t hash)
823 this->ensure_can_add();
826 if (slot.is_empty()) {
827 slot.occupy(std::forward<ForwardKey>(key),
hash);
829 occupied_and_removed_slots_++;
832 if (slot.contains(key, is_equal_,
hash)) {
839 template<
typename ForwardKey>
bool add_overwrite__impl(ForwardKey &&key,
const uint64_t hash)
841 this->ensure_can_add();
844 if (slot.is_empty()) {
845 slot.occupy(std::forward<ForwardKey>(key),
hash);
847 occupied_and_removed_slots_++;
850 if (slot.contains(key, is_equal_,
hash)) {
851 Key &stored_key = *slot.key();
852 stored_key = std::forward<ForwardKey>(key);
860 template<
typename ForwardKey>
bool remove__impl(
const ForwardKey &key,
const uint64_t hash)
863 if (slot.contains(key, is_equal_,
hash)) {
868 if (slot.is_empty()) {
875 template<
typename ForwardKey>
876 void remove_contained__impl(
const ForwardKey &key,
const uint64_t hash)
881 if (slot.contains(key, is_equal_,
hash)) {
890 template<
typename ForwardKey>
891 const Key &lookup_key_or_add__impl(ForwardKey &&key,
const uint64_t hash)
893 this->ensure_can_add();
896 if (slot.contains(key, is_equal_,
hash)) {
899 if (slot.is_empty()) {
900 slot.occupy(std::forward<ForwardKey>(key),
hash);
902 occupied_and_removed_slots_++;
909 template<
typename ForwardKey>
915 if (slot.contains(key, is_equal_,
hash)) {
918 if (slot.is_empty()) {
926 void ensure_can_add()
928 if (occupied_and_removed_slots_ >= usable_slots_) {
929 this->realloc_and_reinsert(this->
size() + 1);
930 BLI_assert(occupied_and_removed_slots_ < usable_slots_);
939template<
typename 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
unsigned long long int uint64_t
static int64_t inline_buffer_capacity()
void reinitialize(const int64_t new_size)
void print(const char *name) const
constexpr 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
static constexpr int64_t compute_total_slots(int64_t min_usable_slots, uint8_t numerator, uint8_t denominator)
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)
const std::string & const_reference
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)
bool add_overwrite_as(ForwardKey &&key)
Set(const std::initializer_list< Key > &values)
int64_t size_in_bytes() const
void clear_and_keep_capacity()
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)
const std::string * const_pointer
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)
bool add_overwrite(Key &&key)
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)
bool add_overwrite(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)
Container & copy_assign_container(Container &dst, const Container &src)
Set< Key, InlineBufferCapacity, ProbingStrategy, Hash, IsEqual, Slot, RawAllocator > RawSet
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
SimpleSetSlot< Key > type