libhatchet
Loading...
Searching...
No Matches
hxflat_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 "hxrange.hpp"
20
21HX_NS_BEGIN_
22
23#if HX_CPLUSPLUS >= 202002L
25template<typename T_>
26concept hxflat_map_concept_ = requires(T_& x_) {
27 sizeof(T_);
28 x_.~T_();
29};
31#else
32#define hxflat_map_concept_ typename
33#endif
34
38template<typename key_t_, typename mapped_t_>
40public:
44 bool operator==(const hxflat_map_const_value_t& x_) const {
45 return hxkey_equal(key, x_.key) && hxkey_equal(value, x_.value);
46 }
47
51 bool operator<(const hxflat_map_const_value_t& x_) const {
52 if(!hxkey_equal(key, x_.key)) { return hxkey_less(key, x_.key); }
53 return hxkey_less(value, x_.value);
54 }
55
57 const key_t_& key;
58
60 const mapped_t_& value;
61
62protected:
64 template<hxflat_map_concept_, hxflat_map_concept_, typename, bool, hxsize_t> friend class hxflat_map;
65 hxflat_map_const_value_t(const key_t_& key_, const mapped_t_& mapped_)
66 : key(key_), value(mapped_) { }
68};
69
72template<typename key_t_, typename mapped_t_>
74public:
78 bool operator==(const hxflat_map_value_t& x_) const {
79 return hxkey_equal(key, x_.key) && hxkey_equal(value, x_.value);
80 }
81
85 bool operator<(const hxflat_map_value_t& x_) const {
86 if(!hxkey_equal(key, x_.key)) { return hxkey_less(key, x_.key); }
87 return hxkey_less(value, x_.value);
88 }
89
91 const key_t_& key;
92
94 mapped_t_& value;
95
96protected:
98 template<hxflat_map_concept_, hxflat_map_concept_, typename, bool, hxsize_t> friend class hxflat_map;
99 hxflat_map_value_t(const key_t_& key_, mapped_t_& mapped_)
100 : key(key_), value(mapped_) { }
102};
103
131template<hxflat_map_concept_ key_t_,
132 hxflat_map_concept_ mapped_t_,
133 typename compare_t_=hxkey_less_t<key_t_>,
134 bool multi_t_=true,
137public:
138 using key_t = key_t_;
139 using mapped_t = mapped_t_;
140 using compare_t = compare_t_;
141
145 public:
147 const_iterator(void) : m_map_(hxnull), m_index_(0) { }
148
154
158
162
165 const_iterator operator+(hxsize_t n_) const { const_iterator t_(*this); t_ += n_; return t_; }
166
169 const_iterator operator-(hxsize_t n_) const { const_iterator t_(*this); t_ -= n_; return t_; }
170
174
179
182
184 const_iterator operator++(int) { const_iterator t_(*this); operator++(); return t_; }
185
187 const_iterator& operator--(void) { return operator+=(-1); }
188
190 const_iterator operator--(int) { const_iterator t_(*this); operator--(); return t_; }
191
194 bool operator==(const const_iterator& x_) const;
195
198 bool operator<(const const_iterator& x_) const;
199
202 bool operator>(const const_iterator& x_) const { return x_ < *this; }
203
206 bool operator<=(const const_iterator& x_) const { return !(x_ < *this); }
207
210 bool operator>=(const const_iterator& x_) const { return !(*this < x_); }
211
212#if HX_CPLUSPLUS < 202002L
215 bool operator!=(const const_iterator& x_) const;
216#endif
217
220 const key_t_& key(void) const;
221
224 const mapped_t_& value(void) const;
225
226 protected:
228 friend class hxflat_map;
229 const_iterator(const hxflat_map* map_, hxsize_t index_)
230 : m_map_(map_), m_index_(index_) { }
231 const hxflat_map* m_map_;
232 hxsize_t m_index_;
234 };
235
238 class iterator : public const_iterator {
239 public:
241 iterator(void) { }
242
248
252
256
259 iterator operator+(hxsize_t n_) const { iterator t_(*this); t_ += n_; return t_; }
260
263 iterator operator-(hxsize_t n_) const { iterator t_(*this); t_ -= n_; return t_; }
264
268
273
276
278 iterator operator++(int) { iterator t_(*this); const_iterator::operator++(); return t_; }
279
282
284 iterator operator--(int) { iterator t_(*this); const_iterator::operator--(); return t_; }
285
288 mapped_t_& value(void) const;
289
290 protected:
292 friend class hxflat_map;
293 iterator(hxflat_map* map_, hxsize_t index_) : const_iterator(map_, index_) { }
294 iterator(const const_iterator& x_) : const_iterator(x_) { }
296 };
297
299 class pair_t_ {
300 public:
301 key_t_ key_;
302 mapped_t_ mapped_;
303 };
305
308 explicit hxflat_map(void);
309
314 hxflat_map(const hxflat_map& x_) noexcept;
315
320 hxflat_map(hxflat_map&& x_) noexcept;
321
326 hxflat_map(std::initializer_list<pair_t_> x_) noexcept;
327
329 ~hxflat_map(void) noexcept;
330
331#if HX_CPLUSPLUS >= 202302L
337 template<typename self_t_, typename callable_t_>
339 this self_t_&& self_, const key_t_& key_, callable_t_&& callable_)
340 -> hxremove_cvref_t<decltype(
341 hxforward<callable_t_>(callable_)(
343
347 template<typename self_t_, typename callable_t_>
349 this self_t_&& self_, const_iterator it_, callable_t_&& callable_)
350 -> hxremove_cvref_t<decltype(
353#endif // HX_CPLUSPLUS >= 202302L
354
358 void operator=(const hxflat_map& x_) noexcept;
359
363 template<hxsize_t capacity_x_>
364 void operator=(const hxflat_map<key_t_, mapped_t_, compare_t_, multi_t_,
365 capacity_x_>& x_) noexcept;
366
370 void operator=(hxflat_map&& x_) noexcept;
371
376
378
382 template<hxsize_t capacity_x_>
383 hxattr_nodiscard bool operator==(const hxflat_map<key_t_, mapped_t_, compare_t_,
384 multi_t_, capacity_x_>& x_) const;
385
389 template<hxsize_t capacity_x_>
390 hxattr_nodiscard bool operator<(const hxflat_map<key_t_, mapped_t_, compare_t_,
391 multi_t_, capacity_x_>& x_) const;
392
394 const_iterator begin(void) const { return const_iterator(this, 0); }
395
397 iterator begin(void) { return iterator(this, 0); }
398
400 hxattr_nodiscard hxsize_t capacity(void) const { return m_keys_.capacity(); }
401
404 const_iterator cbegin(void) const { return const_iterator(this, 0); }
405
407 const_iterator cend(void) const { return const_iterator(this, m_size_); }
408
410 void clear(void) noexcept;
411
414 hxattr_nodiscard hxsize_t count(const key_t_& key_) const;
415
420 template<typename... args_t_>
421 iterator emplace(const key_t_& key_, args_t_&&... args_) noexcept;
422
424 hxattr_nodiscard bool empty(void) const { return m_size_ == 0; }
425
427 const_iterator end(void) const { return const_iterator(this, m_size_); }
428
430 iterator end(void) { return iterator(this, m_size_); }
431
435 hxsize_t erase(const key_t_& key_) noexcept;
436
441
445 hxattr_nodiscard const_iterator find(const key_t_& key_) const;
446
447 hxattr_nodiscard iterator find(const key_t_& key_);
448
450 hxattr_nodiscard bool full(void) const { return m_size_ == m_keys_.capacity(); }
451
454 hxattr_nodiscard bool has_value(const key_t_& key_) const;
455
462 iterator insert(const key_t_& key_, const mapped_t_& mapped_) noexcept;
463
467 iterator insert(const key_t_& key_, mapped_t_&& mapped_) noexcept;
468
471 hxattr_nodiscard const key_t_* keys(void) const noexcept;
472
476 hxattr_nodiscard const_iterator lower_bound(const key_t_& key_) const;
477
479
481 hxattr_nodiscard hxsize_t max_size(void) const { return this->capacity(); }
482
483#if HX_CPLUSPLUS >= 202302L
489 template<typename self_t_, typename callable_t_>
491 this self_t_&& self_, const key_t_& key_, callable_t_&& callable_)
492 -> decltype(self_.end());
493
498 template<typename self_t_, typename callable_t_>
500 this self_t_&& self_, const_iterator it_, callable_t_&& callable_)
501 -> decltype(self_.end());
502#endif // HX_CPLUSPLUS >= 202302L
503
511 void reserve(hxsize_t cap_,
514
516 hxattr_nodiscard hxsize_t size(void) const { return m_size_; }
517
520 void swap(hxflat_map& x_) noexcept;
521
525 hxattr_nodiscard const_iterator upper_bound(const key_t_& key_) const;
526
528
529#if HX_CPLUSPLUS >= 202302L
534 template<typename self_t_, typename... args_t_>
536 this self_t_&& self_, const key_t_& key_, args_t_&&... args_);
537
541 template<typename self_t_, typename... args_t_>
543 this self_t_&& self_, const_iterator it_, args_t_&&... args_);
544#endif // HX_CPLUSPLUS >= 202302L
545
548 hxattr_nodiscard const mapped_t_* values(void) const noexcept;
549
550 hxattr_nodiscard mapped_t_* values(void) noexcept;
551
552private:
554 template<hxflat_map_concept_, hxflat_map_concept_, typename, bool, hxsize_t>
555 friend class hxflat_map;
556
557 template<typename mapped_u_>
558 iterator insert_at_(hxsize_t index_, const key_t_& key_, mapped_u_&& mapped_) noexcept;
559
560 hxsize_t m_size_;
564};
565
566#include "detail/hxflat_map.inl"
567HX_NS_END_
hxallocator<1+> - Provides static allocation when capacity is greater than zero.
Definition hxallocator.hpp:25
const_iterator - A random-access iterator over key-value pairs.
Definition hxflat_map.hpp:144
const_iterator operator+(hxsize_t n_) const
Returns an iterator advanced by n positions.
Definition hxflat_map.hpp:165
const_iterator & operator--(void)
Retreats the iterator to the previous element.
Definition hxflat_map.hpp:187
hxflat_map_const_value_t< key_t_, mapped_t_ > operator[](hxsize_t n_) const
Returns a hxflat_map_const_value_t proxy referencing the key and value n positions ahead of this one.
Definition hxflat_map.hpp:178
bool operator==(const const_iterator &x_) const
Compares two iterators for equality.
const_iterator & operator++(void)
Advances the iterator to the next element.
Definition hxflat_map.hpp:181
bool operator>=(const const_iterator &x_) const
Returns true when this iterator is not ordered before x.
Definition hxflat_map.hpp:210
bool operator>(const const_iterator &x_) const
Returns true when this iterator is ordered after x.
Definition hxflat_map.hpp:202
const_iterator & operator-=(hxsize_t n_)
Moves the iterator back by n positions.
Definition hxflat_map.hpp:161
bool operator<(const const_iterator &x_) const
Returns true when this iterator is ordered before x.
const_iterator operator--(int)
Retreats the iterator to the previous element (post-decrement).
Definition hxflat_map.hpp:190
const mapped_t_ & value(void) const
Returns the mapped value at the current position.
hxflat_map_const_value_t< key_t_, mapped_t_ > operator*(void) const
Returns a hxflat_map_const_value_t proxy referencing the key and value at the current position.
Definition hxflat_map.hpp:151
const_iterator operator-(hxsize_t n_) const
Returns an iterator retreated by n positions.
Definition hxflat_map.hpp:169
const_iterator operator++(int)
Advances the iterator to the next element (post-increment).
Definition hxflat_map.hpp:184
const key_t_ & key(void) const
Returns the key at the current position.
bool operator<=(const const_iterator &x_) const
Returns true when this iterator is not ordered after x.
Definition hxflat_map.hpp:206
hxsize_t operator-(const const_iterator &x_) const
Returns the signed distance between two iterators.
const_iterator & operator+=(hxsize_t n_)
Advances the iterator by n positions.
const_iterator(void)
Constructs an end iterator.
Definition hxflat_map.hpp:147
iterator - A mutable random-access iterator that allows modifying the mapped value.
Definition hxflat_map.hpp:238
iterator & operator+=(hxsize_t n_)
Advances the iterator by n positions.
Definition hxflat_map.hpp:251
hxflat_map_value_t< key_t_, mapped_t_ > operator*(void) const
Returns a hxflat_map_value_t proxy referencing the key and value at the current position,...
Definition hxflat_map.hpp:245
iterator operator++(int)
Advances the iterator to the next element (post-increment).
Definition hxflat_map.hpp:278
mapped_t_ & value(void) const
Returns the mapped value at the current position, allowing mutation.
iterator operator+(hxsize_t n_) const
Returns an iterator advanced by n positions.
Definition hxflat_map.hpp:259
iterator(void)
Constructs an end iterator.
Definition hxflat_map.hpp:241
iterator & operator-=(hxsize_t n_)
Moves the iterator back by n positions.
Definition hxflat_map.hpp:255
iterator & operator++(void)
Advances the iterator to the next element.
Definition hxflat_map.hpp:275
iterator & operator--(void)
Retreats the iterator to the previous element.
Definition hxflat_map.hpp:281
iterator operator--(int)
Retreats the iterator to the previous element (post-decrement).
Definition hxflat_map.hpp:284
hxsize_t operator-(const const_iterator &x_) const
Returns the signed distance from x to this position.
Definition hxflat_map.hpp:267
iterator operator-(hxsize_t n_) const
Returns an iterator retreated by n positions.
Definition hxflat_map.hpp:263
hxflat_map_value_t< key_t_, mapped_t_ > operator[](hxsize_t n_) const
Returns a hxflat_map_value_t proxy referencing the key and value n positions ahead of this one.
Definition hxflat_map.hpp:272
hxflat_map_const_value_t - A proxy referencing the key and mapped value at a fixed position,...
Definition hxflat_map.hpp:39
const key_t_ & key
The referenced key.
Definition hxflat_map.hpp:57
bool operator<(const hxflat_map_const_value_t &x_) const
Returns true when this element is ordered before x, comparing keys first and then values with hxkey_e...
Definition hxflat_map.hpp:51
const mapped_t_ & value
The referenced mapped value.
Definition hxflat_map.hpp:60
bool operator==(const hxflat_map_const_value_t &x_) const
Compares the referenced key and value for equality with x, using hxkey_equal on both.
Definition hxflat_map.hpp:44
hxflat_map_value_t - A proxy referencing the key and mapped value at a fixed position,...
Definition hxflat_map.hpp:73
mapped_t_ & value
The referenced mapped value, allowing mutation.
Definition hxflat_map.hpp:94
const key_t_ & key
The referenced key.
Definition hxflat_map.hpp:91
bool operator<(const hxflat_map_value_t &x_) const
Returns true when this element is ordered before x, comparing keys first and then values with hxkey_e...
Definition hxflat_map.hpp:85
bool operator==(const hxflat_map_value_t &x_) const
Compares the referenced key and value for equality with x, using hxkey_equal on both.
Definition hxflat_map.hpp:78
hxflat_map - A sorted associative container that stores keys and mapped values in two parallel arrays...
Definition hxflat_map.hpp:136
iterator upper_bound(const key_t_ &key_)
const_iterator end(void) const
Returns a const iterator pointing past the last element.
Definition hxflat_map.hpp:427
iterator emplace(const key_t_ &key_, args_t_ &&... args_) noexcept
Constructs and inserts a mapped value from args, returning an iterator to the new or existing element...
iterator begin(void)
Returns an iterator pointing to the first element.
Definition hxflat_map.hpp:397
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< mapped_t_ & >())))>
Returns the result of calling callable with the mapped value for the first key matching key,...
bool full(void) const
Returns true if the map has reached its capacity.
Definition hxflat_map.hpp:450
hxflat_map(hxflat_map &&x_) noexcept
Move constructs from a temporary hxflat_map.
hxsize_t capacity(void) const
Returns the number of elements the map can hold.
Definition hxflat_map.hpp:400
bool has_value(const key_t_ &key_) const
Returns true if an element matching key exists.
const_iterator begin(void) const
Returns a const iterator pointing to the first element.
Definition hxflat_map.hpp:394
iterator insert(const key_t_ &key_, const mapped_t_ &mapped_) noexcept
Inserts a key-value pair.
mapped_t_ value_or(this self_t_ &&self_, const_iterator it_, args_t_ &&... args_)
Iterator overload of value_or.
void reserve(hxsize_t cap_, hxsystem_allocator_t allocator_=hxsystem_allocator_current, hxalignment_t alignment_=hxalignment) noexcept
Allocates storage for cap keys and values.
key_t_ key_t
Definition hxflat_map.hpp:138
iterator erase(const_iterator it_) noexcept
Removes the element at the iterator position and destroys the key-value pair.
iterator end(void)
Returns an iterator pointing past the last element.
Definition hxflat_map.hpp:430
compare_t_ compare_t
Definition hxflat_map.hpp:140
const mapped_t_ * values(void) const noexcept
Returns a const pointer to the underlying mapped value storage.
auto or_else(this self_t_ &&self_, const key_t_ &key_, callable_t_ &&callable_) -> decltype(self_.end())
Returns an iterator to the first element matching key, or the result of calling callable when lookup ...
mapped_t_ mapped_t
Definition hxflat_map.hpp:139
hxflat_map(void)
Constructs an empty map.
void swap(hxflat_map &x_) noexcept
Swaps the contents with x.
iterator lower_bound(const key_t_ &key_)
hxsize_t max_size(void) const
Returns the capacity of the map.
Definition hxflat_map.hpp:481
bool operator==(const hxflat_map< key_t_, mapped_t_, compare_t_, multi_t_, capacity_x_ > &x_) const
Returns true if this map and x contain the same key-value pairs in the same order using hxkey_equal o...
mapped_t_ value_or(this self_t_ &&self_, const key_t_ &key_, args_t_ &&... args_)
Returns a copy of the mapped value for the first key matching key, or a mapped value constructed from...
hxsize_t count(const key_t_ &key_) const
Returns the number of elements with the given key.
const_iterator find(const key_t_ &key_) const
Returns a const iterator to key, or end() if the key is not found.
const key_t_ * keys(void) const noexcept
Returns a const pointer to the underlying key storage.
bool empty(void) const
Checks if the map contains no elements.
Definition hxflat_map.hpp:424
void operator=(const hxflat_map< key_t_, mapped_t_, compare_t_, multi_t_, capacity_x_ > &x_) noexcept
Cross-capacity copy assignment.
const_iterator lower_bound(const key_t_ &key_) const
Returns an iterator to the first element whose key is not ordered before key.
iterator insert(const key_t_ &key_, mapped_t_ &&mapped_) noexcept
Move-value overload of insert.
auto or_else(this self_t_ &&self_, const_iterator it_, callable_t_ &&callable_) -> decltype(self_.end())
Iterator overload of or_else.
const_iterator cbegin(void) const
Returns a const iterator pointing to the first element (alias for begin).
Definition hxflat_map.hpp:404
void operator=(hxflat_map &&x_) noexcept
Move assigns from a temporary map using swap.
hxsize_t erase(const key_t_ &key_) noexcept
Removes all elements with the given key and destroys their key-value pairs.
bool operator<(const hxflat_map< key_t_, mapped_t_, compare_t_, multi_t_, capacity_x_ > &x_) const
Returns true if this map compares less than x lexicographically, using hxkey_equal and hxkey_less on ...
hxsize_t size(void) const
Returns the number of elements in the map.
Definition hxflat_map.hpp:516
hxflat_map(std::initializer_list< pair_t_ > x_) noexcept
Constructs a map by inserting every key-value pair from x in order using insert.
hxflat_map(const hxflat_map &x_) noexcept
Copy constructs from another hxflat_map.
const_iterator operator[](hxsize_t index_) const
Returns a const iterator to the element at index.
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 mapped_t_ & >())))>
Iterator overload of and_then.
iterator find(const key_t_ &key_)
~hxflat_map(void) noexcept
Destructs the map and destroys all key-value pairs.
iterator operator[](hxsize_t index_)
mapped_t_ * values(void) noexcept
void operator=(const hxflat_map &x_) noexcept
Assigns the contents of x to this map.
const_iterator cend(void) const
Returns a const iterator pointing past the last element.
Definition hxflat_map.hpp:407
void clear(void) noexcept
Removes all elements and destroys their key-value pairs.
const_iterator upper_bound(const key_t_ &key_) const
Returns an iterator to the first element whose key is ordered after key.
hxkey_less_t<T> - A constexpr callable that returns true if the first object is less than the second.
Definition hxkey.hpp:91
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
Implements or includes std::initializer_list depending on HX_USE_LIBCXX.
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
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
hxattr_noexcept hxsystem_allocator_t hxalignment_t alignment_
Definition hxmemory_manager.h:121
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
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.
#define hxnull
hxnull - The null pointer value for a given pointer type represented by the numeric literal 0.
Definition libhatchet.h:280
ptrdiff_t hxsize_t
hxsize_t - A signed size type, same as ssize_t or ptrdiff_t.
Definition libhatchet.h:207