3 // Copyright (C) 2005, 2006 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 2, 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 // You should have received a copy of the GNU General Public License
17 // along with this library; see the file COPYING. If not, write to
18 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19 // MA 02111-1307, USA.
21 // As a special exception, you may use this file as part of a free
22 // software library without restriction. Specifically, if other files
23 // instantiate templates or use macros or inline functions from this
24 // file, or you compile this file and link it with other files to
25 // produce an executable, this file does not by itself cause the
26 // resulting executable to be covered by the GNU General Public
27 // License. This exception does not however invalidate any other
28 // reasons why the executable file might be covered by the GNU General
31 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
33 // Permission to use, copy, modify, sell, and distribute this software
34 // is hereby granted without fee, provided that the above copyright
35 // notice appears in all copies, and that both that copyright notice
36 // and this permission notice appear in supporting documentation. None
37 // of the above authors, nor IBM Haifa Research Laboratories, make any
38 // representation about the suitability of this software for any
39 // purpose. It is provided "as is" without express or implied
43 * @file internal_node.hpp
44 * Contains an internal PB_DS_BASE_C_DEC for a patricia tree.
47 #ifndef PB_DS_PAT_TRIE_INTERNAL_NODE_HPP
48 #define PB_DS_PAT_TRIE_INTERNAL_NODE_HPP
50 #ifdef PB_DS_PAT_TRIE_DEBUG_
52 #endif // #ifdef PB_DS_PAT_TRIE_DEBUG_
59 #define PB_DS_CLASS_T_DEC \
62 class E_Access_Traits, \
66 #define PB_DS_CLASS_C_DEC \
67 pat_trie_internal_node< \
73 #define PB_DS_BASE_C_DEC \
80 #define PB_DS_LEAF_C_DEC \
87 #define PB_DS_STATIC_ASSERT(UNIQUE, E) \
89 static_assert_dumclass< \
90 sizeof(static_assert<(bool)(E)>)> \
91 UNIQUE##static_assert_type
93 #ifdef PB_DS_PAT_TRIE_DEBUG_
94 #define PB_DS_DBG_ASSERT(X) assert(X)
95 #define PB_DS_DBG_VERIFY(X) assert(X)
96 #define PB_DS_DBG_ONLY(X) X
97 #else // #ifdef PB_DS_PAT_TRIE_DEBUG_
98 #define PB_DS_DBG_ASSERT(X)
99 #define PB_DS_DBG_VERIFY(X) {if((X)==0);}
100 #define PB_DS_DBG_ONLY(X) ;
101 #endif // #ifdef PB_DS_PAT_TRIE_DEBUG_
103 template<typename Type_Traits,
104 class E_Access_Traits,
107 struct pat_trie_internal_node : public PB_DS_BASE_C_DEC
113 E_Access_Traits::max_size + 1
117 typedef typename Allocator::size_type size_type;
119 typedef E_Access_Traits e_access_traits;
122 typename Allocator::template rebind<
123 e_access_traits>::other::const_pointer
124 const_e_access_traits_pointer;
126 typedef typename e_access_traits::const_iterator const_e_iterator;
129 typename Allocator::template rebind<
130 PB_DS_BASE_C_DEC >::other::pointer
134 typename Allocator::template rebind<
135 PB_DS_BASE_C_DEC >::other::const_pointer
138 typedef PB_DS_LEAF_C_DEC leaf;
141 typename Allocator::template rebind<
145 typedef typename leaf_allocator::pointer leaf_pointer;
147 typedef typename leaf_allocator::const_pointer const_leaf_pointer;
150 typename Allocator::template rebind<
151 PB_DS_CLASS_C_DEC>::other
152 internal_node_allocator;
155 typename Allocator::template rebind<
156 PB_DS_CLASS_C_DEC>::other::const_pointer
157 const_internal_node_pointer;
160 typename Allocator::template rebind<
161 PB_DS_CLASS_C_DEC>::other::pointer
162 internal_node_pointer;
164 PB_DS_STATIC_ASSERT(min_arr_size, arr_size >= 2);
166 typedef typename Type_Traits::value_type value_type;
168 #ifdef PB_DS_PAT_TRIE_DEBUG_
170 typename PB_DS_BASE_C_DEC::subtree_debug_info
172 #endif // #ifdef PB_DS_PAT_TRIE_DEBUG_
174 typedef PB_DS_BASE_C_DEC base_type;
178 get_pref_pos(const_e_iterator b_it, const_e_iterator e_it, const_e_access_traits_pointer p_traits) const;
180 #ifdef PB_DS_PAT_TRIE_DEBUG_
181 virtual subtree_debug_info
182 assert_valid_imp(const_e_access_traits_pointer p_traits) const;
183 #endif // #ifdef PB_DS_PAT_TRIE_DEBUG_
187 typename Allocator::template rebind<
188 node_pointer>::other::pointer
189 node_pointer_pointer;
192 typename Allocator::template rebind<
193 node_pointer>::other::reference
194 node_pointer_reference;
196 #include <ext/pb_ds/detail/pat_trie_/const_child_iterator.hpp>
197 #include <ext/pb_ds/detail/pat_trie_/child_iterator.hpp>
200 pat_trie_internal_node(size_type e_ind, const const_e_iterator pref_b_it);
203 update_prefixes(const_e_access_traits_pointer p_traits);
218 get_child_node(const_e_iterator b_it, const_e_iterator e_it, const_e_access_traits_pointer p_traits);
220 inline const_node_pointer
221 get_child_node(const_e_iterator b_it, const_e_iterator e_it, const_e_access_traits_pointer p_traits) const;
224 get_child_it(const_e_iterator b_it, const_e_iterator e_it, const_e_access_traits_pointer p_traits);
227 get_lower_bound_child_node(const_e_iterator b_it, const_e_iterator e_it, size_type checked_ind, const_e_access_traits_pointer p_traits);
230 add_child(node_pointer p_nd, const_e_iterator b_it, const_e_iterator e_it, const_e_access_traits_pointer p_traits);
232 inline const_node_pointer
233 get_join_child(const_node_pointer p_nd, const_e_access_traits_pointer p_traits) const;
236 get_join_child(node_pointer p_nd, const_e_access_traits_pointer p_traits);
239 remove_child(node_pointer p_nd);
242 remove_child(iterator it);
245 replace_child(node_pointer p_nd, const_e_iterator b_it, const_e_iterator e_it, const_e_access_traits_pointer p_traits);
247 inline const_e_iterator
250 inline const_e_iterator
257 should_be_mine(const_e_iterator b_it, const_e_iterator e_it, size_type checked_ind, const_e_access_traits_pointer p_traits) const;
260 leftmost_descendant();
263 leftmost_descendant() const;
266 rightmost_descendant();
269 rightmost_descendant() const;
271 #ifdef PB_DS_PAT_TRIE_DEBUG_
274 #endif // #ifdef PB_DS_PAT_TRIE_DEBUG_
277 pat_trie_internal_node(const PB_DS_CLASS_C_DEC& other);
280 get_begin_pos() const;
283 const size_type m_e_ind;
285 const_e_iterator m_pref_b_it;
286 const_e_iterator m_pref_e_it;
288 node_pointer m_a_p_children[arr_size];
290 static leaf_allocator s_leaf_alloc;
292 static internal_node_allocator s_internal_node_alloc;
296 typename PB_DS_CLASS_C_DEC::leaf_allocator
297 PB_DS_CLASS_C_DEC::s_leaf_alloc;
300 typename PB_DS_CLASS_C_DEC::internal_node_allocator
301 PB_DS_CLASS_C_DEC::s_internal_node_alloc;
304 inline typename PB_DS_CLASS_C_DEC::size_type
306 get_pref_pos(const_e_iterator b_it, const_e_iterator e_it, const_e_access_traits_pointer p_traits) const
308 if (static_cast<size_t>(std::distance(b_it, e_it)) <= m_e_ind)
311 std::advance(b_it, m_e_ind);
313 return (1 + p_traits->e_pos(*b_it));
318 pat_trie_internal_node(size_type e_ind, const const_e_iterator pref_b_it) :
319 PB_DS_BASE_C_DEC(pat_trie_internal_node_type),
321 m_pref_b_it(pref_b_it),
322 m_pref_e_it(pref_b_it)
324 std::advance(m_pref_e_it, m_e_ind);
326 std::fill(m_a_p_children, m_a_p_children + arr_size,
327 static_cast<node_pointer>(NULL));
333 update_prefixes(const_e_access_traits_pointer p_traits)
335 node_pointer p_first =* begin();
337 if (p_first->m_type == pat_trie_leaf_node_type)
340 E_Access_Traits::extract_key(
341 static_cast<const_leaf_pointer>(p_first)->value()));
344 PB_DS_DBG_ASSERT(p_first->m_type == pat_trie_internal_node_type);
346 m_pref_b_it = static_cast<internal_node_pointer>(p_first)->pref_b_it();
349 m_pref_e_it = m_pref_b_it;
351 std::advance(m_pref_e_it, m_e_ind);
355 typename PB_DS_CLASS_C_DEC::const_iterator
359 return (const_iterator(
360 const_cast<node_pointer_pointer>(m_a_p_children) + get_begin_pos(),
361 const_cast<node_pointer_pointer>(m_a_p_children) + arr_size));
365 typename PB_DS_CLASS_C_DEC::iterator
370 m_a_p_children + get_begin_pos(),
371 m_a_p_children + arr_size));
375 typename PB_DS_CLASS_C_DEC::const_iterator
379 return (const_iterator(
380 const_cast<node_pointer_pointer>(m_a_p_children) + arr_size,
381 const_cast<node_pointer_pointer>(m_a_p_children) + arr_size));
385 typename PB_DS_CLASS_C_DEC::iterator
389 return (iterator( m_a_p_children + arr_size, m_a_p_children + arr_size));
393 inline typename PB_DS_CLASS_C_DEC::node_pointer
395 get_child_node(const_e_iterator b_it, const_e_iterator e_it, const_e_access_traits_pointer p_traits)
397 const size_type i = get_pref_pos( b_it, e_it, p_traits);
399 PB_DS_DBG_ASSERT(i < arr_size);
401 return (m_a_p_children[i]);
405 inline typename PB_DS_CLASS_C_DEC::iterator
407 get_child_it(const_e_iterator b_it, const_e_iterator e_it, const_e_access_traits_pointer p_traits)
409 const size_type i = get_pref_pos( b_it, e_it, p_traits);
411 PB_DS_DBG_ASSERT(i < arr_size);
413 PB_DS_DBG_ASSERT(m_a_p_children[i] != NULL);
415 return (iterator(m_a_p_children + i, m_a_p_children + i));
419 inline typename PB_DS_CLASS_C_DEC::const_node_pointer
421 get_child_node(const_e_iterator b_it, const_e_iterator e_it, const_e_access_traits_pointer p_traits) const
423 return (const_cast<node_pointer>(get_child_node(b_it, e_it, p_traits)));
427 typename PB_DS_CLASS_C_DEC::node_pointer
429 get_lower_bound_child_node(const_e_iterator b_it, const_e_iterator e_it, size_type checked_ind, const_e_access_traits_pointer p_traits)
431 if (!should_be_mine(b_it, e_it, checked_ind, p_traits))
433 if (p_traits->cmp_prefixes(b_it, e_it, m_pref_b_it, m_pref_e_it, true))
434 return (leftmost_descendant());
436 return (rightmost_descendant());
439 size_type i = get_pref_pos( b_it, e_it, p_traits);
441 PB_DS_DBG_ASSERT(i < arr_size);
443 if (m_a_p_children[i] != NULL)
444 return (m_a_p_children[i]);
446 while (++i < arr_size)
447 if (m_a_p_children[i] != NULL)
449 if (m_a_p_children[i]->m_type == pat_trie_leaf_node_type)
450 return (m_a_p_children[i]);
452 PB_DS_DBG_ASSERT(m_a_p_children[i]->m_type ==
453 pat_trie_internal_node_type);
455 return (static_cast<internal_node_pointer>(
456 m_a_p_children[i])->leftmost_descendant());
459 return (rightmost_descendant());
463 inline typename PB_DS_CLASS_C_DEC::node_pointer
465 add_child(node_pointer p_nd, const_e_iterator b_it, const_e_iterator e_it, const_e_access_traits_pointer p_traits)
467 const size_type i = get_pref_pos( b_it, e_it, p_traits);
469 PB_DS_DBG_ASSERT(i < arr_size);
471 if (m_a_p_children[i] == NULL)
473 m_a_p_children[i] = p_nd;
475 p_nd->m_p_parent = this;
480 return (m_a_p_children[i]);
484 typename PB_DS_CLASS_C_DEC::const_node_pointer
486 get_join_child(const_node_pointer p_nd, const_e_access_traits_pointer p_traits) const
488 return (const_cast<internal_node_pointer>(this)->get_join_child(
489 const_cast<node_pointer>(p_nd),
494 typename PB_DS_CLASS_C_DEC::node_pointer
496 get_join_child(node_pointer p_nd, const_e_access_traits_pointer p_traits)
500 const_e_iterator b_it;
501 const_e_iterator e_it;
503 if (p_nd->m_type == pat_trie_leaf_node_type)
505 typename Type_Traits::const_key_reference r_key =
506 e_access_traits::extract_key(
507 static_cast<const_leaf_pointer>(p_nd)->value());
509 b_it = p_traits->begin(r_key);
510 e_it = p_traits->end(r_key);
514 b_it = static_cast<internal_node_pointer>(p_nd)->pref_b_it();
515 e_it = static_cast<internal_node_pointer>(p_nd)->pref_e_it();
518 i = get_pref_pos(b_it, e_it, p_traits);
520 PB_DS_DBG_ASSERT(i < arr_size);
522 return (m_a_p_children[i]);
528 remove_child(node_pointer p_nd)
532 for (; i < arr_size; ++i)
533 if (m_a_p_children[i] == p_nd)
535 m_a_p_children[i] = NULL;
540 PB_DS_DBG_ASSERT(i != arr_size);
544 typename PB_DS_CLASS_C_DEC::iterator
546 remove_child(iterator it)
552 * it.m_p_p_cur = NULL;
560 replace_child(node_pointer p_nd, const_e_iterator b_it, const_e_iterator e_it, const_e_access_traits_pointer p_traits)
562 const size_type i = get_pref_pos( b_it, e_it, p_traits);
564 PB_DS_DBG_ASSERT(i < arr_size);
566 m_a_p_children[i] = p_nd;
568 p_nd->m_p_parent = this;
572 inline typename PB_DS_CLASS_C_DEC::const_e_iterator
576 return (m_pref_b_it);
580 inline typename PB_DS_CLASS_C_DEC::const_e_iterator
584 return (m_pref_e_it);
588 inline typename PB_DS_CLASS_C_DEC::size_type
598 should_be_mine(const_e_iterator b_it, const_e_iterator e_it, size_type checked_ind, const_e_access_traits_pointer p_traits) const
603 const size_type num_es = std::distance(b_it, e_it);
605 if (num_es < m_e_ind)
608 const_e_iterator key_b_it = b_it;
609 std::advance(key_b_it, checked_ind);
610 const_e_iterator key_e_it = b_it;
611 std::advance(key_e_it, m_e_ind);
613 const_e_iterator value_b_it = m_pref_b_it;
614 std::advance(value_b_it, checked_ind);
615 const_e_iterator value_e_it = m_pref_b_it;
616 std::advance(value_e_it, m_e_ind);
618 return (p_traits->equal_prefixes( key_b_it, key_e_it, value_b_it, value_e_it));
622 typename PB_DS_CLASS_C_DEC::leaf_pointer
624 leftmost_descendant()
626 node_pointer p_pot =* begin();
628 if (p_pot->m_type == pat_trie_leaf_node_type)
629 return (static_cast<leaf_pointer>(p_pot));
631 PB_DS_DBG_ASSERT(p_pot->m_type == pat_trie_internal_node_type);
633 return (static_cast<internal_node_pointer>(p_pot)->leftmost_descendant());
637 typename PB_DS_CLASS_C_DEC::const_leaf_pointer
639 leftmost_descendant() const
641 return (const_cast<internal_node_pointer>(this)->leftmost_descendant());
645 typename PB_DS_CLASS_C_DEC::leaf_pointer
647 rightmost_descendant()
649 const size_type num_children = std::distance(begin(), end());
651 PB_DS_DBG_ASSERT(num_children >= 2);
653 iterator it = begin();
654 std::advance(it, num_children - 1);
656 node_pointer p_pot =* it;
658 if (p_pot->m_type == pat_trie_leaf_node_type)
659 return (static_cast<leaf_pointer>(p_pot));
661 PB_DS_DBG_ASSERT(p_pot->m_type == pat_trie_internal_node_type);
663 return (static_cast<internal_node_pointer>(p_pot)->rightmost_descendant());
667 typename PB_DS_CLASS_C_DEC::const_leaf_pointer
669 rightmost_descendant() const
671 return (const_cast<internal_node_pointer>(this)->rightmost_descendant());
674 #ifdef PB_DS_PAT_TRIE_DEBUG_
676 typename PB_DS_CLASS_C_DEC::size_type
682 #endif // #ifdef PB_DS_PAT_TRIE_DEBUG_
685 typename PB_DS_CLASS_C_DEC::size_type
687 get_begin_pos() const
691 for (i = 0; i < arr_size&& m_a_p_children[i] == NULL; ++i)
697 #ifdef PB_DS_PAT_TRIE_DEBUG_
699 typename PB_DS_CLASS_C_DEC::subtree_debug_info
701 assert_valid_imp(const_e_access_traits_pointer p_traits) const
703 PB_DS_DBG_ASSERT(base_type::m_type == pat_trie_internal_node_type);
706 static_cast<size_type>(std::distance(pref_b_it(), pref_e_it())) ==
710 std::distance(begin(), end()) >= 2);
712 for (typename pat_trie_internal_node::const_iterator it = begin();
715 const_node_pointer p_nd =* it;
717 PB_DS_DBG_ASSERT(p_nd->m_p_parent == this);
719 subtree_debug_info child_ret = p_nd->assert_valid_imp(p_traits);
722 static_cast<size_type>(std::distance(child_ret.first, child_ret.second)) >=
725 PB_DS_DBG_ASSERT(should_be_mine(child_ret.first, child_ret.second, 0, p_traits));
728 get_pref_pos(child_ret.first, child_ret.second, p_traits) ==
729 static_cast<size_type>(it.m_p_p_cur - m_a_p_children));
732 return (std::make_pair(pref_b_it(), pref_e_it()));
734 #endif // #ifdef PB_DS_PAT_TRIE_DEBUG_
736 #undef PB_DS_CLASS_T_DEC
738 #undef PB_DS_CLASS_C_DEC
740 #undef PB_DS_BASE_C_DEC
742 #undef PB_DS_LEAF_C_DEC
744 #undef PB_DS_STATIC_ASSERT
746 #undef PB_DS_DBG_ASSERT
747 #undef PB_DS_DBG_VERIFY
748 #undef PB_DS_DBG_ONLY
750 } // namespace detail
753 #endif // #ifndef PB_DS_PAT_TRIE_NODE_BASE_HPP