libhatchet
Loading...
Searching...
No Matches
hxslot_map.hpp
Go to the documentation of this file.
1#pragma once
2// SPDX-FileCopyrightText: © 2017-2026 Adrian Johnston.
3// SPDX-License-Identifier: MIT
4// This file is licensed under the MIT license found in the LICENSE.md file.
5
9
10#include "libhatchet.h"
11
12// HX_USE_MACROS_WITH_MODULE allows including macros alongside the module.
13#if HX_USE_MACROS_WITH_MODULE
14#error Header does not provide macros alone.
15#endif
16
17#include "hxallocator.hpp"
18#include "hxutility.h"
19
20HX_NS_BEGIN_
21
23// Makes the mask a compile time constant when non-0.
24template<hxsize_t mask_>
25class hxslot_map_mask_ {
26public:
27 hxinline_constexpr uint32_t get_mask_(void) const { return static_cast<uint32_t>(mask_); }
28 hxinline void set_mask_(uint32_t) const { } // GCOVR_EXCL_LINE. Unreachable code below c++17.
29};
30
31template<>
32class hxslot_map_mask_<hxallocator_dynamic_capacity> {
33public:
34 hxinline hxattr_nodiscard uint32_t get_mask_(void) const { return m_mask_; }
35 hxinline void set_mask_(uint32_t mask_) { m_mask_ = mask_; }
36private:
37 uint32_t m_mask_;
38};
40
41#if HX_CPLUSPLUS >= 202002L
43template<typename T_>
44concept hxslot_map_concept_ = requires(T_& x_) {
45 sizeof(T_);
46 x_.~T_();
47};
49#else
50#define hxslot_map_concept_ typename
51#endif
52
63template<hxslot_map_concept_ T_, uint32_t table_size_bits_=hxallocator_dynamic_capacity>
65public:
66 static_assert(table_size_bits_ < 31u, "Slot index must fit in the low 31-bits of the handle");
67
69 using iterator = T_*;
70
72 using const_iterator = const T_*;
73
74 using value_t = T_;
75
78
81
82#if HX_CPLUSPLUS >= 202302L
88 template<typename self_t_, typename callable_t_>
90 this self_t_&& self_, hxhandle_t handle_, callable_t_&& callable_)
91 -> hxremove_cvref_t<decltype(
92 hxforward<callable_t_>(callable_)(
94#endif // HX_CPLUSPLUS >= 202302L
95
98 hxinline hxattr_flatten const T_* begin(void) const { return this->data(); }
99
100 hxinline hxattr_flatten T_* begin(void) { return this->data(); }
101
104
108 const T_* cbegin(void) const { return this->data(); }
109
112 hxattr_nodiscard const T_* cend(void) const;
113
115 void clear(void) noexcept;
116
119 const T_* data(void) const { return m_values_.data(); }
120
122 T_* data(void) { return m_values_.data(); }
123
127 template<typename... args_t_>
128 hxhandle_t emplace(args_t_&&... args_) noexcept;
129
131 hxinline hxattr_nodiscard bool empty(void) const { return m_size_ == 0u; }
132
135 hxattr_nodiscard const T_* end(void) const;
136
138 T_* end(void) { return this->data() + this->size(); }
139
143 template<typename callable_t_>
144 hxsize_t erase_if(callable_t_&& callable_) noexcept;
145
147 hxattr_nodiscard bool full(void) const;
148
153
157 template<typename... args_t_>
158 hxhandle_t insert(args_t_&&... args_) noexcept;
159
161 hxinline hxattr_nodiscard hxsize_t max_size(void) const { return this->capacity(); }
162
163#if HX_CPLUSPLUS >= 202302L
169 template<typename self_t_, typename callable_t_>
171 this self_t_&& self_, hxhandle_t handle_, callable_t_&& callable_)
172 -> decltype(self_.end());
173#endif // HX_CPLUSPLUS >= 202302L
174
178 bool reset(hxhandle_t handle_) noexcept;
179
184 void set_size_bits(uint32_t bits_);
185
187 hxinline hxattr_nodiscard hxsize_t size(void) const { return static_cast<hxsize_t>(m_size_); }
188
192 hxattr_nodiscard T_* value(hxhandle_t handle_) noexcept;
193
194 hxattr_nodiscard const T_* value(hxhandle_t handle_) const noexcept;
195
196#if HX_CPLUSPLUS >= 202302L
201 template<typename self_t_, typename... args_t_>
203 this self_t_&& self_, hxhandle_t handle_, args_t_&&... args_);
204#endif // HX_CPLUSPLUS >= 202302L
205
206private:
207 // See detail/hxslot_map.inl for the design.
208 static hxinline_constexpr hxsize_t s_capacity_ =
209 table_size_bits_ == hxallocator_dynamic_capacity
211 : static_cast<hxsize_t>(1) << table_size_bits_;
212
213 static hxinline_constexpr hxsize_t s_value_capacity_ =
214 table_size_bits_ == hxallocator_dynamic_capacity
216 : s_capacity_ - 1;
217
218 class slot_t_ {
219 public:
220 uint64_t m_handle_;
221 uint32_t m_index_;
222 uint32_t m_backref_;
223 };
224
225 void build_free_list_(void);
226
227 uint32_t m_size_;
228 hxslot_map_mask_<s_value_capacity_> m_mask_;
231};
232
233#include "detail/hxslot_map.inl"
234HX_NS_END_
hxallocator<1+> - Provides static allocation when capacity is greater than zero.
Definition hxallocator.hpp:25
const T * cend(void) const
Returns a const T* to the end of the values.
hxsize_t max_size(void) const
Returns the maximum number of values that can be stored.
Definition hxslot_map.hpp:161
T * data(void)
Definition hxslot_map.hpp:122
void clear(void) noexcept
Destroys all values and invalidates their handles.
auto and_then(this self_t_ &&self_, hxhandle_t handle_, callable_t_ &&callable_) -> hxremove_cvref_t< decltype(hxforward< callable_t_ >(callable_)(hxforward_like< self_t_ >(hxdeclval< T & >())))>
Returns the result of calling callable with the value referenced by handle, otherwise returns hxnil.
T * value(hxhandle_t handle_) noexcept
Returns a pointer to the value referenced by handle if it resolves, otherwise end().
void set_size_bits(uint32_t bits_)
Sets the number of index bits and allocates memory for the map (only for dynamic capacity).
hxsize_t capacity(void) const
Returns the number of values that can be stored.
auto or_else(this self_t_ &&self_, hxhandle_t handle_, callable_t_ &&callable_) -> decltype(self_.end())
Returns a pointer to the value referenced by handle, or the result of calling callable when the handl...
hxsize_t erase_if(callable_t_ &&callable_) noexcept
Returns the number of values destroyed.
hxsize_t size(void) const
Returns the number of values in the map.
Definition hxslot_map.hpp:187
bool empty(void) const
Checks if the map is empty.
Definition hxslot_map.hpp:131
T value_or(this self_t_ &&self_, hxhandle_t handle_, args_t_ &&... args_)
Returns a copy of the value referenced by handle, or a value constructed from args when the handle do...
bool reset(hxhandle_t handle_) noexcept
Returns true if handle resolved and its value was destroyed.
T * end(void)
Definition hxslot_map.hpp:138
bool full(void) const
Checks if the map is full.
const T * begin(void) const
Returns a const T* to the beginning of the values (alias for data).
Definition hxslot_map.hpp:98
T * iterator
iterator - Random access iterator.
Definition hxslot_map.hpp:69
const T * data(void) const
Returns a const pointer to the first of size contiguous values.
Definition hxslot_map.hpp:119
const T * cbegin(void) const
Returns a const T* to the beginning of the values (alias for begin).
Definition hxslot_map.hpp:108
hxhandle_t handle_at(hxsize_t index_) const noexcept
Returns the handle for the value at begin() + index.
T * begin(void)
Definition hxslot_map.hpp:100
const T * const_iterator
const_iterator - Const random access iterator.
Definition hxslot_map.hpp:72
const T * end(void) const
Returns a const T* to the end of the values.
hxslot_map(void)
Constructs an empty map with a capacity of 2^table_size_bits - 1.
T value_t
Definition hxslot_map.hpp:74
const T * value(hxhandle_t handle_) const noexcept
hxhandle_t insert(args_t_ &&... args_) noexcept
Returns a non-zero handle referencing a value constructed at the end of data from args.
hxhandle_t emplace(args_t_ &&... args_) noexcept
Returns a non-zero handle referencing a value constructed at the end of data from args.
~hxslot_map()
Destructs the map and destroys all values.
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
#define hxinline
hxinline - Force a function to be inlined into its callers.
Definition hxsettings.h:125
#define hxinline_constexpr
hxinline_constexpr - Enables C++17 compatable "inline constexpr" usage for variables so they can be e...
Definition hxsettings.h:275
#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
A few utility functions and most standard C++ meta programming functions.
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.
uint64_t hxhandle_t
hxhandle_t - An opaque 64-bit handle.
Definition libhatchet.h:213
ptrdiff_t hxsize_t
hxsize_t - A signed size type, same as ssize_t or ptrdiff_t.
Definition libhatchet.h:207