35 template<
typename X=K, std::enable_if_t<std::is_same_v<X,std::type_index>,
int> = 0>
39 template<
typename X=K, std::enable_if_t<!std::is_same_v<X,std::type_index>,
int> = 0>
43 constexpr wfree_unordered_map_item(wfree_unordered_map_item
const &)
noexcept =
delete;
44 constexpr wfree_unordered_map_item(wfree_unordered_map_item &&) noexcept = delete;
45 ~wfree_unordered_map_item() noexcept = default;
46 constexpr wfree_unordered_map_item &operator=(wfree_unordered_map_item const &) noexcept = delete;
47 constexpr wfree_unordered_map_item &operator=(wfree_unordered_map_item &&) noexcept = delete;
59 using mapped_type = V;
62 static constexpr size_t CAPACITY = MAX_NR_ITEMS * 2;
74 static size_t make_hash(K
const &key)
noexcept {
79 void insert(K key, V
value)
noexcept {
80 ttlet
hash = make_hash(key);
82 auto index =
hash % CAPACITY;
84 auto &item = items[index];
88 if (item.hash.compare_exchange_strong(item_hash, 1, std::memory_order::acquire)) {
92 item.hash.store(
hash, std::memory_order::release);
95 }
else if (item_hash ==
hash && key == item.key) {
106 index = (index + 1) % CAPACITY;
115 for (ttlet &item: items) {
116 if (item.hash >= 3) {
123 V& operator[](K
const &key)
noexcept {
124 ttlet
hash = make_hash(key);
126 auto index =
hash % CAPACITY;
128 auto &item = items[index];
131 size_t item_hash = 0;
132 if (item.hash.compare_exchange_strong(item_hash, 1, std::memory_order::acquire)) {
135 item.hash.store(
hash, std::memory_order::release);
137 if constexpr (std::is_default_constructible_v<V>) {
145 }
else if (item_hash ==
hash && key == item.key) {
155 index = (index + 1) % CAPACITY;
160 std::optional<V> get(K
const &key)
const noexcept {
161 ttlet
hash = make_hash(key);
163 auto index =
hash % CAPACITY;
165 auto &item = items[index];
167 auto item_hash = item.hash.load(std::memory_order::acquire);
169 if (item_hash ==
hash && key == item.key) {
171 return { item.value };
173 }
else if (item_hash == 0) {
178 index = (index + 1) % CAPACITY;
183 V get(K
const &key, V
const &default_value)
const noexcept {
184 if (ttlet optional_value = get(key)) {
185 return *optional_value;
187 return default_value;
191 std::optional<V> erase(K
const &key)
noexcept {
192 ttlet
hash = make_hash(key);
194 auto index =
hash % CAPACITY;
196 auto &item = items[index];
197 auto item_hash = item.hash.load(std::memory_order::acquire);
199 if (item_hash ==
hash && key == item.key) {
201 item.hash.store(1, std::memory_order::release);
202 return { item.value };
204 }
else if (item_hash == 0) {
209 index = (index + 1) % CAPACITY;