Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_flat_map.H
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
67#ifndef TPL_FLAT_MAP_H
68#define TPL_FLAT_MAP_H
69
70#include <algorithm>
71#include <initializer_list>
72#include <iterator>
73#include <utility>
74
75#include <ah-errors.H>
76#include <ahFunction.H>
77#include <htlist.H>
78#include <tpl_memArray.H>
79#include <tpl_sort_utils.H>
80
81namespace Aleph {
82
126template <typename Key, typename T, class Compare = Aleph::less<Key>>
128{
131 Compare cmp_;
132
133 // Index of the first key not less than k (lower bound position).
134 size_t lower_idx(const Key &k) const
135 {
136 size_t lo = 0, hi = keys_.size();
137 while (lo < hi)
138 {
139 const size_t mid = lo + ((hi - lo) >> 1);
140 if (cmp_(keys_(mid), k))
141 lo = mid + 1;
142 else
143 hi = mid;
144 }
145 return lo;
146 }
147
148 // Index of the first key greater than k (upper bound position).
149 size_t upper_idx(const Key &k) const
150 {
151 size_t lo = 0, hi = keys_.size();
152 while (lo < hi)
153 {
154 const size_t mid = lo + ((hi - lo) >> 1);
155 if (not cmp_(k, keys_(mid)))
156 lo = mid + 1;
157 else
158 hi = mid;
159 }
160 return lo;
161 }
162
163 // True if pos holds a key equivalent to k. Assumes pos == lower_idx(k).
164 bool match_at(size_t pos, const Key &k) const
165 {
166 return pos < keys_.size() and not cmp_(k, keys_(pos));
167 }
168
169 // Opens one slot at pos in both arrays. reserve() is invoked before any
170 // logical size change, so allocation failures preserve the map's logical
171 // contents even though one backing array may already have grown.
172 void make_room(const size_t pos)
173 {
174 if (keys_.size() == keys_.capacity())
175 keys_.reserve(keys_.capacity() << 1);
176 if (vals_.size() == vals_.capacity())
177 vals_.reserve(vals_.capacity() << 1);
178 keys_.putn(1);
179 vals_.putn(1);
180 Key *kp = keys_.get_ptr();
181 T *vp = vals_.get_ptr();
182 for (size_t i = keys_.size() - 1; i > pos; --i)
183 {
184 kp[i] = std::move(kp[i - 1]);
185 vp[i] = std::move(vp[i - 1]);
186 }
187 }
188
189 // Removes the slot at pos from both arrays. Failed shrinking
190 // reallocations are ignored: the logical removal always succeeds.
191 void remove_at(const size_t pos)
192 {
193 Key *kp = keys_.get_ptr();
194 T *vp = vals_.get_ptr();
195 const size_t last = keys_.size() - 1;
196 for (size_t i = pos; i < last; ++i)
197 {
198 kp[i] = std::move(kp[i + 1]);
199 vp[i] = std::move(vp[i + 1]);
200 }
201 try
202 {
203 (void) keys_.get();
204 }
205 catch (const std::bad_alloc &)
206 { /* shrink failed; logical removal already done */
207 }
208 try
209 {
210 (void) vals_.get();
211 }
212 catch (const std::bad_alloc &)
213 { /* shrink failed; logical removal already done */
214 }
215 }
216
217 // Sorts freshly loaded parallel arrays by key and drops duplicate keys,
218 // keeping the first occurrence of each equivalence class.
220 {
221 const size_t m = keys_.size();
223 Key *kp = keys_.get_ptr();
224 T *vp = vals_.get_ptr();
225 for (size_t i = 0; i < m; ++i)
226 tmp.put(std::pair<Key, T>(std::move(kp[i]), std::move(vp[i])));
227
228 std::pair<Key, T> *tp = tmp.get_ptr();
229 timsort(tp, m, [this](const auto &a, const auto &b)
230 {
231 return cmp_(a.first, b.first);
232 });
233
234 size_t out = 0;
235 for (size_t i = 0; i < m; ++i)
236 if (out == 0 or cmp_(kp[out - 1], tp[i].first))
237 {
238 kp[out] = std::move(tp[i].first);
239 vp[out] = std::move(tp[i].second);
240 ++out;
241 }
242 const size_t excess = m - out;
243 if (excess > 0)
244 {
245 try { (void) keys_.get(excess); } catch (const std::bad_alloc &)
246 { /* shrink failed */ }
247 try { (void) vals_.get(excess); } catch (const std::bad_alloc &)
248 { /* shrink failed */ }
249 }
250 }
251
252public:
253 using Item_Type = std::pair<Key, T>;
254 using Key_Type = Key;
255 using key_type = Key;
256 using mapped_type = T;
257 using value_type = std::pair<Key, T>;
258 using key_compare = Compare;
259 using size_type = size_t;
260
271 template <bool IsConst>
273 {
274 using VPtr = std::conditional_t<IsConst, const T *, T *>;
275
276 const Key *k_ = nullptr;
277 VPtr v_ = nullptr;
278
279 public:
282 {
283 const Key &first;
284 std::conditional_t<IsConst, const T &, T &> second;
285 };
286
288 struct pointer
289 {
293 {
294 return &ref;
295 }
296 };
297
298 using iterator_category = std::random_access_iterator_tag;
299 using value_type = std::pair<Key, T>;
300 using difference_type = std::ptrdiff_t;
301
303 basic_iterator() = default;
304
306 basic_iterator(const Key *k, VPtr v) noexcept : k_(k), v_(v) {}
307
309 template <bool B> requires (IsConst and not B)
311 {}
312
314 const Key *key_ptr() const noexcept
315 {
316 return k_;
317 }
318
321 {
322 return v_;
323 }
324
327 {
328 return {*k_, *v_};
329 }
330
333 {
334 return {{*k_, *v_}};
335 }
336
339 {
340 return {*(k_ + i), *(v_ + i)};
341 }
342
345 {
346 ++k_;
347 ++v_;
348 return *this;
349 }
350
353 {
354 basic_iterator ret = *this;
355 ++*this;
356 return ret;
357 }
358
361 {
362 --k_;
363 --v_;
364 return *this;
365 }
366
369 {
370 basic_iterator ret = *this;
371 --*this;
372 return ret;
373 }
374
377 {
378 k_ += i;
379 v_ += i;
380 return *this;
381 }
382
385 {
386 return *this += -i;
387 }
388
391 {
392 basic_iterator ret = *this;
393 return ret += i;
394 }
395
398 {
399 basic_iterator ret = *this;
400 return ret -= i;
401 }
402
405 {
406 return k_ - it.key_ptr();
407 }
408
410 bool operator == (const basic_iterator &it) const noexcept
411 {
412 return k_ == it.key_ptr();
413 }
414
416 bool operator != (const basic_iterator &it) const noexcept
417 {
418 return k_ != it.key_ptr();
419 }
420
422 bool operator < (const basic_iterator &it) const noexcept
423 {
424 return k_ < it.key_ptr();
425 }
426
428 bool operator <= (const basic_iterator &it) const noexcept
429 {
430 return k_ <= it.key_ptr();
431 }
432
434 bool operator > (const basic_iterator &it) const noexcept
435 {
436 return k_ > it.key_ptr();
437 }
438
440 bool operator >= (const basic_iterator &it) const noexcept
441 {
442 return k_ >= it.key_ptr();
443 }
444 };
445
448
455 explicit FlatMap(size_t cap = MemArray<Key>::Min_Dim) : keys_(cap), vals_(cap) {}
456
463 explicit FlatMap(const Compare &cmp, size_t cap = MemArray<Key>::Min_Dim)
464 : keys_(cap), vals_(cap), cmp_(cmp)
465 {}
466
481 template <class It>
482 // Mirrors the loop below instead of std::input_iterator: this map's own
483 // iterators yield a proxy with no common reference with std::pair, so
484 // they fail std::indirectly_readable while working fine here.
485 requires requires(It first, It last, MemArray<Key> & ks, MemArray<T> & vs,
486 const std::remove_reference_t<std::iter_reference_t<It>> & p)
487 {
488 static_cast<bool>(first != last);
489 ++first;
490 ks.put(p.first);
491 vs.put(p.second);
492 }
493 FlatMap(It first, It last, const Compare &cmp = Compare())
494 : keys_(MemArray<Key>::Min_Dim), vals_(MemArray<T>::Min_Dim), cmp_(cmp)
495 {
496 for (; first != last; ++first)
497 {
498 const auto &p = *first;
499 keys_.put(p.first);
500 vals_.put(p.second);
501 }
503 }
504
511 FlatMap(std::initializer_list<std::pair<Key, T>> l, const Compare &cmp = Compare())
512 : FlatMap(l.begin(), l.end(), cmp)
513 {}
514
516 FlatMap(const FlatMap &) = default;
517
520
523
526
528
533 {
534 keys_.swap(m.keys_);
535 vals_.swap(m.vals_);
536 std::swap(cmp_, m.cmp_);
537 }
538
539 // -- capacity -------------------------------------------------------------
540
543 {
544 return keys_.size();
545 }
546
549 {
550 return keys_.is_empty();
551 }
552
555 {
556 return keys_.capacity();
557 }
558
563 void reserve(size_t cap)
564 {
565 keys_.reserve(cap);
566 vals_.reserve(cap);
567 }
568
574 {
575 keys_.empty();
576 vals_.empty();
577 }
578
581 {
582 empty();
583 }
584
585 // -- lookup ---------------------------------------------------------------
586
592 iterator find(const Key &k)
593 {
594 const size_t pos = lower_idx(k);
595 return match_at(pos, k) ? begin() + pos : end();
596 }
597
599 const_iterator find(const Key &k) const
600 {
601 const size_t pos = lower_idx(k);
602 return match_at(pos, k) ? begin() + pos : end();
603 }
604
610 [[nodiscard]] bool contains(const Key &k) const
611 {
612 return match_at(lower_idx(k), k);
613 }
614
620 [[nodiscard]] size_t count(const Key &k) const
621 {
622 return contains(k) ? 1 : 0;
623 }
624
631 {
632 return begin() + lower_idx(k);
633 }
634
636 const_iterator lower_bound(const Key &k) const
637 {
638 return begin() + lower_idx(k);
639 }
640
647 {
648 return begin() + upper_idx(k);
649 }
650
652 const_iterator upper_bound(const Key &k) const
653 {
654 return begin() + upper_idx(k);
655 }
656
662 std::pair<iterator, iterator> equal_range(const Key &k)
663 {
664 return {lower_bound(k), upper_bound(k)};
665 }
666
668 std::pair<const_iterator, const_iterator> equal_range(const Key &k) const
669 {
670 return {lower_bound(k), upper_bound(k)};
671 }
672
679 T &at(const Key &k)
680 {
681 const size_t pos = lower_idx(k);
682 ah_out_of_range_error_if(not match_at(pos, k)) << "FlatMap::at(): key not found";
683 return vals_(pos);
684 }
685
687 const T &at(const Key &k) const
688 {
689 const size_t pos = lower_idx(k);
690 ah_out_of_range_error_if(not match_at(pos, k)) << "FlatMap::at(): key not found";
691 return vals_(pos);
692 }
693
700 T &operator [] (const Key &k)
701 {
702 const size_t pos = lower_idx(k);
703 if (match_at(pos, k))
704 return vals_(pos);
705 make_room(pos);
706 keys_.get_ptr()[pos] = k;
707 vals_.get_ptr()[pos] = T();
708 return vals_(pos);
709 }
710
720 {
721 const size_t pos = lower_idx(k);
722 if (match_at(pos, k))
723 return vals_(pos);
724 make_room(pos);
725 keys_.get_ptr()[pos] = std::move(k);
726 vals_.get_ptr()[pos] = T();
727 return vals_(pos);
728 }
729
730 // -- positional access ----------------------------------------------------
731
738 const Key &nth_key(size_t i) const
739 {
740 return keys_[i];
741 }
742
749 T &nth_value(size_t i)
750 {
751 return vals_[i];
752 }
753
755 const T &nth_value(size_t i) const
756 {
757 return vals_[i];
758 }
759
760 // -- modifiers ------------------------------------------------------------
761
770 std::pair<iterator, bool> insert(const Key &k, const T &v)
771 {
772 const size_t pos = lower_idx(k);
773 if (match_at(pos, k))
774 return {begin() + pos, false};
775 make_room(pos);
776 keys_.get_ptr()[pos] = k;
777 vals_.get_ptr()[pos] = v;
778 return {begin() + pos, true};
779 }
780
782 std::pair<iterator, bool> insert(Key &&k, T &&v)
783 {
784 const size_t pos = lower_idx(k);
785 if (match_at(pos, k))
786 return {begin() + pos, false};
787 make_room(pos);
788 keys_.get_ptr()[pos] = std::move(k);
789 vals_.get_ptr()[pos] = std::move(v);
790 return {begin() + pos, true};
791 }
792
798 std::pair<iterator, bool> insert(const std::pair<Key, T> &p)
799 {
800 return insert(p.first, p.second);
801 }
802
804 std::pair<iterator, bool> insert(std::pair<Key, T> &&p)
805 {
806 return insert(std::move(p.first), std::move(p.second));
807 }
808
817 std::pair<iterator, bool> insert_or_assign(const Key &k, const T &v)
818 {
819 const size_t pos = lower_idx(k);
820 if (match_at(pos, k))
821 {
822 vals_(pos) = v;
823 return {begin() + pos, false};
824 }
825 make_room(pos);
826 keys_.get_ptr()[pos] = k;
827 vals_.get_ptr()[pos] = v;
828 return {begin() + pos, true};
829 }
830
832 std::pair<iterator, bool> insert_or_assign(Key &&k, T &&v)
833 {
834 const size_t pos = lower_idx(k);
835 if (match_at(pos, k))
836 {
837 vals_(pos) = std::move(v);
838 return {begin() + pos, false};
839 }
840 make_room(pos);
841 keys_.get_ptr()[pos] = std::move(k);
842 vals_.get_ptr()[pos] = std::move(v);
843 return {begin() + pos, true};
844 }
845
856 template <class... KArgs>
857 std::pair<iterator, bool> emplace(KArgs &&...kargs)
858 {
859 return insert(Key(std::forward<KArgs>(kargs)...), T());
860 }
861
868 size_t erase(const Key &k)
869 {
870 const size_t pos = lower_idx(k);
871 if (not match_at(pos, k))
872 return 0;
873 remove_at(pos);
874 return 1;
875 }
876
884 {
885 const size_t pos = it.key_ptr() - keys_.get_ptr();
886 ah_out_of_range_error_if(pos >= size()) << "FlatMap::erase(): iterator out of range";
887 remove_at(pos);
888 return begin() + pos;
889 }
890
891 // -- iteration ------------------------------------------------------------
892
895 {
896 return iterator(keys_.get_ptr(), vals_.get_ptr());
897 }
898
901 {
902 return iterator(keys_.get_ptr() + size(), vals_.get_ptr() + size());
903 }
904
907 {
908 return const_iterator(keys_.get_ptr(), vals_.get_ptr());
909 }
910
913 {
914 return const_iterator(keys_.get_ptr() + size(), vals_.get_ptr() + size());
915 }
916
919 {
920 return begin();
921 }
922
925 {
926 return end();
927 }
928
931 {
932 return keys_.get_ptr();
933 }
934
937 {
938 return vals_.get_ptr();
939 }
940
943 {
944 return vals_.get_ptr();
945 }
946
953 {
955 const Key *p = keys_.get_ptr();
956 for (size_t i = 0; i < size(); ++i)
957 ret.append(p[i]);
958 return ret;
959 }
960
967 {
969 const T *p = vals_.get_ptr();
970 for (size_t i = 0; i < size(); ++i)
971 ret.append(p[i]);
972 return ret;
973 }
974
984 template <class Operation>
986 {
987 const Key *kp = keys_.get_ptr();
988 T *vp = vals_.get_ptr();
989 const size_t m = size();
990 for (size_t i = 0; i < m; ++i)
991 if (not operation(kp[i], vp[i]))
992 return false;
993 return true;
994 }
995
1002 template <class Operation>
1004 {
1005 const Key *kp = keys_.get_ptr();
1006 const T *vp = vals_.get_ptr();
1007 const size_t m = size();
1008 for (size_t i = 0; i < m; ++i)
1009 if (not operation(kp[i], vp[i]))
1010 return false;
1011 return true;
1012 }
1013
1014 // -- comparison -----------------------------------------------------------
1015
1021 bool operator == (const FlatMap &m) const
1022 {
1023 return size() == m.size() and
1024 std::equal(keys_.get_ptr(), keys_.get_ptr() + size(), m.keys_.get_ptr()) and
1025 std::equal(vals_.get_ptr(), vals_.get_ptr() + size(), m.vals_.get_ptr());
1026 }
1027
1029 bool operator != (const FlatMap &m) const
1030 {
1031 return not (*this == m);
1032 }
1033};
1034
1035} // end namespace Aleph
1036
1037#endif // TPL_FLAT_MAP_H
Exception handling system with formatted messages for Aleph-w.
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
Definition ah-errors.H:584
Standard functor implementations and comparison objects.
size_t size_t int32_t * out
Definition ca-c-api.h:120
Doubly-linked list (defined in tpl_dynList.H).
Definition htlist.H:1155
T & append(const T &item)
Definition htlist.H:1271
Generic filter iterator wrapper.
Random-access proxy iterator over (key, value) entries.
reference operator*() const noexcept
Dereference to the (key, value) proxy.
VPtr val_ptr() const noexcept
Cursor into the value array (internal use).
basic_iterator & operator++() noexcept
Pre-increment.
basic_iterator()=default
Construct a singular iterator.
basic_iterator operator-(difference_type i) const noexcept
Iterator i positions backward.
std::pair< Key, T > value_type
Materialized entry type.
bool operator==(const basic_iterator &it) const noexcept
Equality: same position.
std::ptrdiff_t difference_type
Signed distance type.
const Key * key_ptr() const noexcept
Cursor into the key array (internal use).
pointer operator->() const noexcept
Member access through the proxy (e.g. it->second).
basic_iterator(const Key *k, VPtr v) noexcept
Construct from parallel key/value cursors (internal use).
bool operator<=(const basic_iterator &it) const noexcept
Ordering by position.
reference operator[](difference_type i) const noexcept
Proxy for the entry i positions away.
std::conditional_t< IsConst, const T *, T * > VPtr
bool operator>=(const basic_iterator &it) const noexcept
Ordering by position.
std::random_access_iterator_tag iterator_category
Category.
bool operator<(const basic_iterator &it) const noexcept
Strict ordering by position.
basic_iterator & operator+=(difference_type i) noexcept
Advance by i positions.
bool operator>(const basic_iterator &it) const noexcept
Strict ordering by position.
basic_iterator(const basic_iterator< B > &it) noexcept
Convert a mutable iterator into a const iterator.
basic_iterator & operator-=(difference_type i) noexcept
Retreat by i positions.
bool operator!=(const basic_iterator &it) const noexcept
Inequality: different position.
basic_iterator operator+(difference_type i) const noexcept
Iterator i positions forward.
basic_iterator & operator--() noexcept
Pre-decrement.
Ordered map stored as two parallel sorted contiguous arrays.
T & operator[](const Key &k)
Access the value mapped to k, inserting a default if absent.
FlatMap(FlatMap &&) noexcept=default
Move constructor. The source is left valid but unspecified.
const Key & nth_key(size_t i) const
Key of the i-th entry in sorted order (checked).
std::pair< iterator, bool > insert(const std::pair< Key, T > &p)
Insert a (key, value) pair if the key is not mapped.
FlatMap(size_t cap=MemArray< Key >::Min_Dim)
Construct an empty map.
T & at(const Key &k)
Checked access to the value mapped to k.
const Key * keys_data() const noexcept
Pointer to the sorted, contiguous key storage. O(1).
size_t upper_idx(const Key &k) const
FlatMap(const Compare &cmp, size_t cap=MemArray< Key >::Min_Dim)
Construct an empty map with a specific comparator.
void reserve(size_t cap)
Reserve capacity for at least cap entries.
iterator erase(const_iterator it)
Remove the entry at iterator it.
const T * values_data() const noexcept
std::pair< iterator, bool > insert(const Key &k, const T &v)
Insert (k, v) if k is not mapped.
size_t count(const Key &k) const
Count entries with key k (0 or 1).
MemArray< Key > keys_
bool contains(const Key &k) const
Test whether key k is mapped.
size_t capacity() const noexcept
Return the capacity of the backing key array. O(1).
const_iterator find(const Key &k) const
iterator upper_bound(const Key &k)
First entry whose key is greater than k.
const_iterator lower_bound(const Key &k) const
Compare key_compare
STL convention: comparator type.
bool traverse(Operation operation) const
Const traversal in key order while operation returns true.
DynList< Key > keys() const
Copy all keys, in ascending order, into a DynList.
const_iterator cend() const noexcept
Const iterator past the entry with the greatest key. O(1).
basic_iterator< false > iterator
Mutable-value iterator.
void clear() noexcept
Remove all entries. Alias of empty(). Capacity is kept.
size_t erase(const Key &k)
Remove the entry with key k, if present.
MemArray< T > vals_
const T & nth_value(size_t i) const
std::pair< iterator, bool > insert(Key &&k, T &&v)
const_iterator end() const noexcept
Const iterator past the entry with the greatest key. O(1).
const_iterator upper_bound(const Key &k) const
void empty() noexcept
Remove all entries (Aleph convention).
bool is_empty() const noexcept
Return true if the map holds no entries. O(1).
T * values_data() noexcept
Pointer to the contiguous value storage (parallel to keys). O(1).
std::pair< iterator, bool > insert(std::pair< Key, T > &&p)
void remove_at(const size_t pos)
size_t size_type
STL convention: size type.
Key Key_Type
Aleph convention: key type.
bool operator!=(const FlatMap &m) const
Inequality: negation of operator==.
void swap(FlatMap &m) noexcept(std::is_nothrow_swappable_v< Compare >)
Swap contents with m in O(1).
size_t lower_idx(const Key &k) const
iterator lower_bound(const Key &k)
First entry whose key is not less than k.
DynList< T > values() const
Copy all values, in ascending key order, into a DynList.
Key key_type
STL convention: key type.
FlatMap(const FlatMap &)=default
Copy constructor (requires copyable Key and T).
bool match_at(size_t pos, const Key &k) const
bool traverse(Operation operation)
Traverse entries in key order while operation returns true.
void make_room(const size_t pos)
std::pair< Key, T > Item_Type
Aleph convention: element type.
std::pair< iterator, iterator > equal_range(const Key &k)
Range of entries with key equivalent to k.
FlatMap(It first, It last, const Compare &cmp=Compare())
Construct from an iterator range of pairs.
const_iterator cbegin() const noexcept
Const iterator to the entry with the smallest key. O(1).
std::pair< iterator, bool > insert_or_assign(const Key &k, const T &v)
Insert (k, v) or overwrite the value if k is mapped.
std::pair< iterator, bool > insert_or_assign(Key &&k, T &&v)
basic_iterator< true > const_iterator
Const-value iterator.
void sort_and_unique()
std::pair< const_iterator, const_iterator > equal_range(const Key &k) const
FlatMap(std::initializer_list< std::pair< Key, T > > l, const Compare &cmp=Compare())
Construct from an initializer list of pairs.
const_iterator begin() const noexcept
Const iterator to the entry with the smallest key. O(1).
T & nth_value(size_t i)
Value of the i-th entry in sorted order (checked).
bool operator==(const FlatMap &m) const
Equality: same size and pairwise equal keys and values.
T mapped_type
STL convention: mapped type.
iterator begin() noexcept
Iterator to the entry with the smallest key. O(1).
const T & at(const Key &k) const
size_t size() const noexcept
Return the number of stored entries. O(1).
iterator find(const Key &k)
Find the entry with key k.
std::pair< iterator, bool > emplace(KArgs &&...kargs)
Build a key from kargs and insert it with a default value.
iterator end() noexcept
Iterator past the entry with the greatest key. O(1).
std::pair< Key, T > value_type
STL convention: value type.
Simple, scalable and fast dynamic array.
void reserve(const size_t cap)
Reserves cap cells into the array.
size_t size() const noexcept
Return the number of elements.
void putn(const size_t more)
Reserve more additional logical slots in the array.
T * get_ptr() const noexcept
Return the current base of array.
constexpr size_t capacity() const noexcept
The type of element of array.
bool is_empty() const noexcept
Return true is the array is empty.
void empty() noexcept
Empties the container.
T get(const size_t i=1)
Remove i elements from the end.
void swap(MemArray &a) noexcept
Swap in constant time this with a
T & put(const T &item)
Put a copy of item at the end of sequence.
constexpr size_t size() const noexcept
Returns the number of entries in the table.
Definition hashDry.H:619
int cmp(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
Definition gmpfrxx.h:4129
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
Singly linked list implementations with head-tail access.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
void timsort(T *a, const size_t n, const Compare &cmp=Compare())
Timsort — adaptive, stable, natural merge sort.
and
Check uniqueness with explicit hash + equality functors.
std::decay_t< typename HeadC::Item_Type > T
Definition ah-zip.H:105
STL namespace.
Proxy returned by operator->, keeps the reference alive.
reference ref
Materialized reference proxy.
reference * operator->() noexcept
Give access to the members of the proxy.
Proxy returned by operator*: references into the parallel arrays.
const Key & first
The entry's key.
std::conditional_t< IsConst, const T &, T & > second
The entry's value.
FooMap m(5, fst_unit_pair_hash, snd_unit_pair_hash)
static int * k
Simple, scalable, contiguous dynamic array.
Comprehensive sorting algorithms and search utilities for Aleph-w.
DynList< int > l