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
44 * Contains an implementation class for a patricia tree.
48 * This implementation loosely borrows ideas from:
49 * 1) "Fast Mergeable Integer Maps", Okasaki, Gill 1998
50 * 2) "Ptset: Sets of integers implemented as Patricia trees",
51 * Jean-Christophe Filliatr, 2000
54 #include <ext/pb_ds/detail/pat_trie_/synth_e_access_traits.hpp>
55 #include <ext/pb_ds/detail/pat_trie_/node_base.hpp>
56 #include <ext/pb_ds/exception.hpp>
57 #include <ext/pb_ds/tag_and_trait.hpp>
58 #include <ext/pb_ds/detail/eq_fn/eq_by_less.hpp>
59 #include <ext/pb_ds/detail/types_traits.hpp>
60 #include <ext/pb_ds/tree_policy.hpp>
61 #include <ext/pb_ds/detail/cond_dealtor.hpp>
62 #include <ext/pb_ds/detail/type_utils.hpp>
69 #ifdef PB_DS_USE_MAP_DEBUG_BASE
70 #include <ext/pb_ds/detail/map_debug_base.hpp>
71 #endif // #ifdef PB_DS_USE_MAP_DEBUG_BASE
78 #ifdef PB_DS_PAT_TRIE_DEBUG_
79 #define PB_DS_DBG_ASSERT(X) assert(X)
80 #define PB_DS_DBG_VERIFY(X) assert(X)
81 #define PB_DS_DBG_ONLY(X) X
82 #else // #ifdef PB_DS_PAT_TRIE_DEBUG_
83 #define PB_DS_DBG_ASSERT(X)
84 #define PB_DS_DBG_VERIFY(X) {if((X)==0);}
85 #define PB_DS_DBG_ONLY(X) ;
86 #endif // #ifdef PB_DS_PAT_TRIE_DEBUG_
88 #define PB_DS_CLASS_T_DEC \
92 class Node_And_It_Traits, \
95 #ifdef PB_DS_DATA_TRUE_INDICATOR
96 #define PB_DS_CLASS_NAME \
98 #endif // #ifdef PB_DS_DATA_TRUE_INDICATOR
100 #ifdef PB_DS_DATA_FALSE_INDICATOR
101 #define PB_DS_CLASS_NAME \
103 #endif // #ifdef PB_DS_DATA_FALSE_INDICATOR
105 #define PB_DS_CLASS_C_DEC \
109 Node_And_It_Traits, \
112 #define PB_DS_TYPES_TRAITS_C_DEC \
119 #ifdef PB_DS_USE_MAP_DEBUG_BASE
120 #define PB_DS_MAP_DEBUG_BASE_C_DEC \
127 typename Allocator::template rebind< \
128 Key>::other::const_reference>
129 #endif // #ifdef PB_DS_USE_MAP_DEBUG_BASE
131 #ifdef PB_DS_DATA_TRUE_INDICATOR
132 #define PB_DS_V2F(X) (X).first
133 #define PB_DS_V2S(X) (X).second
134 #define PB_DS_EP2VP(X)& ((X)->m_value)
135 #endif // #ifdef PB_DS_DATA_TRUE_INDICATOR
137 #ifdef PB_DS_DATA_FALSE_INDICATOR
138 #define PB_DS_V2F(X) (X)
139 #define PB_DS_V2S(X) Mapped_Data()
140 #define PB_DS_EP2VP(X)& ((X)->m_value.first)
141 #endif // #ifdef PB_DS_DATA_FALSE_INDICATOR
143 #define PB_DS_STATIC_ASSERT(UNIQUE, E) \
145 static_assert_dumclass< \
146 sizeof(static_assert<(bool)(E)>)> \
147 UNIQUE##static_assert_type
150 * class description = PATRICIA trie implementation.">
152 template<typename Key,
154 class Node_And_It_Traits,
156 class PB_DS_CLASS_NAME :
157 #ifdef PB_DS_PAT_TRIE_DEBUG_
158 public PB_DS_MAP_DEBUG_BASE_C_DEC,
159 #endif // #ifdef PB_DS_PAT_TRIE_DEBUG_
160 public Node_And_It_Traits::synth_e_access_traits,
161 public Node_And_It_Traits::node_update,
162 public PB_DS_TYPES_TRAITS_C_DEC
168 typename Node_And_It_Traits::synth_e_access_traits
169 synth_e_access_traits;
172 typename Allocator::template rebind<
173 synth_e_access_traits>::other::const_pointer
174 const_e_access_traits_pointer;
177 typename synth_e_access_traits::const_iterator
180 typedef typename Node_And_It_Traits::node node;
183 typename Allocator::template rebind<
184 node>::other::const_pointer
188 typename Allocator::template rebind<
189 node>::other::pointer
192 typedef typename Node_And_It_Traits::head head;
195 typename Allocator::template rebind<
199 typedef typename head_allocator::pointer head_pointer;
201 typedef typename Node_And_It_Traits::leaf leaf;
204 typename Allocator::template rebind<
208 typedef typename leaf_allocator::const_pointer const_leaf_pointer;
210 typedef typename leaf_allocator::pointer leaf_pointer;
212 typedef typename Node_And_It_Traits::internal_node internal_node;
215 typename Allocator::template rebind<
216 internal_node>::other
217 internal_node_allocator;
220 typename internal_node_allocator::const_pointer
221 const_internal_node_pointer;
224 typename internal_node_allocator::pointer
225 internal_node_pointer;
227 typedef PB_DS_TYPES_TRAITS_C_DEC traits_base;
229 #include <ext/pb_ds/detail/pat_trie_/cond_dtor_entry_dealtor.hpp>
231 #ifdef PB_DS_PAT_TRIE_DEBUG_
232 typedef PB_DS_MAP_DEBUG_BASE_C_DEC map_debug_base;
233 #endif // #ifdef PB_DS_PAT_TRIE_DEBUG_
235 #include <ext/pb_ds/detail/pat_trie_/split_join_branch_bag.hpp>
238 typename Node_And_It_Traits::null_node_update_pointer
239 null_node_update_pointer;
242 typedef pat_trie_tag container_category;
244 typedef typename Allocator::size_type size_type;
246 typedef typename Allocator::difference_type difference_type;
248 typedef typename PB_DS_TYPES_TRAITS_C_DEC::key_type key_type;
250 typedef typename PB_DS_TYPES_TRAITS_C_DEC::key_pointer key_pointer;
253 typename PB_DS_TYPES_TRAITS_C_DEC::const_key_pointer
256 typedef typename PB_DS_TYPES_TRAITS_C_DEC::key_reference key_reference;
259 typename PB_DS_TYPES_TRAITS_C_DEC::const_key_reference
262 typedef typename PB_DS_TYPES_TRAITS_C_DEC::mapped_type mapped_type;
265 typename PB_DS_TYPES_TRAITS_C_DEC::mapped_pointer
269 typename PB_DS_TYPES_TRAITS_C_DEC::const_mapped_pointer
270 const_mapped_pointer;
273 typename PB_DS_TYPES_TRAITS_C_DEC::mapped_reference
277 typename PB_DS_TYPES_TRAITS_C_DEC::const_mapped_reference
278 const_mapped_reference;
280 typedef typename PB_DS_TYPES_TRAITS_C_DEC::value_type value_type;
282 typedef typename PB_DS_TYPES_TRAITS_C_DEC::pointer pointer;
284 typedef typename PB_DS_TYPES_TRAITS_C_DEC::const_pointer const_pointer;
286 typedef typename PB_DS_TYPES_TRAITS_C_DEC::reference reference;
289 typename PB_DS_TYPES_TRAITS_C_DEC::const_reference
293 typename Node_And_It_Traits::const_iterator
294 const_point_iterator;
296 typedef typename Node_And_It_Traits::iterator point_iterator;
298 typedef const_point_iterator const_iterator;
300 typedef point_iterator iterator;
303 typename Node_And_It_Traits::const_reverse_iterator
304 const_reverse_iterator;
306 typedef typename Node_And_It_Traits::reverse_iterator reverse_iterator;
309 typename Node_And_It_Traits::const_node_iterator
312 typedef typename Node_And_It_Traits::node_iterator node_iterator;
314 typedef typename Node_And_It_Traits::e_access_traits e_access_traits;
316 typedef typename Node_And_It_Traits::node_update node_update;
318 typedef Allocator allocator;
324 PB_DS_CLASS_NAME(const e_access_traits& r_e_access_traits);
326 PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other);
329 swap(PB_DS_CLASS_C_DEC& other);
343 get_e_access_traits();
345 const e_access_traits&
346 get_e_access_traits() const;
352 get_node_update() const;
357 insert(const_reference r_val);
359 inline mapped_reference
360 operator[](const_key_reference r_key)
362 #ifdef PB_DS_DATA_TRUE_INDICATOR
363 return (insert(std::make_pair(
365 mapped_type())).first->second);
366 #else // #ifdef PB_DS_DATA_TRUE_INDICATOR
369 return (traits_base::s_null_mapped);
370 #endif // #ifdef PB_DS_DATA_TRUE
373 inline point_iterator
374 find(const_key_reference r_key);
376 inline const_point_iterator
377 find(const_key_reference r_key) const;
379 inline point_iterator
380 lower_bound(const_key_reference r_key);
382 inline const_point_iterator
383 lower_bound(const_key_reference r_key) const;
385 inline point_iterator
386 upper_bound(const_key_reference r_key);
388 inline const_point_iterator
389 upper_bound(const_key_reference r_key) const;
395 erase(const_key_reference r_key);
397 inline const_iterator
398 erase(const_iterator it);
400 #ifdef PB_DS_DATA_TRUE_INDICATOR
403 #endif // #ifdef PB_DS_DATA_TRUE_INDICATOR
405 inline const_reverse_iterator
406 erase(const_reverse_iterator it);
408 #ifdef PB_DS_DATA_TRUE_INDICATOR
409 inline reverse_iterator
410 erase(reverse_iterator it);
411 #endif // #ifdef PB_DS_DATA_TRUE_INDICATOR
413 template<typename Pred>
418 join(PB_DS_CLASS_C_DEC& other);
421 split(const_key_reference r_key, PB_DS_CLASS_C_DEC& other);
426 inline const_iterator
432 inline const_iterator
435 inline reverse_iterator
438 inline const_reverse_iterator
441 inline reverse_iterator
444 inline const_reverse_iterator
447 inline const_node_iterator
453 inline const_node_iterator
459 #ifdef PB_DS_PAT_TRIE_TRACE_
464 #endif // #ifdef PB_DS_PAT_TRIE_TRACE_
468 template<typename It>
470 copy_from_range(It first_it, It last_it);
473 value_swap(PB_DS_CLASS_C_DEC& other);
476 recursive_copy_node(const_node_pointer p_other_nd);
484 apply_update(node_pointer p_nd, null_node_update_pointer);
486 template<typename Node_Update_>
488 apply_update(node_pointer p_nd, Node_Update_* p_update);
491 join_prep(PB_DS_CLASS_C_DEC& other, split_join_branch_bag& r_bag);
494 rec_join_prep(const_node_pointer p_l, const_node_pointer p_r, split_join_branch_bag& r_bag);
497 rec_join_prep(const_leaf_pointer p_l, const_leaf_pointer p_r, split_join_branch_bag& r_bag);
500 rec_join_prep(const_leaf_pointer p_l, const_internal_node_pointer p_r, split_join_branch_bag& r_bag);
503 rec_join_prep(const_internal_node_pointer p_l, const_leaf_pointer p_r, split_join_branch_bag& r_bag);
506 rec_join_prep(const_internal_node_pointer p_l, const_internal_node_pointer p_r, split_join_branch_bag& r_bag);
509 rec_join(node_pointer p_l, node_pointer p_r, size_type checked_ind, split_join_branch_bag& r_bag);
512 rec_join(leaf_pointer p_l, leaf_pointer p_r, split_join_branch_bag& r_bag);
515 rec_join(leaf_pointer p_l, internal_node_pointer p_r, size_type checked_ind, split_join_branch_bag& r_bag);
518 rec_join(internal_node_pointer p_l, leaf_pointer p_r, size_type checked_ind, split_join_branch_bag& r_bag);
521 rec_join(internal_node_pointer p_l, internal_node_pointer p_r, split_join_branch_bag& r_bag);
524 keys_diff_ind(typename e_access_traits::const_iterator b_l, typename e_access_traits::const_iterator e_l, typename e_access_traits::const_iterator b_r, typename e_access_traits::const_iterator e_r);
526 internal_node_pointer
527 insert_branch(node_pointer p_left_nd, node_pointer p_right_nd, split_join_branch_bag& r_bag);
530 update_min_max_for_inserted_leaf(leaf_pointer p_l);
533 erase_leaf(leaf_pointer p_l);
536 actual_erase_leaf(leaf_pointer p_lf);
539 clear_imp(node_pointer p_nd);
542 erase_fixup(internal_node_pointer p_nd);
545 update_min_max_for_erased_leaf(leaf_pointer p_l);
547 static inline const_e_iterator
548 pref_begin(const_node_pointer p_nd);
550 static inline const_e_iterator
551 pref_end(const_node_pointer p_nd);
554 find_imp(const_key_reference r_key);
557 lower_bound_imp(const_key_reference r_key);
560 upper_bound_imp(const_key_reference r_key);
562 inline static const_leaf_pointer
563 leftmost_descendant(const_node_pointer p_nd);
565 inline static leaf_pointer
566 leftmost_descendant(node_pointer p_nd);
568 inline static const_leaf_pointer
569 rightmost_descendant(const_node_pointer p_nd);
571 inline static leaf_pointer
572 rightmost_descendant(node_pointer p_nd);
574 #ifdef PB_DS_PAT_TRIE_DEBUG_
577 assert_valid() const;
580 assert_iterators() const;
583 assert_reverse_iterators() const;
586 recursive_count_leafs(const_node_pointer p_nd);
588 #endif // #ifdef PB_DS_PAT_TRIE_DEBUG_
590 #ifdef PB_DS_PAT_TRIE_TRACE_
593 trace_node(const_node_pointer p_nd, size_type level);
595 template<typename Metadata_>
597 trace_node_metadata(const_node_pointer p_nd, type_to_type<Metadata_>);
600 trace_node_metadata(const_node_pointer, type_to_type<null_node_metadata>);
602 #endif // #ifdef PB_DS_PAT_TRIE_TRACE_
605 split_prep(const_key_reference r_key, PB_DS_CLASS_C_DEC& other, split_join_branch_bag& r_bag);
608 rec_split(node_pointer p_nd, const_e_iterator b_it, const_e_iterator e_it, PB_DS_CLASS_C_DEC& other, split_join_branch_bag& r_bag);
611 split_insert_branch(size_type e_ind, const_e_iterator b_it, typename internal_node::iterator child_b_it, size_type num_children, split_join_branch_bag& r_bag);
614 static head_allocator s_head_allocator;
616 static internal_node_allocator s_internal_node_allocator;
618 static leaf_allocator s_leaf_allocator;
620 head_pointer m_p_head;
625 #include <ext/pb_ds/detail/pat_trie_/constructors_destructor_fn_imps.hpp>
626 #include <ext/pb_ds/detail/pat_trie_/iterators_fn_imps.hpp>
627 #include <ext/pb_ds/detail/pat_trie_/insert_join_fn_imps.hpp>
628 #include <ext/pb_ds/detail/pat_trie_/erase_fn_imps.hpp>
629 #include <ext/pb_ds/detail/pat_trie_/find_fn_imps.hpp>
630 #include <ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp>
631 #include <ext/pb_ds/detail/pat_trie_/policy_access_fn_imps.hpp>
632 #include <ext/pb_ds/detail/pat_trie_/split_fn_imps.hpp>
633 #include <ext/pb_ds/detail/pat_trie_/debug_fn_imps.hpp>
634 #include <ext/pb_ds/detail/pat_trie_/trace_fn_imps.hpp>
635 #include <ext/pb_ds/detail/pat_trie_/update_fn_imps.hpp>
637 #undef PB_DS_CLASS_C_DEC
639 #undef PB_DS_CLASS_T_DEC
641 #undef PB_DS_CLASS_NAME
643 #undef PB_DS_TYPES_TRAITS_C_DEC
645 #undef PB_DS_MAP_DEBUG_BASE_C_DEC
651 #undef PB_DS_DBG_ASSERT
652 #undef PB_DS_DBG_VERIFY
653 #undef PB_DS_DBG_ONLY
655 #undef PB_DS_STATIC_ASSERT
657 } // namespace detail