2011-05-07 François Dumont <francois.cppdevs@free.fr>
[official-gcc.git] / libstdc++-v3 / include / ext / pb_ds / detail / bin_search_tree_ / bin_search_tree_.hpp
blob8be0f80c5b2c6229a936b8f632e9caf21376f9ca
1 // -*- C++ -*-
3 // Copyright (C) 2005, 2006, 2009, 2010, 2011 Free Software Foundation, Inc.
4 //
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
9 // version.
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
34 // warranty.
36 /**
37 * @file bin_search_tree_.hpp
38 * Contains an implementation class for bin_search_tree_.
41 * This implementation uses an idea from the SGI STL (using a @a header node
42 * which is needed for efficient iteration).
45 #include <ext/pb_ds/exception.hpp>
46 #include <ext/pb_ds/detail/eq_fn/eq_by_less.hpp>
47 #include <ext/pb_ds/detail/types_traits.hpp>
48 #include <ext/pb_ds/detail/debug_map_base.hpp>
49 #include <ext/pb_ds/tree_policy.hpp>
50 #include <ext/pb_ds/detail/cond_dealtor.hpp>
51 #include <ext/pb_ds/detail/type_utils.hpp>
52 #include <ext/pb_ds/detail/tree_trace_base.hpp>
53 #include <utility>
54 #include <functional>
55 #include <debug/debug.h>
57 namespace __gnu_pbds
59 namespace detail
62 #define PB_DS_CLASS_T_DEC \
63 template<typename Key, typename Mapped, class Cmp_Fn, \
64 class Node_And_It_Traits, class Allocator>
66 #ifdef PB_DS_DATA_TRUE_INDICATOR
67 #define PB_DS_CLASS_NAME \
68 bin_search_tree_data_
69 #endif
71 #ifdef PB_DS_DATA_FALSE_INDICATOR
72 #define PB_DS_CLASS_NAME \
73 bin_search_tree_no_data_
74 #endif
76 #define PB_DS_CLASS_C_DEC \
77 PB_DS_CLASS_NAME< \
78 Key, \
79 Mapped, \
80 Cmp_Fn, \
81 Node_And_It_Traits, \
82 Allocator>
84 #define PB_DS_TYPES_TRAITS_C_DEC \
85 types_traits< \
86 Key, \
87 Mapped, \
88 Allocator, \
89 false>
91 #ifdef _GLIBCXX_DEBUG
92 #define PB_DS_DEBUG_MAP_BASE_C_DEC \
93 debug_map_base<Key, eq_by_less<Key, Cmp_Fn>, \
94 typename Allocator::template rebind<Key>::other::const_reference>
95 #endif
97 #ifdef PB_DS_DATA_TRUE_INDICATOR
98 #define PB_DS_V2F(X) (X).first
99 #define PB_DS_V2S(X) (X).second
100 #define PB_DS_EP2VP(X)& ((X)->m_value)
101 #endif
103 #ifdef PB_DS_DATA_FALSE_INDICATOR
104 #define PB_DS_V2F(X) (X)
105 #define PB_DS_V2S(X) Mapped_Data()
106 #define PB_DS_EP2VP(X)& ((X)->m_value.first)
107 #endif
109 #ifdef PB_DS_TREE_TRACE
110 #define PB_DS_TREE_TRACE_BASE_C_DEC \
111 tree_trace_base< \
112 typename Node_And_It_Traits::const_node_iterator, \
113 typename Node_And_It_Traits::node_iterator, \
114 Cmp_Fn, \
115 true, \
116 Allocator>
117 #endif
120 * class description = "8i|\|4ree $34rc|-| 7r33 74813.">
122 template<typename Key,
123 typename Mapped,
124 class Cmp_Fn,
125 class Node_And_It_Traits,
126 class Allocator>
127 class PB_DS_CLASS_NAME :
128 #ifdef _GLIBCXX_DEBUG
129 public PB_DS_DEBUG_MAP_BASE_C_DEC,
130 #endif
131 #ifdef PB_DS_TREE_TRACE
132 public PB_DS_TREE_TRACE_BASE_C_DEC,
133 #endif
134 public Cmp_Fn,
135 public PB_DS_TYPES_TRAITS_C_DEC,
136 public Node_And_It_Traits::node_update
139 protected:
140 typedef
141 typename Allocator::template rebind<
142 typename Node_And_It_Traits::node>::other
143 node_allocator;
145 typedef typename node_allocator::value_type node;
147 typedef typename node_allocator::pointer node_pointer;
149 typedef PB_DS_TYPES_TRAITS_C_DEC traits_base;
151 typedef
152 typename Node_And_It_Traits::null_node_update_pointer
153 null_node_update_pointer;
155 private:
156 typedef cond_dealtor< node, Allocator> cond_dealtor_t;
158 #ifdef _GLIBCXX_DEBUG
159 typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base;
160 #endif
162 public:
164 typedef typename Allocator::size_type size_type;
166 typedef typename Allocator::difference_type difference_type;
168 typedef typename PB_DS_TYPES_TRAITS_C_DEC::key_type key_type;
170 typedef typename PB_DS_TYPES_TRAITS_C_DEC::key_pointer key_pointer;
172 typedef
173 typename PB_DS_TYPES_TRAITS_C_DEC::const_key_pointer
174 const_key_pointer;
176 typedef typename PB_DS_TYPES_TRAITS_C_DEC::key_reference key_reference;
178 typedef
179 typename PB_DS_TYPES_TRAITS_C_DEC::const_key_reference
180 const_key_reference;
182 #ifdef PB_DS_DATA_TRUE_INDICATOR
183 typedef typename PB_DS_TYPES_TRAITS_C_DEC::mapped_type mapped_type;
185 typedef
186 typename PB_DS_TYPES_TRAITS_C_DEC::mapped_pointer
187 mapped_pointer;
189 typedef
190 typename PB_DS_TYPES_TRAITS_C_DEC::const_mapped_pointer
191 const_mapped_pointer;
193 typedef
194 typename PB_DS_TYPES_TRAITS_C_DEC::mapped_reference
195 mapped_reference;
197 typedef
198 typename PB_DS_TYPES_TRAITS_C_DEC::const_mapped_reference
199 const_mapped_reference;
200 #endif
202 typedef typename PB_DS_TYPES_TRAITS_C_DEC::value_type value_type;
204 typedef typename PB_DS_TYPES_TRAITS_C_DEC::pointer pointer;
206 typedef typename PB_DS_TYPES_TRAITS_C_DEC::const_pointer const_pointer;
208 typedef typename PB_DS_TYPES_TRAITS_C_DEC::reference reference;
210 typedef
211 typename PB_DS_TYPES_TRAITS_C_DEC::const_reference
212 const_reference;
214 typedef
215 typename Node_And_It_Traits::const_point_iterator
216 const_point_iterator;
218 typedef const_point_iterator const_iterator;
220 typedef typename Node_And_It_Traits::point_iterator point_iterator;
222 typedef point_iterator iterator;
224 typedef
225 typename Node_And_It_Traits::const_reverse_iterator
226 const_reverse_iterator;
228 typedef typename Node_And_It_Traits::reverse_iterator reverse_iterator;
230 typedef
231 typename Node_And_It_Traits::const_node_iterator
232 const_node_iterator;
234 typedef typename Node_And_It_Traits::node_iterator node_iterator;
236 typedef Cmp_Fn cmp_fn;
238 typedef Allocator allocator_type;
240 typedef typename Node_And_It_Traits::node_update node_update;
242 public:
244 PB_DS_CLASS_NAME();
246 PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn);
248 PB_DS_CLASS_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_update);
250 PB_DS_CLASS_NAME(const PB_DS_CLASS_C_DEC& other);
252 void
253 swap(PB_DS_CLASS_C_DEC& other);
255 ~PB_DS_CLASS_NAME();
257 inline bool
258 empty() const;
260 inline size_type
261 size() const;
263 inline size_type
264 max_size() const;
266 Cmp_Fn&
267 get_cmp_fn();
269 const Cmp_Fn&
270 get_cmp_fn() const;
272 inline point_iterator
273 lower_bound(const_key_reference r_key);
275 inline const_point_iterator
276 lower_bound(const_key_reference r_key) const;
278 inline point_iterator
279 upper_bound(const_key_reference r_key);
281 inline const_point_iterator
282 upper_bound(const_key_reference r_key) const;
284 inline point_iterator
285 find(const_key_reference r_key);
287 inline const_point_iterator
288 find(const_key_reference r_key) const;
290 inline iterator
291 begin();
293 inline const_iterator
294 begin() const;
296 inline iterator
297 end();
299 inline const_iterator
300 end() const;
302 inline reverse_iterator
303 rbegin();
305 inline const_reverse_iterator
306 rbegin() const;
308 inline reverse_iterator
309 rend();
311 inline const_reverse_iterator
312 rend() const;
314 inline const_node_iterator
315 node_begin() const;
317 inline node_iterator
318 node_begin();
320 inline const_node_iterator
321 node_end() const;
323 inline node_iterator
324 node_end();
326 void
327 clear();
329 protected:
331 void
332 value_swap(PB_DS_CLASS_C_DEC& other);
334 void
335 initialize_min_max();
337 inline iterator
338 insert_imp_empty(const_reference r_value);
340 inline iterator
341 insert_leaf_new(const_reference r_value, node_pointer p_nd, bool left_nd);
343 inline node_pointer
344 get_new_node_for_leaf_insert(const_reference r_val, false_type);
346 inline node_pointer
347 get_new_node_for_leaf_insert(const_reference r_val, true_type);
349 inline void
350 actual_erase_node(node_pointer p_nd);
352 inline std::pair<node_pointer, bool>
353 erase(node_pointer p_nd);
355 inline void
356 update_min_max_for_erased_node(node_pointer p_nd);
358 static void
359 clear_imp(node_pointer p_nd);
361 inline std::pair<
362 point_iterator,
363 bool>
364 insert_leaf(const_reference r_value);
366 inline void
367 rotate_left(node_pointer p_x);
369 inline void
370 rotate_right(node_pointer p_y);
372 inline void
373 rotate_parent(node_pointer p_nd);
375 inline void
376 apply_update(node_pointer p_nd, null_node_update_pointer);
378 template<typename Node_Update_>
379 inline void
380 apply_update(node_pointer p_nd, Node_Update_* p_update);
382 inline void
383 update_to_top(node_pointer p_nd, null_node_update_pointer);
385 template<typename Node_Update_>
386 inline void
387 update_to_top(node_pointer p_nd, Node_Update_* p_update);
389 bool
390 join_prep(PB_DS_CLASS_C_DEC& other);
392 void
393 join_finish(PB_DS_CLASS_C_DEC& other);
395 bool
396 split_prep(const_key_reference r_key, PB_DS_CLASS_C_DEC& other);
398 void
399 split_finish(PB_DS_CLASS_C_DEC& other);
401 size_type
402 recursive_count(node_pointer p_nd) const;
404 #ifdef _GLIBCXX_DEBUG
405 void
406 assert_valid(const char* file, int line) const;
408 void
409 structure_only_assert_valid(const char* file, int line) const;
411 void
412 assert_node_consistent(const node_pointer p_nd,
413 const char* file, int line) const;
414 #endif
416 private:
417 #ifdef _GLIBCXX_DEBUG
418 void
419 assert_iterators(const char* file, int line) const;
421 void
422 assert_consistent_with_debug_base(const char* file, int line) const;
424 void
425 assert_node_consistent_with_left(const node_pointer p_nd,
426 const char* file, int line) const;
428 void
429 assert_node_consistent_with_right(const node_pointer p_nd,
430 const char* file, int line) const;
432 void
433 assert_consistent_with_debug_base(const node_pointer p_nd,
434 const char* file, int line) const;
436 void
437 assert_min(const char* file, int line) const;
439 void
440 assert_min_imp(const node_pointer p_nd,
441 const char* file, int line) const;
443 void
444 assert_max(const char* file, int line) const;
446 void
447 assert_max_imp(const node_pointer p_nd,
448 const char* file, int line) const;
450 void
451 assert_size(const char* file, int line) const;
453 typedef std::pair< const_pointer, const_pointer> node_consistent_t;
455 node_consistent_t
456 assert_node_consistent_(const node_pointer p_nd,
457 const char* file, int line) const;
458 #endif
460 void
461 initialize();
463 node_pointer
464 recursive_copy_node(const node_pointer p_nd);
466 protected:
467 node_pointer m_p_head;
469 size_type m_size;
471 static node_allocator s_node_allocator;
474 #define PB_DS_ASSERT_VALID(X) \
475 _GLIBCXX_DEBUG_ONLY(X.assert_valid(__FILE__, __LINE__);)
477 #define PB_DS_STRUCT_ONLY_ASSERT_VALID(X) \
478 _GLIBCXX_DEBUG_ONLY(X.structure_only_assert_valid(__FILE__, __LINE__);)
480 #define PB_DS_ASSERT_NODE_CONSISTENT(_Node) \
481 _GLIBCXX_DEBUG_ONLY(assert_node_consistent(_Node, __FILE__, __LINE__);)
483 #define PB_DS_CHECK_KEY_EXISTS(_Key) \
484 _GLIBCXX_DEBUG_ONLY(debug_base::check_key_exists(_Key, __FILE__, __LINE__);)
486 #define PB_DS_CHECK_KEY_DOES_NOT_EXIST(_Key) \
487 _GLIBCXX_DEBUG_ONLY(debug_base::check_key_does_not_exist(_Key, \
488 __FILE__, __LINE__);)
490 #define PB_DS_DEBUG_VERIFY(_Cond) \
491 _GLIBCXX_DEBUG_VERIFY_AT(_Cond, \
492 _M_message(#_Cond" assertion from %1;:%2;") \
493 ._M_string(__FILE__)._M_integer(__LINE__) \
494 ,__file,__line)
496 #include <ext/pb_ds/detail/bin_search_tree_/constructors_destructor_fn_imps.hpp>
497 #include <ext/pb_ds/detail/bin_search_tree_/iterators_fn_imps.hpp>
498 #include <ext/pb_ds/detail/bin_search_tree_/debug_fn_imps.hpp>
499 #include <ext/pb_ds/detail/bin_search_tree_/insert_fn_imps.hpp>
500 #include <ext/pb_ds/detail/bin_search_tree_/erase_fn_imps.hpp>
501 #include <ext/pb_ds/detail/bin_search_tree_/find_fn_imps.hpp>
502 #include <ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hpp>
503 #include <ext/pb_ds/detail/bin_search_tree_/split_join_fn_imps.hpp>
504 #include <ext/pb_ds/detail/bin_search_tree_/rotate_fn_imps.hpp>
505 #include <ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp>
507 #undef PB_DS_DEBUG_VERIFY
508 #undef PB_DS_CHECK_KEY_DOES_NOT_EXIST
509 #undef PB_DS_CHECK_KEY_EXISTS
510 #undef PB_DS_ASSERT_NODE_CONSISTENT
511 #undef PB_DS_STRUCT_ONLY_ASSERT_VALID
512 #undef PB_DS_ASSERT_VALID
513 #undef PB_DS_CLASS_C_DEC
514 #undef PB_DS_CLASS_T_DEC
515 #undef PB_DS_CLASS_NAME
516 #undef PB_DS_TYPES_TRAITS_C_DEC
517 #undef PB_DS_DEBUG_MAP_BASE_C_DEC
519 #ifdef PB_DS_TREE_TRACE
520 #undef PB_DS_TREE_TRACE_BASE_C_DEC
521 #endif
523 #undef PB_DS_V2F
524 #undef PB_DS_EP2VP
525 #undef PB_DS_V2S
527 } // namespace detail
528 } // namespace __gnu_pbds