15#if HX_USE_MACROS_WITH_MODULE
16#error Header does not provide macros alone.
26#include "detail/hxpow2_allocator.hpp"
30#if HX_CPLUSPLUS >= 202002L
32template<
typename node_t_>
33concept hxhash_table_concept_ =
34 requires(node_t_& node_,
const node_t_& const_node_) {
35 sizeof(
typename node_t_::key_t);
42#define hxhash_table_concept_ typename
50 template<hxhash_table_concept_ node_t_,
typename deleter_t_,
bool multi_t_,
65template<
typename key_t_>
72 template<
typename ref_t_>
93 const key_t_&
hash_key(
void)
const {
return m_key_; }
109template<
typename key_t_,
typename value_t_>
124 template<
typename ref_t_>
139 const value_t_&
value(
void)
const {
return m_value_; }
142 value_t_&
value(
void) {
return m_value_; }
150class hxhash_table_base_ {
152 template<hxhash_table_concept_ node_t_,
typename deleter_t_,
bool multi_t_, u
int32_t table_size_bits_>
153 friend class hxhash_table;
154 using hxhash_equal_fn_ = bool(*)(
const hxhash_node_base* node_,
const void* key_);
155 using hxhash_deleter_fn_ = void(*)(hxhash_node_base* node_,
void* context_);
156 static hxsize_t chain_count_multi_(
const hxhash_node_base* head_,
const void* key_,
157 hxhash_equal_fn_ equal_);
158 static void chain_erase_at_(hxhash_node_base** head_, hxhash_node_base* node_);
159 static hxsize_t chain_erase_multi_(hxhash_node_base** head_,
const void* key_,
160 hxhash_equal_fn_ equal_, hxhash_deleter_fn_ deleter_,
void* deleter_context_);
161 static hxhash_node_base* chain_extract_(hxhash_node_base** head_,
const void* key_,
162 hxhash_equal_fn_ equal_);
163 static hxsize_t chain_length_(
const hxhash_node_base* head_);
164 static hxhash_node_base* chain_replace_(hxhash_node_base** head_, hxhash_node_base* node_,
165 const void* key_, hxhash_equal_fn_ equal_);
166 static void table_clear_(hxhash_node_base** table_,
hxsize_t bucket_count_,
167 hxhash_deleter_fn_ deleter_,
void* deleter_context_);
219template<hxhash_table_concept_ node_t_,
221 bool multi_t_ =
false,
226 using key_t =
typename node_t_::key_t;
238 m_current_node_(
hxnull) { }
246#if HX_CPLUSPLUS < 202002L
249 bool operator!=(const const_iterator& x_) const { return !(*this == x_); }
260 void next_bucket_(
void);
264 node_t_* m_current_node_;
305 template<hxrange_concept_ range_t_,
306 hxenable_if_t<!hxis_lvalue_reference<range_t_>(),
int> = 0>
309#if HX_CPLUSPLUS >= 202302L
315 template<
typename self_t_,
typename callable_t_>
317 this self_t_&& self_,
const key_t& key_, callable_t_&& callable_)
325 template<
typename self_t_,
typename callable_t_>
327 this self_t_&& self_,
const_iterator it_, callable_t_&& callable_)
351 template<
typename deleter_u_>
352 void clear(deleter_u_&& deleter_)
noexcept;
375 hxenable_if_t<multi_, iterator>
emplace(args_t_&&... args_)
noexcept;
393 template<
typename deleter_u_>
394 hxsize_t erase(
const typename node_t_::key_t& key_, deleter_u_&& deleter_)
noexcept;
443 template<
typename deleter_u_>
452#if HX_CPLUSPLUS >= 202302L
458 template<
typename self_t_,
typename callable_t_>
460 this self_t_&& self_,
const key_t& key_, callable_t_&& callable_)
461 ->
decltype(self_.end());
467 template<
typename self_t_,
typename callable_t_>
469 this self_t_&& self_,
const_iterator it_, callable_t_&& callable_)
470 ->
decltype(self_.end());
508 const typename node_t_::key_t& key_, args_t_&&... args_)
noexcept;
510#if HX_CPLUSPLUS >= 202302L
516 auto value_or(
this self_t_&& self_,
const key_t& key_,
const node_t_* default_value_)
517 ->
decltype(self_.end());
524 ->
decltype(self_.end());
528 static_assert(table_size_bits_ <
hxhash_bits,
"Hash bits must be [0..hxhash_bits)");
537 hxdetail_::hxpow2_allocator_<hxhash_node_base*, table_size_bits_, true> m_table_;
540#include "detail/hxhash_table.inl"
hxdefault_delete - A callable that deletes objects of type T using hxdelete.
Definition hxmemory_manager.h:265
hxhash_node_base - Intrusive hash-chain node base.
Definition hxhash_table.hpp:47
hxhash_t hash_val
Definition hxhash_table.hpp:58
friend class hxhash_table
Definition hxhash_table.hpp:51
hxhash_node_base * hash_next
Definition hxhash_table.hpp:57
friend class hxhash_table_base_
Definition hxhash_table.hpp:49
hxhash_node_base(hxhash_t hash_)
Constructs an unlinked node with the given cached hash.
Definition hxhash_table.hpp:55
const_iterator - A const forward iterator over the elements of the hash table.
Definition hxhash_table.hpp:234
bool operator==(const const_iterator &x_) const
Compares two iterators for equality.
const node_t_ * operator->(void) const
Dereferences the iterator to access the current node_t's pointer.
const_iterator operator++(int)
Advances the iterator to the next element (post-increment).
Definition hxhash_table.hpp:242
const_iterator(void)
Constructs an iterator pointing to the end of the hash table.
Definition hxhash_table.hpp:237
const_iterator & operator++(void)
Advances the iterator to the next element.
const node_t_ & operator*(void) const
Dereferences the iterator to access the current node_t.
iterator - A mutable iterator that can modify the elements of the hash table.
Definition hxhash_table.hpp:271
node_t_ & operator*(void) const
Dereferences the iterator to access the current node_t.
iterator(void)
Constructs an iterator pointing to the end of the hash table.
Definition hxhash_table.hpp:274
iterator operator++(int)
Advances the iterator to the next element (post-increment).
Definition hxhash_table.hpp:278
iterator & operator++(void)
Advances the iterator to the next element.
Definition hxhash_table.hpp:276
node_t_ * operator->(void) const
Dereferences the iterator to access the current node_t's pointer.
hxhash_table_map_node(const key_t_ &key_)
Default-initializes a node.
Definition hxhash_table.hpp:118
hxhash_table_map_node(const key_t_ &key_, ref_t_ &&value_)
Constructs a node whose value is copy- or move-initialized.
Definition hxhash_table.hpp:125
const value_t_ & value(void) const
Returns the stored value.
Definition hxhash_table.hpp:139
value_t_ & value(void)
Returns the stored value, allowing mutation.
Definition hxhash_table.hpp:142
key_t_ key_t
Definition hxhash_table.hpp:112
value_t_ value_t
Definition hxhash_table.hpp:113
bool operator<(const hxhash_table_map_node &x_) const
Returns true if this node is ordered before x, comparing keys first and then values with hxkey_equal ...
bool operator==(const hxhash_table_map_node &x_) const
Returns true if this node and x have equal keys and values, using hxkey_equal.
hxhash_t hash_value(void) const
Returns the cached hash value for the stored key.
Definition hxhash_table.hpp:97
const key_t_ & hash_key(void) const
The key and hash identify the node_t and should not change once added.
Definition hxhash_table.hpp:93
bool operator<(const hxhash_table_set_node &x_) const
Returns true if this node's key is ordered before x's key, using hxkey_less.
Definition hxhash_table.hpp:90
hxhash_table_set_node(ref_t_ &&key_)
Constructs a node from the key and caches its hash for reuse.
Definition hxhash_table.hpp:73
static hxhash_t hash_value(const key_t_ &key_)
Returns the hash value computed for key.
Definition hxhash_table.hpp:102
key_t_ key_t
Definition hxhash_table.hpp:68
bool operator==(const hxhash_table_set_node &x_) const
Returns true if this node and x have equal keys, using hxkey_equal.
Definition hxhash_table.hpp:85
hxhash_table_set_node(void)=delete
Assignment is undefined. The key is immutable.
hxhash_table_set_node & operator=(const hxhash_table_set_node &x_)=delete
hxhash_table_set_node(const hxhash_table_set_node &src_)=delete
const deleter_t_ & deleter(void) const
Returns a const reference to the stored deleter.
void clear(deleter_u_ &&deleter_) noexcept
Removes all nodes and if deleter is true then calls deleter() on every node.
bool empty(void) const
Checks if the hash table is empty.
Definition hxhash_table.hpp:378
~hxhash_table(void)
Destructs the hash table and deletes all resources.
Definition hxhash_table.hpp:298
hxhash_table(deleter_t_ deleter_=deleter_t_())
Constructs an empty hash table with a capacity of 2^table_size_bits and an optional deleter instance.
hxsize_t bucket_count(void) const
Returns the number of buckets in the hash table.
Definition hxhash_table.hpp:340
auto value_or(this self_t_ &&self_, const key_t &key_, const node_t_ *default_value_) -> decltype(self_.end())
Returns an iterator to the first node matching key, or an iterator to default_value when lookup fails...
hxenable_if_t<!multi_, iterator > try_emplace(const typename node_t_::key_t &key_, args_t_ &&... args_) noexcept
try_emplace - Returns an iterator to the node if it was inserted, or an iterator to the existing node...
iterator erase(const const_iterator &it_) noexcept
Removes and calls the stored deleter on the node_t referenced by it.
hxsize_t erase(const typename node_t_::key_t &key_) noexcept
Removes and calls the stored deleter on nodes with an equivalent key.
iterator find(const typename node_t_::key_t &key_, const const_iterator &previous_=const_iterator())
hxsize_t count(const typename node_t_::key_t &key_) const
Counts the number of nodes with the given key.
deleter_t_ & deleter(void)
hxptr< node_t_, deleter_t_ > replace(node_t_ *ptr_) noexcept
replace - Replaces the first node_t matching ptr's key, if any, with ptr and returns an hxptr owning ...
void add_range(range_t_ &&range_) noexcept
Links each node_t from a temporary range into this hash table by address, exactly as insert(node_t*) ...
iterator insert(hxptr< node_t_, deleter_u_ > &&ptr_) noexcept
insert - Returns an iterator to the inserted node.
hxsize_t release_key(const typename node_t_::key_t &key_)
Removes all nodes matching the given key without deleting them.
hxsize_t size(void) const
Returns the number of elements in the hash table.
Definition hxhash_table.hpp:494
bool has_value(const key_t &key_) const
Returns true if a node matching key exists.
auto and_then(this self_t_ &&self_, const_iterator it_, callable_t_ &&callable_) -> hxremove_cvref_t< decltype(hxforward< callable_t_ >(callable_)(hxforward_like< self_t_ >(hxdeclval< const node_t_ & >())))>
Iterator overload of and_then.
iterator end(void)
Returns an iterator pointing to the end of the hash table.
Definition hxhash_table.hpp:384
hxptr< node_t_, deleter_t_ > extract(const typename node_t_::key_t &key_) noexcept
extract - Returns an hxptr owning the first node_t with the given key, or an empty hxptr if no matchi...
iterator begin(void)
Returns an iterator pointing to the beginning of the hash table.
Definition hxhash_table.hpp:337
hxptr< node_t_, deleter_t_ > extract(const const_iterator &it_) noexcept
Removes the node_t referenced by it and returns an hxptr owning it.
const_iterator cbegin(void) const
Returns a const iterator pointing to the beginning of the hash table.
Definition hxhash_table.hpp:343
node_t_ node_t
Definition hxhash_table.hpp:225
iterator insert(node_t_ *ptr_) noexcept
insert - Returns an iterator to the inserted node.
const_iterator find(const typename node_t_::key_t &key_, const const_iterator &previous_=const_iterator()) const
Returns an iterator to a node_t matching key, or end() if none exists.
const_iterator end(void) const
Returns a const iterator pointing to the end of the hash table.
Definition hxhash_table.hpp:381
const_iterator begin(void) const
Returns a const iterator pointing to the beginning of the hash table.
Definition hxhash_table.hpp:334
auto or_else(this self_t_ &&self_, const_iterator it_, callable_t_ &&callable_) -> decltype(self_.end())
Iterator overload of or_else.
const_iterator cend(void) const
Returns a const iterator pointing to the end of the hash table.
Definition hxhash_table.hpp:346
void release_all(void)
Clears the hash table without deleting any nodes.
hxsize_t erase(const typename node_t_::key_t &key_, deleter_u_ &&deleter_) noexcept
Releases all nodes matching key and calls deleter on every node.
auto and_then(this self_t_ &&self_, const key_t &key_, callable_t_ &&callable_) -> hxremove_cvref_t< decltype(hxforward< callable_t_ >(callable_)(hxforward_like< self_t_ >(hxdeclval< node_t_ & >())))>
Returns the result of calling callable with the first node matching key, otherwise returns hxnil.
hxsize_t load_max(void) const
Returns the size of the largest bucket.
void set_size_bits(hxhash_t bits_)
Sets the number of hash bits and allocate memory for the table.
void clear(void) noexcept
Removes all nodes and calls the stored deleter on every node.
Definition hxhash_table.hpp:355
auto or_else(this self_t_ &&self_, const key_t &key_, callable_t_ &&callable_) -> decltype(self_.end())
Returns an iterator to the first node matching key, or the result of calling callable when lookup fai...
auto value_or(this self_t_ &&self_, const_iterator it_, const node_t_ *default_value_) -> decltype(self_.end())
Iterator overload of value_or.
typename node_t_::key_t key_t
Definition hxhash_table.hpp:226
float load_factor(void) const
Returns the average number of nodes per bucket.
hxenable_if_t< multi_, iterator > emplace(args_t_ &&... args_) noexcept
emplace - Returns an iterator to the node constructed with hxnew.
hxptr<T, deleter_t> - A unique owning pointer.
Definition hxptr.hpp:30
hxconvertible_to - A concept that requires one type to be convertible to another.
Definition hxutility.h:255
Similar to std::allocator.
HX_NS_BEGIN_ constexpr hxsize_t hxallocator_dynamic_capacity
hxallocator_dynamic_capacity - A capacity value that allows for dynamic allocation.
Definition hxallocator.hpp:20
User-specializable key-equal, key-less, and key-hash callables.
constexpr bool hxkey_equal(const A_ &a_, const B_ &b_)
hxkey_equal - Returns true if a and b are equivalent, deducing A and invoking hxkey_equal_t<A>.
Definition hxkey.hpp:80
hxhash_t hxkey_hash(const T &x_)
hxkey_hash - Returns the hash of x, deducing T and invoking hxkey_hash_t<T>.
Definition hxkey.hpp:179
constexpr bool hxkey_less(const A_ &a_, const B_ &b_)
hxkey_less - Returns true if a is less than b, deducing A and invoking hxkey_less_t<A>.
Definition hxkey.hpp:115
@ hxsystem_allocator_current
hxsystem_allocator_current - Use current allocation scope.
Definition hxmemory_manager.h:80
HX_C_BEGIN_ typedef unsigned int hxalignment_t
hxalignment_t - A positive integer power of 2 for aligning allocations.
Definition hxmemory_manager.h:62
int hxsystem_allocator_t
hxsystem_allocator_t - This is extendable by the application.
Definition hxmemory_manager.h:75
hxattr_noexcept hxsystem_allocator_t allocator_
Definition hxmemory_manager.h:120
constexpr hxalignment_t hxalignment
hxalignment - The default alignment.
Definition hxmemory_manager.h:67
Read-only range utilities for libhatchet.
#define hxattr_nodiscard
hxattr_nodiscard - Indicates the caller should not discard the return value.
Definition hxsettings.h:98
#define hxattr_flatten
hxattr_flatten - Inline every call inside a function's body into it, recursively, regardless of the c...
Definition hxsettings.h:90
constexpr T && hxforward(hxremove_reference_t< T > &&x_)
hxforward - Implements std::forward.
Definition hxutility.h:353
hxremove_cv_t< hxremove_reference_t< T > > hxremove_cvref_t
hxremove_cvref_t<T> - Returns T with const, volatile, and references removed.
Definition hxutility.h:103
T && hxdeclval(void) noexcept
hxdeclval - Implements std::declval.
constexpr hxforward_like_t_< like_t_, value_t_ > hxforward_like(value_t_ &value_)
hxforward_like<T> - Returns value with the constness and value category of T.
Definition hxutility.h:387
Provides core macros, memory management and feature detection.
constexpr hxhash_t hxhash_bits
hxhash_bits - Number of bits in hxhash_t.
Definition libhatchet.h:285
#define hxnull
hxnull - The null pointer value for a given pointer type represented by the numeric literal 0.
Definition libhatchet.h:280
uint32_t hxhash_t
hxhash_t - Unsigned 32-bit hash value. Expect collisions.
Definition libhatchet.h:210
ptrdiff_t hxsize_t
hxsize_t - A signed size type, same as ssize_t or ptrdiff_t.
Definition libhatchet.h:207