OSDN Git Service

2011-05-07 François Dumont <francois.cppdevs@free.fr>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / ext / pb_ds / detail / ov_tree_map_ / ov_tree_map_.hpp
1 // -*- C++ -*-
2
3 // Copyright (C) 2005, 2006, 2009, 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.
10
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.
15
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.
19
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/>.
24
25 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
26
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.
35
36 /**
37  * @file ov_tree_map_.hpp
38  * Contains an implementation class for ov_tree_.
39  */
40
41 #include <map>
42 #include <set>
43 #include <ext/pb_ds/tree_policy.hpp>
44 #include <ext/pb_ds/detail/eq_fn/eq_by_less.hpp>
45 #include <ext/pb_ds/detail/types_traits.hpp>
46 #include <ext/pb_ds/detail/debug_map_base.hpp>
47 #include <ext/pb_ds/detail/type_utils.hpp>
48 #include <ext/pb_ds/exception.hpp>
49 #include <ext/pb_ds/detail/tree_trace_base.hpp>
50 #include <utility>
51 #include <functional>
52 #include <algorithm>
53 #include <vector>
54 #include <assert.h>
55 #include <debug/debug.h>
56
57 namespace __gnu_pbds
58 {
59   namespace detail
60   {
61 #define PB_DS_CLASS_T_DEC \
62     template<typename Key, typename Mapped, class Cmp_Fn, \
63              class Node_And_It_Traits, class Allocator>
64
65 #ifdef PB_DS_DATA_TRUE_INDICATOR
66 #define PB_DS_OV_TREE_CLASS_NAME ov_tree_data_
67 #endif 
68
69 #ifdef PB_DS_DATA_FALSE_INDICATOR
70 #define PB_DS_OV_TREE_CLASS_NAME ov_tree_no_data_
71 #endif 
72
73 #ifdef PB_DS_DATA_TRUE_INDICATOR
74 #define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_const_node_iterator_data_
75 #else 
76 #define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_const_node_iterator_no_data_
77 #endif 
78
79 #define PB_DS_CLASS_C_DEC \
80    PB_DS_OV_TREE_CLASS_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, Allocator>
81
82 #define PB_DS_TYPES_TRAITS_C_DEC \
83     types_traits<Key, Mapped, Allocator, false>
84
85 #ifdef _GLIBCXX_DEBUG
86 #define PB_DS_DEBUG_MAP_BASE_C_DEC \
87     debug_map_base<Key, eq_by_less<Key, Cmp_Fn>, \
88         typename Allocator::template rebind<Key>::other::const_reference>
89 #endif 
90
91 #ifdef PB_DS_DATA_TRUE_INDICATOR
92 #define PB_DS_V2F(X) (X).first
93 #define PB_DS_V2S(X) (X).second
94 #define PB_DS_EP2VP(X)& ((X)->m_value)
95 #endif 
96
97 #ifdef PB_DS_DATA_FALSE_INDICATOR
98 #define PB_DS_V2F(X) (X)
99 #define PB_DS_V2S(X) Mapped_Data()
100 #define PB_DS_EP2VP(X)& ((X)->m_value.first)
101 #endif 
102
103 #ifdef PB_DS_TREE_TRACE
104 #define PB_DS_TREE_TRACE_BASE_C_DEC \
105     tree_trace_base<typename Node_And_It_Traits::const_node_iterator,   \
106                     typename Node_And_It_Traits::node_iterator,         \
107                     Cmp_Fn, false, Allocator>
108 #endif
109
110 #define PB_DS_ASSERT_VALID(X)                                           \
111   _GLIBCXX_DEBUG_ONLY(X.assert_valid(__FILE__, __LINE__);)
112
113 #define PB_DS_CHECK_KEY_EXISTS(_Key)                                    \
114   _GLIBCXX_DEBUG_ONLY(debug_base::check_key_exists(_Key, __FILE__, __LINE__);)
115
116 #define PB_DS_CHECK_KEY_DOES_NOT_EXIST(_Key)                            \
117   _GLIBCXX_DEBUG_ONLY(debug_base::check_key_does_not_exist(_Key,        \
118                                                            __FILE__, __LINE__);)
119
120     // Ordered-vector tree associative-container.
121     template<typename Key, typename Mapped, class Cmp_Fn,
122              class Node_And_It_Traits, class Allocator>
123     class PB_DS_OV_TREE_CLASS_NAME :
124 #ifdef _GLIBCXX_DEBUG
125       protected PB_DS_DEBUG_MAP_BASE_C_DEC,
126 #endif 
127 #ifdef PB_DS_TREE_TRACE
128       public PB_DS_TREE_TRACE_BASE_C_DEC,
129 #endif 
130       public Cmp_Fn,
131       public Node_And_It_Traits::node_update,
132       public PB_DS_TYPES_TRAITS_C_DEC
133     {
134     private:
135       typedef PB_DS_TYPES_TRAITS_C_DEC traits_base;
136
137       typedef typename remove_const<typename traits_base::value_type>::type non_const_value_type;
138
139       typedef typename Allocator::template rebind<non_const_value_type>::other value_allocator;
140       typedef typename value_allocator::pointer value_vector;
141
142
143       typedef Cmp_Fn cmp_fn_base;
144
145 #ifdef _GLIBCXX_DEBUG
146       typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base;
147 #endif 
148
149       typedef typename traits_base::pointer mapped_pointer_;
150       typedef typename traits_base::const_pointer const_mapped_pointer_;
151
152       typedef typename Node_And_It_Traits::metadata_type metadata_type;
153
154       typedef typename Allocator::template rebind<metadata_type>::other metadata_allocator;
155       typedef typename metadata_allocator::pointer metadata_pointer;
156       typedef typename metadata_allocator::const_reference const_metadata_reference;
157       typedef typename metadata_allocator::reference metadata_reference;
158
159       typedef
160       typename Node_And_It_Traits::null_node_update_pointer
161       null_node_update_pointer;
162
163     public:
164
165       typedef Allocator allocator_type;
166       typedef typename Allocator::size_type size_type;
167       typedef typename Allocator::difference_type difference_type;
168
169       typedef Cmp_Fn cmp_fn;
170
171       typedef typename Node_And_It_Traits::node_update node_update;
172
173       typedef typename traits_base::key_type key_type;
174       typedef typename traits_base::key_pointer key_pointer;
175       typedef typename traits_base::const_key_pointer const_key_pointer;
176       typedef typename traits_base::key_reference key_reference;
177       typedef typename traits_base::const_key_reference const_key_reference;
178       typedef typename traits_base::mapped_type mapped_type;
179       typedef typename traits_base::mapped_pointer mapped_pointer;
180       typedef typename traits_base::const_mapped_pointer const_mapped_pointer;
181       typedef typename traits_base::mapped_reference mapped_reference;
182       typedef typename traits_base::const_mapped_reference const_mapped_reference;
183       typedef typename traits_base::value_type value_type;
184       typedef typename traits_base::pointer pointer;
185       typedef typename traits_base::const_pointer const_pointer;
186       typedef typename traits_base::reference reference;
187       typedef typename traits_base::const_reference const_reference;
188
189       typedef const_pointer const_point_iterator;
190
191 #ifdef PB_DS_DATA_TRUE_INDICATOR
192       typedef pointer point_iterator;
193 #else 
194       typedef const_point_iterator point_iterator;
195 #endif 
196
197       typedef const_point_iterator const_iterator;
198
199       typedef point_iterator iterator;
200
201 #include <ext/pb_ds/detail/ov_tree_map_/cond_dtor.hpp>
202
203       typedef
204       typename Node_And_It_Traits::const_node_iterator
205       const_node_iterator;
206
207       typedef typename Node_And_It_Traits::node_iterator node_iterator;
208
209     public:
210
211       PB_DS_OV_TREE_CLASS_NAME();
212
213       PB_DS_OV_TREE_CLASS_NAME(const Cmp_Fn&);
214
215       PB_DS_OV_TREE_CLASS_NAME(const Cmp_Fn&, const node_update&);
216
217       PB_DS_OV_TREE_CLASS_NAME(const PB_DS_CLASS_C_DEC&);
218
219       ~PB_DS_OV_TREE_CLASS_NAME();
220
221       void
222       swap(PB_DS_CLASS_C_DEC&);
223
224       template<typename It>
225       void
226       copy_from_range(It, It);
227
228       inline size_type
229       max_size() const;
230
231       inline bool
232       empty() const;
233
234       inline size_type
235       size() const;
236
237       Cmp_Fn& 
238       get_cmp_fn();
239
240       const Cmp_Fn& 
241       get_cmp_fn() const;
242
243       inline mapped_reference
244       operator[](const_key_reference r_key)
245       {
246 #ifdef PB_DS_DATA_TRUE_INDICATOR
247         PB_DS_ASSERT_VALID((*this))
248         point_iterator it = lower_bound(r_key);
249         if (it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*it)))
250           {
251             PB_DS_CHECK_KEY_EXISTS(r_key)
252             PB_DS_ASSERT_VALID((*this))
253              return it->second;
254           }
255
256         return (insert_new_val(it, std::make_pair(r_key, mapped_type()))->second);
257 #else 
258         insert(r_key);
259         return traits_base::s_null_mapped;
260 #endif 
261       }
262
263       inline std::pair<point_iterator, bool>
264       insert(const_reference r_value)
265       {
266         PB_DS_ASSERT_VALID((*this))
267         const_key_reference r_key = PB_DS_V2F(r_value);
268         point_iterator it = lower_bound(r_key);
269
270         if (it != end()&&  !Cmp_Fn::operator()(r_key, PB_DS_V2F(*it)))
271           {
272             PB_DS_ASSERT_VALID((*this))
273             PB_DS_CHECK_KEY_EXISTS(r_key)
274             return std::make_pair(it, false);
275           }
276
277         return std::make_pair(insert_new_val(it, r_value), true);
278       }
279
280       inline point_iterator
281       lower_bound(const_key_reference r_key)
282       {
283         pointer it = m_a_values;
284         pointer e_it = m_a_values + m_size;
285         while (it != e_it)
286           {
287             pointer mid_it = it + ((e_it - it) >> 1);
288             if (cmp_fn_base::operator()(PB_DS_V2F(*mid_it), r_key))
289               it = ++mid_it;
290             else
291               e_it = mid_it;
292           }
293         return it;
294       }
295
296       inline const_point_iterator
297       lower_bound(const_key_reference r_key) const
298       { return const_cast<PB_DS_CLASS_C_DEC& >(*this).lower_bound(r_key); }
299
300       inline point_iterator
301       upper_bound(const_key_reference r_key)
302       {
303         iterator pot_it = lower_bound(r_key);
304         if (pot_it != end()&&  !Cmp_Fn::operator()(r_key, PB_DS_V2F(*pot_it)))
305           {
306             PB_DS_CHECK_KEY_EXISTS(r_key)
307             return ++pot_it;
308           }
309
310         PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key)
311         return pot_it;
312       }
313
314       inline const_point_iterator
315       upper_bound(const_key_reference r_key) const
316       { return const_cast<PB_DS_CLASS_C_DEC&>(*this).upper_bound(r_key); }
317
318       inline point_iterator
319       find(const_key_reference r_key)
320       {
321         PB_DS_ASSERT_VALID((*this))
322         iterator pot_it = lower_bound(r_key);
323         if (pot_it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*pot_it)))
324           {
325             PB_DS_CHECK_KEY_EXISTS(r_key)
326             return pot_it;
327           }
328
329         PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key)
330         return end();
331       }
332
333       inline const_point_iterator
334       find(const_key_reference r_key) const
335       { return (const_cast<PB_DS_CLASS_C_DEC& >(*this).find(r_key)); }
336
337       bool
338       erase(const_key_reference);
339
340       template<typename Pred>
341       inline size_type
342       erase_if(Pred);
343
344       inline iterator
345       erase(iterator it)
346       { return erase_imp<iterator>(it); }
347
348       void
349       clear();
350
351       void
352       join(PB_DS_CLASS_C_DEC&);
353
354       void
355       split(const_key_reference, PB_DS_CLASS_C_DEC&);
356
357       inline iterator
358       begin()
359       { return m_a_values; }
360
361       inline const_iterator
362       begin() const
363       { return m_a_values; }
364
365       inline iterator
366       end()
367       { return m_end_it; }
368
369       inline const_iterator
370       end() const
371       { return m_end_it; }
372
373       inline const_node_iterator
374       node_begin() const;
375
376       inline const_node_iterator
377       node_end() const;
378
379       inline node_iterator
380       node_begin();
381
382       inline node_iterator
383       node_end();
384
385     private:
386
387       inline void
388       update(node_iterator /*it*/, null_node_update_pointer);
389
390       template<typename Node_Update>
391       void
392       update(node_iterator, Node_Update*);
393
394       void
395       reallocate_metadata(null_node_update_pointer, size_type);
396
397       template<typename Node_Update_>
398       void
399       reallocate_metadata(Node_Update_*, size_type);
400
401       template<typename It>
402       void
403       copy_from_ordered_range(It, It);
404
405       void
406       value_swap(PB_DS_CLASS_C_DEC&);
407
408       template<typename It>
409       void
410       copy_from_ordered_range(It, It, It, It);
411
412       template<typename Ptr>
413       inline static Ptr
414       mid_pointer(Ptr p_begin, Ptr p_end)
415       {
416         _GLIBCXX_DEBUG_ASSERT(p_end >= p_begin);
417         return (p_begin + (p_end - p_begin) / 2);
418       }
419
420       inline iterator
421       insert_new_val(iterator it, const_reference r_value)
422       {
423 #ifdef PB_DS_REGRESSION
424           typename Allocator::group_adjustor adjust(m_size);
425 #endif 
426
427         PB_DS_CHECK_KEY_DOES_NOT_EXIST(PB_DS_V2F(r_value))
428
429         value_vector a_values = s_value_alloc.allocate(m_size + 1);
430
431         iterator source_it = begin();
432         iterator source_end_it = end();
433         iterator target_it = a_values;
434         iterator ret_it;
435
436         cond_dtor<size_type> cd(a_values, target_it, m_size + 1);
437         while (source_it != it)
438           {
439             new (const_cast<void* >(static_cast<const void* >(target_it)))
440               value_type(*source_it++);
441             ++target_it;
442           }
443
444         new (const_cast<void* >(static_cast<const void* >(ret_it = target_it)))
445           value_type(r_value);
446         ++target_it;
447
448         while (source_it != source_end_it)
449           {
450             new (const_cast<void* >(static_cast<const void* >(target_it)))
451               value_type(*source_it++);
452             ++target_it;
453           }
454
455         reallocate_metadata((node_update* )this, m_size + 1);
456         cd.set_no_action();
457         if (m_size != 0)
458           {
459             cond_dtor<size_type> cd1(m_a_values, m_end_it, m_size);
460           }
461
462         ++m_size;
463         m_a_values = a_values;
464         m_end_it = m_a_values + m_size;
465         _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_value)));
466         update(node_begin(), (node_update* )this);
467         PB_DS_ASSERT_VALID((*this))
468         return ret_it;
469       }
470
471 #ifdef _GLIBCXX_DEBUG
472       void
473       assert_valid(const char* file, int line) const;
474
475       void
476       assert_iterators(const char* file, int line) const;
477 #endif 
478
479       template<typename It>
480       It
481       erase_imp(It it);
482
483       inline const_node_iterator
484       PB_DS_node_begin_imp() const;
485
486       inline const_node_iterator
487       PB_DS_node_end_imp() const;
488
489       inline node_iterator
490       PB_DS_node_begin_imp();
491
492       inline node_iterator
493       PB_DS_node_end_imp();
494
495     private:
496       static value_allocator s_value_alloc;
497       static metadata_allocator s_metadata_alloc;
498
499       value_vector m_a_values;
500       metadata_pointer m_a_metadata;
501       iterator m_end_it;
502       size_type m_size;
503     };
504
505 #define PB_DS_DEBUG_VERIFY(_Cond)                                       \
506   _GLIBCXX_DEBUG_VERIFY_AT(_Cond,                                       \
507                            _M_message(#_Cond" assertion from %1;:%2;")  \
508                            ._M_string(__FILE__)._M_integer(__LINE__)    \
509                            ,__file,__line)
510
511 #include <ext/pb_ds/detail/ov_tree_map_/constructors_destructor_fn_imps.hpp>
512 #include <ext/pb_ds/detail/ov_tree_map_/iterators_fn_imps.hpp>
513 #include <ext/pb_ds/detail/ov_tree_map_/debug_fn_imps.hpp>
514 #include <ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp>
515 #include <ext/pb_ds/detail/ov_tree_map_/insert_fn_imps.hpp>
516 #include <ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp>
517 #include <ext/pb_ds/detail/ov_tree_map_/split_join_fn_imps.hpp>
518 #include <ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp>
519
520 #undef PB_DS_DEBUG_VERIFY
521 #undef PB_DS_CHECK_KEY_DOES_NOT_EXIST
522 #undef PB_DS_CHECK_KEY_EXISTS
523 #undef PB_DS_ASSERT_VALID
524 #undef PB_DS_CLASS_C_DEC
525 #undef PB_DS_CLASS_T_DEC
526 #undef PB_DS_OV_TREE_CLASS_NAME
527 #undef PB_DS_TYPES_TRAITS_C_DEC
528 #undef PB_DS_DEBUG_MAP_BASE_C_DEC
529 #ifdef PB_DS_TREE_TRACE
530 #undef PB_DS_TREE_TRACE_BASE_C_DEC
531 #endif 
532
533 #undef PB_DS_V2F
534 #undef PB_DS_EP2VP
535 #undef PB_DS_V2S
536 #undef PB_DS_CONST_NODE_ITERATOR_NAME
537
538   } // namespace detail
539 } // namespace __gnu_pbds