Chris@101
|
1 /* Copyright 2003-2014 Joaquin M Lopez Munoz.
|
Chris@16
|
2 * Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
3 * (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
4 * http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5 *
|
Chris@16
|
6 * See http://www.boost.org/libs/multi_index for library home page.
|
Chris@16
|
7 *
|
Chris@16
|
8 * The internal implementation of red-black trees is based on that of SGI STL
|
Chris@16
|
9 * stl_tree.h file:
|
Chris@16
|
10 *
|
Chris@16
|
11 * Copyright (c) 1996,1997
|
Chris@16
|
12 * Silicon Graphics Computer Systems, Inc.
|
Chris@16
|
13 *
|
Chris@16
|
14 * Permission to use, copy, modify, distribute and sell this software
|
Chris@16
|
15 * and its documentation for any purpose is hereby granted without fee,
|
Chris@16
|
16 * provided that the above copyright notice appear in all copies and
|
Chris@16
|
17 * that both that copyright notice and this permission notice appear
|
Chris@16
|
18 * in supporting documentation. Silicon Graphics makes no
|
Chris@16
|
19 * representations about the suitability of this software for any
|
Chris@16
|
20 * purpose. It is provided "as is" without express or implied warranty.
|
Chris@16
|
21 *
|
Chris@16
|
22 *
|
Chris@16
|
23 * Copyright (c) 1994
|
Chris@16
|
24 * Hewlett-Packard Company
|
Chris@16
|
25 *
|
Chris@16
|
26 * Permission to use, copy, modify, distribute and sell this software
|
Chris@16
|
27 * and its documentation for any purpose is hereby granted without fee,
|
Chris@16
|
28 * provided that the above copyright notice appear in all copies and
|
Chris@16
|
29 * that both that copyright notice and this permission notice appear
|
Chris@16
|
30 * in supporting documentation. Hewlett-Packard Company makes no
|
Chris@16
|
31 * representations about the suitability of this software for any
|
Chris@16
|
32 * purpose. It is provided "as is" without express or implied warranty.
|
Chris@16
|
33 *
|
Chris@16
|
34 */
|
Chris@16
|
35
|
Chris@16
|
36 #ifndef BOOST_MULTI_INDEX_ORDERED_INDEX_HPP
|
Chris@16
|
37 #define BOOST_MULTI_INDEX_ORDERED_INDEX_HPP
|
Chris@16
|
38
|
Chris@101
|
39 #if defined(_MSC_VER)
|
Chris@16
|
40 #pragma once
|
Chris@16
|
41 #endif
|
Chris@16
|
42
|
Chris@16
|
43 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
Chris@16
|
44 #include <algorithm>
|
Chris@16
|
45 #include <boost/call_traits.hpp>
|
Chris@16
|
46 #include <boost/detail/no_exceptions_support.hpp>
|
Chris@16
|
47 #include <boost/detail/workaround.hpp>
|
Chris@16
|
48 #include <boost/foreach_fwd.hpp>
|
Chris@16
|
49 #include <boost/iterator/reverse_iterator.hpp>
|
Chris@16
|
50 #include <boost/move/core.hpp>
|
Chris@16
|
51 #include <boost/mpl/bool.hpp>
|
Chris@16
|
52 #include <boost/mpl/if.hpp>
|
Chris@16
|
53 #include <boost/mpl/push_front.hpp>
|
Chris@16
|
54 #include <boost/multi_index/detail/access_specifier.hpp>
|
Chris@16
|
55 #include <boost/multi_index/detail/bidir_node_iterator.hpp>
|
Chris@16
|
56 #include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
|
Chris@16
|
57 #include <boost/multi_index/detail/index_node_base.hpp>
|
Chris@16
|
58 #include <boost/multi_index/detail/modify_key_adaptor.hpp>
|
Chris@16
|
59 #include <boost/multi_index/detail/ord_index_node.hpp>
|
Chris@16
|
60 #include <boost/multi_index/detail/ord_index_ops.hpp>
|
Chris@16
|
61 #include <boost/multi_index/detail/safe_mode.hpp>
|
Chris@16
|
62 #include <boost/multi_index/detail/scope_guard.hpp>
|
Chris@16
|
63 #include <boost/multi_index/detail/unbounded.hpp>
|
Chris@16
|
64 #include <boost/multi_index/detail/value_compare.hpp>
|
Chris@16
|
65 #include <boost/multi_index/detail/vartempl_support.hpp>
|
Chris@16
|
66 #include <boost/multi_index/ordered_index_fwd.hpp>
|
Chris@16
|
67 #include <boost/ref.hpp>
|
Chris@16
|
68 #include <boost/tuple/tuple.hpp>
|
Chris@16
|
69 #include <boost/type_traits/is_same.hpp>
|
Chris@16
|
70 #include <utility>
|
Chris@16
|
71
|
Chris@16
|
72 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
Chris@16
|
73 #include <initializer_list>
|
Chris@16
|
74 #endif
|
Chris@16
|
75
|
Chris@16
|
76 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
Chris@16
|
77 #include <boost/archive/archive_exception.hpp>
|
Chris@16
|
78 #include <boost/bind.hpp>
|
Chris@16
|
79 #include <boost/multi_index/detail/duplicates_iterator.hpp>
|
Chris@16
|
80 #include <boost/throw_exception.hpp>
|
Chris@16
|
81 #endif
|
Chris@16
|
82
|
Chris@16
|
83 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
|
Chris@16
|
84 #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) \
|
Chris@16
|
85 detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
|
Chris@16
|
86 detail::make_obj_guard(x,&ordered_index::check_invariant_); \
|
Chris@16
|
87 BOOST_JOIN(check_invariant_,__LINE__).touch();
|
Chris@16
|
88 #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \
|
Chris@16
|
89 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(*this)
|
Chris@16
|
90 #else
|
Chris@16
|
91 #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x)
|
Chris@16
|
92 #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
|
Chris@16
|
93 #endif
|
Chris@16
|
94
|
Chris@16
|
95 namespace boost{
|
Chris@16
|
96
|
Chris@16
|
97 namespace multi_index{
|
Chris@16
|
98
|
Chris@16
|
99 namespace detail{
|
Chris@16
|
100
|
Chris@16
|
101 /* ordered_index adds a layer of ordered indexing to a given Super */
|
Chris@16
|
102
|
Chris@16
|
103 /* Most of the implementation of unique and non-unique indices is
|
Chris@16
|
104 * shared. We tell from one another on instantiation time by using
|
Chris@16
|
105 * these tags.
|
Chris@16
|
106 */
|
Chris@16
|
107
|
Chris@16
|
108 struct ordered_unique_tag{};
|
Chris@16
|
109 struct ordered_non_unique_tag{};
|
Chris@16
|
110
|
Chris@16
|
111 template<
|
Chris@16
|
112 typename KeyFromValue,typename Compare,
|
Chris@16
|
113 typename SuperMeta,typename TagList,typename Category
|
Chris@16
|
114 >
|
Chris@16
|
115 class ordered_index:
|
Chris@16
|
116 BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
|
Chris@16
|
117
|
Chris@16
|
118 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
119 ,public safe_mode::safe_container<
|
Chris@16
|
120 ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category> >
|
Chris@16
|
121 #endif
|
Chris@16
|
122
|
Chris@16
|
123 {
|
Chris@16
|
124 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
|
Chris@16
|
125 BOOST_WORKAROUND(__MWERKS__,<=0x3003)
|
Chris@16
|
126 /* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
|
Chris@16
|
127 * lifetime of const references bound to temporaries --precisely what
|
Chris@16
|
128 * scopeguards are.
|
Chris@16
|
129 */
|
Chris@16
|
130
|
Chris@16
|
131 #pragma parse_mfunc_templ off
|
Chris@16
|
132 #endif
|
Chris@16
|
133
|
Chris@16
|
134 typedef typename SuperMeta::type super;
|
Chris@16
|
135
|
Chris@16
|
136 protected:
|
Chris@16
|
137 typedef ordered_index_node<
|
Chris@16
|
138 typename super::node_type> node_type;
|
Chris@16
|
139
|
Chris@16
|
140 private:
|
Chris@16
|
141 typedef typename node_type::impl_type node_impl_type;
|
Chris@16
|
142 typedef typename node_impl_type::pointer node_impl_pointer;
|
Chris@16
|
143
|
Chris@16
|
144 public:
|
Chris@16
|
145 /* types */
|
Chris@16
|
146
|
Chris@16
|
147 typedef typename KeyFromValue::result_type key_type;
|
Chris@16
|
148 typedef typename node_type::value_type value_type;
|
Chris@16
|
149 typedef KeyFromValue key_from_value;
|
Chris@16
|
150 typedef Compare key_compare;
|
Chris@16
|
151 typedef value_comparison<
|
Chris@16
|
152 value_type,KeyFromValue,Compare> value_compare;
|
Chris@16
|
153 typedef tuple<key_from_value,key_compare> ctor_args;
|
Chris@16
|
154 typedef typename super::final_allocator_type allocator_type;
|
Chris@16
|
155 typedef typename allocator_type::reference reference;
|
Chris@16
|
156 typedef typename allocator_type::const_reference const_reference;
|
Chris@16
|
157
|
Chris@16
|
158 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
159 typedef safe_mode::safe_iterator<
|
Chris@16
|
160 bidir_node_iterator<node_type>,
|
Chris@16
|
161 ordered_index> iterator;
|
Chris@16
|
162 #else
|
Chris@16
|
163 typedef bidir_node_iterator<node_type> iterator;
|
Chris@16
|
164 #endif
|
Chris@16
|
165
|
Chris@16
|
166 typedef iterator const_iterator;
|
Chris@16
|
167
|
Chris@16
|
168 typedef std::size_t size_type;
|
Chris@16
|
169 typedef std::ptrdiff_t difference_type;
|
Chris@16
|
170 typedef typename allocator_type::pointer pointer;
|
Chris@16
|
171 typedef typename allocator_type::const_pointer const_pointer;
|
Chris@16
|
172 typedef typename
|
Chris@16
|
173 boost::reverse_iterator<iterator> reverse_iterator;
|
Chris@16
|
174 typedef typename
|
Chris@16
|
175 boost::reverse_iterator<const_iterator> const_reverse_iterator;
|
Chris@16
|
176 typedef TagList tag_list;
|
Chris@16
|
177
|
Chris@16
|
178 protected:
|
Chris@16
|
179 typedef typename super::final_node_type final_node_type;
|
Chris@16
|
180 typedef tuples::cons<
|
Chris@16
|
181 ctor_args,
|
Chris@16
|
182 typename super::ctor_args_list> ctor_args_list;
|
Chris@16
|
183 typedef typename mpl::push_front<
|
Chris@16
|
184 typename super::index_type_list,
|
Chris@16
|
185 ordered_index>::type index_type_list;
|
Chris@16
|
186 typedef typename mpl::push_front<
|
Chris@16
|
187 typename super::iterator_type_list,
|
Chris@16
|
188 iterator>::type iterator_type_list;
|
Chris@16
|
189 typedef typename mpl::push_front<
|
Chris@16
|
190 typename super::const_iterator_type_list,
|
Chris@16
|
191 const_iterator>::type const_iterator_type_list;
|
Chris@16
|
192 typedef typename super::copy_map_type copy_map_type;
|
Chris@16
|
193
|
Chris@16
|
194 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
Chris@16
|
195 typedef typename super::index_saver_type index_saver_type;
|
Chris@16
|
196 typedef typename super::index_loader_type index_loader_type;
|
Chris@16
|
197 #endif
|
Chris@16
|
198
|
Chris@16
|
199 private:
|
Chris@16
|
200 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
201 typedef safe_mode::safe_container<ordered_index> safe_super;
|
Chris@16
|
202 #endif
|
Chris@16
|
203
|
Chris@16
|
204 typedef typename call_traits<
|
Chris@16
|
205 value_type>::param_type value_param_type;
|
Chris@16
|
206 typedef typename call_traits<
|
Chris@16
|
207 key_type>::param_type key_param_type;
|
Chris@16
|
208
|
Chris@16
|
209 /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
|
Chris@16
|
210 * expansion.
|
Chris@16
|
211 */
|
Chris@16
|
212
|
Chris@16
|
213 typedef std::pair<iterator,bool> emplace_return_type;
|
Chris@16
|
214
|
Chris@16
|
215 public:
|
Chris@16
|
216
|
Chris@16
|
217 /* construct/copy/destroy
|
Chris@16
|
218 * Default and copy ctors are in the protected section as indices are
|
Chris@16
|
219 * not supposed to be created on their own. No range ctor either.
|
Chris@16
|
220 */
|
Chris@16
|
221
|
Chris@16
|
222 ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& operator=(
|
Chris@16
|
223 const ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x)
|
Chris@16
|
224 {
|
Chris@16
|
225 this->final()=x.final();
|
Chris@16
|
226 return *this;
|
Chris@16
|
227 }
|
Chris@16
|
228
|
Chris@16
|
229 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
Chris@16
|
230 ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& operator=(
|
Chris@16
|
231 std::initializer_list<value_type> list)
|
Chris@16
|
232 {
|
Chris@16
|
233 this->final()=list;
|
Chris@16
|
234 return *this;
|
Chris@16
|
235 }
|
Chris@16
|
236 #endif
|
Chris@16
|
237
|
Chris@101
|
238 allocator_type get_allocator()const BOOST_NOEXCEPT
|
Chris@16
|
239 {
|
Chris@16
|
240 return this->final().get_allocator();
|
Chris@16
|
241 }
|
Chris@16
|
242
|
Chris@16
|
243 /* iterators */
|
Chris@16
|
244
|
Chris@101
|
245 iterator
|
Chris@101
|
246 begin()BOOST_NOEXCEPT{return make_iterator(leftmost());}
|
Chris@101
|
247 const_iterator
|
Chris@101
|
248 begin()const BOOST_NOEXCEPT{return make_iterator(leftmost());}
|
Chris@101
|
249 iterator
|
Chris@101
|
250 end()BOOST_NOEXCEPT{return make_iterator(header());}
|
Chris@101
|
251 const_iterator
|
Chris@101
|
252 end()const BOOST_NOEXCEPT{return make_iterator(header());}
|
Chris@101
|
253 reverse_iterator
|
Chris@101
|
254 rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());}
|
Chris@101
|
255 const_reverse_iterator
|
Chris@101
|
256 rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());}
|
Chris@101
|
257 reverse_iterator
|
Chris@101
|
258 rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());}
|
Chris@101
|
259 const_reverse_iterator
|
Chris@101
|
260 rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());}
|
Chris@101
|
261 const_iterator
|
Chris@101
|
262 cbegin()const BOOST_NOEXCEPT{return begin();}
|
Chris@101
|
263 const_iterator
|
Chris@101
|
264 cend()const BOOST_NOEXCEPT{return end();}
|
Chris@101
|
265 const_reverse_iterator
|
Chris@101
|
266 crbegin()const BOOST_NOEXCEPT{return rbegin();}
|
Chris@101
|
267 const_reverse_iterator
|
Chris@101
|
268 crend()const BOOST_NOEXCEPT{return rend();}
|
Chris@16
|
269
|
Chris@16
|
270 iterator iterator_to(const value_type& x)
|
Chris@16
|
271 {
|
Chris@16
|
272 return make_iterator(node_from_value<node_type>(&x));
|
Chris@16
|
273 }
|
Chris@16
|
274
|
Chris@16
|
275 const_iterator iterator_to(const value_type& x)const
|
Chris@16
|
276 {
|
Chris@16
|
277 return make_iterator(node_from_value<node_type>(&x));
|
Chris@16
|
278 }
|
Chris@16
|
279
|
Chris@16
|
280 /* capacity */
|
Chris@16
|
281
|
Chris@101
|
282 bool empty()const BOOST_NOEXCEPT{return this->final_empty_();}
|
Chris@101
|
283 size_type size()const BOOST_NOEXCEPT{return this->final_size_();}
|
Chris@101
|
284 size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();}
|
Chris@16
|
285
|
Chris@16
|
286 /* modifiers */
|
Chris@16
|
287
|
Chris@16
|
288 BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
Chris@16
|
289 emplace_return_type,emplace,emplace_impl)
|
Chris@16
|
290
|
Chris@16
|
291 BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
|
Chris@16
|
292 iterator,emplace_hint,emplace_hint_impl,iterator,position)
|
Chris@16
|
293
|
Chris@16
|
294 std::pair<iterator,bool> insert(const value_type& x)
|
Chris@16
|
295 {
|
Chris@16
|
296 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
Chris@16
|
297 std::pair<final_node_type*,bool> p=this->final_insert_(x);
|
Chris@16
|
298 return std::pair<iterator,bool>(make_iterator(p.first),p.second);
|
Chris@16
|
299 }
|
Chris@16
|
300
|
Chris@16
|
301 std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
|
Chris@16
|
302 {
|
Chris@16
|
303 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
Chris@16
|
304 std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
|
Chris@16
|
305 return std::pair<iterator,bool>(make_iterator(p.first),p.second);
|
Chris@16
|
306 }
|
Chris@16
|
307
|
Chris@16
|
308 iterator insert(iterator position,const value_type& x)
|
Chris@16
|
309 {
|
Chris@16
|
310 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
311 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
312 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
Chris@16
|
313 std::pair<final_node_type*,bool> p=this->final_insert_(
|
Chris@16
|
314 x,static_cast<final_node_type*>(position.get_node()));
|
Chris@16
|
315 return make_iterator(p.first);
|
Chris@16
|
316 }
|
Chris@16
|
317
|
Chris@16
|
318 iterator insert(iterator position,BOOST_RV_REF(value_type) x)
|
Chris@16
|
319 {
|
Chris@16
|
320 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
321 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
322 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
Chris@16
|
323 std::pair<final_node_type*,bool> p=this->final_insert_rv_(
|
Chris@16
|
324 x,static_cast<final_node_type*>(position.get_node()));
|
Chris@16
|
325 return make_iterator(p.first);
|
Chris@16
|
326 }
|
Chris@16
|
327
|
Chris@16
|
328 template<typename InputIterator>
|
Chris@16
|
329 void insert(InputIterator first,InputIterator last)
|
Chris@16
|
330 {
|
Chris@16
|
331 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
Chris@16
|
332 node_type* hint=header(); /* end() */
|
Chris@16
|
333 for(;first!=last;++first){
|
Chris@16
|
334 hint=this->final_insert_ref_(
|
Chris@16
|
335 *first,static_cast<final_node_type*>(hint)).first;
|
Chris@16
|
336 node_type::increment(hint);
|
Chris@16
|
337 }
|
Chris@16
|
338 }
|
Chris@16
|
339
|
Chris@16
|
340 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
Chris@16
|
341 void insert(std::initializer_list<value_type> list)
|
Chris@16
|
342 {
|
Chris@16
|
343 insert(list.begin(),list.end());
|
Chris@16
|
344 }
|
Chris@16
|
345 #endif
|
Chris@16
|
346
|
Chris@16
|
347 iterator erase(iterator position)
|
Chris@16
|
348 {
|
Chris@16
|
349 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
350 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
|
Chris@16
|
351 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
352 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
Chris@16
|
353 this->final_erase_(static_cast<final_node_type*>(position++.get_node()));
|
Chris@16
|
354 return position;
|
Chris@16
|
355 }
|
Chris@16
|
356
|
Chris@16
|
357 size_type erase(key_param_type x)
|
Chris@16
|
358 {
|
Chris@16
|
359 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
Chris@16
|
360 std::pair<iterator,iterator> p=equal_range(x);
|
Chris@16
|
361 size_type s=0;
|
Chris@16
|
362 while(p.first!=p.second){
|
Chris@16
|
363 p.first=erase(p.first);
|
Chris@16
|
364 ++s;
|
Chris@16
|
365 }
|
Chris@16
|
366 return s;
|
Chris@16
|
367 }
|
Chris@16
|
368
|
Chris@16
|
369 iterator erase(iterator first,iterator last)
|
Chris@16
|
370 {
|
Chris@16
|
371 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
|
Chris@16
|
372 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
|
Chris@16
|
373 BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
|
Chris@16
|
374 BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
|
Chris@16
|
375 BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
|
Chris@16
|
376 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
Chris@16
|
377 while(first!=last){
|
Chris@16
|
378 first=erase(first);
|
Chris@16
|
379 }
|
Chris@16
|
380 return first;
|
Chris@16
|
381 }
|
Chris@16
|
382
|
Chris@16
|
383 bool replace(iterator position,const value_type& x)
|
Chris@16
|
384 {
|
Chris@16
|
385 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
386 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
|
Chris@16
|
387 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
388 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
Chris@16
|
389 return this->final_replace_(
|
Chris@16
|
390 x,static_cast<final_node_type*>(position.get_node()));
|
Chris@16
|
391 }
|
Chris@16
|
392
|
Chris@16
|
393 bool replace(iterator position,BOOST_RV_REF(value_type) x)
|
Chris@16
|
394 {
|
Chris@16
|
395 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
396 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
|
Chris@16
|
397 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
398 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
Chris@16
|
399 return this->final_replace_rv_(
|
Chris@16
|
400 x,static_cast<final_node_type*>(position.get_node()));
|
Chris@16
|
401 }
|
Chris@16
|
402
|
Chris@16
|
403 template<typename Modifier>
|
Chris@16
|
404 bool modify(iterator position,Modifier mod)
|
Chris@16
|
405 {
|
Chris@16
|
406 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
407 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
|
Chris@16
|
408 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
409 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
Chris@16
|
410
|
Chris@16
|
411 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
412 /* MSVC++ 6.0 optimizer on safe mode code chokes if this
|
Chris@16
|
413 * this is not added. Left it for all compilers as it does no
|
Chris@16
|
414 * harm.
|
Chris@16
|
415 */
|
Chris@16
|
416
|
Chris@16
|
417 position.detach();
|
Chris@16
|
418 #endif
|
Chris@16
|
419
|
Chris@16
|
420 return this->final_modify_(
|
Chris@16
|
421 mod,static_cast<final_node_type*>(position.get_node()));
|
Chris@16
|
422 }
|
Chris@16
|
423
|
Chris@16
|
424 template<typename Modifier,typename Rollback>
|
Chris@101
|
425 bool modify(iterator position,Modifier mod,Rollback back_)
|
Chris@16
|
426 {
|
Chris@16
|
427 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
428 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
|
Chris@16
|
429 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
430 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
Chris@16
|
431
|
Chris@16
|
432 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
433 /* MSVC++ 6.0 optimizer on safe mode code chokes if this
|
Chris@16
|
434 * this is not added. Left it for all compilers as it does no
|
Chris@16
|
435 * harm.
|
Chris@16
|
436 */
|
Chris@16
|
437
|
Chris@16
|
438 position.detach();
|
Chris@16
|
439 #endif
|
Chris@16
|
440
|
Chris@16
|
441 return this->final_modify_(
|
Chris@101
|
442 mod,back_,static_cast<final_node_type*>(position.get_node()));
|
Chris@16
|
443 }
|
Chris@16
|
444
|
Chris@16
|
445 template<typename Modifier>
|
Chris@16
|
446 bool modify_key(iterator position,Modifier mod)
|
Chris@16
|
447 {
|
Chris@16
|
448 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
449 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
|
Chris@16
|
450 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
451 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
Chris@16
|
452 return modify(
|
Chris@16
|
453 position,modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key));
|
Chris@16
|
454 }
|
Chris@16
|
455
|
Chris@16
|
456 template<typename Modifier,typename Rollback>
|
Chris@101
|
457 bool modify_key(iterator position,Modifier mod,Rollback back_)
|
Chris@16
|
458 {
|
Chris@16
|
459 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
460 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
|
Chris@16
|
461 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
462 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
Chris@16
|
463 return modify(
|
Chris@16
|
464 position,
|
Chris@16
|
465 modify_key_adaptor<Modifier,value_type,KeyFromValue>(mod,key),
|
Chris@101
|
466 modify_key_adaptor<Rollback,value_type,KeyFromValue>(back_,key));
|
Chris@16
|
467 }
|
Chris@16
|
468
|
Chris@16
|
469 void swap(ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x)
|
Chris@16
|
470 {
|
Chris@16
|
471 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
Chris@16
|
472 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x);
|
Chris@16
|
473 this->final_swap_(x.final());
|
Chris@16
|
474 }
|
Chris@16
|
475
|
Chris@101
|
476 void clear()BOOST_NOEXCEPT
|
Chris@16
|
477 {
|
Chris@16
|
478 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
Chris@16
|
479 this->final_clear_();
|
Chris@16
|
480 }
|
Chris@16
|
481
|
Chris@16
|
482 /* observers */
|
Chris@16
|
483
|
Chris@16
|
484 key_from_value key_extractor()const{return key;}
|
Chris@16
|
485 key_compare key_comp()const{return comp_;}
|
Chris@16
|
486 value_compare value_comp()const{return value_compare(key,comp_);}
|
Chris@16
|
487
|
Chris@16
|
488 /* set operations */
|
Chris@16
|
489
|
Chris@16
|
490 /* Internally, these ops rely on const_iterator being the same
|
Chris@16
|
491 * type as iterator.
|
Chris@16
|
492 */
|
Chris@16
|
493
|
Chris@16
|
494 template<typename CompatibleKey>
|
Chris@16
|
495 iterator find(const CompatibleKey& x)const
|
Chris@16
|
496 {
|
Chris@16
|
497 return make_iterator(ordered_index_find(root(),header(),key,x,comp_));
|
Chris@16
|
498 }
|
Chris@16
|
499
|
Chris@16
|
500 template<typename CompatibleKey,typename CompatibleCompare>
|
Chris@16
|
501 iterator find(
|
Chris@16
|
502 const CompatibleKey& x,const CompatibleCompare& comp)const
|
Chris@16
|
503 {
|
Chris@16
|
504 return make_iterator(ordered_index_find(root(),header(),key,x,comp));
|
Chris@16
|
505 }
|
Chris@16
|
506
|
Chris@16
|
507 template<typename CompatibleKey>
|
Chris@16
|
508 size_type count(const CompatibleKey& x)const
|
Chris@16
|
509 {
|
Chris@16
|
510 return count(x,comp_);
|
Chris@16
|
511 }
|
Chris@16
|
512
|
Chris@16
|
513 template<typename CompatibleKey,typename CompatibleCompare>
|
Chris@16
|
514 size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const
|
Chris@16
|
515 {
|
Chris@16
|
516 std::pair<iterator,iterator> p=equal_range(x,comp);
|
Chris@16
|
517 size_type n=std::distance(p.first,p.second);
|
Chris@16
|
518 return n;
|
Chris@16
|
519 }
|
Chris@16
|
520
|
Chris@16
|
521 template<typename CompatibleKey>
|
Chris@16
|
522 iterator lower_bound(const CompatibleKey& x)const
|
Chris@16
|
523 {
|
Chris@16
|
524 return make_iterator(
|
Chris@16
|
525 ordered_index_lower_bound(root(),header(),key,x,comp_));
|
Chris@16
|
526 }
|
Chris@16
|
527
|
Chris@16
|
528 template<typename CompatibleKey,typename CompatibleCompare>
|
Chris@16
|
529 iterator lower_bound(
|
Chris@16
|
530 const CompatibleKey& x,const CompatibleCompare& comp)const
|
Chris@16
|
531 {
|
Chris@16
|
532 return make_iterator(
|
Chris@16
|
533 ordered_index_lower_bound(root(),header(),key,x,comp));
|
Chris@16
|
534 }
|
Chris@16
|
535
|
Chris@16
|
536 template<typename CompatibleKey>
|
Chris@16
|
537 iterator upper_bound(const CompatibleKey& x)const
|
Chris@16
|
538 {
|
Chris@16
|
539 return make_iterator(
|
Chris@16
|
540 ordered_index_upper_bound(root(),header(),key,x,comp_));
|
Chris@16
|
541 }
|
Chris@16
|
542
|
Chris@16
|
543 template<typename CompatibleKey,typename CompatibleCompare>
|
Chris@16
|
544 iterator upper_bound(
|
Chris@16
|
545 const CompatibleKey& x,const CompatibleCompare& comp)const
|
Chris@16
|
546 {
|
Chris@16
|
547 return make_iterator(
|
Chris@16
|
548 ordered_index_upper_bound(root(),header(),key,x,comp));
|
Chris@16
|
549 }
|
Chris@16
|
550
|
Chris@16
|
551 template<typename CompatibleKey>
|
Chris@16
|
552 std::pair<iterator,iterator> equal_range(
|
Chris@16
|
553 const CompatibleKey& x)const
|
Chris@16
|
554 {
|
Chris@16
|
555 std::pair<node_type*,node_type*> p=
|
Chris@16
|
556 ordered_index_equal_range(root(),header(),key,x,comp_);
|
Chris@16
|
557 return std::pair<iterator,iterator>(
|
Chris@16
|
558 make_iterator(p.first),make_iterator(p.second));
|
Chris@16
|
559 }
|
Chris@16
|
560
|
Chris@16
|
561 template<typename CompatibleKey,typename CompatibleCompare>
|
Chris@16
|
562 std::pair<iterator,iterator> equal_range(
|
Chris@16
|
563 const CompatibleKey& x,const CompatibleCompare& comp)const
|
Chris@16
|
564 {
|
Chris@16
|
565 std::pair<node_type*,node_type*> p=
|
Chris@16
|
566 ordered_index_equal_range(root(),header(),key,x,comp);
|
Chris@16
|
567 return std::pair<iterator,iterator>(
|
Chris@16
|
568 make_iterator(p.first),make_iterator(p.second));
|
Chris@16
|
569 }
|
Chris@16
|
570
|
Chris@16
|
571 /* range */
|
Chris@16
|
572
|
Chris@16
|
573 template<typename LowerBounder,typename UpperBounder>
|
Chris@16
|
574 std::pair<iterator,iterator>
|
Chris@16
|
575 range(LowerBounder lower,UpperBounder upper)const
|
Chris@16
|
576 {
|
Chris@16
|
577 typedef typename mpl::if_<
|
Chris@16
|
578 is_same<LowerBounder,unbounded_type>,
|
Chris@16
|
579 BOOST_DEDUCED_TYPENAME mpl::if_<
|
Chris@16
|
580 is_same<UpperBounder,unbounded_type>,
|
Chris@16
|
581 both_unbounded_tag,
|
Chris@16
|
582 lower_unbounded_tag
|
Chris@16
|
583 >::type,
|
Chris@16
|
584 BOOST_DEDUCED_TYPENAME mpl::if_<
|
Chris@16
|
585 is_same<UpperBounder,unbounded_type>,
|
Chris@16
|
586 upper_unbounded_tag,
|
Chris@16
|
587 none_unbounded_tag
|
Chris@16
|
588 >::type
|
Chris@16
|
589 >::type dispatch;
|
Chris@16
|
590
|
Chris@16
|
591 return range(lower,upper,dispatch());
|
Chris@16
|
592 }
|
Chris@16
|
593
|
Chris@16
|
594 BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
Chris@16
|
595 ordered_index(const ctor_args_list& args_list,const allocator_type& al):
|
Chris@16
|
596 super(args_list.get_tail(),al),
|
Chris@16
|
597 key(tuples::get<0>(args_list.get_head())),
|
Chris@16
|
598 comp_(tuples::get<1>(args_list.get_head()))
|
Chris@16
|
599 {
|
Chris@16
|
600 empty_initialize();
|
Chris@16
|
601 }
|
Chris@16
|
602
|
Chris@16
|
603 ordered_index(
|
Chris@16
|
604 const ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x):
|
Chris@16
|
605 super(x),
|
Chris@16
|
606
|
Chris@16
|
607 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
608 safe_super(),
|
Chris@16
|
609 #endif
|
Chris@16
|
610
|
Chris@16
|
611 key(x.key),
|
Chris@16
|
612 comp_(x.comp_)
|
Chris@16
|
613 {
|
Chris@16
|
614 /* Copy ctor just takes the key and compare objects from x. The rest is
|
Chris@16
|
615 * done in a subsequent call to copy_().
|
Chris@16
|
616 */
|
Chris@16
|
617 }
|
Chris@16
|
618
|
Chris@16
|
619 ordered_index(
|
Chris@16
|
620 const ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x,
|
Chris@16
|
621 do_not_copy_elements_tag):
|
Chris@16
|
622 super(x,do_not_copy_elements_tag()),
|
Chris@16
|
623
|
Chris@16
|
624 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
625 safe_super(),
|
Chris@16
|
626 #endif
|
Chris@16
|
627
|
Chris@16
|
628 key(x.key),
|
Chris@16
|
629 comp_(x.comp_)
|
Chris@16
|
630 {
|
Chris@16
|
631 empty_initialize();
|
Chris@16
|
632 }
|
Chris@16
|
633
|
Chris@16
|
634 ~ordered_index()
|
Chris@16
|
635 {
|
Chris@16
|
636 /* the container is guaranteed to be empty by now */
|
Chris@16
|
637 }
|
Chris@16
|
638
|
Chris@16
|
639 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
640 iterator make_iterator(node_type* node){return iterator(node,this);}
|
Chris@16
|
641 const_iterator make_iterator(node_type* node)const
|
Chris@16
|
642 {return const_iterator(node,const_cast<ordered_index*>(this));}
|
Chris@16
|
643 #else
|
Chris@16
|
644 iterator make_iterator(node_type* node){return iterator(node);}
|
Chris@16
|
645 const_iterator make_iterator(node_type* node)const
|
Chris@16
|
646 {return const_iterator(node);}
|
Chris@16
|
647 #endif
|
Chris@16
|
648
|
Chris@16
|
649 void copy_(
|
Chris@16
|
650 const ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x,
|
Chris@16
|
651 const copy_map_type& map)
|
Chris@16
|
652 {
|
Chris@16
|
653 if(!x.root()){
|
Chris@16
|
654 empty_initialize();
|
Chris@16
|
655 }
|
Chris@16
|
656 else{
|
Chris@16
|
657 header()->color()=x.header()->color();
|
Chris@16
|
658
|
Chris@16
|
659 node_type* root_cpy=map.find(static_cast<final_node_type*>(x.root()));
|
Chris@16
|
660 header()->parent()=root_cpy->impl();
|
Chris@16
|
661
|
Chris@16
|
662 node_type* leftmost_cpy=map.find(
|
Chris@16
|
663 static_cast<final_node_type*>(x.leftmost()));
|
Chris@16
|
664 header()->left()=leftmost_cpy->impl();
|
Chris@16
|
665
|
Chris@16
|
666 node_type* rightmost_cpy=map.find(
|
Chris@16
|
667 static_cast<final_node_type*>(x.rightmost()));
|
Chris@16
|
668 header()->right()=rightmost_cpy->impl();
|
Chris@16
|
669
|
Chris@16
|
670 typedef typename copy_map_type::const_iterator copy_map_iterator;
|
Chris@16
|
671 for(copy_map_iterator it=map.begin(),it_end=map.end();it!=it_end;++it){
|
Chris@16
|
672 node_type* org=it->first;
|
Chris@16
|
673 node_type* cpy=it->second;
|
Chris@16
|
674
|
Chris@16
|
675 cpy->color()=org->color();
|
Chris@16
|
676
|
Chris@16
|
677 node_impl_pointer parent_org=org->parent();
|
Chris@16
|
678 if(parent_org==node_impl_pointer(0))cpy->parent()=node_impl_pointer(0);
|
Chris@16
|
679 else{
|
Chris@16
|
680 node_type* parent_cpy=map.find(
|
Chris@16
|
681 static_cast<final_node_type*>(node_type::from_impl(parent_org)));
|
Chris@16
|
682 cpy->parent()=parent_cpy->impl();
|
Chris@16
|
683 if(parent_org->left()==org->impl()){
|
Chris@16
|
684 parent_cpy->left()=cpy->impl();
|
Chris@16
|
685 }
|
Chris@16
|
686 else if(parent_org->right()==org->impl()){
|
Chris@16
|
687 /* header() does not satisfy this nor the previous check */
|
Chris@16
|
688 parent_cpy->right()=cpy->impl();
|
Chris@16
|
689 }
|
Chris@16
|
690 }
|
Chris@16
|
691
|
Chris@16
|
692 if(org->left()==node_impl_pointer(0))
|
Chris@16
|
693 cpy->left()=node_impl_pointer(0);
|
Chris@16
|
694 if(org->right()==node_impl_pointer(0))
|
Chris@16
|
695 cpy->right()=node_impl_pointer(0);
|
Chris@16
|
696 }
|
Chris@16
|
697 }
|
Chris@16
|
698
|
Chris@16
|
699 super::copy_(x,map);
|
Chris@16
|
700 }
|
Chris@16
|
701
|
Chris@16
|
702 template<typename Variant>
|
Chris@101
|
703 final_node_type* insert_(
|
Chris@101
|
704 value_param_type v,final_node_type*& x,Variant variant)
|
Chris@16
|
705 {
|
Chris@16
|
706 link_info inf;
|
Chris@16
|
707 if(!link_point(key(v),inf,Category())){
|
Chris@101
|
708 return static_cast<final_node_type*>(node_type::from_impl(inf.pos));
|
Chris@16
|
709 }
|
Chris@16
|
710
|
Chris@101
|
711 final_node_type* res=super::insert_(v,x,variant);
|
Chris@16
|
712 if(res==x){
|
Chris@101
|
713 node_impl_type::link(
|
Chris@101
|
714 static_cast<node_type*>(x)->impl(),inf.side,inf.pos,header()->impl());
|
Chris@16
|
715 }
|
Chris@16
|
716 return res;
|
Chris@16
|
717 }
|
Chris@16
|
718
|
Chris@16
|
719 template<typename Variant>
|
Chris@101
|
720 final_node_type* insert_(
|
Chris@101
|
721 value_param_type v,node_type* position,final_node_type*& x,Variant variant)
|
Chris@16
|
722 {
|
Chris@16
|
723 link_info inf;
|
Chris@16
|
724 if(!hinted_link_point(key(v),position,inf,Category())){
|
Chris@101
|
725 return static_cast<final_node_type*>(node_type::from_impl(inf.pos));
|
Chris@16
|
726 }
|
Chris@16
|
727
|
Chris@101
|
728 final_node_type* res=super::insert_(v,position,x,variant);
|
Chris@16
|
729 if(res==x){
|
Chris@101
|
730 node_impl_type::link(
|
Chris@101
|
731 static_cast<node_type*>(x)->impl(),inf.side,inf.pos,header()->impl());
|
Chris@16
|
732 }
|
Chris@16
|
733 return res;
|
Chris@16
|
734 }
|
Chris@16
|
735
|
Chris@16
|
736 void erase_(node_type* x)
|
Chris@16
|
737 {
|
Chris@16
|
738 node_impl_type::rebalance_for_erase(
|
Chris@16
|
739 x->impl(),header()->parent(),header()->left(),header()->right());
|
Chris@16
|
740 super::erase_(x);
|
Chris@16
|
741
|
Chris@16
|
742 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
743 detach_iterators(x);
|
Chris@16
|
744 #endif
|
Chris@16
|
745 }
|
Chris@16
|
746
|
Chris@16
|
747 void delete_all_nodes_()
|
Chris@16
|
748 {
|
Chris@16
|
749 delete_all_nodes(root());
|
Chris@16
|
750 }
|
Chris@16
|
751
|
Chris@16
|
752 void clear_()
|
Chris@16
|
753 {
|
Chris@16
|
754 super::clear_();
|
Chris@16
|
755 empty_initialize();
|
Chris@16
|
756
|
Chris@16
|
757 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
758 safe_super::detach_dereferenceable_iterators();
|
Chris@16
|
759 #endif
|
Chris@16
|
760 }
|
Chris@16
|
761
|
Chris@16
|
762 void swap_(ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x)
|
Chris@16
|
763 {
|
Chris@16
|
764 std::swap(key,x.key);
|
Chris@16
|
765 std::swap(comp_,x.comp_);
|
Chris@16
|
766
|
Chris@16
|
767 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
768 safe_super::swap(x);
|
Chris@16
|
769 #endif
|
Chris@16
|
770
|
Chris@16
|
771 super::swap_(x);
|
Chris@16
|
772 }
|
Chris@16
|
773
|
Chris@16
|
774 void swap_elements_(
|
Chris@16
|
775 ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x)
|
Chris@16
|
776 {
|
Chris@16
|
777 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
778 safe_super::swap(x);
|
Chris@16
|
779 #endif
|
Chris@16
|
780
|
Chris@16
|
781 super::swap_elements_(x);
|
Chris@16
|
782 }
|
Chris@16
|
783
|
Chris@16
|
784 template<typename Variant>
|
Chris@16
|
785 bool replace_(value_param_type v,node_type* x,Variant variant)
|
Chris@16
|
786 {
|
Chris@16
|
787 if(in_place(v,x,Category())){
|
Chris@16
|
788 return super::replace_(v,x,variant);
|
Chris@16
|
789 }
|
Chris@16
|
790
|
Chris@16
|
791 node_type* next=x;
|
Chris@16
|
792 node_type::increment(next);
|
Chris@16
|
793
|
Chris@16
|
794 node_impl_type::rebalance_for_erase(
|
Chris@16
|
795 x->impl(),header()->parent(),header()->left(),header()->right());
|
Chris@16
|
796
|
Chris@16
|
797 BOOST_TRY{
|
Chris@16
|
798 link_info inf;
|
Chris@16
|
799 if(link_point(key(v),inf,Category())&&super::replace_(v,x,variant)){
|
Chris@16
|
800 node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
|
Chris@16
|
801 return true;
|
Chris@16
|
802 }
|
Chris@16
|
803 node_impl_type::restore(x->impl(),next->impl(),header()->impl());
|
Chris@16
|
804 return false;
|
Chris@16
|
805 }
|
Chris@16
|
806 BOOST_CATCH(...){
|
Chris@16
|
807 node_impl_type::restore(x->impl(),next->impl(),header()->impl());
|
Chris@16
|
808 BOOST_RETHROW;
|
Chris@16
|
809 }
|
Chris@16
|
810 BOOST_CATCH_END
|
Chris@16
|
811 }
|
Chris@16
|
812
|
Chris@16
|
813 bool modify_(node_type* x)
|
Chris@16
|
814 {
|
Chris@16
|
815 bool b;
|
Chris@16
|
816 BOOST_TRY{
|
Chris@16
|
817 b=in_place(x->value(),x,Category());
|
Chris@16
|
818 }
|
Chris@16
|
819 BOOST_CATCH(...){
|
Chris@16
|
820 erase_(x);
|
Chris@16
|
821 BOOST_RETHROW;
|
Chris@16
|
822 }
|
Chris@16
|
823 BOOST_CATCH_END
|
Chris@16
|
824 if(!b){
|
Chris@16
|
825 node_impl_type::rebalance_for_erase(
|
Chris@16
|
826 x->impl(),header()->parent(),header()->left(),header()->right());
|
Chris@16
|
827 BOOST_TRY{
|
Chris@16
|
828 link_info inf;
|
Chris@16
|
829 if(!link_point(key(x->value()),inf,Category())){
|
Chris@16
|
830 super::erase_(x);
|
Chris@16
|
831
|
Chris@16
|
832 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
833 detach_iterators(x);
|
Chris@16
|
834 #endif
|
Chris@16
|
835 return false;
|
Chris@16
|
836 }
|
Chris@16
|
837 node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
|
Chris@16
|
838 }
|
Chris@16
|
839 BOOST_CATCH(...){
|
Chris@16
|
840 super::erase_(x);
|
Chris@16
|
841
|
Chris@16
|
842 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
843 detach_iterators(x);
|
Chris@16
|
844 #endif
|
Chris@16
|
845
|
Chris@16
|
846 BOOST_RETHROW;
|
Chris@16
|
847 }
|
Chris@16
|
848 BOOST_CATCH_END
|
Chris@16
|
849 }
|
Chris@16
|
850
|
Chris@16
|
851 BOOST_TRY{
|
Chris@16
|
852 if(!super::modify_(x)){
|
Chris@16
|
853 node_impl_type::rebalance_for_erase(
|
Chris@16
|
854 x->impl(),header()->parent(),header()->left(),header()->right());
|
Chris@16
|
855
|
Chris@16
|
856 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
857 detach_iterators(x);
|
Chris@16
|
858 #endif
|
Chris@16
|
859
|
Chris@16
|
860 return false;
|
Chris@16
|
861 }
|
Chris@16
|
862 else return true;
|
Chris@16
|
863 }
|
Chris@16
|
864 BOOST_CATCH(...){
|
Chris@16
|
865 node_impl_type::rebalance_for_erase(
|
Chris@16
|
866 x->impl(),header()->parent(),header()->left(),header()->right());
|
Chris@16
|
867
|
Chris@16
|
868 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
869 detach_iterators(x);
|
Chris@16
|
870 #endif
|
Chris@16
|
871
|
Chris@16
|
872 BOOST_RETHROW;
|
Chris@16
|
873 }
|
Chris@16
|
874 BOOST_CATCH_END
|
Chris@16
|
875 }
|
Chris@16
|
876
|
Chris@16
|
877 bool modify_rollback_(node_type* x)
|
Chris@16
|
878 {
|
Chris@16
|
879 if(in_place(x->value(),x,Category())){
|
Chris@16
|
880 return super::modify_rollback_(x);
|
Chris@16
|
881 }
|
Chris@16
|
882
|
Chris@16
|
883 node_type* next=x;
|
Chris@16
|
884 node_type::increment(next);
|
Chris@16
|
885
|
Chris@16
|
886 node_impl_type::rebalance_for_erase(
|
Chris@16
|
887 x->impl(),header()->parent(),header()->left(),header()->right());
|
Chris@16
|
888
|
Chris@16
|
889 BOOST_TRY{
|
Chris@16
|
890 link_info inf;
|
Chris@16
|
891 if(link_point(key(x->value()),inf,Category())&&
|
Chris@16
|
892 super::modify_rollback_(x)){
|
Chris@16
|
893 node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
|
Chris@16
|
894 return true;
|
Chris@16
|
895 }
|
Chris@16
|
896 node_impl_type::restore(x->impl(),next->impl(),header()->impl());
|
Chris@16
|
897 return false;
|
Chris@16
|
898 }
|
Chris@16
|
899 BOOST_CATCH(...){
|
Chris@16
|
900 node_impl_type::restore(x->impl(),next->impl(),header()->impl());
|
Chris@16
|
901 BOOST_RETHROW;
|
Chris@16
|
902 }
|
Chris@16
|
903 BOOST_CATCH_END
|
Chris@16
|
904 }
|
Chris@16
|
905
|
Chris@16
|
906 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
Chris@16
|
907 /* serialization */
|
Chris@16
|
908
|
Chris@16
|
909 template<typename Archive>
|
Chris@16
|
910 void save_(
|
Chris@16
|
911 Archive& ar,const unsigned int version,const index_saver_type& sm)const
|
Chris@16
|
912 {
|
Chris@16
|
913 save_(ar,version,sm,Category());
|
Chris@16
|
914 }
|
Chris@16
|
915
|
Chris@16
|
916 template<typename Archive>
|
Chris@16
|
917 void load_(Archive& ar,const unsigned int version,const index_loader_type& lm)
|
Chris@16
|
918 {
|
Chris@16
|
919 load_(ar,version,lm,Category());
|
Chris@16
|
920 }
|
Chris@16
|
921 #endif
|
Chris@16
|
922
|
Chris@16
|
923 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
|
Chris@16
|
924 /* invariant stuff */
|
Chris@16
|
925
|
Chris@16
|
926 bool invariant_()const
|
Chris@16
|
927 {
|
Chris@16
|
928 if(size()==0||begin()==end()){
|
Chris@16
|
929 if(size()!=0||begin()!=end()||
|
Chris@16
|
930 header()->left()!=header()->impl()||
|
Chris@16
|
931 header()->right()!=header()->impl())return false;
|
Chris@16
|
932 }
|
Chris@16
|
933 else{
|
Chris@16
|
934 if((size_type)std::distance(begin(),end())!=size())return false;
|
Chris@16
|
935
|
Chris@16
|
936 std::size_t len=node_impl_type::black_count(
|
Chris@16
|
937 leftmost()->impl(),root()->impl());
|
Chris@16
|
938 for(const_iterator it=begin(),it_end=end();it!=it_end;++it){
|
Chris@16
|
939 node_type* x=it.get_node();
|
Chris@16
|
940 node_type* left_x=node_type::from_impl(x->left());
|
Chris@16
|
941 node_type* right_x=node_type::from_impl(x->right());
|
Chris@16
|
942
|
Chris@16
|
943 if(x->color()==red){
|
Chris@16
|
944 if((left_x&&left_x->color()==red)||
|
Chris@16
|
945 (right_x&&right_x->color()==red))return false;
|
Chris@16
|
946 }
|
Chris@16
|
947 if(left_x&&comp_(key(x->value()),key(left_x->value())))return false;
|
Chris@16
|
948 if(right_x&&comp_(key(right_x->value()),key(x->value())))return false;
|
Chris@16
|
949 if(!left_x&&!right_x&&
|
Chris@16
|
950 node_impl_type::black_count(x->impl(),root()->impl())!=len)
|
Chris@16
|
951 return false;
|
Chris@16
|
952 }
|
Chris@16
|
953
|
Chris@16
|
954 if(leftmost()->impl()!=node_impl_type::minimum(root()->impl()))
|
Chris@16
|
955 return false;
|
Chris@16
|
956 if(rightmost()->impl()!=node_impl_type::maximum(root()->impl()))
|
Chris@16
|
957 return false;
|
Chris@16
|
958 }
|
Chris@16
|
959
|
Chris@16
|
960 return super::invariant_();
|
Chris@16
|
961 }
|
Chris@16
|
962
|
Chris@16
|
963
|
Chris@16
|
964 /* This forwarding function eases things for the boost::mem_fn construct
|
Chris@16
|
965 * in BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT. Actually,
|
Chris@16
|
966 * final_check_invariant is already an inherited member function of
|
Chris@16
|
967 * ordered_index.
|
Chris@16
|
968 */
|
Chris@16
|
969 void check_invariant_()const{this->final_check_invariant_();}
|
Chris@16
|
970 #endif
|
Chris@16
|
971
|
Chris@16
|
972 private:
|
Chris@16
|
973 node_type* header()const{return this->final_header();}
|
Chris@16
|
974 node_type* root()const{return node_type::from_impl(header()->parent());}
|
Chris@16
|
975 node_type* leftmost()const{return node_type::from_impl(header()->left());}
|
Chris@16
|
976 node_type* rightmost()const{return node_type::from_impl(header()->right());}
|
Chris@16
|
977
|
Chris@16
|
978 void empty_initialize()
|
Chris@16
|
979 {
|
Chris@16
|
980 header()->color()=red;
|
Chris@16
|
981 /* used to distinguish header() from root, in iterator.operator++ */
|
Chris@16
|
982
|
Chris@16
|
983 header()->parent()=node_impl_pointer(0);
|
Chris@16
|
984 header()->left()=header()->impl();
|
Chris@16
|
985 header()->right()=header()->impl();
|
Chris@16
|
986 }
|
Chris@16
|
987
|
Chris@16
|
988 struct link_info
|
Chris@16
|
989 {
|
Chris@101
|
990 /* coverity[uninit_ctor]: suppress warning */
|
Chris@16
|
991 link_info():side(to_left){}
|
Chris@16
|
992
|
Chris@16
|
993 ordered_index_side side;
|
Chris@16
|
994 node_impl_pointer pos;
|
Chris@16
|
995 };
|
Chris@16
|
996
|
Chris@16
|
997 bool link_point(key_param_type k,link_info& inf,ordered_unique_tag)
|
Chris@16
|
998 {
|
Chris@16
|
999 node_type* y=header();
|
Chris@16
|
1000 node_type* x=root();
|
Chris@16
|
1001 bool c=true;
|
Chris@16
|
1002 while(x){
|
Chris@16
|
1003 y=x;
|
Chris@16
|
1004 c=comp_(k,key(x->value()));
|
Chris@16
|
1005 x=node_type::from_impl(c?x->left():x->right());
|
Chris@16
|
1006 }
|
Chris@16
|
1007 node_type* yy=y;
|
Chris@16
|
1008 if(c){
|
Chris@16
|
1009 if(yy==leftmost()){
|
Chris@16
|
1010 inf.side=to_left;
|
Chris@16
|
1011 inf.pos=y->impl();
|
Chris@16
|
1012 return true;
|
Chris@16
|
1013 }
|
Chris@16
|
1014 else node_type::decrement(yy);
|
Chris@16
|
1015 }
|
Chris@16
|
1016
|
Chris@16
|
1017 if(comp_(key(yy->value()),k)){
|
Chris@16
|
1018 inf.side=c?to_left:to_right;
|
Chris@16
|
1019 inf.pos=y->impl();
|
Chris@16
|
1020 return true;
|
Chris@16
|
1021 }
|
Chris@16
|
1022 else{
|
Chris@16
|
1023 inf.pos=yy->impl();
|
Chris@16
|
1024 return false;
|
Chris@16
|
1025 }
|
Chris@16
|
1026 }
|
Chris@16
|
1027
|
Chris@16
|
1028 bool link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
|
Chris@16
|
1029 {
|
Chris@16
|
1030 node_type* y=header();
|
Chris@16
|
1031 node_type* x=root();
|
Chris@16
|
1032 bool c=true;
|
Chris@16
|
1033 while (x){
|
Chris@16
|
1034 y=x;
|
Chris@16
|
1035 c=comp_(k,key(x->value()));
|
Chris@16
|
1036 x=node_type::from_impl(c?x->left():x->right());
|
Chris@16
|
1037 }
|
Chris@16
|
1038 inf.side=c?to_left:to_right;
|
Chris@16
|
1039 inf.pos=y->impl();
|
Chris@16
|
1040 return true;
|
Chris@16
|
1041 }
|
Chris@16
|
1042
|
Chris@16
|
1043 bool lower_link_point(key_param_type k,link_info& inf,ordered_non_unique_tag)
|
Chris@16
|
1044 {
|
Chris@16
|
1045 node_type* y=header();
|
Chris@16
|
1046 node_type* x=root();
|
Chris@16
|
1047 bool c=false;
|
Chris@16
|
1048 while (x){
|
Chris@16
|
1049 y=x;
|
Chris@16
|
1050 c=comp_(key(x->value()),k);
|
Chris@16
|
1051 x=node_type::from_impl(c?x->right():x->left());
|
Chris@16
|
1052 }
|
Chris@16
|
1053 inf.side=c?to_right:to_left;
|
Chris@16
|
1054 inf.pos=y->impl();
|
Chris@16
|
1055 return true;
|
Chris@16
|
1056 }
|
Chris@16
|
1057
|
Chris@16
|
1058 bool hinted_link_point(
|
Chris@16
|
1059 key_param_type k,node_type* position,link_info& inf,ordered_unique_tag)
|
Chris@16
|
1060 {
|
Chris@16
|
1061 if(position->impl()==header()->left()){
|
Chris@16
|
1062 if(size()>0&&comp_(k,key(position->value()))){
|
Chris@16
|
1063 inf.side=to_left;
|
Chris@16
|
1064 inf.pos=position->impl();
|
Chris@16
|
1065 return true;
|
Chris@16
|
1066 }
|
Chris@16
|
1067 else return link_point(k,inf,ordered_unique_tag());
|
Chris@16
|
1068 }
|
Chris@16
|
1069 else if(position==header()){
|
Chris@16
|
1070 if(comp_(key(rightmost()->value()),k)){
|
Chris@16
|
1071 inf.side=to_right;
|
Chris@16
|
1072 inf.pos=rightmost()->impl();
|
Chris@16
|
1073 return true;
|
Chris@16
|
1074 }
|
Chris@16
|
1075 else return link_point(k,inf,ordered_unique_tag());
|
Chris@16
|
1076 }
|
Chris@16
|
1077 else{
|
Chris@16
|
1078 node_type* before=position;
|
Chris@16
|
1079 node_type::decrement(before);
|
Chris@16
|
1080 if(comp_(key(before->value()),k)&&comp_(k,key(position->value()))){
|
Chris@16
|
1081 if(before->right()==node_impl_pointer(0)){
|
Chris@16
|
1082 inf.side=to_right;
|
Chris@16
|
1083 inf.pos=before->impl();
|
Chris@16
|
1084 return true;
|
Chris@16
|
1085 }
|
Chris@16
|
1086 else{
|
Chris@16
|
1087 inf.side=to_left;
|
Chris@16
|
1088 inf.pos=position->impl();
|
Chris@16
|
1089 return true;
|
Chris@16
|
1090 }
|
Chris@16
|
1091 }
|
Chris@16
|
1092 else return link_point(k,inf,ordered_unique_tag());
|
Chris@16
|
1093 }
|
Chris@16
|
1094 }
|
Chris@16
|
1095
|
Chris@16
|
1096 bool hinted_link_point(
|
Chris@16
|
1097 key_param_type k,node_type* position,link_info& inf,ordered_non_unique_tag)
|
Chris@16
|
1098 {
|
Chris@16
|
1099 if(position->impl()==header()->left()){
|
Chris@16
|
1100 if(size()>0&&!comp_(key(position->value()),k)){
|
Chris@16
|
1101 inf.side=to_left;
|
Chris@16
|
1102 inf.pos=position->impl();
|
Chris@16
|
1103 return true;
|
Chris@16
|
1104 }
|
Chris@16
|
1105 else return lower_link_point(k,inf,ordered_non_unique_tag());
|
Chris@16
|
1106 }
|
Chris@16
|
1107 else if(position==header()){
|
Chris@16
|
1108 if(!comp_(k,key(rightmost()->value()))){
|
Chris@16
|
1109 inf.side=to_right;
|
Chris@16
|
1110 inf.pos=rightmost()->impl();
|
Chris@16
|
1111 return true;
|
Chris@16
|
1112 }
|
Chris@16
|
1113 else return link_point(k,inf,ordered_non_unique_tag());
|
Chris@16
|
1114 }
|
Chris@16
|
1115 else{
|
Chris@16
|
1116 node_type* before=position;
|
Chris@16
|
1117 node_type::decrement(before);
|
Chris@16
|
1118 if(!comp_(k,key(before->value()))){
|
Chris@16
|
1119 if(!comp_(key(position->value()),k)){
|
Chris@16
|
1120 if(before->right()==node_impl_pointer(0)){
|
Chris@16
|
1121 inf.side=to_right;
|
Chris@16
|
1122 inf.pos=before->impl();
|
Chris@16
|
1123 return true;
|
Chris@16
|
1124 }
|
Chris@16
|
1125 else{
|
Chris@16
|
1126 inf.side=to_left;
|
Chris@16
|
1127 inf.pos=position->impl();
|
Chris@16
|
1128 return true;
|
Chris@16
|
1129 }
|
Chris@16
|
1130 }
|
Chris@16
|
1131 else return lower_link_point(k,inf,ordered_non_unique_tag());
|
Chris@16
|
1132 }
|
Chris@16
|
1133 else return link_point(k,inf,ordered_non_unique_tag());
|
Chris@16
|
1134 }
|
Chris@16
|
1135 }
|
Chris@16
|
1136
|
Chris@16
|
1137 void delete_all_nodes(node_type* x)
|
Chris@16
|
1138 {
|
Chris@16
|
1139 if(!x)return;
|
Chris@16
|
1140
|
Chris@16
|
1141 delete_all_nodes(node_type::from_impl(x->left()));
|
Chris@16
|
1142 delete_all_nodes(node_type::from_impl(x->right()));
|
Chris@16
|
1143 this->final_delete_node_(static_cast<final_node_type*>(x));
|
Chris@16
|
1144 }
|
Chris@16
|
1145
|
Chris@16
|
1146 bool in_place(value_param_type v,node_type* x,ordered_unique_tag)
|
Chris@16
|
1147 {
|
Chris@16
|
1148 node_type* y;
|
Chris@16
|
1149 if(x!=leftmost()){
|
Chris@16
|
1150 y=x;
|
Chris@16
|
1151 node_type::decrement(y);
|
Chris@16
|
1152 if(!comp_(key(y->value()),key(v)))return false;
|
Chris@16
|
1153 }
|
Chris@16
|
1154
|
Chris@16
|
1155 y=x;
|
Chris@16
|
1156 node_type::increment(y);
|
Chris@16
|
1157 return y==header()||comp_(key(v),key(y->value()));
|
Chris@16
|
1158 }
|
Chris@16
|
1159
|
Chris@16
|
1160 bool in_place(value_param_type v,node_type* x,ordered_non_unique_tag)
|
Chris@16
|
1161 {
|
Chris@16
|
1162 node_type* y;
|
Chris@16
|
1163 if(x!=leftmost()){
|
Chris@16
|
1164 y=x;
|
Chris@16
|
1165 node_type::decrement(y);
|
Chris@16
|
1166 if(comp_(key(v),key(y->value())))return false;
|
Chris@16
|
1167 }
|
Chris@16
|
1168
|
Chris@16
|
1169 y=x;
|
Chris@16
|
1170 node_type::increment(y);
|
Chris@16
|
1171 return y==header()||!comp_(key(y->value()),key(v));
|
Chris@16
|
1172 }
|
Chris@16
|
1173
|
Chris@16
|
1174 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
1175 void detach_iterators(node_type* x)
|
Chris@16
|
1176 {
|
Chris@16
|
1177 iterator it=make_iterator(x);
|
Chris@16
|
1178 safe_mode::detach_equivalent_iterators(it);
|
Chris@16
|
1179 }
|
Chris@16
|
1180 #endif
|
Chris@16
|
1181
|
Chris@16
|
1182 template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
|
Chris@16
|
1183 std::pair<iterator,bool> emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
|
Chris@16
|
1184 {
|
Chris@16
|
1185 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
Chris@16
|
1186 std::pair<final_node_type*,bool>p=
|
Chris@16
|
1187 this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
|
Chris@16
|
1188 return std::pair<iterator,bool>(make_iterator(p.first),p.second);
|
Chris@16
|
1189 }
|
Chris@16
|
1190
|
Chris@16
|
1191 template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
|
Chris@16
|
1192 iterator emplace_hint_impl(
|
Chris@16
|
1193 iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
|
Chris@16
|
1194 {
|
Chris@16
|
1195 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
1196 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
1197 BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
|
Chris@16
|
1198 std::pair<final_node_type*,bool>p=
|
Chris@16
|
1199 this->final_emplace_hint_(
|
Chris@16
|
1200 static_cast<final_node_type*>(position.get_node()),
|
Chris@16
|
1201 BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
|
Chris@16
|
1202 return make_iterator(p.first);
|
Chris@16
|
1203 }
|
Chris@16
|
1204
|
Chris@16
|
1205 template<typename LowerBounder,typename UpperBounder>
|
Chris@16
|
1206 std::pair<iterator,iterator>
|
Chris@16
|
1207 range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const
|
Chris@16
|
1208 {
|
Chris@16
|
1209 node_type* y=header();
|
Chris@16
|
1210 node_type* z=root();
|
Chris@16
|
1211
|
Chris@16
|
1212 while(z){
|
Chris@16
|
1213 if(!lower(key(z->value()))){
|
Chris@16
|
1214 z=node_type::from_impl(z->right());
|
Chris@16
|
1215 }
|
Chris@16
|
1216 else if(!upper(key(z->value()))){
|
Chris@16
|
1217 y=z;
|
Chris@16
|
1218 z=node_type::from_impl(z->left());
|
Chris@16
|
1219 }
|
Chris@16
|
1220 else{
|
Chris@16
|
1221 return std::pair<iterator,iterator>(
|
Chris@16
|
1222 make_iterator(
|
Chris@16
|
1223 lower_range(node_type::from_impl(z->left()),z,lower)),
|
Chris@16
|
1224 make_iterator(
|
Chris@16
|
1225 upper_range(node_type::from_impl(z->right()),y,upper)));
|
Chris@16
|
1226 }
|
Chris@16
|
1227 }
|
Chris@16
|
1228
|
Chris@16
|
1229 return std::pair<iterator,iterator>(make_iterator(y),make_iterator(y));
|
Chris@16
|
1230 }
|
Chris@16
|
1231
|
Chris@16
|
1232 template<typename LowerBounder,typename UpperBounder>
|
Chris@16
|
1233 std::pair<iterator,iterator>
|
Chris@16
|
1234 range(LowerBounder,UpperBounder upper,lower_unbounded_tag)const
|
Chris@16
|
1235 {
|
Chris@16
|
1236 return std::pair<iterator,iterator>(
|
Chris@16
|
1237 begin(),
|
Chris@16
|
1238 make_iterator(upper_range(root(),header(),upper)));
|
Chris@16
|
1239 }
|
Chris@16
|
1240
|
Chris@16
|
1241 template<typename LowerBounder,typename UpperBounder>
|
Chris@16
|
1242 std::pair<iterator,iterator>
|
Chris@16
|
1243 range(LowerBounder lower,UpperBounder,upper_unbounded_tag)const
|
Chris@16
|
1244 {
|
Chris@16
|
1245 return std::pair<iterator,iterator>(
|
Chris@16
|
1246 make_iterator(lower_range(root(),header(),lower)),
|
Chris@16
|
1247 end());
|
Chris@16
|
1248 }
|
Chris@16
|
1249
|
Chris@16
|
1250 template<typename LowerBounder,typename UpperBounder>
|
Chris@16
|
1251 std::pair<iterator,iterator>
|
Chris@16
|
1252 range(LowerBounder,UpperBounder,both_unbounded_tag)const
|
Chris@16
|
1253 {
|
Chris@16
|
1254 return std::pair<iterator,iterator>(begin(),end());
|
Chris@16
|
1255 }
|
Chris@16
|
1256
|
Chris@16
|
1257 template<typename LowerBounder>
|
Chris@16
|
1258 node_type * lower_range(node_type* top,node_type* y,LowerBounder lower)const
|
Chris@16
|
1259 {
|
Chris@16
|
1260 while(top){
|
Chris@16
|
1261 if(lower(key(top->value()))){
|
Chris@16
|
1262 y=top;
|
Chris@16
|
1263 top=node_type::from_impl(top->left());
|
Chris@16
|
1264 }
|
Chris@16
|
1265 else top=node_type::from_impl(top->right());
|
Chris@16
|
1266 }
|
Chris@16
|
1267
|
Chris@16
|
1268 return y;
|
Chris@16
|
1269 }
|
Chris@16
|
1270
|
Chris@16
|
1271 template<typename UpperBounder>
|
Chris@16
|
1272 node_type * upper_range(node_type* top,node_type* y,UpperBounder upper)const
|
Chris@16
|
1273 {
|
Chris@16
|
1274 while(top){
|
Chris@16
|
1275 if(!upper(key(top->value()))){
|
Chris@16
|
1276 y=top;
|
Chris@16
|
1277 top=node_type::from_impl(top->left());
|
Chris@16
|
1278 }
|
Chris@16
|
1279 else top=node_type::from_impl(top->right());
|
Chris@16
|
1280 }
|
Chris@16
|
1281
|
Chris@16
|
1282 return y;
|
Chris@16
|
1283 }
|
Chris@16
|
1284
|
Chris@16
|
1285 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
Chris@16
|
1286 template<typename Archive>
|
Chris@16
|
1287 void save_(
|
Chris@16
|
1288 Archive& ar,const unsigned int version,const index_saver_type& sm,
|
Chris@16
|
1289 ordered_unique_tag)const
|
Chris@16
|
1290 {
|
Chris@16
|
1291 super::save_(ar,version,sm);
|
Chris@16
|
1292 }
|
Chris@16
|
1293
|
Chris@16
|
1294 template<typename Archive>
|
Chris@16
|
1295 void load_(
|
Chris@16
|
1296 Archive& ar,const unsigned int version,const index_loader_type& lm,
|
Chris@16
|
1297 ordered_unique_tag)
|
Chris@16
|
1298 {
|
Chris@16
|
1299 super::load_(ar,version,lm);
|
Chris@16
|
1300 }
|
Chris@16
|
1301
|
Chris@16
|
1302 template<typename Archive>
|
Chris@16
|
1303 void save_(
|
Chris@16
|
1304 Archive& ar,const unsigned int version,const index_saver_type& sm,
|
Chris@16
|
1305 ordered_non_unique_tag)const
|
Chris@16
|
1306 {
|
Chris@16
|
1307 typedef duplicates_iterator<node_type,value_compare> dup_iterator;
|
Chris@16
|
1308
|
Chris@16
|
1309 sm.save(
|
Chris@16
|
1310 dup_iterator(begin().get_node(),end().get_node(),value_comp()),
|
Chris@16
|
1311 dup_iterator(end().get_node(),value_comp()),
|
Chris@16
|
1312 ar,version);
|
Chris@16
|
1313 super::save_(ar,version,sm);
|
Chris@16
|
1314 }
|
Chris@16
|
1315
|
Chris@16
|
1316 template<typename Archive>
|
Chris@16
|
1317 void load_(
|
Chris@16
|
1318 Archive& ar,const unsigned int version,const index_loader_type& lm,
|
Chris@16
|
1319 ordered_non_unique_tag)
|
Chris@16
|
1320 {
|
Chris@16
|
1321 lm.load(
|
Chris@101
|
1322 ::boost::bind(
|
Chris@101
|
1323 &ordered_index::rearranger,this,::boost::arg<1>(),::boost::arg<2>()),
|
Chris@16
|
1324 ar,version);
|
Chris@16
|
1325 super::load_(ar,version,lm);
|
Chris@16
|
1326 }
|
Chris@16
|
1327
|
Chris@16
|
1328 void rearranger(node_type* position,node_type *x)
|
Chris@16
|
1329 {
|
Chris@16
|
1330 if(!position||comp_(key(position->value()),key(x->value()))){
|
Chris@16
|
1331 position=lower_bound(key(x->value())).get_node();
|
Chris@16
|
1332 }
|
Chris@16
|
1333 else if(comp_(key(x->value()),key(position->value()))){
|
Chris@16
|
1334 /* inconsistent rearrangement */
|
Chris@16
|
1335 throw_exception(
|
Chris@16
|
1336 archive::archive_exception(
|
Chris@16
|
1337 archive::archive_exception::other_exception));
|
Chris@16
|
1338 }
|
Chris@16
|
1339 else node_type::increment(position);
|
Chris@16
|
1340
|
Chris@16
|
1341 if(position!=x){
|
Chris@16
|
1342 node_impl_type::rebalance_for_erase(
|
Chris@16
|
1343 x->impl(),header()->parent(),header()->left(),header()->right());
|
Chris@16
|
1344 node_impl_type::restore(
|
Chris@16
|
1345 x->impl(),position->impl(),header()->impl());
|
Chris@16
|
1346 }
|
Chris@16
|
1347 }
|
Chris@16
|
1348 #endif /* serialization */
|
Chris@16
|
1349
|
Chris@16
|
1350 key_from_value key;
|
Chris@16
|
1351 key_compare comp_;
|
Chris@16
|
1352
|
Chris@16
|
1353 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
|
Chris@16
|
1354 BOOST_WORKAROUND(__MWERKS__,<=0x3003)
|
Chris@16
|
1355 #pragma parse_mfunc_templ reset
|
Chris@16
|
1356 #endif
|
Chris@16
|
1357 };
|
Chris@16
|
1358
|
Chris@16
|
1359 /* comparison */
|
Chris@16
|
1360
|
Chris@16
|
1361 template<
|
Chris@16
|
1362 typename KeyFromValue1,typename Compare1,
|
Chris@16
|
1363 typename SuperMeta1,typename TagList1,typename Category1,
|
Chris@16
|
1364 typename KeyFromValue2,typename Compare2,
|
Chris@16
|
1365 typename SuperMeta2,typename TagList2,typename Category2
|
Chris@16
|
1366 >
|
Chris@16
|
1367 bool operator==(
|
Chris@16
|
1368 const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
|
Chris@16
|
1369 const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y)
|
Chris@16
|
1370 {
|
Chris@16
|
1371 return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
|
Chris@16
|
1372 }
|
Chris@16
|
1373
|
Chris@16
|
1374 template<
|
Chris@16
|
1375 typename KeyFromValue1,typename Compare1,
|
Chris@16
|
1376 typename SuperMeta1,typename TagList1,typename Category1,
|
Chris@16
|
1377 typename KeyFromValue2,typename Compare2,
|
Chris@16
|
1378 typename SuperMeta2,typename TagList2,typename Category2
|
Chris@16
|
1379 >
|
Chris@16
|
1380 bool operator<(
|
Chris@16
|
1381 const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
|
Chris@16
|
1382 const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y)
|
Chris@16
|
1383 {
|
Chris@16
|
1384 return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
|
Chris@16
|
1385 }
|
Chris@16
|
1386
|
Chris@16
|
1387 template<
|
Chris@16
|
1388 typename KeyFromValue1,typename Compare1,
|
Chris@16
|
1389 typename SuperMeta1,typename TagList1,typename Category1,
|
Chris@16
|
1390 typename KeyFromValue2,typename Compare2,
|
Chris@16
|
1391 typename SuperMeta2,typename TagList2,typename Category2
|
Chris@16
|
1392 >
|
Chris@16
|
1393 bool operator!=(
|
Chris@16
|
1394 const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
|
Chris@16
|
1395 const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y)
|
Chris@16
|
1396 {
|
Chris@16
|
1397 return !(x==y);
|
Chris@16
|
1398 }
|
Chris@16
|
1399
|
Chris@16
|
1400 template<
|
Chris@16
|
1401 typename KeyFromValue1,typename Compare1,
|
Chris@16
|
1402 typename SuperMeta1,typename TagList1,typename Category1,
|
Chris@16
|
1403 typename KeyFromValue2,typename Compare2,
|
Chris@16
|
1404 typename SuperMeta2,typename TagList2,typename Category2
|
Chris@16
|
1405 >
|
Chris@16
|
1406 bool operator>(
|
Chris@16
|
1407 const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
|
Chris@16
|
1408 const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y)
|
Chris@16
|
1409 {
|
Chris@16
|
1410 return y<x;
|
Chris@16
|
1411 }
|
Chris@16
|
1412
|
Chris@16
|
1413 template<
|
Chris@16
|
1414 typename KeyFromValue1,typename Compare1,
|
Chris@16
|
1415 typename SuperMeta1,typename TagList1,typename Category1,
|
Chris@16
|
1416 typename KeyFromValue2,typename Compare2,
|
Chris@16
|
1417 typename SuperMeta2,typename TagList2,typename Category2
|
Chris@16
|
1418 >
|
Chris@16
|
1419 bool operator>=(
|
Chris@16
|
1420 const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
|
Chris@16
|
1421 const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y)
|
Chris@16
|
1422 {
|
Chris@16
|
1423 return !(x<y);
|
Chris@16
|
1424 }
|
Chris@16
|
1425
|
Chris@16
|
1426 template<
|
Chris@16
|
1427 typename KeyFromValue1,typename Compare1,
|
Chris@16
|
1428 typename SuperMeta1,typename TagList1,typename Category1,
|
Chris@16
|
1429 typename KeyFromValue2,typename Compare2,
|
Chris@16
|
1430 typename SuperMeta2,typename TagList2,typename Category2
|
Chris@16
|
1431 >
|
Chris@16
|
1432 bool operator<=(
|
Chris@16
|
1433 const ordered_index<KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1>& x,
|
Chris@16
|
1434 const ordered_index<KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2>& y)
|
Chris@16
|
1435 {
|
Chris@16
|
1436 return !(x>y);
|
Chris@16
|
1437 }
|
Chris@16
|
1438
|
Chris@16
|
1439 /* specialized algorithms */
|
Chris@16
|
1440
|
Chris@16
|
1441 template<
|
Chris@16
|
1442 typename KeyFromValue,typename Compare,
|
Chris@16
|
1443 typename SuperMeta,typename TagList,typename Category
|
Chris@16
|
1444 >
|
Chris@16
|
1445 void swap(
|
Chris@16
|
1446 ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x,
|
Chris@16
|
1447 ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& y)
|
Chris@16
|
1448 {
|
Chris@16
|
1449 x.swap(y);
|
Chris@16
|
1450 }
|
Chris@16
|
1451
|
Chris@16
|
1452 } /* namespace multi_index::detail */
|
Chris@16
|
1453
|
Chris@16
|
1454 /* ordered_index specifiers */
|
Chris@16
|
1455
|
Chris@16
|
1456 template<typename Arg1,typename Arg2,typename Arg3>
|
Chris@16
|
1457 struct ordered_unique
|
Chris@16
|
1458 {
|
Chris@16
|
1459 typedef typename detail::ordered_index_args<
|
Chris@16
|
1460 Arg1,Arg2,Arg3> index_args;
|
Chris@16
|
1461 typedef typename index_args::tag_list_type::type tag_list_type;
|
Chris@16
|
1462 typedef typename index_args::key_from_value_type key_from_value_type;
|
Chris@16
|
1463 typedef typename index_args::compare_type compare_type;
|
Chris@16
|
1464
|
Chris@16
|
1465 template<typename Super>
|
Chris@16
|
1466 struct node_class
|
Chris@16
|
1467 {
|
Chris@16
|
1468 typedef detail::ordered_index_node<Super> type;
|
Chris@16
|
1469 };
|
Chris@16
|
1470
|
Chris@16
|
1471 template<typename SuperMeta>
|
Chris@16
|
1472 struct index_class
|
Chris@16
|
1473 {
|
Chris@16
|
1474 typedef detail::ordered_index<
|
Chris@16
|
1475 key_from_value_type,compare_type,
|
Chris@16
|
1476 SuperMeta,tag_list_type,detail::ordered_unique_tag> type;
|
Chris@16
|
1477 };
|
Chris@16
|
1478 };
|
Chris@16
|
1479
|
Chris@16
|
1480 template<typename Arg1,typename Arg2,typename Arg3>
|
Chris@16
|
1481 struct ordered_non_unique
|
Chris@16
|
1482 {
|
Chris@16
|
1483 typedef detail::ordered_index_args<
|
Chris@16
|
1484 Arg1,Arg2,Arg3> index_args;
|
Chris@16
|
1485 typedef typename index_args::tag_list_type::type tag_list_type;
|
Chris@16
|
1486 typedef typename index_args::key_from_value_type key_from_value_type;
|
Chris@16
|
1487 typedef typename index_args::compare_type compare_type;
|
Chris@16
|
1488
|
Chris@16
|
1489 template<typename Super>
|
Chris@16
|
1490 struct node_class
|
Chris@16
|
1491 {
|
Chris@16
|
1492 typedef detail::ordered_index_node<Super> type;
|
Chris@16
|
1493 };
|
Chris@16
|
1494
|
Chris@16
|
1495 template<typename SuperMeta>
|
Chris@16
|
1496 struct index_class
|
Chris@16
|
1497 {
|
Chris@16
|
1498 typedef detail::ordered_index<
|
Chris@16
|
1499 key_from_value_type,compare_type,
|
Chris@16
|
1500 SuperMeta,tag_list_type,detail::ordered_non_unique_tag> type;
|
Chris@16
|
1501 };
|
Chris@16
|
1502 };
|
Chris@16
|
1503
|
Chris@16
|
1504 } /* namespace multi_index */
|
Chris@16
|
1505
|
Chris@16
|
1506 } /* namespace boost */
|
Chris@16
|
1507
|
Chris@16
|
1508 /* Boost.Foreach compatibility */
|
Chris@16
|
1509
|
Chris@16
|
1510 template<
|
Chris@16
|
1511 typename KeyFromValue,typename Compare,
|
Chris@16
|
1512 typename SuperMeta,typename TagList,typename Category
|
Chris@16
|
1513 >
|
Chris@16
|
1514 inline boost::mpl::true_* boost_foreach_is_noncopyable(
|
Chris@16
|
1515 boost::multi_index::detail::ordered_index<
|
Chris@16
|
1516 KeyFromValue,Compare,SuperMeta,TagList,Category>*&,
|
Chris@16
|
1517 boost::foreach::tag)
|
Chris@16
|
1518 {
|
Chris@16
|
1519 return 0;
|
Chris@16
|
1520 }
|
Chris@16
|
1521
|
Chris@16
|
1522 #undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
|
Chris@16
|
1523 #undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF
|
Chris@16
|
1524
|
Chris@16
|
1525 #endif
|