59 typedef typename std::allocator_traits<ArbitraryAllocator>::template rebind_alloc<YFastLeaf> Alloc;
64 class IteratorBase:
private YFastTrie::Where {
67 using YFastTrie::Where::leaf;
68 using YFastTrie::Where::xleaf;
69 using YFastTrie::Where::trie;
71 unsigned int _last_rebuild = 0;
74 typedef const typename YFastLeaf::Key
key_type;
77 typedef std::bidirectional_iterator_tag iterator_category;
78 typedef std::ptrdiff_t difference_type;
83 IteratorBase() =
default;
84 explicit IteratorBase(
const typename YFastTrie::Where& where): YFastTrie::Where(where), _last_rebuild(trie->rebuilds()) {}
86 template <
bool Const_>
87 bool same_as(
const IteratorBase<Const_>& other)
const {
88 return trie == other.trie && leaf == other.leaf;
92 auto succ = YFastTrie::Value::succ(leaf);
93 if (
succ !=
nullptr) {
97 if (trie->rebuilds() > _last_rebuild) {
98 auto where = trie->find(leaf->key);
100 _last_rebuild = trie->rebuilds();
103 if (xleaf !=
nullptr) {
104 leaf = xleaf->value.leftmost();
113 auto pred = YFastTrie::Value::pred(leaf);
114 if (
pred !=
nullptr) {
118 if (trie->rebuilds() > _last_rebuild) {
119 auto where = trie->find(leaf->key);
121 _last_rebuild = trie->rebuilds();
124 if (xleaf !=
nullptr) {
125 leaf = xleaf->value.rightmost();
135 if (leaf ==
nullptr) {
136 throw std::out_of_range(
"yfast::fastmap::iterator");
142 if (leaf ==
nullptr) {
143 throw std::out_of_range(
"yfast::fastmap::iterator");
145 return leaf->deref();
149 if (leaf ==
nullptr) {
150 throw std::out_of_range(
"yfast::fastmap::iterator");
152 return leaf->deref();
156 if (leaf ==
nullptr) {
157 throw std::out_of_range(
"yfast::fastmap::iterator");
159 return &leaf->deref();
163 template <
bool Const>
164 class ForwardIteratorBase:
public IteratorBase<Const> {
167 using IteratorBase<Const>::leaf;
168 using IteratorBase<Const>::trie;
169 using IteratorBase<Const>::same_as;
170 using IteratorBase<Const>::forward;
171 using IteratorBase<Const>::backward;
174 ForwardIteratorBase() =
default;
175 explicit ForwardIteratorBase(
const typename YFastTrie::Where& where): IteratorBase<Const>(where) {}
178 if (leaf !=
nullptr) {
184 if (leaf !=
nullptr) {
188 *
this = ForwardIteratorBase(trie->rightmost());
193 template <
bool Const_>
194 bool operator == (
const ForwardIteratorBase<Const_>& other)
const {
195 return same_as(other);
198 template <
bool Const_>
199 bool operator != (
const ForwardIteratorBase<Const_>& other)
const {
200 return !same_as(other);
204 template <
bool Const>
205 class ReverseIteratorBase:
public IteratorBase<Const> {
206 friend class fastmap;
208 using IteratorBase<Const>::leaf;
209 using IteratorBase<Const>::trie;
210 using IteratorBase<Const>::same_as;
211 using IteratorBase<Const>::forward;
212 using IteratorBase<Const>::backward;
215 ReverseIteratorBase() =
default;
216 explicit ReverseIteratorBase(
const typename YFastTrie::Where& where): IteratorBase<Const>(where) {}
219 if (leaf !=
nullptr) {
225 if (leaf !=
nullptr) {
229 *
this = ReverseIteratorBase(trie->leftmost());
234 template <
bool Const_>
235 bool operator == (
const ReverseIteratorBase<Const_>& other)
const {
236 return same_as(other);
239 template <
bool Const_>
240 bool operator != (
const ReverseIteratorBase<Const_>& other)
const {
241 return !same_as(other);
252 class iterator:
public ForwardIteratorBase<false> {
253 friend class fastmap;
255 using ForwardIteratorBase<
false>::inc;
256 using ForwardIteratorBase<
false>::dec;
258 explicit iterator(
const typename YFastTrie::Where& where): ForwardIteratorBase<false>(where) {}
261 iterator() =
default;
262 iterator(
const iterator& other) =
default;
264 iterator& operator ++ () {
269 iterator operator ++ (
int) {
275 iterator& operator -- () {
280 iterator operator -- (
int) {
292 const typename YFastTrie::Where& where = --i;
300 class const_iterator:
public ForwardIteratorBase<true> {
301 friend class fastmap;
303 using ForwardIteratorBase<
true>::inc;
304 using ForwardIteratorBase<
true>::dec;
306 explicit const_iterator(
const typename YFastTrie::Where& where): ForwardIteratorBase<true>(where) {}
309 const_iterator() =
default;
310 const_iterator(
const const_iterator& other) =
default;
311 const_iterator(
const iterator& other): ForwardIteratorBase<true>(other) {}
313 const_iterator& operator ++ () {
318 const_iterator operator ++ (
int) {
324 const_iterator& operator -- () {
329 const_iterator operator -- (
int) {
341 const typename YFastTrie::Where& where = --i;
349 class reverse_iterator:
public ReverseIteratorBase<false> {
350 friend class fastmap;
352 using ReverseIteratorBase<
false>::inc;
353 using ReverseIteratorBase<
false>::dec;
355 explicit reverse_iterator(
const typename YFastTrie::Where& where): ReverseIteratorBase<false>(where) {}
358 reverse_iterator() =
default;
359 reverse_iterator(
const reverse_iterator& other) =
default;
361 reverse_iterator& operator ++ () {
366 reverse_iterator operator ++ (
int) {
372 reverse_iterator& operator -- () {
377 reverse_iterator operator -- (
int) {
387 class const_reverse_iterator:
public ReverseIteratorBase<true> {
388 friend class fastmap;
390 using ReverseIteratorBase<
true>::inc;
391 using ReverseIteratorBase<
true>::dec;
393 explicit const_reverse_iterator(
const typename YFastTrie::Where& where): ReverseIteratorBase<true>(where) {}
396 const_reverse_iterator() =
default;
397 const_reverse_iterator(
const const_reverse_iterator& other) =
default;
398 const_reverse_iterator(
const reverse_iterator& other): ReverseIteratorBase<true>(other) {}
400 const_reverse_iterator& operator ++ () {
405 const_reverse_iterator operator ++ (
int) {
411 const_reverse_iterator& operator -- () {
416 const_reverse_iterator operator -- (
int) {
428 explicit fastmap(BitExtractor bx = BitExtractor(), Compare cmp = Compare(), ArbitraryAllocator alloc = ArbitraryAllocator()): _alloc(alloc), _trie(bx, cmp, alloc) {}
429 fastmap(std::initializer_list<std::pair<Key, Value>> array, BitExtractor bx = BitExtractor(), Compare cmp = Compare(), ArbitraryAllocator alloc = ArbitraryAllocator()): _alloc(alloc), _trie(bx, cmp, alloc) {
430 for (
auto& pair: array) {
431 insert(pair.first, pair.second);
434 fastmap(
const fastmap& other) =
delete;
435 fastmap(fastmap&& other)
noexcept =
default;
437 ~fastmap() {
clear(); }
442 [[nodiscard]] std::size_t
size()
const {
return _trie.size(); }
447 [[nodiscard]]
bool empty()
const {
return _trie.size() == 0; }
539 auto where = _trie.find(key);
549 auto where = _trie.find(key);
560 auto where = _trie.pred(key, strict);
571 auto where = _trie.pred(key, strict);
582 auto where = _trie.succ(key, strict);
593 auto where = _trie.succ(key, strict);
621 return succ(key,
true);
630 return succ(key,
true);
641 YFastLeaf* leaf = std::allocator_traits<Alloc>::allocate(_alloc, 1);
642 std::allocator_traits<Alloc>::construct(_alloc, leaf, key);
643 auto where = _trie.insert(leaf);
655 typename const_iterator::value_type&
at(
const Key& key)
const {
658 throw std::out_of_range(
"yfast::fastmap::at");
669 template <
typename ... Args>
671 YFastLeaf* leaf = std::allocator_traits<Alloc>::allocate(_alloc, 1);
672 std::allocator_traits<Alloc>::construct(_alloc, leaf, key, args ...);
673 auto where = _trie.insert(leaf);
674 if (where.leaf !=
nullptr) {
675 std::allocator_traits<Alloc>::destroy(_alloc, where.leaf);
676 std::allocator_traits<Alloc>::deallocate(_alloc, where.leaf, 1);
687 template <
typename Iterator>
689 if (i.trie != &_trie) {
690 throw std::invalid_argument(
"yfast::fastmap::erase");
692 if (i.leaf ==
nullptr) {
697 _trie.remove(i.leaf, i.xleaf);
698 std::allocator_traits<Alloc>::destroy(_alloc, i.leaf);
699 std::allocator_traits<Alloc>::deallocate(_alloc, i.leaf, 1);
721 typename YFastTrie::XFastLeaf* xleaf = _trie.leftmost().xleaf;
722 while (xleaf !=
nullptr) {
723 destroy_subtree(xleaf->value.root());
730 void destroy_subtree(YFastLeaf* leaf) {
731 if (leaf !=
nullptr) {
732 destroy_subtree(leaf->left());
733 destroy_subtree(leaf->right());
734 std::allocator_traits<Alloc>::destroy(_alloc, leaf);
735 std::allocator_traits<Alloc>::deallocate(_alloc, leaf, 1);