3 // Copyright (C) 2005, 2006, 2009, 2011 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the terms
7 // of the GNU General Public License as published by the Free Software
8 // Foundation; either version 3, or (at your option) any later
11 // This library is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
25 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
27 // Permission to use, copy, modify, sell, and distribute this software
28 // is hereby granted without fee, provided that the above copyright
29 // notice appears in all copies, and that both that copyright notice
30 // and this permission notice appear in supporting documentation. None
31 // of the above authors, nor IBM Haifa Research Laboratories, make any
32 // representation about the suitability of this software for any
33 // purpose. It is provided "as is" without express or implied
37 * @file pat_trie_/pat_trie_base.hpp
38 * Contains the base class for a patricia tree.
41 #ifndef PB_DS_PAT_TRIE_BASE
42 #define PB_DS_PAT_TRIE_BASE
44 #include <debug/debug.h>
50 /// Base type for PATRICIA trees.
53 /// Three types of nodes.
61 /// Metadata base primary template.
62 template<typename Metadata, typename _Alloc>
65 typedef Metadata metadata_type;
66 typedef _Alloc allocator_type;
67 typedef typename _Alloc::template rebind<Metadata> __rebind_m;
68 typedef typename __rebind_m::other::const_reference const_reference;
72 { return m_metadata; }
74 metadata_type m_metadata;
77 /// Specialization for null metadata.
78 template<typename _Alloc>
79 struct _Metadata<null_type, _Alloc>
81 typedef null_type metadata_type;
82 typedef _Alloc allocator_type;
87 template<typename _ATraits, typename Metadata>
92 typedef typename Metadata::allocator_type _Alloc;
95 typedef _Alloc allocator_type;
96 typedef _ATraits access_traits;
97 typedef typename _ATraits::type_traits type_traits;
98 typedef typename _Alloc::template rebind<_Node_base> __rebind_n;
99 typedef typename __rebind_n::other::pointer node_pointer;
101 node_pointer m_p_parent;
102 const node_type m_type;
104 _Node_base(node_type type) : m_type(type)
107 typedef typename _Alloc::template rebind<_ATraits> __rebind_at;
108 typedef typename __rebind_at::other::const_pointer a_const_pointer;
109 typedef typename _ATraits::const_iterator a_const_iterator;
111 #ifdef _GLIBCXX_DEBUG
112 typedef std::pair<a_const_iterator, a_const_iterator> node_debug_info;
115 assert_valid(a_const_pointer p_traits,
116 const char* __file, int __line) const
117 { assert_valid_imp(p_traits, __file, __line); }
119 virtual node_debug_info
120 assert_valid_imp(a_const_pointer, const char*, int) const = 0;
125 /// Head node for PATRICIA tree.
126 template<typename _ATraits, typename Metadata>
128 : public _Node_base<_ATraits, Metadata>
130 typedef _Node_base<_ATraits, Metadata> base_type;
131 typedef typename base_type::type_traits type_traits;
132 typedef typename base_type::node_pointer node_pointer;
134 node_pointer m_p_min;
135 node_pointer m_p_max;
137 _Head() : base_type(head_node) { }
139 #ifdef _GLIBCXX_DEBUG
140 typedef typename base_type::node_debug_info node_debug_info;
141 typedef typename base_type::a_const_pointer a_const_pointer;
143 virtual node_debug_info
144 assert_valid_imp(a_const_pointer, const char* __file, int __line) const
146 _GLIBCXX_DEBUG_VERIFY_AT(false,
147 _M_message("Assertion from %1;:%2;")
148 ._M_string(__FILE__)._M_integer(__LINE__),
150 return node_debug_info();
156 /// Leaf node for PATRICIA tree.
157 template<typename _ATraits, typename Metadata>
159 : public _Node_base<_ATraits, Metadata>
161 typedef _Node_base<_ATraits, Metadata> base_type;
162 typedef typename base_type::type_traits type_traits;
163 typedef typename type_traits::value_type value_type;
164 typedef typename type_traits::reference reference;
165 typedef typename type_traits::const_reference const_reference;
173 _Leaf(const_reference other)
174 : base_type(leaf_node), m_value(other) { }
184 #ifdef _GLIBCXX_DEBUG
185 typedef typename base_type::node_debug_info node_debug_info;
186 typedef typename base_type::a_const_pointer a_const_pointer;
188 virtual node_debug_info
189 assert_valid_imp(a_const_pointer p_traits,
190 const char* __file, int __line) const
192 PB_DS_DEBUG_VERIFY(base_type::m_type == leaf_node);
194 const_reference r_val = value();
195 return std::make_pair(p_traits->begin(p_traits->extract_key(r_val)),
196 p_traits->end(p_traits->extract_key(r_val)));
205 /// Internal node type, PATRICIA tree.
206 template<typename _ATraits, typename Metadata>
208 : public _Node_base<_ATraits, Metadata>
210 typedef _Node_base<_ATraits, Metadata> base_type;
211 typedef typename base_type::type_traits type_traits;
212 typedef typename base_type::access_traits access_traits;
213 typedef typename type_traits::value_type value_type;
214 typedef typename base_type::allocator_type _Alloc;
215 typedef _Alloc allocator_type;
216 typedef typename _Alloc::size_type size_type;
219 typedef typename base_type::a_const_pointer a_const_pointer;
220 typedef typename base_type::a_const_iterator a_const_iterator;
222 typedef typename base_type::node_pointer node_pointer;
223 typedef typename _Alloc::template rebind<base_type> __rebind_n;
224 typedef typename __rebind_n::other::const_pointer node_const_pointer;
226 typedef _Leaf<_ATraits, Metadata> leaf;
227 typedef typename _Alloc::template rebind<leaf>::other __rebind_l;
228 typedef typename __rebind_l::pointer leaf_pointer;
229 typedef typename __rebind_l::const_pointer leaf_const_pointer;
231 typedef typename _Alloc::template rebind<_Inode>::other __rebind_in;
232 typedef typename __rebind_in::pointer inode_pointer;
233 typedef typename __rebind_in::const_pointer inode_const_pointer;
236 get_pref_pos(a_const_iterator, a_const_iterator, a_const_pointer) const;
239 typedef typename _Alloc::template rebind<node_pointer>::other __rebind_np;
240 typedef typename __rebind_np::pointer node_pointer_pointer;
241 typedef typename __rebind_np::reference node_pointer_reference;
245 arr_size = _ATraits::max_size + 1
247 PB_DS_STATIC_ASSERT(min_arr_size, arr_size >= 2);
250 /// Constant child iterator.
251 struct const_iterator
253 node_pointer_pointer m_p_p_cur;
254 node_pointer_pointer m_p_p_end;
256 typedef std::forward_iterator_tag iterator_category;
257 typedef typename _Alloc::difference_type difference_type;
258 typedef node_pointer value_type;
259 typedef node_pointer_pointer pointer;
260 typedef node_pointer_reference reference;
262 const_iterator(node_pointer_pointer p_p_cur = 0,
263 node_pointer_pointer p_p_end = 0)
264 : m_p_p_cur(p_p_cur), m_p_p_end(p_p_end)
268 operator==(const const_iterator& other) const
269 { return m_p_p_cur == other.m_p_p_cur; }
272 operator!=(const const_iterator& other) const
273 { return m_p_p_cur != other.m_p_p_cur; }
280 while (m_p_p_cur != m_p_p_end && *m_p_p_cur == 0);
287 const_iterator ret_it(*this);
292 const node_pointer_pointer
295 _GLIBCXX_DEBUG_ONLY(assert_referencible();)
302 _GLIBCXX_DEBUG_ONLY(assert_referencible();)
307 #ifdef _GLIBCXX_DEBUG
309 assert_referencible() const
310 { _GLIBCXX_DEBUG_ASSERT(m_p_p_cur != m_p_p_end && *m_p_p_cur != 0); }
316 struct iterator : public const_iterator
319 typedef std::forward_iterator_tag iterator_category;
320 typedef typename _Alloc::difference_type difference_type;
321 typedef node_pointer value_type;
322 typedef node_pointer_pointer pointer;
323 typedef node_pointer_reference reference;
326 iterator(node_pointer_pointer p_p_cur = 0,
327 node_pointer_pointer p_p_end = 0)
328 : const_iterator(p_p_cur, p_p_end) { }
331 operator==(const iterator& other) const
332 { return const_iterator::m_p_p_cur == other.m_p_p_cur; }
335 operator!=(const iterator& other) const
336 { return const_iterator::m_p_p_cur != other.m_p_p_cur; }
341 const_iterator::operator++();
348 iterator ret_it(*this);
356 _GLIBCXX_DEBUG_ONLY(const_iterator::assert_referencible();)
357 return const_iterator::m_p_p_cur;
363 _GLIBCXX_DEBUG_ONLY(const_iterator::assert_referencible();)
364 return *const_iterator::m_p_p_cur;
369 _Inode(size_type, const a_const_iterator);
372 update_prefixes(a_const_pointer);
387 get_child_node(a_const_iterator, a_const_iterator, a_const_pointer);
389 inline node_const_pointer
390 get_child_node(a_const_iterator, a_const_iterator, a_const_pointer) const;
393 get_child_it(a_const_iterator, a_const_iterator, a_const_pointer);
396 get_lower_bound_child_node(a_const_iterator, a_const_iterator,
397 size_type, a_const_pointer);
400 add_child(node_pointer, a_const_iterator, a_const_iterator,
403 inline node_const_pointer
404 get_join_child(node_const_pointer, a_const_pointer) const;
407 get_join_child(node_pointer, a_const_pointer);
410 remove_child(node_pointer);
413 remove_child(iterator);
416 replace_child(node_pointer, a_const_iterator, a_const_iterator,
419 inline a_const_iterator
422 inline a_const_iterator
426 should_be_mine(a_const_iterator, a_const_iterator, size_type,
427 a_const_pointer) const;
430 leftmost_descendant();
433 leftmost_descendant() const;
436 rightmost_descendant();
439 rightmost_descendant() const;
441 #ifdef _GLIBCXX_DEBUG
442 typedef typename base_type::node_debug_info node_debug_info;
444 virtual node_debug_info
445 assert_valid_imp(a_const_pointer, const char*, int) const;
453 _Inode(const _Inode&);
456 get_begin_pos() const;
458 static __rebind_l s_leaf_alloc;
459 static __rebind_in s_inode_alloc;
461 const size_type m_e_ind;
462 a_const_iterator m_pref_b_it;
463 a_const_iterator m_pref_e_it;
464 node_pointer m_a_p_children[arr_size];
467 #define PB_DS_CONST_IT_C_DEC \
468 _CIter<Node, Leaf, Head, Inode, Is_Forward_Iterator>
470 #define PB_DS_CONST_ODIR_IT_C_DEC \
471 _CIter<Node, Leaf, Head, Inode, !Is_Forward_Iterator>
473 #define PB_DS_IT_C_DEC \
474 _Iter<Node, Leaf, Head, Inode, Is_Forward_Iterator>
476 #define PB_DS_ODIR_IT_C_DEC \
477 _Iter<Node, Leaf, Head, Inode, !Is_Forward_Iterator>
481 template<typename Node, typename Leaf, typename Head, typename Inode,
482 bool Is_Forward_Iterator>
486 // These types are all the same for the first four template arguments.
487 typedef typename Node::allocator_type allocator_type;
488 typedef typename Node::type_traits type_traits;
490 typedef std::bidirectional_iterator_tag iterator_category;
491 typedef typename allocator_type::difference_type difference_type;
492 typedef typename type_traits::value_type value_type;
493 typedef typename type_traits::pointer pointer;
494 typedef typename type_traits::reference reference;
495 typedef typename type_traits::const_pointer const_pointer;
496 typedef typename type_traits::const_reference const_reference;
498 typedef allocator_type _Alloc;
499 typedef typename _Alloc::template rebind<Node> __rebind_n;
500 typedef typename __rebind_n::other::pointer node_pointer;
501 typedef typename _Alloc::template rebind<Leaf> __rebind_l;
502 typedef typename __rebind_l::other::pointer leaf_pointer;
503 typedef typename __rebind_l::other::const_pointer leaf_const_pointer;
504 typedef typename _Alloc::template rebind<Head> __rebind_h;
505 typedef typename __rebind_h::other::pointer head_pointer;
507 typedef typename _Alloc::template rebind<Inode> __rebind_in;
508 typedef typename __rebind_in::other::pointer inode_pointer;
509 typedef typename Inode::iterator inode_iterator;
513 _CIter(node_pointer p_nd = 0) : m_p_nd(p_nd)
516 _CIter(const PB_DS_CONST_ODIR_IT_C_DEC& other)
517 : m_p_nd(other.m_p_nd)
521 operator=(const _CIter& other)
523 m_p_nd = other.m_p_nd;
528 operator=(const PB_DS_CONST_ODIR_IT_C_DEC& other)
530 m_p_nd = other.m_p_nd;
537 _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == leaf_node);
538 return &static_cast<leaf_pointer>(m_p_nd)->value();
544 _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == leaf_node);
545 return static_cast<leaf_pointer>(m_p_nd)->value();
549 operator==(const _CIter& other) const
550 { return m_p_nd == other.m_p_nd; }
553 operator==(const PB_DS_CONST_ODIR_IT_C_DEC& other) const
554 { return m_p_nd == other.m_p_nd; }
557 operator!=(const _CIter& other) const
558 { return m_p_nd != other.m_p_nd; }
561 operator!=(const PB_DS_CONST_ODIR_IT_C_DEC& other) const
562 { return m_p_nd != other.m_p_nd; }
567 inc(integral_constant<int, Is_Forward_Iterator>());
574 _CIter ret_it(m_p_nd);
582 dec(integral_constant<int, Is_Forward_Iterator>());
589 _CIter ret_it(m_p_nd);
597 { dec(true_type()); }
602 if (m_p_nd->m_type == head_node)
604 m_p_nd = static_cast<head_pointer>(m_p_nd)->m_p_min;
608 node_pointer p_y = m_p_nd->m_p_parent;
609 while (p_y->m_type != head_node && get_larger_sibling(m_p_nd) == 0)
612 p_y = p_y->m_p_parent;
615 if (p_y->m_type == head_node)
620 m_p_nd = leftmost_descendant(get_larger_sibling(m_p_nd));
625 { inc(true_type()); }
630 if (m_p_nd->m_type == head_node)
632 m_p_nd = static_cast<head_pointer>(m_p_nd)->m_p_max;
636 node_pointer p_y = m_p_nd->m_p_parent;
637 while (p_y->m_type != head_node && get_smaller_sibling(m_p_nd) == 0)
640 p_y = p_y->m_p_parent;
643 if (p_y->m_type == head_node)
648 m_p_nd = rightmost_descendant(get_smaller_sibling(m_p_nd));
652 get_larger_sibling(node_pointer p_nd)
654 inode_pointer p_parent = static_cast<inode_pointer>(p_nd->m_p_parent);
656 inode_iterator it = p_parent->begin();
660 inode_iterator next_it = it;
662 return (next_it == p_parent->end())? 0 : *next_it;
666 get_smaller_sibling(node_pointer p_nd)
668 inode_pointer p_parent = static_cast<inode_pointer>(p_nd->m_p_parent);
670 inode_iterator it = p_parent->begin();
674 inode_iterator prev_it;
684 _GLIBCXX_DEBUG_ASSERT(false);
689 leftmost_descendant(node_pointer p_nd)
691 if (p_nd->m_type == leaf_node)
692 return static_cast<leaf_pointer>(p_nd);
693 return static_cast<inode_pointer>(p_nd)->leftmost_descendant();
697 rightmost_descendant(node_pointer p_nd)
699 if (p_nd->m_type == leaf_node)
700 return static_cast<leaf_pointer>(p_nd);
701 return static_cast<inode_pointer>(p_nd)->rightmost_descendant();
707 template<typename Node, typename Leaf, typename Head, typename Inode,
708 bool Is_Forward_Iterator>
710 : public _CIter<Node, Leaf, Head, Inode, Is_Forward_Iterator>
713 typedef _CIter<Node, Leaf, Head, Inode, Is_Forward_Iterator>
715 typedef typename base_type::allocator_type allocator_type;
716 typedef typename base_type::type_traits type_traits;
717 typedef typename type_traits::value_type value_type;
718 typedef typename type_traits::pointer pointer;
719 typedef typename type_traits::reference reference;
721 typedef typename base_type::node_pointer node_pointer;
722 typedef typename base_type::leaf_pointer leaf_pointer;
723 typedef typename base_type::leaf_const_pointer leaf_const_pointer;
724 typedef typename base_type::head_pointer head_pointer;
725 typedef typename base_type::inode_pointer inode_pointer;
727 _Iter(node_pointer p_nd = 0)
728 : base_type(p_nd) { }
730 _Iter(const PB_DS_ODIR_IT_C_DEC& other)
731 : base_type(other.m_p_nd) { }
734 operator=(const _Iter& other)
736 base_type::m_p_nd = other.m_p_nd;
741 operator=(const PB_DS_ODIR_IT_C_DEC& other)
743 base_type::m_p_nd = other.m_p_nd;
750 _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd->m_type == leaf_node);
751 return &static_cast<leaf_pointer>(base_type::m_p_nd)->value();
757 _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd->m_type == leaf_node);
758 return static_cast<leaf_pointer>(base_type::m_p_nd)->value();
764 base_type::operator++();
771 _Iter ret(base_type::m_p_nd);
779 base_type::operator--();
786 _Iter ret(base_type::m_p_nd);
792 #undef PB_DS_CONST_ODIR_IT_C_DEC
793 #undef PB_DS_ODIR_IT_C_DEC
796 #define PB_DS_PAT_TRIE_NODE_CONST_ITERATOR_C_DEC \
797 _Node_citer<Node, Leaf, Head, Inode, _CIterator, Iterator, _ATraits, _Alloc>
799 #define PB_DS_PAT_TRIE_NODE_ITERATOR_C_DEC \
800 _Node_iter<Node, Leaf, Head, Inode, _CIterator, Iterator, _ATraits, _Alloc>
802 /// Node const iterator.
803 template<typename Node,
813 typedef typename _Alloc::template rebind<Node> __rebind_n;
814 typedef typename __rebind_n::other::pointer node_pointer;
816 typedef typename _Alloc::template rebind<Leaf> __rebind_l;
817 typedef typename __rebind_l::other::pointer leaf_pointer;
818 typedef typename __rebind_l::other::const_pointer leaf_const_pointer;
820 typedef typename _Alloc::template rebind<Inode> __rebind_in;
821 typedef typename __rebind_in::other::pointer inode_pointer;
822 typedef typename __rebind_in::other::const_pointer inode_const_pointer;
824 typedef typename Node::a_const_pointer a_const_pointer;
825 typedef typename Node::a_const_iterator a_const_iterator;
831 if (m_p_nd->m_type == leaf_node)
833 leaf_const_pointer lcp = static_cast<leaf_const_pointer>(m_p_nd);
834 return m_p_traits->begin(m_p_traits->extract_key(lcp->value()));
836 _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node);
837 return static_cast<inode_const_pointer>(m_p_nd)->pref_b_it();
843 if (m_p_nd->m_type == leaf_node)
845 leaf_const_pointer lcp = static_cast<leaf_const_pointer>(m_p_nd);
846 return m_p_traits->end(m_p_traits->extract_key(lcp->value()));
848 _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node);
849 return static_cast<inode_const_pointer>(m_p_nd)->pref_e_it();
853 typedef trivial_iterator_tag iterator_category;
854 typedef trivial_iterator_difference_type difference_type;
855 typedef typename _Alloc::size_type size_type;
857 typedef _CIterator value_type;
858 typedef value_type reference;
859 typedef value_type const_reference;
862 typedef typename Node::metadata_type metadata_type;
864 /// Const metadata reference type.
865 typedef typename _Alloc::template rebind<metadata_type> __rebind_m;
866 typedef typename __rebind_m::other __rebind_ma;
867 typedef typename __rebind_ma::const_reference metadata_const_reference;
870 _Node_citer(node_pointer p_nd = 0, a_const_pointer p_traits = 0)
871 : m_p_nd(const_cast<node_pointer>(p_nd)), m_p_traits(p_traits)
874 /// Subtree valid prefix.
875 std::pair<a_const_iterator, a_const_iterator>
877 { return std::make_pair(pref_begin(), pref_end()); }
879 /// Const access; returns the __const iterator* associated with
880 /// the current leaf.
884 _GLIBCXX_DEBUG_ASSERT(num_children() == 0);
885 return _CIterator(m_p_nd);
889 metadata_const_reference
891 { return m_p_nd->get_metadata(); }
893 /// Returns the number of children in the corresponding node.
897 if (m_p_nd->m_type == leaf_node)
899 _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node);
900 inode_pointer inp = static_cast<inode_pointer>(m_p_nd);
901 return std::distance(inp->begin(), inp->end());
904 /// Returns a __const node __iterator to the corresponding node's
907 get_child(size_type i) const
909 _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node);
910 inode_pointer inp = static_cast<inode_pointer>(m_p_nd);
911 typename Inode::iterator it = inp->begin();
913 return _Node_citer(*it, m_p_traits);
916 /// Compares content to a different iterator object.
918 operator==(const _Node_citer& other) const
919 { return m_p_nd == other.m_p_nd; }
921 /// Compares content (negatively) to a different iterator object.
923 operator!=(const _Node_citer& other) const
924 { return m_p_nd != other.m_p_nd; }
927 a_const_pointer m_p_traits;
932 template<typename Node,
940 : public _Node_citer<Node, Leaf, Head, Inode, _CIterator, Iterator, _Alloc>
943 typedef _Node_citer<Node, Leaf, Head, Inode,
944 _CIterator, Iterator, _Alloc> base_type;
945 typedef typename _Alloc::template rebind<Node> __rebind_n;
946 typedef typename __rebind_n::other::pointer node_pointer;
947 typedef typename base_type::inode_pointer inode_pointer;
948 typedef typename base_type::a_const_pointer a_const_pointer;
949 typedef Iterator iterator;
952 typedef typename base_type::size_type size_type;
954 typedef Iterator value_type;
955 typedef value_type reference;
956 typedef value_type const_reference;
958 _Node_iter(node_pointer p_nd = 0, a_const_pointer p_traits = 0)
959 : base_type(p_nd, p_traits)
962 /// Access; returns the iterator* associated with the current leaf.
966 _GLIBCXX_DEBUG_ASSERT(base_type::num_children() == 0);
967 return iterator(base_type::m_p_nd);
970 /// Returns a node __iterator to the corresponding node's i-th child.
972 get_child(size_type i) const
974 _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd->m_type == i_node);
976 typename Inode::iterator it =
977 static_cast<inode_pointer>(base_type::m_p_nd)->begin();
980 return _Node_iter(*it, base_type::m_p_traits);
986 #define PB_DS_CLASS_T_DEC \
987 template<typename _ATraits, typename Metadata>
989 #define PB_DS_CLASS_C_DEC \
990 pat_trie_base::_Inode<_ATraits, Metadata>
993 typename PB_DS_CLASS_C_DEC::__rebind_l
994 PB_DS_CLASS_C_DEC::s_leaf_alloc;
997 typename PB_DS_CLASS_C_DEC::__rebind_in
998 PB_DS_CLASS_C_DEC::s_inode_alloc;
1001 inline typename PB_DS_CLASS_C_DEC::size_type
1003 get_pref_pos(a_const_iterator b_it, a_const_iterator e_it,
1004 a_const_pointer p_traits) const
1006 if (static_cast<std::size_t>(std::distance(b_it, e_it)) <= m_e_ind)
1008 std::advance(b_it, m_e_ind);
1009 return 1 + p_traits->e_pos(*b_it);
1014 _Inode(size_type len, const a_const_iterator it)
1015 : base_type(i_node), m_e_ind(len), m_pref_b_it(it), m_pref_e_it(it)
1017 std::advance(m_pref_e_it, m_e_ind);
1018 std::fill(m_a_p_children, m_a_p_children + arr_size,
1019 static_cast<node_pointer>(0));
1025 update_prefixes(a_const_pointer p_traits)
1027 node_pointer p_first = *begin();
1028 if (p_first->m_type == leaf_node)
1030 leaf_const_pointer p = static_cast<leaf_const_pointer>(p_first);
1031 m_pref_b_it = p_traits->begin(access_traits::extract_key(p->value()));
1035 inode_pointer p = static_cast<inode_pointer>(p_first);
1036 _GLIBCXX_DEBUG_ASSERT(p_first->m_type == i_node);
1037 m_pref_b_it = p->pref_b_it();
1039 m_pref_e_it = m_pref_b_it;
1040 std::advance(m_pref_e_it, m_e_ind);
1044 typename PB_DS_CLASS_C_DEC::const_iterator
1048 typedef node_pointer_pointer pointer_type;
1049 pointer_type p = const_cast<pointer_type>(m_a_p_children);
1050 return const_iterator(p + get_begin_pos(), p + arr_size);
1054 typename PB_DS_CLASS_C_DEC::iterator
1058 return iterator(m_a_p_children + get_begin_pos(),
1059 m_a_p_children + arr_size);
1063 typename PB_DS_CLASS_C_DEC::const_iterator
1067 typedef node_pointer_pointer pointer_type;
1068 pointer_type p = const_cast<pointer_type>(m_a_p_children) + arr_size;
1069 return const_iterator(p, p);
1073 typename PB_DS_CLASS_C_DEC::iterator
1076 { return iterator(m_a_p_children + arr_size, m_a_p_children + arr_size); }
1079 inline typename PB_DS_CLASS_C_DEC::node_pointer
1081 get_child_node(a_const_iterator b_it, a_const_iterator e_it,
1082 a_const_pointer p_traits)
1084 const size_type i = get_pref_pos(b_it, e_it, p_traits);
1085 _GLIBCXX_DEBUG_ASSERT(i < arr_size);
1086 return m_a_p_children[i];
1090 inline typename PB_DS_CLASS_C_DEC::iterator
1092 get_child_it(a_const_iterator b_it, a_const_iterator e_it,
1093 a_const_pointer p_traits)
1095 const size_type i = get_pref_pos(b_it, e_it, p_traits);
1096 _GLIBCXX_DEBUG_ASSERT(i < arr_size);
1097 _GLIBCXX_DEBUG_ASSERT(m_a_p_children[i] != 0);
1098 return iterator(m_a_p_children + i, m_a_p_children + i);
1102 inline typename PB_DS_CLASS_C_DEC::node_const_pointer
1104 get_child_node(a_const_iterator b_it, a_const_iterator e_it,
1105 a_const_pointer p_traits) const
1106 { return const_cast<node_pointer>(get_child_node(b_it, e_it, p_traits)); }
1109 typename PB_DS_CLASS_C_DEC::node_pointer
1111 get_lower_bound_child_node(a_const_iterator b_it, a_const_iterator e_it,
1112 size_type checked_ind,
1113 a_const_pointer p_traits)
1115 if (!should_be_mine(b_it, e_it, checked_ind, p_traits))
1117 if (p_traits->cmp_prefixes(b_it, e_it, m_pref_b_it,
1119 return leftmost_descendant();
1120 return rightmost_descendant();
1123 size_type i = get_pref_pos(b_it, e_it, p_traits);
1124 _GLIBCXX_DEBUG_ASSERT(i < arr_size);
1126 if (m_a_p_children[i] != 0)
1127 return m_a_p_children[i];
1129 while (++i < arr_size)
1130 if (m_a_p_children[i] != 0)
1132 const node_type& __nt = m_a_p_children[i]->m_type;
1133 node_pointer ret = m_a_p_children[i];
1135 if (__nt == leaf_node)
1138 _GLIBCXX_DEBUG_ASSERT(__nt == i_node);
1139 inode_pointer inp = static_cast<inode_pointer>(ret);
1140 return inp->leftmost_descendant();
1143 return rightmost_descendant();
1147 inline typename PB_DS_CLASS_C_DEC::node_pointer
1149 add_child(node_pointer p_nd, a_const_iterator b_it, a_const_iterator e_it,
1150 a_const_pointer p_traits)
1152 const size_type i = get_pref_pos(b_it, e_it, p_traits);
1153 _GLIBCXX_DEBUG_ASSERT(i < arr_size);
1154 if (m_a_p_children[i] == 0)
1156 m_a_p_children[i] = p_nd;
1157 p_nd->m_p_parent = this;
1160 return m_a_p_children[i];
1164 typename PB_DS_CLASS_C_DEC::node_const_pointer
1166 get_join_child(node_const_pointer p_nd,
1167 a_const_pointer p_tr) const
1169 node_pointer p = const_cast<node_pointer>(p_nd);
1170 return const_cast<inode_pointer>(this)->get_join_child(p, p_tr);
1174 typename PB_DS_CLASS_C_DEC::node_pointer
1176 get_join_child(node_pointer p_nd, a_const_pointer p_traits)
1179 a_const_iterator b_it;
1180 a_const_iterator e_it;
1181 if (p_nd->m_type == leaf_node)
1183 leaf_const_pointer p = static_cast<leaf_const_pointer>(p_nd);
1185 typedef typename type_traits::key_const_reference kcr;
1186 kcr r_key = access_traits::extract_key(p->value());
1187 b_it = p_traits->begin(r_key);
1188 e_it = p_traits->end(r_key);
1192 b_it = static_cast<inode_pointer>(p_nd)->pref_b_it();
1193 e_it = static_cast<inode_pointer>(p_nd)->pref_e_it();
1195 i = get_pref_pos(b_it, e_it, p_traits);
1196 _GLIBCXX_DEBUG_ASSERT(i < arr_size);
1197 return m_a_p_children[i];
1203 remove_child(node_pointer p_nd)
1206 for (; i < arr_size; ++i)
1207 if (m_a_p_children[i] == p_nd)
1209 m_a_p_children[i] = 0;
1212 _GLIBCXX_DEBUG_ASSERT(i != arr_size);
1218 remove_child(iterator it)
1219 { *it.m_p_p_cur = 0; }
1224 replace_child(node_pointer p_nd, a_const_iterator b_it,
1225 a_const_iterator e_it,
1226 a_const_pointer p_traits)
1228 const size_type i = get_pref_pos(b_it, e_it, p_traits);
1229 _GLIBCXX_DEBUG_ASSERT(i < arr_size);
1230 m_a_p_children[i] = p_nd;
1231 p_nd->m_p_parent = this;
1235 inline typename PB_DS_CLASS_C_DEC::a_const_iterator
1238 { return m_pref_b_it; }
1241 inline typename PB_DS_CLASS_C_DEC::a_const_iterator
1244 { return m_pref_e_it; }
1249 should_be_mine(a_const_iterator b_it, a_const_iterator e_it,
1250 size_type checked_ind,
1251 a_const_pointer p_traits) const
1256 const size_type num_es = std::distance(b_it, e_it);
1257 if (num_es < m_e_ind)
1260 a_const_iterator key_b_it = b_it;
1261 std::advance(key_b_it, checked_ind);
1262 a_const_iterator key_e_it = b_it;
1263 std::advance(key_e_it, m_e_ind);
1265 a_const_iterator value_b_it = m_pref_b_it;
1266 std::advance(value_b_it, checked_ind);
1267 a_const_iterator value_e_it = m_pref_b_it;
1268 std::advance(value_e_it, m_e_ind);
1270 return p_traits->equal_prefixes(key_b_it, key_e_it, value_b_it,
1275 typename PB_DS_CLASS_C_DEC::leaf_pointer
1277 leftmost_descendant()
1279 node_pointer p_pot = *begin();
1280 if (p_pot->m_type == leaf_node)
1281 return (static_cast<leaf_pointer>(p_pot));
1282 _GLIBCXX_DEBUG_ASSERT(p_pot->m_type == i_node);
1283 return static_cast<inode_pointer>(p_pot)->leftmost_descendant();
1287 typename PB_DS_CLASS_C_DEC::leaf_const_pointer
1289 leftmost_descendant() const
1290 { return const_cast<inode_pointer>(this)->leftmost_descendant(); }
1293 typename PB_DS_CLASS_C_DEC::leaf_pointer
1295 rightmost_descendant()
1297 const size_type num_children = std::distance(begin(), end());
1298 _GLIBCXX_DEBUG_ASSERT(num_children >= 2);
1300 iterator it = begin();
1301 std::advance(it, num_children - 1);
1302 node_pointer p_pot =* it;
1303 if (p_pot->m_type == leaf_node)
1304 return static_cast<leaf_pointer>(p_pot);
1305 _GLIBCXX_DEBUG_ASSERT(p_pot->m_type == i_node);
1306 return static_cast<inode_pointer>(p_pot)->rightmost_descendant();
1310 typename PB_DS_CLASS_C_DEC::leaf_const_pointer
1312 rightmost_descendant() const
1313 { return const_cast<inode_pointer>(this)->rightmost_descendant(); }
1316 typename PB_DS_CLASS_C_DEC::size_type
1318 get_begin_pos() const
1321 for (; i < arr_size && m_a_p_children[i] == 0; ++i)
1326 #ifdef _GLIBCXX_DEBUG
1328 typename PB_DS_CLASS_C_DEC::node_debug_info
1330 assert_valid_imp(a_const_pointer p_traits,
1331 const char* __file, int __line) const
1333 PB_DS_DEBUG_VERIFY(base_type::m_type == i_node);
1334 PB_DS_DEBUG_VERIFY(static_cast<size_type>(std::distance(pref_b_it(), pref_e_it())) == m_e_ind);
1335 PB_DS_DEBUG_VERIFY(std::distance(begin(), end()) >= 2);
1337 for (typename _Inode::const_iterator it = begin(); it != end(); ++it)
1339 node_const_pointer p_nd = *it;
1340 PB_DS_DEBUG_VERIFY(p_nd->m_p_parent == this);
1341 node_debug_info child_ret = p_nd->assert_valid_imp(p_traits,
1344 PB_DS_DEBUG_VERIFY(static_cast<size_type>(std::distance(child_ret.first, child_ret.second)) >= m_e_ind);
1345 PB_DS_DEBUG_VERIFY(should_be_mine(child_ret.first, child_ret.second, 0, p_traits));
1346 PB_DS_DEBUG_VERIFY(get_pref_pos(child_ret.first, child_ret.second, p_traits) == static_cast<size_type>(it.m_p_p_cur - m_a_p_children));
1348 return std::make_pair(pref_b_it(), pref_e_it());
1352 #undef PB_DS_CLASS_T_DEC
1353 #undef PB_DS_CLASS_C_DEC
1354 } // namespace detail
1355 } // namespace __gnu_pbds