15 #include <type_traits> 18 #include "CompressedPair.h" 49 template <
typename T,
typename =
void>
52 static constexpr
const bool value =
false;
56 struct is_iterator<T,
std::enable_if_t<!std::is_same_v<typename std::iterator_traits<T>::value_type, void>>>
58 static constexpr
const bool value =
true;
110 using list_iterator =
typename list_type::iterator;
111 using const_list_iterator =
typename list_type::const_iterator;
134 using list_iterator::list_iterator;
135 using list_iterator::operator=;
147 static_cast<const list_iterator&>(*this).to_non_const()
165 public const_list_iterator
174 const_list_iterator(it)
180 const_list_iterator(it)
190 using const_list_iterator::const_list_iterator;
191 using const_list_iterator::operator=;
197 static_cast<const const_list_iterator&>(*this).to_non_const()
207 using vector_iterator =
typename vector_type::iterator;
208 using const_vector_iterator =
typename vector_type::const_iterator;
263 template <
bool IsConst>
264 struct BucketIterator:
265 private std::conditional_t<IsConst, const_iterator, iterator>
268 using self_type = BucketIterator<IsConst>;
269 using base_type = std::conditional_t<IsConst, const_iterator, iterator>;
271 using value_type =
typename base_type::value_type;
272 using reference =
typename base_type::reference;
273 using pointer =
typename base_type::pointer;
275 using iterator_category =
typename base_type::iterator_category;
277 BucketIterator() =
default;
279 friend bool operator==(
const BucketIterator<IsConst>& left,
const BucketIterator<IsConst>& right)
281 if((left.bucket_ != right.bucket_) or (left.mask_ != right.mask_))
287 (left.get_pos().is_null() or left.is_past_the_end())
288 and (right.get_pos().is_null() or right.is_past_the_end())
293 return left.get_pos() == right.get_pos();
296 friend bool operator!=(
const BucketIterator<IsConst>& left,
const BucketIterator<IsConst>& right)
297 {
return not (left == right); }
312 using base_type::operator->;
313 using base_type::operator*;
317 base_type(pos), bucket_(bucket), mask_(table_size - 1u)
322 bool is_past_the_end()
const 324 assert(not get_pos().is_null());
327 return get_pos().is_end() or ((get_pos()->hash & mask_) != bucket_);
330 BucketIterator<false> to_non_const()
const 332 return BucketIterator<false>(
333 get_pos().to_non_const(), bucket_, mask_ + 1
337 const base_type& get_pos()
const 338 {
return static_cast<const base_type&
>(*this); }
341 {
return static_cast<base_type&
>(*this); }
345 template <
class,
class,
class>
355 void _assert_invariants(
bool check_load_factor =
false)
const 357 list_._assert_invariants();
358 assert(table_size() > 0u);
359 assert(((table_size() & (table_size() - 1)) == 0u) and
"Table size not a power of two.");
360 assert(max_load_factor_ > 0.0);
362 assert(iter_dist >= 0);
363 assert(static_cast<size_type>(iter_dist) == size());
364 assert(
std::all_of(table_.begin(), table_.end(), [](
const auto& v){
return v.is_null() or not v.is_end();}));
365 for(
size_type i = 0; i < bucket_count(); ++i)
371 [](
const auto& l,
const auto& r){
return l.hash < r.hash; }
373 assert(
std::all_of(begin(i), end(i), [&](
const auto& v){
return bucket_index(v.hash) == i; }));
377 if(check_load_factor)
378 assert(load_factor_satisfied());
400 const HashFn& hash = HashFn(),
401 const KeyEqual& equal = KeyEqual(),
402 const Allocator& alloc = Allocator()
416 AnySet(bucket_count, HashFn(), KeyEqual(), alloc)
428 AnySet(bucket_count, hash, KeyEqual(), alloc)
447 template <
class InputIt>
452 const HashFn& hash = HashFn(),
453 const KeyEqual& equal = KeyEqual(),
454 const Allocator& alloc = Allocator()
456 AnySet(bucket_count, hash, equal, alloc)
473 template <
class InputIt>
478 const Allocator& alloc
480 AnySet(first, last, bucket_count, HashFn(), KeyEqual(), alloc)
498 template <
class InputIt>
504 const Allocator& alloc
506 AnySet(first, last, bucket_count, hash, KeyEqual(), alloc)
522 max_load_factor_(other.max_load_factor_)
526 assert(size() == 0u);
528 while(not tmp.empty())
530 node =
std::move(tmp.pop(tmp.begin()).first);
532 assert(not static_cast<bool>(node));
546 list_(other.list_,
list_type::make_copy),
547 table_(0, other.alloc_socca()),
548 max_load_factor_(other.max_load_factor_)
550 table_.resize(other.table_.
size());
552 assert(size() == 0u);
554 while(not tmp.empty())
556 node =
std::move(tmp.pop(tmp.begin()).first);
558 assert(not static_cast<bool>(node));
572 list_(
std::move(other.list_)),
573 table_(
std::move(other.table_), alloc),
574 max_load_factor_(other.max_load_factor_)
576 fix_table_after_move();
577 assert(other.empty());
578 if(other.table_.size() == 0u)
579 other.table_.assign(1u,
iterator());
591 list_(
std::move(other.list_)),
592 table_(
std::move(other.table_)),
593 max_load_factor_(other.max_load_factor_)
595 fix_table_after_move();
596 assert(other.empty());
597 if(other.table_.size() == 0u)
598 other.table_.assign(1u,
iterator());
619 const HashFn& hash = HashFn(),
620 const KeyEqual& equal = KeyEqual(),
621 const Allocator& alloc = Allocator()
623 AnySet(ilist.begin(), ilist.end(), bucket_count, hash, equal, alloc)
644 const Allocator& alloc
646 AnySet(ilist, bucket_count, HashFn(), KeyEqual(), alloc)
669 const Allocator& alloc
671 AnySet(ilist, bucket_count, hash, KeyEqual(), alloc)
689 template <
class ... T>
692 size_type bucket_count = 2 * (
sizeof...(T)),
693 const HashFn& hash = HashFn(),
694 const KeyEqual& equal = KeyEqual(),
695 const Allocator& alloc = Allocator()
697 AnySet(bucket_count, hash, equal, alloc)
700 [&](
auto&& ... args) {
701 this->arg_insert(
std::forward<decltype(args)>(args)...);
719 template <
class ... T>
723 const Allocator& alloc
725 AnySet(
std::move(tup), bucket_count, HashFn(), KeyEqual(), alloc)
742 template <
class ... T>
747 const Allocator& alloc
749 AnySet(
std::move(tup), bucket_count, hash, KeyEqual(), alloc)
786 max_load_factor_ =
std::move(other.max_load_factor_);
787 fix_table_after_move();
788 assert(other.empty());
789 if(other.table_.size() == 0u)
790 other.table_.assign(1u,
iterator());
816 {
return list_.cbegin(); }
832 {
return list_.begin(); }
840 {
return list_.cend(); }
856 {
return list_.end(); }
870 {
return not
static_cast<bool>(size()); }
878 {
return list_.size(); }
928 template <
class T,
class ... Args>
932 std::is_same_v<T, std::decay_t<T>>,
933 "Cannot emplace references, arrays, or functions into an AnySet." 935 auto node(make_any_value<T, HashFn, KeyEqual>(get_hasher(), std::forward<Args>(args)...));
936 auto hash_v = node->hash;
937 KeyInfo<T> ki{unsafe_cast<
const T&>(*node), hash_v, bucket_index(hash_v)};
938 return insert_impl<true>(ki.value, ki,
std::move(node));
969 template <
class T,
class ... Args>
971 {
return emplace<T>(std::forward<Args>(args)...); }
989 return insert_impl<true>(std::forward<T>(value), make_key_info(value));
1010 {
return insert(std::forward<T>(value)); }
1029 class = std::enable_if_t<
1030 std::is_copy_constructible_v<typename std::iterator_traits<It>::value_type>
1031 or std::is_rvalue_reference_v<decltype(*std::declval<It>())>
1037 return range_insert(first, last, iter_cat{});
1062 class = std::enable_if_t<
1063 (not (std::is_same_v<std::decay_t<T>, std::decay_t<U>> and detail::is_iterator_v<std::decay_t<T>>))
1065 and (not std::is_same_v<std::decay_t<T>,
iterator>)
1071 std::forward<T>(first),
1072 std::forward<U>(second),
1073 std::forward<V>(args) ...
1093 template <
class T,
class = std::enable_if_t<std::is_copy_constructible_v<T>>>
1096 return insert(ilist.
begin(), ilist.
end());
1112 return pop(pos).second;
1132 iterator pos = first.to_non_const();
1139 done = (nxt == last);
1142 return pos.to_non_const();
1157 template <
class T,
class = std::enable_if_t<not (std::is_same_v<const_iterator, T> or std::is_same_v<iterator, T>)>>
1160 auto [pos, found] = find_position(make_key_info(value));
1178 noexcept(std::is_nothrow_swappable_v<vector_type> and std::is_nothrow_swappable_v<pair_type>)
1181 swap(as_pair(), other.as_pair());
1182 swap(list_, other.list_);
1183 swap(table_, other.table_);
1184 swap(max_load_factor_, other.max_load_factor_);
1185 this->fix_table_after_move();
1186 other.fix_table_after_move();
1204 preemptive_reserve(other.
size());
1205 for(
const auto& any_v: other)
1207 auto [pos, found] = find_position(make_key_info(any_v));
1214 unsafe_splice_at(pos, any_v.clone());
1217 assert(load_factor_satisfied());
1246 preemptive_reserve(other.size());
1247 for(
auto pos = other.begin(); pos != other.end(); )
1249 auto [ins_pos, found] = find_position(make_key_info(*pos));
1257 std::tie(node, pos) = other.pop(pos);
1258 unsafe_splice_at(ins_pos,
std::move(node));
1282 find_position(make_key_info(value)).second
1297 auto [pos, found] = find_position(make_key_info(value));
1315 return static_cast<const self_type*
>(
this)->find(value).to_non_const();
1331 auto pos = find(value);
1351 auto [first, last] =
static_cast<const self_type*
>(
this)->equal_range(value);
1353 first.to_non_const(),
1369 return contains(any_v);
1382 {
return find_matching_value(any_v) != cend(); }
1396 return count(value);
1409 {
return find_matching_value(value) != cend(); }
1425 assert(buck < bucket_count());
1437 {
return cbegin(buck); }
1447 {
return cbegin(buck).to_non_const(); }
1460 assert(buck < bucket_count());
1474 {
return cend(buck); }
1486 {
return cend(buck).to_non_const(); }
1494 {
return table_size(); }
1504 while(maxm > table_.max_size())
1518 assert(buck < bucket_count());
1533 {
return bucket_index(get_hasher()(value)); }
1550 max_load_factor_ = f;
1559 {
return max_load_factor_; }
1567 {
return static_cast<double>(size()) / table_size(); }
1583 assert(bcount > 0u);
1584 auto load_factor_good = [&]() {
1585 return (static_cast<double>(size()) / bcount) <= max_load_factor_;
1587 if(nbuckets < bcount)
1591 while(nbuckets < bcount and load_factor_good())
1593 if((bcount == bucket_count()) and load_factor_good())
1597 else if(nbuckets > bcount)
1599 assert(max_bucket_count() >= nbuckets);
1600 while(nbuckets > bcount)
1602 assert(bcount > 0u);
1606 while(not load_factor_good())
1608 if(bcount > bucket_count())
1610 else if(bcount < bucket_count())
1611 shrink_table(bcount);
1627 rehash(static_cast<size_type>(
std::ceil(count / max_load_factor())));
1641 {
return get_hasher(); }
1649 {
return get_key_equal(); }
1657 {
return table_.get_allocator(); }
1671 {
return left.
swap(right); }
1691 const auto& iter_set = (left.table_size() > right.table_size()) ? right : left;
1693 const auto& search_set = (&left == &iter_set) ? right : left;
1694 for(
const auto& item: iter_set)
1696 auto pos = search_set.find_matching_value(item);
1719 {
return not (left == right); }
1745 assert(not pos_.is_end());
1746 assert(not pos_.is_null());
1748 iterator pos = pos_.to_non_const();
1749 size_type buck_idx = iter_bucket_index(pos);
1750 iterator bucket_head = table_[buck_idx];
1752 assert(not bucket_head.is_null());
1753 assert(not bucket_head.is_end());
1755 if(bucket_head == pos)
1758 auto [node, next] =
std::move(list_.pop(pos));
1766 if(
size_type next_idx = iter_bucket_index(next); next_idx != buck_idx)
1775 table_[next_idx] = next;
1782 assert(table_[buck_idx] == next);
1789 auto [node, next] =
std::move(list_.pop(pos));
1796 if(
size_type next_idx = iter_bucket_index(next); next_idx != buck_idx)
1802 table_[next_idx] = next;
1809 assert(table_[buck_idx] == next);
1827 {
return pos->clone(); }
1843 auto [pos, found] = find_position(make_key_info(*node));
1872 {
return splice_or_copy(
std::move(other), pos); }
1893 {
return splice_or_copy(
std::move(other), first, last); }
1921 template <
class T,
class = std::enable_if_t<std::is_same_v<std::decay_t<T>, self_type>>>
1923 ->
std::pair<decltype(other.begin()), decltype(other.begin())>
1926 return std::make_pair(first.to_non_const(), last.to_non_const());
1932 std::tie(std::ignore, pos, std::ignore) = splice_or_copy(std::forward<T>(other), pos);
1965 template <
class T,
class = std::enable_if_t<std::is_same_v<std::decay_t<T>, self_type>>>
1969 using tuple_t =
std::tuple<iterator, decltype(other.begin()),
bool>;
1970 assert(not pos.is_end());
1971 auto ki = make_key_info(*pos);
1972 auto [ins_pos_, found] = find_position(ki);
1973 auto ins_pos = ins_pos_.to_non_const();
1975 return tuple_t(ins_pos,
std::next(pos).to_non_const(),
false);
1977 std::is_rvalue_reference_v<decltype(other)>
1978 and not std::is_const_v<std::remove_reference_t<decltype(other)>>
1981 auto [node, next] = other.pop(pos);
1984 assert(load_factor_satisfied());
1986 safely_splice_at(ins_pos, ki,
std::move(node)), next.to_non_const(), true
1993 other.unsafe_splice_at(pos,
std::move(node));
1999 assert(load_factor_satisfied());
2001 safely_splice_at(ins_pos, ki, other.dup(pos)),
2012 void fix_table_after_move()
2015 table_[iter_bucket_index(begin())] = begin();
2018 float load_factor(
size_type extra)
const noexcept
2019 {
return static_cast<double>(size() + extra) / table_size(); }
2021 bool load_factor_satisfied(
size_type extra = 0)
const 2022 {
return load_factor(extra) <= max_load_factor(); }
2026 return safely_splice_at(pos, make_key_info(*node),
std::move(node));
2029 template <
class Value>
2035 iterator ins_pos = unsafe_splice_at(pos, ki,
std::move(node));
2037 if(not load_factor_satisfied())
2043 struct RollbackScopeGuard {
2048 ~RollbackScopeGuard()
2057 } guard{*
this, pos,
false};
2063 grow_table(2 * table_size());
2069 auto buck_idx = bucket_index(ki.hash);
2070 auto buck_pos = table_[buck_idx];
2071 assert(not buck_pos.is_null());
2072 assert(not buck_pos.is_end());
2076 assert(iter_bucket_index(buck_pos) == buck_idx);
2078 return buck_pos.to_non_const();
2087 template <
class Value>
2088 iterator initialize_bucket(
const KeyInfo<Value>& ki,
node_handle&& node)
2090 assert(table_[ki.bucket].is_null());
2091 return table_[ki.bucket] = list_.push_back(
std::move(node));
2096 return unsafe_splice_at(pos, make_key_info(*node),
std::move(node));
2099 template <
class Value>
2103 return initialize_bucket(ki,
std::move(node));
2104 else if(pos.is_end())
2105 return list_.splice(pos,
std::move(node));
2107 size_type buck_idx = iter_bucket_index(pos);
2108 iterator ins_pos = list_.splice(pos,
std::move(node));
2109 if(buck_idx != ki.bucket)
2115 assert(iter_bucket_index(next_pos) == buck_idx);
2116 table_[buck_idx] = next_pos;
2121 template <
class Value>
2122 bool insertion_compare(
const Value& value,
const value_type& any_v)
const 2123 {
return compare(value, any_v, get_key_equal()); }
2125 template <
class Value>
2126 bool insertion_compare(
const value_type& any_v,
const Value& value)
const 2127 {
return compare(any_v, value, get_key_equal()); }
2129 template <
class Value>
2130 std::size_t get_hash_value(
const Value& value)
const 2132 if constexpr(std::is_same_v<Value, value_type>)
2135 return get_hasher()(value);
2140 assert(not pos.is_end());
2141 return bucket_index(pos->hash);
2144 template <
class Value>
2145 KeyInfo<Value> make_key_info(
const Value& val)
const 2147 return make_key_info(val, get_hash_value(val));
2150 template <
class Value>
2151 KeyInfo<Value> make_key_info(
const Value& val,
std::size_t hash_v)
const 2153 return KeyInfo<Value>{val, hash_v, bucket_index(hash_v)};
2156 template <
class Value>
2159 auto ki = make_key_info(value);
2160 auto [pos, last] = get_bucket_start(ki);
2161 if(pos.is_null() or (not last.is_null()))
2164 while((not pos.is_end()) and (pos->hash == ki.hash))
2173 template <
class ... T>
2174 std::bitset<
sizeof...(T)> arg_insert(T&& ... args)
2178 preemptive_reserve(
sizeof...(args));
2181 (bs.set(pos++, insert_impl<false>(std::forward<T>(args)).second) , ...);
2183 assert(load_factor() <= max_load_factor());
2191 while(first != last)
2192 count +=
static_cast<size_type>(insert_impl<true>(*first++).second);
2196 template <class It, class = std::enable_if_t<std::is_copy_constructible_v<typename std::iterator_traits<It>::value_type>>>
2201 while(first != last)
2202 count +=
static_cast<size_type>(insert_impl<false>(*first++).second);
2203 assert(load_factor() <= max_load_factor());
2209 auto new_count = size() + ins_count;
2210 size_type new_table_size = table_size();
2211 assert(new_table_size > 0u);
2212 auto compute_new_load_factor = [&](){
2213 return (static_cast<double>(new_count) / new_table_size);
2215 while(compute_new_load_factor() > max_load_factor())
2216 new_table_size *= 2;
2217 if(new_table_size > table_size())
2218 grow_table(new_table_size);
2221 template <
bool CheckLoadFactor,
class T>
2224 return insert_impl<CheckLoadFactor>(
2225 std::forward<T>(value), make_key_info(value), nullptr
2229 template <
bool CheckLoadFactor,
class T>
2232 const KeyInfo<std::decay_t<T>>& ki,
2236 using ValueType = std::decay_t<T>;
2238 auto [pos, found] = find_position(ki);
2243 if constexpr(std::is_constructible_v<ValueType, decltype(value)>)
2247 existing = make_any_value<std::decay_t<T>, HashFn, KeyEqual>(
2248 ki.hash, std::forward<T>(value)
2257 if constexpr(CheckLoadFactor)
2258 ins_pos = safely_splice_at(pos, ki,
std::move(existing));
2260 ins_pos = unsafe_splice_at(pos, ki,
std::move(existing));
2261 assert(not ins_pos.is_null());
2262 assert(not ins_pos.is_end());
2266 ins_pos = pos.to_non_const();
2271 void shrink_table(
size_type new_size) noexcept
2273 assert(new_size < table_size());
2275 assert((new_size & (new_size - 1)) == 0u);
2277 table_.assign(new_size, iterator());
2280 assert(size() == 0u);
2282 while(not tmp.empty())
2284 node =
std::move(tmp.pop(tmp.begin()).first);
2286 assert(not static_cast<bool>(node));
2288 assert(tmp.empty());
2293 assert(new_size > table_size());
2295 assert((new_size & (new_size - 1)) == 0u);
2296 table_.assign(new_size, iterator());
2298 assert(size() == 0u);
2300 while(not tmp.empty())
2302 node =
std::move(tmp.pop(tmp.begin()).first);
2304 assert(not static_cast<bool>(node));
2306 assert(tmp.empty());
2317 template <
class Value>
2319 {
return find_position(ki, get_key_equal()); }
2331 template <
class Value,
class Comp>
2334 if(
auto [pos, last] = get_bucket_start(ki); pos.is_null() and last.is_null())
2339 else if(last.is_null())
2341 assert(pos->hash >= ki.hash);
2342 for(; (not pos.is_end()) and pos->hash == ki.hash; ++pos)
2344 if(compare(ki.value, *pos, comp))
2355 assert(not pos.is_null());
2356 assert(last == cend() or iter_bucket_index(last) != ki.bucket);
2374 template <
class Value>
2377 auto first = table_[ki.bucket];
2381 assert(not first.is_end());
2385 if(pos_hash >= ki.hash)
2390 pos_hash = pos->hash;
2391 }
while(bucket_index(pos_hash) == ki.bucket);
2396 {
return table_.size(); }
2399 {
return table_size() - 1; }
2402 {
return hash & get_mask(); }
2405 {
return left.compare_to(right, get_key_equal()); }
2409 {
return static_cast<pair_type&
>(*this); }
2412 {
return static_cast<pair_type&&
>(*this); }
2415 {
return static_cast<const pair_type&
>(*this); }
2418 {
return static_cast<const pair_type&&
>(*this); }
2420 HashFn& get_hasher() &
2421 {
return as_pair().first(); }
2423 HashFn&& get_hasher() &&
2426 const HashFn& get_hasher()
const &
2427 {
return as_pair().first(); }
2429 const HashFn&& get_hasher()
const &&
2432 KeyEqual& get_key_equal() &
2433 {
return as_pair().second(); }
2435 KeyEqual&& get_key_equal() &&
2438 const KeyEqual& get_key_equal()
const &
2439 {
return as_pair().second(); }
2441 const KeyEqual&& get_key_equal()
const &&
2446 float max_load_factor_{1.0};
2469 te::
AnySet<HashFn, KeyEqual, Allocator> make_anyset(Elements&& ... elements)
Forward iterator type returned from const operations on AnySet instances.
Definition: AnySet.h:164
AnySet & update(AnySet &&other)
Moves elements from other into the set.
Definition: AnySet.h:1244
AnySet(size_type bucket_count, const Allocator &alloc)
Construct an empty AnySet instance. Sets max_load_factor() to 1.0.
Definition: AnySet.h:415
AnySet(std::tuple< T ... > &&tup, size_type bucket_count, const Allocator &alloc)
Construct an AnySet with the contents of the tuple tup. Sets max_load_factor() to 1...
Definition: AnySet.h:720
BucketIterator< true > const_local_iterator
Const iterator type suitable for traversal through an individual bucket.
Definition: AnySet.h:353
value_type * pointer
Pointer to AnyValue.
Definition: AnySet.h:237
std::pair< const_iterator, const_iterator > equal_range(const T &value) const
Obtain a const_iterator range to the elements that have the same type as, and compares equal to the v...
Definition: AnySet.h:1329
AnyValue< HashFn, KeyEqual > value_type
AnyValue.
Definition: AnySet.h:219
T forward_as_tuple(T... args)
HashFn hasher
Hash function type.
Definition: AnySet.h:227
const_iterator end() const
Get a past-the-end const_iterator for this set.
Definition: AnySet.h:847
size_type count(const T &value) const
Returns the number of elements with a value that have the same type as, and compare equal to the valu...
Definition: AnySet.h:1279
const value_type * const_pointer
Pointer to const AnyValue.
Definition: AnySet.h:239
Forward iterator type returned from non-const operations on AnySet instances.
Definition: AnySet.h:125
AnySet(InputIt first, InputIt last, size_type bucket_count, const HashFn &hash, const Allocator &alloc)
Construct an AnySet instance from the range [first, last). Sets max_load_factor() to 1...
Definition: AnySet.h:499
bool contains_value(const value_type &any_v) const
Check if this contains the same value as another set.
Definition: AnySet.h:1367
node_handle dup(const_iterator pos) const
Copy and return the element at the position pointed to by pos.
Definition: AnySet.h:1826
size_type insert(std::initializer_list< T > ilist)
Inserts elements from the list ilist that do not already exist in the set. If multiple elements in th...
Definition: AnySet.h:1094
std::pair< iterator, node_handle > push(node_handle &&node)
Insert the value pointed to by node to this.
Definition: AnySet.h:1841
const_iterator begin() const
Get a const_iterator to the first element in the set.
Definition: AnySet.h:823
bool contains_eq(const T &value) const
Check if this contains value.
Definition: AnySet.h:1408
std::pair< iterator, bool > insert([[maybe_unused]] const_iterator hint, T &&value)
Inserts an element into the set, if the set doesn't already contain an element with an equivalent val...
Definition: AnySet.h:1009
void reserve(size_type count)
Sets the number of buckets to the number needed to accomodate at least count elements without exceedi...
Definition: AnySet.h:1625
friend void swap(AnySet &left, AnySet &right)
Calls left.swap(right).
Definition: AnySet.h:1670
local_iterator end(size_type buck)
Get a local_iterator to the element one past the least element in the bucket at index buck...
Definition: AnySet.h:1485
size_type size() const noexcept
Gets the number of elements in the set, i.e. std::distance(begin(), end()).
Definition: AnySet.h:877
const_iterator cend() const
Get a past-the-end const_iterator for this set.
Definition: AnySet.h:839
std::pair< iterator, bool > emplace(Args &&... args)
Inserts a new element into the container constructed in-place with the given args if there is no elem...
Definition: AnySet.h:929
void rehash(size_type nbuckets)
Sets the number of buckets to the smallest possible value that is at least as large as nbuckets and r...
Definition: AnySet.h:1580
size_type bucket_count() const noexcept
Get the number of buckets in the set.
Definition: AnySet.h:1493
value_type & reference
Reference to AnyValue.
Definition: AnySet.h:233
AnySet(std::tuple< T ... > &&tup, size_type bucket_count, const HashFn &hash, const Allocator &alloc)
Construct an AnySet with the contents of the tuple tup. Sets max_load_factor() to 1...
Definition: AnySet.h:743
const_local_iterator cend(size_type buck) const
Get a const_local_iterator to the element one past the least element in the bucket at index buck...
Definition: AnySet.h:1458
size_type max_bucket_count() const noexcept
Get the maximum possible number of buckets in the set.
Definition: AnySet.h:1501
typename vector_type::difference_type difference_type
Difference type.
Definition: AnySet.h:223
size_type bucket_size(size_type buck) const
Get the number of elements in the bucket at index buck.
Definition: AnySet.h:1516
AnySet(AnySet &&other, const Allocator &alloc)
Move constructs an AnySet instance from other. Constructs the set with the copy of the contents of ot...
Definition: AnySet.h:570
const_local_iterator end(size_type buck) const
Get a const_local_iterator to the element one past the least element in the bucket at index buck...
Definition: AnySet.h:1473
AnySet(InputIt first, InputIt last, size_type bucket_count, const Allocator &alloc)
Construct an AnySet instance from the range [first, last). Sets max_load_factor() to 1...
Definition: AnySet.h:474
bool empty() const noexcept
Checks if the set has no elements, i.e. whether begin() == end().
Definition: AnySet.h:869
AnySet(AnySet &&other)
Copy constructs an AnySet instance from other. Constructs the set with the copy of the contents of ot...
Definition: AnySet.h:589
AnySet(InputIt first, InputIt last, size_type bucket_count=0, const HashFn &hash=HashFn(), const KeyEqual &equal=KeyEqual(), const Allocator &alloc=Allocator())
Construct an AnySet instance from the range [first, last). Sets max_load_factor() to 1...
Definition: AnySet.h:448
key_equal key_eq() const
Get a copy of the equality comparison function.
Definition: AnySet.h:1648
const_iterator cbegin() const
Get a const_iterator to the first element in the set.
Definition: AnySet.h:815
AnySet(size_type bucket_count, const HashFn &hash, const Allocator &alloc)
Construct an empty AnySet instance. Sets max_load_factor() to 1.0.
Definition: AnySet.h:427
auto splice_or_copy(T &&other, const_iterator first, const_iterator last) -> std::pair< decltype(other.begin()), decltype(other.begin())>
Copies or moves the elements in the range [first, last) from other into this.
Definition: AnySet.h:1922
Primary classes and utility functions for AnySet.
Definition: SetOperations.h:21
Definition: CompressedPair.h:47
AnySet & operator=(AnySet &&other) noexcept(std::is_nothrow_move_assignable_v< vector_type >)
Move assigns the contents of this AnySet instance from the contents of other. Moves the load factor...
Definition: AnySet.h:781
std::pair< iterator, iterator > splice(AnySet &other, const_iterator first, const_iterator last)
Moves the elements in the range [first, last) from other into this.
Definition: AnySet.h:1892
AnySet(size_type bucket_count, const HashFn &hash=HashFn(), const KeyEqual &equal=KeyEqual(), const Allocator &alloc=Allocator())
Construct an empty AnySet instance. Sets max_load_factor() to 1.0.
Definition: AnySet.h:398
float max_load_factor() const noexcept
Get the maximum allowable load factor for the set.
Definition: AnySet.h:1558
std::bitset< 2ull+sizeof...(V)> insert(T &&first, U &&second, V &&... args)
Inserts args if they do not already exist in the set. If multiple values in args have the same type a...
Definition: AnySet.h:1068
AnySet(std::initializer_list< T > ilist, size_type bucket_count, const HashFn &hash, const Allocator &alloc)
Construct an AnySet with the contents of the initializer list ilist. Same as AnySet(init.begin(), init.end()). Sets max_load_factor() to 1.0. If multiple elements in the list compare equivalent, only the first encountered is inserted.
Definition: AnySet.h:665
std::pair< iterator, iterator > equal_range(const T &value)
Obtain an iterator range to the elements that have the same type as, and compares equal to the value...
Definition: AnySet.h:1349
void clear() noexcept
Removes all elements from the container. Invalidates any references, pointers, or iterators referring...
Definition: AnySet.h:899
T select_on_container_copy_construction(T... args)
std::pair< iterator, bool > emplace_hint([[maybe_unused]] const_iterator hint, Args &&... args)
Inserts a new element into the container constructed in-place with the given args if there is no elem...
Definition: AnySet.h:970
std::tuple< iterator, iterator, bool > splice(AnySet &other, const_iterator pos)
Moves the element at position pos from other into this.
Definition: AnySet.h:1871
std::pair< iterator, bool > insert(T &&value)
Inserts an element into the set, if the set doesn't already contain an element with an equivalent val...
Definition: AnySet.h:987
const_local_iterator cbegin(size_type buck) const
Get a const_local_iterator to the first element in the bucket at index buck.
Definition: AnySet.h:1423
local_iterator begin(size_type buck)
Get a local_iterator to the first element in the bucket at index buck.
Definition: AnySet.h:1446
iterator erase(const_iterator pos)
Remove the element at the position pointed to by pos from the set.
Definition: AnySet.h:1110
friend bool operator==(const AnySet &left, const AnySet &right)
Compare the contents of two sets.
Definition: AnySet.h:1686
AnySet(const AnySet &other)
Copy constructs an AnySet instance from other. Constructs the set with the copy of the contents of ot...
Definition: AnySet.h:544
typename vector_type::size_type size_type
Size type.
Definition: AnySet.h:221
AnySet & operator=(const AnySet &other)
Copy assigns the contents of this AnySet instance from the contents of other. Copies the load factor...
Definition: AnySet.h:770
const_local_iterator begin(size_type buck) const
Get a const_local_iterator to the first element in the bucket at index buck.
Definition: AnySet.h:1436
AnySet(std::initializer_list< T > ilist, size_type bucket_count=0, const HashFn &hash=HashFn(), const KeyEqual &equal=KeyEqual(), const Allocator &alloc=Allocator())
Construct an AnySet with the contents of the initializer list ilist. Same as AnySet(init.begin(), init.end()). Sets max_load_factor() to 1.0. If multiple elements in the list compare equivalent, only the first encountered is inserted.
Definition: AnySet.h:616
AnySet & operator=(std::initializer_list< T > ilist)
Assigns the contents of this AnySet instance with the contents of ilist.
Definition: AnySet.h:802
iterator begin()
Get a iterator to the first element in the set.
Definition: AnySet.h:831
size_type max_size() const noexcept
Get the maximum number of elements the container is able to hold due to system or library implementat...
Definition: AnySet.h:887
Generic hash function object.
Definition: AnyHash.h:107
const_iterator find(const T &value) const
Obtain a const_iterator to the element that has the same type as, and compares equal to the value...
Definition: AnySet.h:1295
iterator find(const T &value)
Obtain an iterator to the element that has the same type as, and compares equal to the value...
Definition: AnySet.h:1313
size_type bucket(const T &value) const
Get the bucket index of value.
Definition: AnySet.h:1532
allocator_type get_allocator() const
Get a copy of the allocator.
Definition: AnySet.h:1656
AnySet is an associative container that contains a set of unique objects of any constructible type...
Definition: AnySet.h:104
iterator end()
Get a past-the-end iterator for this set.
Definition: AnySet.h:855
KeyEqual key_equal
Key equality comparator type.
Definition: AnySet.h:225
AnySet(std::tuple< T ... > &&tup, size_type bucket_count=2 *(sizeof...(T)), const HashFn &hash=HashFn(), const KeyEqual &equal=KeyEqual(), const Allocator &alloc=Allocator())
Construct an AnySet with the contents of the tuple tup. Sets max_load_factor() to 1...
Definition: AnySet.h:690
std::pair< node_handle, iterator > pop(const_iterator pos_)
Remove and return the element at the position pointed to by pos from the set.
Definition: AnySet.h:1743
AnySet()
Constructs an empty set with 1 bucket. Sets max_load_factor() to 1.0.
Definition: AnySet.h:389
float load_factor() const noexcept
Get the load factor for the set.
Definition: AnySet.h:1566
BucketIterator< false > local_iterator
Iterator type suitable for traversal through an individual bucket.
Definition: AnySet.h:351
const value_type & const_reference
Reference to const AnyValue.
Definition: AnySet.h:235
AnySet(const AnySet &other, const Allocator &alloc)
Copy constructs an AnySet instance from other. Constructs the set with the copy of the contents of ot...
Definition: AnySet.h:518
void swap(AnySet &other) noexcept(std::is_nothrow_swappable_v< vector_type > and std::is_nothrow_swappable_v< pair_type >)
Exchanges the contents of the set with those of other. Does not invoke any move, copy, or swap operations on individual elements. Additionally exchanges the hash functions, comparison functions, and max_load_factor()s of the sets.
Definition: AnySet.h:1177
AnySet(std::initializer_list< T > ilist, size_type bucket_count, const Allocator &alloc)
Construct an AnySet with the contents of the initializer list ilist. Same as AnySet(init.begin(), init.end()). Sets max_load_factor() to 1.0. If multiple elements in the list compare equivalent, only the first encountered is inserted.
Definition: AnySet.h:641
size_type erase(const T &value)
Remove the element from the set whose type is the same type as value and whose value compares equal t...
Definition: AnySet.h:1158
iterator erase(const_iterator first, const_iterator last)
Remove elements in the range [first, last).
Definition: AnySet.h:1130
auto splice_or_copy(T &&other, const_iterator pos) -> std::tuple< iterator, decltype(other.begin()), bool >
Copies or moves the element at position pos from other into this.
Definition: AnySet.h:1966
bool contains_value_eq(const value_type &any_v) const
Check if this contains the same value as another set.
Definition: AnySet.h:1381
hasher hash_function() const
Get a copy of the hash function.
Definition: AnySet.h:1640
friend bool operator!=(const AnySet &left, const AnySet &right)
Compare the contents of two sets.
Definition: AnySet.h:1718
Allocator allocator_type
Allocator type.
Definition: AnySet.h:229
AnySet & update(const AnySet &other)
Add copies of elements from other.
Definition: AnySet.h:1202
bool contains(const T &value) const
Check if this contains value.
Definition: AnySet.h:1394
size_type insert(It first, It last)
Inserts elements from the range [first, last) that do not already exist in the set. If multiple elements in the range have values that compare equivalent, and there is no such element already in the set, only the first encountered is inserted.
Definition: AnySet.h:1034
void max_load_factor(float f)
Set the maximum possible number of buckets in the set.
Definition: AnySet.h:1547