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 ov_tree_map_.hpp
44 * Contains an implementation class for ov_tree_.
49 #include <ext/pb_ds/tree_policy.hpp>
50 #include <ext/pb_ds/detail/eq_fn/eq_by_less.hpp>
51 #include <ext/pb_ds/detail/types_traits.hpp>
52 #include <ext/pb_ds/detail/map_debug_base.hpp>
53 #include <ext/pb_ds/detail/type_utils.hpp>
54 #include <ext/pb_ds/exception.hpp>
55 #include <ext/pb_ds/detail/tree_trace_base.hpp>
67 #ifdef PB_DS_OV_TREE_DEBUG_
68 #define PB_DS_DBG_ASSERT(X) assert(X);
69 #define PB_DS_DBG_VERIFY(X) PB_DS_DBG_ASSERT(X)
70 #define PB_DS_DBG_ONLY(X) X
71 #else // #ifdef PB_DS_OV_TREE_DEBUG_
72 #define PB_DS_DBG_ASSERT(X) ((void)0)
73 #define PB_DS_DBG_VERIFY(X) X
74 #define PB_DS_DBG_ONLY(X) ;
75 #endif // #ifdef PB_DS_OV_TREE_DEBUG_
77 #define PB_DS_CLASS_T_DEC \
82 class Node_And_It_Traits, \
85 #ifdef PB_DS_DATA_TRUE_INDICATOR
86 #define PB_DS_OV_TREE_CLASS_NAME \
88 #endif // #ifdef PB_DS_DATA_TRUE_INDICATOR
90 #ifdef PB_DS_DATA_FALSE_INDICATOR
91 #define PB_DS_OV_TREE_CLASS_NAME \
93 #endif // #ifdef PB_DS_DATA_FALSE_INDICATOR
95 #ifdef PB_DS_DATA_TRUE_INDICATOR
96 #define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_const_node_iterator_data_
97 #else // #ifdef PB_DS_DATA_TRUE_INDICATOR
98 #define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_const_node_iterator_no_data_
99 #endif // #ifdef PB_DS_DATA_TRUE_INDICATOR
101 #define PB_DS_CLASS_C_DEC \
102 PB_DS_OV_TREE_CLASS_NAME< \
106 Node_And_It_Traits, \
109 #define PB_DS_TYPES_TRAITS_C_DEC \
116 #ifdef PB_DS_USE_MAP_DEBUG_BASE
117 #define PB_DS_MAP_DEBUG_BASE_C_DEC \
120 eq_by_less<Key, Cmp_Fn>, \
121 typename Allocator::template rebind< \
122 Key>::other::const_reference>
123 #endif // #ifdef PB_DS_USE_MAP_DEBUG_BASE
125 #ifdef PB_DS_DATA_TRUE_INDICATOR
126 #define PB_DS_V2F(X) (X).first
127 #define PB_DS_V2S(X) (X).second
128 #define PB_DS_EP2VP(X)& ((X)->m_value)
129 #endif // #ifdef PB_DS_DATA_TRUE_INDICATOR
131 #ifdef PB_DS_DATA_FALSE_INDICATOR
132 #define PB_DS_V2F(X) (X)
133 #define PB_DS_V2S(X) Mapped_Data()
134 #define PB_DS_EP2VP(X)& ((X)->m_value.first)
135 #endif // #ifdef PB_DS_DATA_FALSE_INDICATOR
137 #ifdef PB_DS_TREE_TRACE
138 #define PB_DS_TREE_TRACE_BASE_C_DEC \
140 typename Node_And_It_Traits::const_node_iterator, \
141 typename Node_And_It_Traits::node_iterator, \
145 #endif // #ifdef PB_DS_TREE_TRACE
147 // Ordered-vector tree associative-container.
148 template<typename Key,
151 class Node_And_It_Traits,
153 class PB_DS_OV_TREE_CLASS_NAME :
154 #ifdef PB_DS_OV_TREE_DEBUG_
155 protected PB_DS_MAP_DEBUG_BASE_C_DEC,
156 #endif // #ifdef PB_DS_OV_TREE_DEBUG_
157 #ifdef PB_DS_TREE_TRACE
158 public PB_DS_TREE_TRACE_BASE_C_DEC,
159 #endif // #ifdef PB_DS_TREE_TRACE
161 public Node_And_It_Traits::node_update,
162 public PB_DS_TYPES_TRAITS_C_DEC
167 typename remove_const<
168 typename PB_DS_TYPES_TRAITS_C_DEC::value_type>::type
169 non_const_value_type;
172 typename Allocator::template rebind<
173 non_const_value_type>::other
176 typedef typename value_allocator::pointer value_vector;
178 typedef PB_DS_TYPES_TRAITS_C_DEC traits_base;
180 typedef Cmp_Fn cmp_fn_base;
182 #ifdef PB_DS_USE_MAP_DEBUG_BASE
183 typedef PB_DS_MAP_DEBUG_BASE_C_DEC map_debug_base;
184 #endif // #ifdef PB_DS_USE_MAP_DEBUG_BASE
186 typedef typename PB_DS_TYPES_TRAITS_C_DEC::pointer mapped_pointer_;
189 typename PB_DS_TYPES_TRAITS_C_DEC::const_pointer
190 const_mapped_pointer_;
192 typedef typename Node_And_It_Traits::metadata_type metadata_type;
195 typename Allocator::template rebind<
196 metadata_type>::other
199 typedef typename metadata_allocator::pointer metadata_pointer;
202 typename metadata_allocator::const_reference
203 const_metadata_reference;
205 typedef typename metadata_allocator::reference metadata_reference;
208 typename Node_And_It_Traits::null_node_update_pointer
209 null_node_update_pointer;
213 typedef typename Allocator::size_type size_type;
215 typedef typename Allocator::difference_type difference_type;
217 typedef Cmp_Fn cmp_fn;
219 typedef typename Node_And_It_Traits::node_update node_update;
221 typedef Allocator allocator;
223 typedef typename PB_DS_TYPES_TRAITS_C_DEC::key_type key_type;
225 typedef typename PB_DS_TYPES_TRAITS_C_DEC::key_pointer key_pointer;
228 typename PB_DS_TYPES_TRAITS_C_DEC::const_key_pointer
231 typedef typename PB_DS_TYPES_TRAITS_C_DEC::key_reference key_reference;
234 typename PB_DS_TYPES_TRAITS_C_DEC::const_key_reference
237 typedef typename PB_DS_TYPES_TRAITS_C_DEC::mapped_type mapped_type;
240 typename PB_DS_TYPES_TRAITS_C_DEC::mapped_pointer
244 typename PB_DS_TYPES_TRAITS_C_DEC::const_mapped_pointer
245 const_mapped_pointer;
248 typename PB_DS_TYPES_TRAITS_C_DEC::mapped_reference
252 typename PB_DS_TYPES_TRAITS_C_DEC::const_mapped_reference
253 const_mapped_reference;
255 typedef typename PB_DS_TYPES_TRAITS_C_DEC::value_type value_type;
257 typedef typename PB_DS_TYPES_TRAITS_C_DEC::pointer pointer;
259 typedef typename PB_DS_TYPES_TRAITS_C_DEC::const_pointer const_pointer;
261 typedef typename PB_DS_TYPES_TRAITS_C_DEC::reference reference;
264 typename PB_DS_TYPES_TRAITS_C_DEC::const_reference
267 typedef const_pointer const_point_iterator;
269 #ifdef PB_DS_DATA_TRUE_INDICATOR
270 typedef pointer point_iterator;
271 #else // #ifdef PB_DS_DATA_TRUE_INDICATOR
272 typedef const_point_iterator point_iterator;
273 #endif // #ifdef PB_DS_DATA_TRUE_INDICATOR
275 typedef const_point_iterator const_iterator;
277 typedef point_iterator iterator;
279 #include <ext/pb_ds/detail/ov_tree_map_/cond_dtor.hpp>
282 typename Node_And_It_Traits::const_node_iterator
285 typedef typename Node_And_It_Traits::node_iterator node_iterator;
289 PB_DS_OV_TREE_CLASS_NAME();
291 PB_DS_OV_TREE_CLASS_NAME(const Cmp_Fn& r_cmp_fn);
293 PB_DS_OV_TREE_CLASS_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update);
295 PB_DS_OV_TREE_CLASS_NAME(const PB_DS_CLASS_C_DEC& other);
297 ~PB_DS_OV_TREE_CLASS_NAME();
300 swap(PB_DS_CLASS_C_DEC& other);
302 template<typename It>
304 copy_from_range(It first_it, It last_it);
321 inline mapped_reference
322 operator[](const_key_reference r_key)
324 #ifdef PB_DS_DATA_TRUE_INDICATOR
325 PB_DS_DBG_ONLY(assert_valid();)
327 point_iterator it = lower_bound(r_key);
329 if (it != end()&& !Cmp_Fn::operator()(
333 PB_DS_DBG_ONLY(map_debug_base::check_key_exists(r_key));
335 PB_DS_DBG_ONLY(assert_valid();)
340 PB_DS_DBG_ONLY(assert_valid();)
342 return (insert_new_val(it,
345 mapped_type()))->second);
346 #else // #ifdef PB_DS_DATA_TRUE_INDICATOR
349 return (traits_base::s_null_mapped);
350 #endif // #ifdef PB_DS_DATA_TRUE_INDICATOR
353 inline std::pair<point_iterator, bool>
354 insert(const_reference r_value)
356 PB_DS_DBG_ONLY(assert_valid();)
358 const_key_reference r_key = PB_DS_V2F(r_value);
360 point_iterator it = lower_bound(r_key);
362 if (it != end()&& !Cmp_Fn::operator()(
366 PB_DS_DBG_ONLY(assert_valid();)
368 PB_DS_DBG_ONLY(map_debug_base::check_key_exists(r_key));
370 return (std::make_pair(it, false));
373 PB_DS_DBG_ONLY(assert_valid();)
375 return (std::make_pair(insert_new_val(it, r_value), true));
378 inline point_iterator
379 lower_bound(const_key_reference r_key)
381 pointer it = m_a_values;
383 pointer e_it = m_a_values + m_size;
387 pointer mid_it = it + ((e_it - it) >> 1);
389 if (cmp_fn_base::operator()(
400 inline const_point_iterator
401 lower_bound(const_key_reference r_key) const
403 return (const_cast<PB_DS_CLASS_C_DEC& >(*this).lower_bound(r_key));
406 inline point_iterator
407 upper_bound(const_key_reference r_key)
409 iterator pot_it = lower_bound(r_key);
411 if (pot_it != end()&& !Cmp_Fn::operator()(
415 PB_DS_DBG_ONLY(map_debug_base::check_key_exists(r_key));
420 PB_DS_DBG_ONLY(map_debug_base::check_key_does_not_exist(r_key));
425 inline const_point_iterator
426 upper_bound(const_key_reference r_key) const
428 return (const_cast<PB_DS_CLASS_C_DEC& >(*this).upper_bound(r_key));
431 inline point_iterator
432 find(const_key_reference r_key)
434 PB_DS_DBG_ONLY(assert_valid();)
436 iterator pot_it = lower_bound(r_key);
438 if (pot_it != end()&& !Cmp_Fn::operator()(
442 PB_DS_DBG_ONLY(map_debug_base::check_key_exists(r_key));
447 PB_DS_DBG_ONLY(map_debug_base::check_key_does_not_exist(r_key));
452 inline const_point_iterator
453 find(const_key_reference r_key) const
455 return (const_cast<PB_DS_CLASS_C_DEC& >(*this).find(r_key));
459 erase(const_key_reference r_key);
461 template<typename Pred>
468 return (erase_imp<iterator>(it));
475 join(PB_DS_CLASS_C_DEC& other);
478 split(const_key_reference r_key, PB_DS_CLASS_C_DEC& other);
486 inline const_iterator
498 inline const_iterator
504 inline const_node_iterator
507 inline const_node_iterator
519 update(node_iterator /*it*/, null_node_update_pointer);
521 template<typename Node_Update>
523 update(node_iterator it, Node_Update* p_update);
526 reallocate_metadata(null_node_update_pointer, size_type);
528 template<typename Node_Update_>
530 reallocate_metadata(Node_Update_* p_update, size_type new_size);
532 template<typename It>
534 copy_from_ordered_range(It first_it, It last_it);
537 value_swap(PB_DS_CLASS_C_DEC& other);
539 template<typename It>
541 copy_from_ordered_range(It first_it, It last_it, It other_first_it, It other_last_it);
543 template<typename Ptr>
545 mid_pointer(Ptr p_begin, Ptr p_end)
547 PB_DS_DBG_ASSERT(p_end >= p_begin);
549 return (p_begin + (p_end - p_begin) / 2);
553 insert_new_val(iterator it, const_reference r_value)
555 PB_DS_DBG_ONLY(assert_valid();)
557 #ifdef PB_DS_REGRESSION
558 typename Allocator::group_throw_prob_adjustor adjust(m_size);
559 #endif // #ifdef PB_DS_REGRESSION
561 PB_DS_DBG_ONLY(map_debug_base::check_key_does_not_exist(
562 PB_DS_V2F(r_value)));
564 value_vector a_values = s_value_alloc.allocate(m_size + 1);
566 iterator source_it = begin();
567 iterator source_end_it = end();
568 iterator target_it = a_values;
571 cond_dtor<size_type> cd(a_values, target_it, m_size + 1);
573 while (source_it != it)
575 new (const_cast<void* >(
576 static_cast<const void* >(target_it)))
577 value_type(*source_it++);
582 new (const_cast<void* >(
583 static_cast<const void* >(ret_it = target_it)))
588 while (source_it != source_end_it)
590 new (const_cast<void* >(
591 static_cast<const void* >(target_it)))
592 value_type(*source_it++);
597 reallocate_metadata((node_update* )this, m_size + 1);
603 cond_dtor<size_type> cd1(m_a_values, m_end_it, m_size);
608 m_a_values = a_values;
610 m_end_it = m_a_values + m_size;
612 PB_DS_DBG_ONLY(map_debug_base::insert_new(
613 PB_DS_V2F(r_value)));
615 update(node_begin(), (node_update* )this);
617 PB_DS_DBG_ONLY(PB_DS_CLASS_C_DEC::assert_valid();)
622 #ifdef PB_DS_OV_TREE_DEBUG_
625 assert_valid() const;
628 assert_iterators() const;
630 #endif // #ifdef PB_DS_OV_TREE_DEBUG_
632 template<typename It>
636 inline const_node_iterator
637 PB_DS_node_begin_imp() const;
639 inline const_node_iterator
640 PB_DS_node_end_imp() const;
643 PB_DS_node_begin_imp();
646 PB_DS_node_end_imp();
649 value_vector m_a_values;
651 static value_allocator s_value_alloc;
653 metadata_pointer m_a_metadata;
655 static metadata_allocator s_metadata_alloc;
662 #include <ext/pb_ds/detail/ov_tree_map_/constructors_destructor_fn_imps.hpp>
663 #include <ext/pb_ds/detail/ov_tree_map_/iterators_fn_imps.hpp>
664 #include <ext/pb_ds/detail/ov_tree_map_/debug_fn_imps.hpp>
665 #include <ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp>
666 #include <ext/pb_ds/detail/ov_tree_map_/insert_fn_imps.hpp>
667 #include <ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp>
668 #include <ext/pb_ds/detail/ov_tree_map_/split_join_fn_imps.hpp>
669 #include <ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp>
671 #undef PB_DS_CLASS_C_DEC
673 #undef PB_DS_CLASS_T_DEC
675 #undef PB_DS_OV_TREE_CLASS_NAME
677 #undef PB_DS_TYPES_TRAITS_C_DEC
679 #undef PB_DS_MAP_DEBUG_BASE_C_DEC
681 #ifdef PB_DS_TREE_TRACE
682 #undef PB_DS_TREE_TRACE_BASE_C_DEC
683 #endif // #ifdef PB_DS_TREE_TRACE
689 #undef PB_DS_DBG_ASSERT
690 #undef PB_DS_DBG_VERIFY
691 #undef PB_DS_DBG_ONLY
693 #undef PB_DS_CONST_NODE_ITERATOR_NAME
695 } // namespace detail