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>
70 #include <ext/pb_ds/detail/map_debug_base.hpp>
72 #include <debug/debug.h>
79 #define PB_DS_CLASS_T_DEC \
80 template<typename Key, typename Mapped, class Node_And_It_Traits, \
83 #ifdef PB_DS_DATA_TRUE_INDICATOR
84 #define PB_DS_CLASS_NAME \
88 #ifdef PB_DS_DATA_FALSE_INDICATOR
89 #define PB_DS_CLASS_NAME \
93 #define PB_DS_CLASS_C_DEC \
100 #define PB_DS_TYPES_TRAITS_C_DEC \
107 #ifdef _GLIBCXX_DEBUG
108 #define PB_DS_MAP_DEBUG_BASE_C_DEC \
109 map_debug_base<Key, eq_by_less<Key, \
110 std::less<Key> >, typename Allocator::template rebind<Key>::other::const_reference>
113 #ifdef PB_DS_DATA_TRUE_INDICATOR
114 #define PB_DS_V2F(X) (X).first
115 #define PB_DS_V2S(X) (X).second
116 #define PB_DS_EP2VP(X)& ((X)->m_value)
119 #ifdef PB_DS_DATA_FALSE_INDICATOR
120 #define PB_DS_V2F(X) (X)
121 #define PB_DS_V2S(X) Mapped_Data()
122 #define PB_DS_EP2VP(X)& ((X)->m_value.first)
125 #define PB_DS_STATIC_ASSERT(UNIQUE, E) \
127 static_assert_dumclass< \
128 sizeof(static_assert<(bool)(E)>)> \
129 UNIQUE##static_assert_type
132 * class description = PATRICIA trie implementation.">
134 template<typename Key,
136 class Node_And_It_Traits,
138 class PB_DS_CLASS_NAME :
139 #ifdef _GLIBCXX_DEBUG
140 public PB_DS_MAP_DEBUG_BASE_C_DEC,
142 public Node_And_It_Traits::synth_e_access_traits,
143 public Node_And_It_Traits::node_update,
144 public PB_DS_TYPES_TRAITS_C_DEC
150 typename Node_And_It_Traits::synth_e_access_traits
151 synth_e_access_traits;
154 typename Allocator::template rebind<
155 synth_e_access_traits>::other::const_pointer
156 const_e_access_traits_pointer;
159 typename synth_e_access_traits::const_iterator
162 typedef typename Node_And_It_Traits::node node;
165 typename Allocator::template rebind<
166 node>::other::const_pointer
170 typename Allocator::template rebind<
171 node>::other::pointer
174 typedef typename Node_And_It_Traits::head head;
177 typename Allocator::template rebind<
181 typedef typename head_allocator::pointer head_pointer;
183 typedef typename Node_And_It_Traits::leaf leaf;
186 typename Allocator::template rebind<
190 typedef typename leaf_allocator::const_pointer const_leaf_pointer;
192 typedef typename leaf_allocator::pointer leaf_pointer;
194 typedef typename Node_And_It_Traits::internal_node internal_node;
197 typename Allocator::template rebind<
198 internal_node>::other
199 internal_node_allocator;
202 typename internal_node_allocator::const_pointer
203 const_internal_node_pointer;
206 typename internal_node_allocator::pointer
207 internal_node_pointer;
209 typedef PB_DS_TYPES_TRAITS_C_DEC traits_base;
211 #include <ext/pb_ds/detail/pat_trie_/cond_dtor_entry_dealtor.hpp>
213 #ifdef _GLIBCXX_DEBUG
214 typedef PB_DS_MAP_DEBUG_BASE_C_DEC map_debug_base;
217 #include <ext/pb_ds/detail/pat_trie_/split_join_branch_bag.hpp>
220 typename Node_And_It_Traits::null_node_update_pointer
221 null_node_update_pointer;
224 typedef pat_trie_tag container_category;
226 typedef typename Allocator::size_type size_type;
228 typedef typename Allocator::difference_type difference_type;
230 typedef typename PB_DS_TYPES_TRAITS_C_DEC::key_type key_type;
232 typedef typename PB_DS_TYPES_TRAITS_C_DEC::key_pointer key_pointer;
235 typename PB_DS_TYPES_TRAITS_C_DEC::const_key_pointer
238 typedef typename PB_DS_TYPES_TRAITS_C_DEC::key_reference key_reference;
241 typename PB_DS_TYPES_TRAITS_C_DEC::const_key_reference
244 typedef typename PB_DS_TYPES_TRAITS_C_DEC::mapped_type mapped_type;
247 typename PB_DS_TYPES_TRAITS_C_DEC::mapped_pointer
251 typename PB_DS_TYPES_TRAITS_C_DEC::const_mapped_pointer
252 const_mapped_pointer;
255 typename PB_DS_TYPES_TRAITS_C_DEC::mapped_reference
259 typename PB_DS_TYPES_TRAITS_C_DEC::const_mapped_reference
260 const_mapped_reference;
262 typedef typename PB_DS_TYPES_TRAITS_C_DEC::value_type value_type;
264 typedef typename PB_DS_TYPES_TRAITS_C_DEC::pointer pointer;
266 typedef typename PB_DS_TYPES_TRAITS_C_DEC::const_pointer const_pointer;
268 typedef typename PB_DS_TYPES_TRAITS_C_DEC::reference reference;
271 typename PB_DS_TYPES_TRAITS_C_DEC::const_reference
275 typename Node_And_It_Traits::const_iterator
276 const_point_iterator;
278 typedef typename Node_And_It_Traits::iterator point_iterator;
280 typedef const_point_iterator const_iterator;
282 typedef point_iterator iterator;
285 typename Node_And_It_Traits::const_reverse_iterator
286 const_reverse_iterator;
288 typedef typename Node_And_It_Traits::reverse_iterator reverse_iterator;
291 typename Node_And_It_Traits::const_node_iterator
294 typedef typename Node_And_It_Traits::node_iterator node_iterator;
296 typedef typename Node_And_It_Traits::e_access_traits e_access_traits;
298 typedef typename Node_And_It_Traits::node_update node_update;
300 typedef Allocator allocator;
306 PB_DS_CLASS_NAME(const e_access_traits& r_e_access_traits);
308 PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other);
311 swap(PB_DS_CLASS_C_DEC& other);
325 get_e_access_traits();
327 const e_access_traits&
328 get_e_access_traits() const;
334 get_node_update() const;
339 insert(const_reference r_val);
341 inline mapped_reference
342 operator[](const_key_reference r_key)
344 #ifdef PB_DS_DATA_TRUE_INDICATOR
345 return (insert(std::make_pair(
347 mapped_type())).first->second);
348 #else // #ifdef PB_DS_DATA_TRUE_INDICATOR
351 return (traits_base::s_null_mapped);
352 #endif // #ifdef PB_DS_DATA_TRUE
355 inline point_iterator
356 find(const_key_reference r_key);
358 inline const_point_iterator
359 find(const_key_reference r_key) const;
361 inline point_iterator
362 lower_bound(const_key_reference r_key);
364 inline const_point_iterator
365 lower_bound(const_key_reference r_key) const;
367 inline point_iterator
368 upper_bound(const_key_reference r_key);
370 inline const_point_iterator
371 upper_bound(const_key_reference r_key) const;
377 erase(const_key_reference r_key);
379 inline const_iterator
380 erase(const_iterator it);
382 #ifdef PB_DS_DATA_TRUE_INDICATOR
385 #endif // #ifdef PB_DS_DATA_TRUE_INDICATOR
387 inline const_reverse_iterator
388 erase(const_reverse_iterator it);
390 #ifdef PB_DS_DATA_TRUE_INDICATOR
391 inline reverse_iterator
392 erase(reverse_iterator it);
393 #endif // #ifdef PB_DS_DATA_TRUE_INDICATOR
395 template<typename Pred>
400 join(PB_DS_CLASS_C_DEC& other);
403 split(const_key_reference r_key, PB_DS_CLASS_C_DEC& other);
408 inline const_iterator
414 inline const_iterator
417 inline reverse_iterator
420 inline const_reverse_iterator
423 inline reverse_iterator
426 inline const_reverse_iterator
429 inline const_node_iterator
435 inline const_node_iterator
441 #ifdef PB_DS_PAT_TRIE_TRACE_
446 #endif // #ifdef PB_DS_PAT_TRIE_TRACE_
450 template<typename It>
452 copy_from_range(It first_it, It last_it);
455 value_swap(PB_DS_CLASS_C_DEC& other);
458 recursive_copy_node(const_node_pointer p_other_nd);
466 apply_update(node_pointer p_nd, null_node_update_pointer);
468 template<typename Node_Update_>
470 apply_update(node_pointer p_nd, Node_Update_* p_update);
473 join_prep(PB_DS_CLASS_C_DEC& other, split_join_branch_bag& r_bag);
476 rec_join_prep(const_node_pointer p_l, const_node_pointer p_r, split_join_branch_bag& r_bag);
479 rec_join_prep(const_leaf_pointer p_l, const_leaf_pointer p_r, split_join_branch_bag& r_bag);
482 rec_join_prep(const_leaf_pointer p_l, const_internal_node_pointer p_r, split_join_branch_bag& r_bag);
485 rec_join_prep(const_internal_node_pointer p_l, const_leaf_pointer p_r, split_join_branch_bag& r_bag);
488 rec_join_prep(const_internal_node_pointer p_l, const_internal_node_pointer p_r, split_join_branch_bag& r_bag);
491 rec_join(node_pointer p_l, node_pointer p_r, size_type checked_ind, split_join_branch_bag& r_bag);
494 rec_join(leaf_pointer p_l, leaf_pointer p_r, split_join_branch_bag& r_bag);
497 rec_join(leaf_pointer p_l, internal_node_pointer p_r, size_type checked_ind, split_join_branch_bag& r_bag);
500 rec_join(internal_node_pointer p_l, leaf_pointer p_r, size_type checked_ind, split_join_branch_bag& r_bag);
503 rec_join(internal_node_pointer p_l, internal_node_pointer p_r, split_join_branch_bag& r_bag);
506 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);
508 internal_node_pointer
509 insert_branch(node_pointer p_left_nd, node_pointer p_right_nd, split_join_branch_bag& r_bag);
512 update_min_max_for_inserted_leaf(leaf_pointer p_l);
515 erase_leaf(leaf_pointer p_l);
518 actual_erase_leaf(leaf_pointer p_lf);
521 clear_imp(node_pointer p_nd);
524 erase_fixup(internal_node_pointer p_nd);
527 update_min_max_for_erased_leaf(leaf_pointer p_l);
529 static inline const_e_iterator
530 pref_begin(const_node_pointer p_nd);
532 static inline const_e_iterator
533 pref_end(const_node_pointer p_nd);
536 find_imp(const_key_reference r_key);
539 lower_bound_imp(const_key_reference r_key);
542 upper_bound_imp(const_key_reference r_key);
544 inline static const_leaf_pointer
545 leftmost_descendant(const_node_pointer p_nd);
547 inline static leaf_pointer
548 leftmost_descendant(node_pointer p_nd);
550 inline static const_leaf_pointer
551 rightmost_descendant(const_node_pointer p_nd);
553 inline static leaf_pointer
554 rightmost_descendant(node_pointer p_nd);
556 #ifdef _GLIBCXX_DEBUG
558 assert_valid() const;
561 assert_iterators() const;
564 assert_reverse_iterators() const;
567 recursive_count_leafs(const_node_pointer p_nd);
570 #ifdef PB_DS_PAT_TRIE_TRACE_
572 trace_node(const_node_pointer p_nd, size_type level);
574 template<typename Metadata_>
576 trace_node_metadata(const_node_pointer p_nd, type_to_type<Metadata_>);
579 trace_node_metadata(const_node_pointer,
580 type_to_type<null_node_metadata>);
584 split_prep(const_key_reference r_key, PB_DS_CLASS_C_DEC& other,
585 split_join_branch_bag& r_bag);
588 rec_split(node_pointer p_nd, const_e_iterator b_it,
589 const_e_iterator e_it, PB_DS_CLASS_C_DEC& other,
590 split_join_branch_bag& r_bag);
593 split_insert_branch(size_type e_ind, const_e_iterator b_it,
594 typename internal_node::iterator child_b_it,
595 size_type num_children, split_join_branch_bag&);
598 static head_allocator s_head_allocator;
600 static internal_node_allocator s_internal_node_allocator;
602 static leaf_allocator s_leaf_allocator;
604 head_pointer m_p_head;
609 #include <ext/pb_ds/detail/pat_trie_/constructors_destructor_fn_imps.hpp>
610 #include <ext/pb_ds/detail/pat_trie_/iterators_fn_imps.hpp>
611 #include <ext/pb_ds/detail/pat_trie_/insert_join_fn_imps.hpp>
612 #include <ext/pb_ds/detail/pat_trie_/erase_fn_imps.hpp>
613 #include <ext/pb_ds/detail/pat_trie_/find_fn_imps.hpp>
614 #include <ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp>
615 #include <ext/pb_ds/detail/pat_trie_/policy_access_fn_imps.hpp>
616 #include <ext/pb_ds/detail/pat_trie_/split_fn_imps.hpp>
617 #include <ext/pb_ds/detail/pat_trie_/debug_fn_imps.hpp>
618 #include <ext/pb_ds/detail/pat_trie_/trace_fn_imps.hpp>
619 #include <ext/pb_ds/detail/pat_trie_/update_fn_imps.hpp>
621 #undef PB_DS_CLASS_C_DEC
622 #undef PB_DS_CLASS_T_DEC
623 #undef PB_DS_CLASS_NAME
624 #undef PB_DS_TYPES_TRAITS_C_DEC
625 #undef PB_DS_MAP_DEBUG_BASE_C_DEC
631 #undef PB_DS_STATIC_ASSERT
633 } // namespace detail