neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
segmented_tree.hpp
Go to the documentation of this file.
1// segmented_tree.h
2/*
3 * Copyright (c) 2020 Leigh Johnston.
4 *
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * * Neither the name of Leigh Johnston nor the names of any
19 * other contributors to this software may be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#pragma once
37
38#include <neolib/neolib.hpp>
39#include <variant>
42
43namespace neolib
44{
45 template <typename T, size_t N = 64, typename Alloc = std::allocator<T> >
47 {
49 typedef self_type tree_type;
50 public:
51 typedef T value_type;
52 typedef Alloc allocator_type;
55 typedef typename std::allocator_traits<allocator_type>::pointer pointer;
56 typedef typename std::allocator_traits<allocator_type>::const_pointer const_pointer;
57 typedef typename std::allocator_traits<allocator_type>::difference_type difference_type;
58 typedef typename std::allocator_traits<allocator_type>::size_type size_type;
59 private:
60 class node
61 {
62 friend class segmented_tree<T, N, Alloc>;
63 public:
64 typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<node> node_allocator_type;
66 private:
67 struct root_place_holder {};
68 public:
69 node() :
70 iParent{ nullptr },
71 iSkipChildren{ false },
72 iDescendentCount{ 0 },
73 iSkippedDescendentCount{ 0 },
74 iContents{ root_place_holder{} }
75 {}
76 node(const node& other) :
77 iParent{ other.iParent },
78 iChildren( other.iChildren ),
79 iSkipChildren{ other.iSkipChildren },
80 iDescendentCount{ other.iDescendentCount },
81 iSkippedDescendentCount{ other.iSkippedDescendentCount },
82 iContents{ other.iContents }
83 {
84 update_parents(*this);
85 }
86 node(node&& other) :
87 iParent{},
88 iSkipChildren{ false },
89 iDescendentCount{ 0 },
90 iSkippedDescendentCount{ 0 },
91 iContents{ root_place_holder{} }
92 {
93 std::swap(iParent, other.iParent);
94 std::swap(iChildren, other.iChildren);
95 std::swap(iSkipChildren, other.iSkipChildren);
96 std::swap(iDescendentCount, other.iDescendentCount);
97 std::swap(iSkippedDescendentCount, other.iSkippedDescendentCount);
98 std::swap(iContents, other.iContents);
99 update_parents(*this);
100 }
101 node(node& parent, const value_type& value) :
102 iParent{ &parent },
103 iSkipChildren{ false },
104 iDescendentCount{ 0 },
105 iSkippedDescendentCount{ 0 },
106 iContents { value }
107 {
108 }
109 ~node()
110 {
111 }
112 public:
113 node& operator=(const node& other)
114 {
115 iParent = other.iParent;
116 iChildren = other.iChildren;
117 iSkipChildren = other.iSkipChildren;
118 iDescendentCount = other.iDescendentCount;
119 iSkippedDescendentCount = other.iSkippedDescendentCount;
120 iContents = other.iContents;
121 update_parents(*this);
122 return *this;
123 }
124 node& operator=(node&& other)
125 {
126 std::swap(iParent, other.iParent);
127 std::swap(iChildren, other.iChildren);
128 std::swap(iSkipChildren, other.iSkipChildren);
129 std::swap(iDescendentCount, other.iDescendentCount);
130 std::swap(iSkippedDescendentCount, other.iSkippedDescendentCount);
131 std::swap(iContents, other.iContents);
132 update_parents(*this);
133 return *this;
134 }
135 private:
136 bool is_root() const
137 {
138 return iParent == nullptr;
139 }
140 const node& parent() const
141 {
142 if (!is_root())
143 return *iParent;
144 return *this;
145 }
146 node& parent()
147 {
148 if (!is_root())
149 return *iParent;
150 return *this;
151 }
152 const value_type& value() const
153 {
154 return std::get<value_type>(iContents);
155 }
156 value_type& value()
157 {
158 return std::get<value_type>(iContents);
159 }
160 const child_list& children() const
161 {
162 return iChildren;
163 }
164 child_list& children()
165 {
166 return iChildren;
167 }
168 bool empty() const
169 {
170 return iChildren.empty();
171 }
172 std::size_t depth() const
173 {
174 std::size_t result = 0;
175 node const* n = this;
176 while (!n->parent().is_root())
177 {
178 ++result;
179 n = &n->parent();
180 }
181 return result;
182 }
183 bool children_skipped() const
184 {
185 return iSkipChildren;
186 }
187 void skip_children()
188 {
189 if (!iSkipChildren)
190 {
191 iSkipChildren = true;
192 parent().increment_skipped_descendent_count(descendent_count() - skipped_descendent_count());
193 }
194 }
195 void unskip_children()
196 {
197 if (iSkipChildren)
198 {
199 iSkipChildren = false;
200 parent().decrement_skipped_descendent_count(descendent_count() - skipped_descendent_count());
201 }
202 }
203 private:
204 std::size_t descendent_count() const
205 {
206 return iDescendentCount;
207 }
208 void increment_descendent_count()
209 {
210 ++iDescendentCount;
211 if (!is_root())
212 parent().increment_descendent_count();
213 }
214 void decrement_descendent_count()
215 {
216 --iDescendentCount;
217 if (!is_root())
218 parent().decrement_descendent_count();
219 }
220 std::size_t skipped_descendent_count() const
221 {
222 return iSkippedDescendentCount;
223 }
224 void increment_skipped_descendent_count(std::size_t aCount)
225 {
226 iSkippedDescendentCount += aCount;
227 if (!is_root())
228 parent().increment_skipped_descendent_count(aCount);
229 }
230 void decrement_skipped_descendent_count(std::size_t aCount)
231 {
232 iSkippedDescendentCount -= aCount;
233 if (!is_root())
234 parent().decrement_skipped_descendent_count(aCount);
235 }
236 void update_parents(node& parent)
237 {
238 for (auto& child : parent.children())
239 {
240 child.iParent = &parent;
241 update_parents(child);
242 }
243 }
244 private:
245 node* iParent;
246 child_list iChildren;
247 bool iSkipChildren;
248 std::size_t iDescendentCount;
249 std::size_t iSkippedDescendentCount;
250 std::variant<value_type, root_place_holder> iContents;
251 };
252 typedef typename node::child_list node_child_list;
253 typedef typename node::child_list::const_iterator node_child_list_const_iterator;
254 typedef typename node::child_list::iterator node_child_list_iterator;
255 public:
256 enum class iterator_type
257 {
258 Normal,
259 Sibling,
260 Skip
261 };
262 template <iterator_type Type>
263 class basic_const_iterator;
264 template <iterator_type Type>
266 {
267 typedef basic_iterator<Type> self_type;
268 friend class segmented_tree<T, N, Alloc>;
269 public:
270 typedef std::bidirectional_iterator_tag iterator_category; // todo: make iterator random access when logarithmic complexty indexing available
273 typedef typename tree_type::pointer pointer;
275 public:
276 basic_iterator() : iParentNode{}, iBaseIterator{} {}
277 basic_iterator(node& parentNode, node_child_list_iterator childIterator) : iParentNode{ &parentNode }, iBaseIterator{ childIterator } {}
278 template <iterator_type Type2>
279 basic_iterator(basic_iterator<Type2> const& other) : iParentNode{ other.iParentNode }, iBaseIterator{ other.iBaseIterator } {}
280 public:
281 template <iterator_type Type2>
282 bool operator==(basic_iterator<Type2> const& other) const
283 {
284 return iParentNode == other.iParentNode && iBaseIterator == other.iBaseIterator;
285 }
286 template <iterator_type Type2>
287 bool operator!=(basic_iterator<Type2> const& other) const
288 {
289 return !(*this == other);
290 }
291 public:
292 self_type& operator++()
293 {
294 if constexpr (Type == iterator_type::Sibling)
295 ++iBaseIterator;
296 else
297 {
298 if (children().empty() || (Type == iterator_type::Skip && children_skipped()))
299 {
300 ++iBaseIterator;
301 while (iBaseIterator == parent_node().children().end() && !parent_node().is_root())
302 *this = self_type{ parent_node().parent(), std::next(parent_node().parent().children().iter(parent_node())) };
303 }
304 else
305 *this = self_type{ our_node(), children().begin() };
306 }
307 return *this;
308 }
309 self_type operator++(int) const
310 {
311 self_type temp = *this;
312 ++temp;
313 return temp;
314 }
315 self_type& operator--()
316 {
317 if constexpr (Type == iterator_type::Sibling)
318 --iBaseIterator;
319 else
320 {
321 if (iBaseIterator == parent_node().children().begin())
322 *this = self_type{ parent_node().parent(), parent_node().parent().children().iter(parent_node()) };
323 else
324 {
325 --iBaseIterator;
326 while (!children().empty() && !(Type == iterator_type::Skip && children_skipped()))
327 *this = self_type{ our_node(), std::prev(children().end()) };
328 }
329 }
330 return *this;
331 }
332 self_type operator--(int) const
333 {
334 self_type temp = *this;
335 --temp;
336 return temp;
337 }
338 public:
340 {
341 return our_node().value();
342 }
344 {
345 return &(**this);
346 }
347 public:
349 {
350 return basic_const_iterator<iterator_type::Sibling>{ parent_node().parent(), parent_node().parent().children().iter(parent_node()) };
351 }
357 {
358 return basic_iterator<iterator_type::Sibling>{ parent_node().parent(), parent_node().parent().children().iter(parent_node()) };
359 }
377 {
378 return cend();
379 }
381 {
382 return basic_iterator<iterator_type::Sibling>{ our_node(), children().end() };
383 }
384 std::reverse_iterator<basic_const_iterator<iterator_type::Sibling>> crbegin() const
385 {
386 return std::make_reverse_iterator(cend());
387 }
388 std::reverse_iterator<basic_const_iterator<iterator_type::Sibling>> rbegin() const
389 {
390 return std::make_reverse_iterator(cend());
391 }
392 std::reverse_iterator<basic_iterator<iterator_type::Sibling>> rbegin()
393 {
394 return std::make_reverse_iterator(end());
395 }
396 std::reverse_iterator<basic_const_iterator<iterator_type::Sibling>> crend() const
397 {
398 return std::make_reverse_iterator(cbegin());
399 }
400 std::reverse_iterator<basic_const_iterator<iterator_type::Sibling>> rend() const
401 {
402 return std::make_reverse_iterator(cbegin());
403 }
404 std::reverse_iterator<basic_iterator<iterator_type::Sibling>> rend()
405 {
406 return std::make_reverse_iterator(begin());
407 }
408 public:
409 bool parent_is_root() const
410 {
411 return parent_node().is_root();
412 }
413 std::size_t depth() const
414 {
415 return our_node().depth();
416 }
417 std::size_t descendent_count() const
418 {
419 return our_node().descendent_count();
420 }
421 bool children_skipped() const
422 {
423 return our_node().children_skipped();
424 }
426 {
427 our_node().skip_children();
428 }
430 {
431 our_node().unskip_children();
432 }
433 private:
434 bool is_singular() const { return iParentNode == nullptr; }
435 node& parent_node() const { if (is_singular()) throw singular_iterator(); return *iParentNode; }
436 node& our_node() const { if (is_singular()) throw singular_iterator(); return *base(); }
437 node_child_list_iterator base() const { if (is_singular()) throw singular_iterator(); return iBaseIterator; }
438 node_child_list& children() const { if (is_singular()) throw singular_iterator(); return our_node().children(); }
439 private:
440 node* iParentNode;
441 node_child_list_iterator iBaseIterator;
442 };
443 template <iterator_type Type>
445 {
446 typedef basic_const_iterator<Type> self_type;
447 friend class segmented_tree<T, N, Alloc>;
448 public:
449 typedef std::bidirectional_iterator_tag iterator_category; // todo: make iterator random access when logarithmic complexty indexing available
454 public:
455 basic_const_iterator() : iParentNode{}, iBaseIterator{} {}
456 basic_const_iterator(node const& parentNode, node_child_list_const_iterator childIterator) : iParentNode{ &parentNode }, iBaseIterator{ childIterator } {}
457 template <iterator_type Type2>
458 basic_const_iterator(basic_const_iterator<Type2> const& other) : iParentNode{ other.iParentNode }, iBaseIterator{ other.iBaseIterator } {}
459 template <iterator_type Type2>
460 basic_const_iterator(basic_iterator<Type2> const& other) : iParentNode{ other.iParentNode }, iBaseIterator{ other.iBaseIterator } {}
461 public:
462 template <iterator_type Type2>
464 {
465 return iParentNode == other.iParentNode && iBaseIterator == other.iBaseIterator;
466 }
467 template <iterator_type Type2>
469 {
470 return !(*this == other);
471 }
472 public:
473 self_type& operator++()
474 {
475 if constexpr (Type == iterator_type::Sibling)
476 ++iBaseIterator;
477 else
478 {
479 if (children().empty() || (Type == iterator_type::Skip && children_skipped()))
480 {
481 ++iBaseIterator;
482 while (iBaseIterator == parent_node().children().end() && !parent_node().is_root())
483 *this = self_type{ parent_node().parent(), std::next(parent_node().parent().children().iter(parent_node())) };
484 }
485 else
486 *this = self_type{ our_node(), children().begin() };
487 }
488 return *this;
489 }
490 self_type operator++(int) const
491 {
492 self_type temp = *this;
493 ++temp;
494 return temp;
495 }
496 self_type& operator--()
497 {
498 if constexpr (Type == iterator_type::Sibling)
499 --iBaseIterator;
500 else
501 {
502 if (iBaseIterator == parent_node().children().begin())
503 *this = self_type{ parent_node().parent(), parent_node().parent().children().iter(parent_node()) };
504 else
505 {
506 --iBaseIterator;
507 while (!children().empty() && !(Type == iterator_type::Skip && children_skipped()))
508 *this = self_type{ our_node(), std::prev(children().end()) };
509 }
510 }
511 return *this;
512 }
513 self_type operator--(int) const
514 {
515 self_type temp = *this;
516 --temp;
517 return temp;
518 }
519 public:
521 {
522 return our_node().value();
523 }
525 {
526 return &(**this);
527 }
528 public:
530 {
531 return basic_const_iterator<iterator_type::Sibling>{ parent_node().parent(), parent_node().parent().children().iter(parent_node()) };
532 }
550 {
551 return cend();
552 }
553 std::reverse_iterator<basic_const_iterator<iterator_type::Sibling>> crbegin() const
554 {
555 return std::make_reverse_iterator(cend());
556 }
557 std::reverse_iterator<basic_const_iterator<iterator_type::Sibling>> rbegin() const
558 {
559 return std::make_reverse_iterator(cend());
560 }
561 std::reverse_iterator<basic_const_iterator<iterator_type::Sibling>> crend() const
562 {
563 return std::make_reverse_iterator(cbegin());
564 }
565 std::reverse_iterator<basic_const_iterator<iterator_type::Sibling>> rend() const
566 {
567 return std::make_reverse_iterator(cbegin());
568 }
569 public:
570 bool parent_is_root() const
571 {
572 return parent_node().is_root();
573 }
574 std::size_t depth() const
575 {
576 return our_node().depth();
577 }
578 std::size_t descendent_count() const
579 {
580 return our_node().descendent_count();
581 }
582 bool children_skipped() const
583 {
584 return our_node().children_skipped();
585 }
586 private:
587 bool is_singular() const { return iParentNode == nullptr; }
588 node const& parent_node() const { if (is_singular()) throw singular_iterator(); return *iParentNode; }
589 node const& our_node() const { if (is_singular()) throw singular_iterator(); return *base(); }
590 node_child_list_const_iterator base() const { if (is_singular()) throw singular_iterator(); return iBaseIterator; }
591 node_child_list const& children() const { if (is_singular()) throw singular_iterator(); return our_node().children(); }
592 private:
593 node const* iParentNode;
594 node_child_list_const_iterator iBaseIterator;
595 };
602
603 // construction
604 public:
606 {
607 }
609 {
610 }
611
612 // traversals
613 public:
614 bool empty() const
615 {
616 return root().empty();
617 }
618 std::size_t size() const
619 {
620 return root().descendent_count();
621 }
622 std::size_t ksize() const
623 {
624 return root().descendent_count() - root().skipped_descendent_count();
625 }
627 {
628 return const_iterator{ root(), root().children().begin() };
629 }
631 {
632 return cbegin();
633 }
635 {
636 return iterator{ root(), root().children().begin() };
637 }
639 {
640 return const_iterator{ root(), root().children().end() };
641 }
643 {
644 return cend();
645 }
647 {
648 return iterator{ root(), root().children().end() };
649 }
651 {
652 return const_sibling_iterator{ root(), root().children().begin() };
653 }
655 {
656 return csbegin();
657 }
659 {
660 return sibling_iterator{ root(), root().children().begin() };
661 }
663 {
664 return const_sibling_iterator{ root(), root().children().end() };
665 }
667 {
668 return csend();
669 }
671 {
672 return sibling_iterator{ root(), root().children().end() };
673 }
675 {
676 return const_skip_iterator{ root(), root().children().begin() };
677 }
679 {
680 return ckbegin();
681 }
683 {
684 return skip_iterator{ root(), root().children().begin() };
685 }
687 {
688 return const_skip_iterator{ root(), root().children().end() };
689 }
691 {
692 return cend();
693 }
695 {
696 return skip_iterator{ root(), root().children().end() };
697 }
698 std::reverse_iterator<const_iterator> crbegin() const
699 {
700 return std::make_reverse_iterator(cend());
701 }
702 std::reverse_iterator<const_iterator> rbegin() const
703 {
704 return std::make_reverse_iterator(cend());
705 }
706 std::reverse_iterator<iterator> rbegin()
707 {
708 return std::make_reverse_iterator(end());
709 }
710 std::reverse_iterator<const_iterator> crend() const
711 {
712 return std::make_reverse_iterator(cbegin());
713 }
714 std::reverse_iterator<const_iterator> rend() const
715 {
716 return std::make_reverse_iterator(cbegin());
717 }
718 std::reverse_iterator<iterator> rend()
719 {
720 return std::make_reverse_iterator(begin());
721 }
722 std::reverse_iterator<const_sibling_iterator> crsbegin() const
723 {
724 return std::make_reverse_iterator(csend());
725 }
726 std::reverse_iterator<const_sibling_iterator> rsbegin() const
727 {
728 return std::make_reverse_iterator(csend());
729 }
730 std::reverse_iterator<sibling_iterator> rsbegin()
731 {
732 return std::make_reverse_iterator(send());
733 }
734 std::reverse_iterator<const_sibling_iterator> crsend() const
735 {
736 return std::make_reverse_iterator(csbegin());
737 }
738 std::reverse_iterator<const_sibling_iterator> rsend() const
739 {
740 return std::make_reverse_iterator(csbegin());
741 }
742 std::reverse_iterator<sibling_iterator> rsend()
743 {
744 return std::make_reverse_iterator(sbegin());
745 }
746 std::reverse_iterator<const_skip_iterator> crkbegin() const
747 {
748 return std::make_reverse_iterator(ckend());
749 }
750 std::reverse_iterator<const_skip_iterator> rkbegin() const
751 {
752 return std::make_reverse_iterator(ckend());
753 }
754 std::reverse_iterator<skip_iterator> rkbegin()
755 {
756 return std::make_reverse_iterator(kend());
757 }
758 std::reverse_iterator<const_skip_iterator> crkend() const
759 {
760 return std::make_reverse_iterator(ckbegin());
761 }
762 std::reverse_iterator<const_skip_iterator> rkend() const
763 {
764 return std::make_reverse_iterator(ckbegin());
765 }
766 std::reverse_iterator<skip_iterator> rkend()
767 {
768 return std::make_reverse_iterator(kbegin());
769 }
770
771 // modifiers
772 public:
773 void clear()
774 {
775 iRoot.~node();
776 new(&iRoot) node{};
777 }
779 {
780 auto& parent = const_cast<node&>(position.parent_node());
781 auto& children = const_cast<node_child_list&>(parent.children());
782 auto result = sibling_iterator{ parent, children.emplace_insert(position.base(), parent, value) };
783 parent.increment_descendent_count();
784 return result;
785 }
786 void push_back(const value_type& value)
787 {
788 push_back(root(), value);
789 }
790 void push_back(const_iterator pos, const value_type& value)
791 {
792 push_back(to_node(pos), value);
793 }
794 void push_front(const value_type& value)
795 {
796 push_front(root(), value);
797 }
798 void push_front(const_iterator pos, const value_type& value)
799 {
800 push_front(to_node(pos), value);
801 }
803 {
804 auto mutablePos = std::next(begin(), std::distance(cbegin(), pos));
805 node& parent = mutablePos.parent_node();
806 auto result = iterator{ parent, parent.children().erase(mutablePos.base()) };
807 parent.decrement_descendent_count();
808 return result;
809 }
810 void sort()
811 {
812 sort(std::less<value_type>{});
813 }
814 template <typename Predicate>
815 void sort(Predicate pred)
816 {
817 sort(root(), pred);
818 }
819
820 // implementation
821 private:
822 node const& root() const
823 {
824 return iRoot;
825 }
826 node& root()
827 {
828 return iRoot;
829 }
830 const node& to_node(const_iterator pos) const
831 {
832 if (!pos.is_singular())
833 return pos.our_node();
834 return root();
835 }
836 node& to_node(const_iterator pos)
837 {
838 if (!pos.is_singular())
839 return std::next(begin(), std::distance(cbegin(), pos)).our_node();
840 return root();
841 }
842 node const& first_node() const
843 {
844 auto n = &root();
845 while (!n->empty())
846 n = &n->children()[0];
847 return *n;
848 }
849 node& first_node()
850 {
851 return const_cast<node&>(const_cast<const self_type&>(*this).first_node());
852 }
853 node const& last_node() const
854 {
855 auto n = &root();
856 while (!n->empty())
857 n = &*std::prev(n->children().end());
858 return *n;
859 }
860 node& last_node()
861 {
862 return const_cast<node&>(const_cast<const self_type&>(*this).last_node());
863 }
864 private:
865 void push_back(node& parent, const value_type& value)
866 {
867 parent.children().emplace_back(parent, value);
868 parent.increment_descendent_count();
869 }
870 void push_front(node& parent, const value_type& value)
871 {
872 parent.children().emplace_front(parent, value);
873 parent.increment_descendent_count();
874 }
875 private:
876 template <typename Predicate>
877 void sort(node& parent, Predicate pred)
878 {
879 std::sort(parent.children().begin(), parent.children().end(),
880 [&pred](const node& lhs, const node& rhs)
881 {
882 auto const& lhsValue = lhs.value();
883 auto const& rhsValue = rhs.value();
884 auto result = pred(lhsValue, rhsValue);
885 return result;
886 });
887 if (parent.children().size() != parent.descendent_count())
888 for (auto& child : parent.children())
889 sort(child, pred);
890 }
891
892 // state
893 private:
894 node iRoot;
895 };
896}
const_iterator end() const
const_iterator begin() const
iterator emplace_insert(const_iterator aPosition, Args &&... aArguments)
basic_const_iterator< iterator_type::Sibling > cparent() const
std::bidirectional_iterator_tag iterator_category
basic_const_iterator(basic_const_iterator< Type2 > const &other)
basic_const_iterator< iterator_type::Sibling > begin() const
std::reverse_iterator< basic_const_iterator< iterator_type::Sibling > > crend() const
bool operator!=(basic_const_iterator< Type2 > const &other) const
std::reverse_iterator< basic_const_iterator< iterator_type::Sibling > > rbegin() const
bool operator==(basic_const_iterator< Type2 > const &other) const
basic_const_iterator< iterator_type::Sibling > cbegin() const
basic_const_iterator(basic_iterator< Type2 > const &other)
basic_const_iterator< iterator_type::Sibling > parent() const
basic_const_iterator< iterator_type::Sibling > end() const
std::reverse_iterator< basic_const_iterator< iterator_type::Sibling > > crbegin() const
basic_const_iterator< iterator_type::Sibling > cend() const
basic_const_iterator(node const &parentNode, node_child_list_const_iterator childIterator)
std::reverse_iterator< basic_const_iterator< iterator_type::Sibling > > rend() const
std::reverse_iterator< basic_iterator< iterator_type::Sibling > > rbegin()
basic_const_iterator< iterator_type::Sibling > end() const
std::reverse_iterator< basic_const_iterator< iterator_type::Sibling > > rend() const
basic_const_iterator< iterator_type::Sibling > begin() const
basic_const_iterator< iterator_type::Sibling > cbegin() const
std::bidirectional_iterator_tag iterator_category
std::reverse_iterator< basic_iterator< iterator_type::Sibling > > rend()
basic_const_iterator< iterator_type::Sibling > parent() const
std::reverse_iterator< basic_const_iterator< iterator_type::Sibling > > rbegin() const
basic_iterator< iterator_type::Sibling > parent()
basic_iterator< iterator_type::Sibling > end()
basic_const_iterator< iterator_type::Sibling > cend() const
basic_iterator(basic_iterator< Type2 > const &other)
basic_iterator< iterator_type::Sibling > begin()
std::reverse_iterator< basic_const_iterator< iterator_type::Sibling > > crbegin() const
bool operator!=(basic_iterator< Type2 > const &other) const
basic_const_iterator< iterator_type::Sibling > cparent() const
bool operator==(basic_iterator< Type2 > const &other) const
std::reverse_iterator< basic_const_iterator< iterator_type::Sibling > > crend() const
basic_iterator(node &parentNode, node_child_list_iterator childIterator)
tree_type::difference_type difference_type
const_sibling_iterator csbegin() const
void push_front(const value_type &value)
std::size_t size() const
const_skip_iterator ckend() const
const_sibling_iterator sbegin() const
std::reverse_iterator< const_iterator > crend() const
const_iterator begin() const
std::reverse_iterator< skip_iterator > rkend()
std::reverse_iterator< const_skip_iterator > rkbegin() const
sibling_iterator insert(const_sibling_iterator position, const value_type &value)
const_iterator cbegin() const
basic_iterator< iterator_type::Normal > iterator
std::reverse_iterator< sibling_iterator > rsend()
std::reverse_iterator< const_skip_iterator > crkbegin() const
std::reverse_iterator< iterator > rend()
std::reverse_iterator< const_iterator > rend() const
std::reverse_iterator< const_sibling_iterator > rsend() const
std::allocator_traits< allocator_type >::const_pointer const_pointer
std::size_t ksize() const
std::reverse_iterator< const_sibling_iterator > crsbegin() const
basic_iterator< iterator_type::Sibling > sibling_iterator
void push_back(const_iterator pos, const value_type &value)
const_iterator end() const
const_iterator cend() const
iterator erase(const_iterator pos)
const_skip_iterator ckbegin() const
std::reverse_iterator< iterator > rbegin()
std::reverse_iterator< const_sibling_iterator > rsbegin() const
sibling_iterator send()
std::allocator_traits< allocator_type >::difference_type difference_type
basic_const_iterator< iterator_type::Skip > const_skip_iterator
std::allocator_traits< allocator_type >::size_type size_type
std::reverse_iterator< sibling_iterator > rsbegin()
const_sibling_iterator csend() const
std::reverse_iterator< const_skip_iterator > rkend() const
const_skip_iterator kbegin() const
std::reverse_iterator< const_iterator > rbegin() const
sibling_iterator sbegin()
std::reverse_iterator< const_sibling_iterator > crsend() const
void push_back(const value_type &value)
const_sibling_iterator send() const
void push_front(const_iterator pos, const value_type &value)
basic_const_iterator< iterator_type::Normal > const_iterator
basic_const_iterator< iterator_type::Sibling > const_sibling_iterator
std::allocator_traits< allocator_type >::pointer pointer
std::reverse_iterator< const_iterator > crbegin() const
const value_type & const_reference
const_skip_iterator kend() const
void sort(Predicate pred)
std::reverse_iterator< const_skip_iterator > crkend() const
basic_iterator< iterator_type::Skip > skip_iterator
std::reverse_iterator< skip_iterator > rkbegin()
void swap(plf::hive< element_type, allocator_type > &a, plf::hive< element_type, allocator_type > &b) noexcept(std::allocator_traits< allocator_type >::propagate_on_container_swap::value||std::allocator_traits< allocator_type >::is_always_equal::value)
Definition plf_hive.h:4776
it_type next(it_type it, const typename iterator_traits< it_type >::difference_type distance=1)
Definition plf_hive.h:89
iterator_traits< it_type >::difference_type distance(const it_type first, const it_type last)
Definition plf_hive.h:107
it_type prev(it_type it, const typename iterator_traits< it_type >::difference_type distance=1)
Definition plf_hive.h:98