Chris@16
|
1 /* Copyright 2003-2013 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
|
Chris@16
|
9 #ifndef BOOST_MULTI_INDEX_SEQUENCED_INDEX_HPP
|
Chris@16
|
10 #define BOOST_MULTI_INDEX_SEQUENCED_INDEX_HPP
|
Chris@16
|
11
|
Chris@16
|
12 #if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
Chris@16
|
13 #pragma once
|
Chris@16
|
14 #endif
|
Chris@16
|
15
|
Chris@16
|
16 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
Chris@16
|
17 #include <boost/call_traits.hpp>
|
Chris@16
|
18 #include <boost/detail/allocator_utilities.hpp>
|
Chris@16
|
19 #include <boost/detail/no_exceptions_support.hpp>
|
Chris@16
|
20 #include <boost/detail/workaround.hpp>
|
Chris@16
|
21 #include <boost/foreach_fwd.hpp>
|
Chris@16
|
22 #include <boost/iterator/reverse_iterator.hpp>
|
Chris@16
|
23 #include <boost/move/core.hpp>
|
Chris@16
|
24 #include <boost/move/utility.hpp>
|
Chris@16
|
25 #include <boost/mpl/bool.hpp>
|
Chris@16
|
26 #include <boost/mpl/not.hpp>
|
Chris@16
|
27 #include <boost/mpl/push_front.hpp>
|
Chris@16
|
28 #include <boost/multi_index/detail/access_specifier.hpp>
|
Chris@16
|
29 #include <boost/multi_index/detail/bidir_node_iterator.hpp>
|
Chris@16
|
30 #include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
|
Chris@16
|
31 #include <boost/multi_index/detail/index_node_base.hpp>
|
Chris@16
|
32 #include <boost/multi_index/detail/safe_ctr_proxy.hpp>
|
Chris@16
|
33 #include <boost/multi_index/detail/safe_mode.hpp>
|
Chris@16
|
34 #include <boost/multi_index/detail/scope_guard.hpp>
|
Chris@16
|
35 #include <boost/multi_index/detail/seq_index_node.hpp>
|
Chris@16
|
36 #include <boost/multi_index/detail/seq_index_ops.hpp>
|
Chris@16
|
37 #include <boost/multi_index/detail/vartempl_support.hpp>
|
Chris@16
|
38 #include <boost/multi_index/sequenced_index_fwd.hpp>
|
Chris@16
|
39 #include <boost/tuple/tuple.hpp>
|
Chris@16
|
40 #include <boost/type_traits/is_integral.hpp>
|
Chris@16
|
41 #include <cstddef>
|
Chris@16
|
42 #include <functional>
|
Chris@16
|
43 #include <utility>
|
Chris@16
|
44
|
Chris@16
|
45 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
Chris@16
|
46 #include<initializer_list>
|
Chris@16
|
47 #endif
|
Chris@16
|
48
|
Chris@16
|
49 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
Chris@16
|
50 #include <boost/bind.hpp>
|
Chris@16
|
51 #endif
|
Chris@16
|
52
|
Chris@16
|
53 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
|
Chris@16
|
54 #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) \
|
Chris@16
|
55 detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
|
Chris@16
|
56 detail::make_obj_guard(x,&sequenced_index::check_invariant_); \
|
Chris@16
|
57 BOOST_JOIN(check_invariant_,__LINE__).touch();
|
Chris@16
|
58 #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT \
|
Chris@16
|
59 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(*this)
|
Chris@16
|
60 #else
|
Chris@16
|
61 #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x)
|
Chris@16
|
62 #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT
|
Chris@16
|
63 #endif
|
Chris@16
|
64
|
Chris@16
|
65 namespace boost{
|
Chris@16
|
66
|
Chris@16
|
67 namespace multi_index{
|
Chris@16
|
68
|
Chris@16
|
69 namespace detail{
|
Chris@16
|
70
|
Chris@16
|
71 /* sequenced_index adds a layer of sequenced indexing to a given Super */
|
Chris@16
|
72
|
Chris@16
|
73 template<typename SuperMeta,typename TagList>
|
Chris@16
|
74 class sequenced_index:
|
Chris@16
|
75 BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
|
Chris@16
|
76
|
Chris@16
|
77 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
78 #if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
Chris@16
|
79 ,public safe_ctr_proxy_impl<
|
Chris@16
|
80 bidir_node_iterator<
|
Chris@16
|
81 sequenced_index_node<typename SuperMeta::type::node_type> >,
|
Chris@16
|
82 sequenced_index<SuperMeta,TagList> >
|
Chris@16
|
83 #else
|
Chris@16
|
84 ,public safe_mode::safe_container<
|
Chris@16
|
85 sequenced_index<SuperMeta,TagList> >
|
Chris@16
|
86 #endif
|
Chris@16
|
87 #endif
|
Chris@16
|
88
|
Chris@16
|
89 {
|
Chris@16
|
90 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
|
Chris@16
|
91 BOOST_WORKAROUND(__MWERKS__,<=0x3003)
|
Chris@16
|
92 /* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
|
Chris@16
|
93 * lifetime of const references bound to temporaries --precisely what
|
Chris@16
|
94 * scopeguards are.
|
Chris@16
|
95 */
|
Chris@16
|
96
|
Chris@16
|
97 #pragma parse_mfunc_templ off
|
Chris@16
|
98 #endif
|
Chris@16
|
99
|
Chris@16
|
100 typedef typename SuperMeta::type super;
|
Chris@16
|
101
|
Chris@16
|
102 protected:
|
Chris@16
|
103 typedef sequenced_index_node<
|
Chris@16
|
104 typename super::node_type> node_type;
|
Chris@16
|
105
|
Chris@16
|
106 private:
|
Chris@16
|
107 typedef typename node_type::impl_type node_impl_type;
|
Chris@16
|
108
|
Chris@16
|
109 public:
|
Chris@16
|
110 /* types */
|
Chris@16
|
111
|
Chris@16
|
112 typedef typename node_type::value_type value_type;
|
Chris@16
|
113 typedef tuples::null_type ctor_args;
|
Chris@16
|
114 typedef typename super::final_allocator_type allocator_type;
|
Chris@16
|
115 typedef typename allocator_type::reference reference;
|
Chris@16
|
116 typedef typename allocator_type::const_reference const_reference;
|
Chris@16
|
117
|
Chris@16
|
118 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
119 #if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
Chris@16
|
120 typedef safe_mode::safe_iterator<
|
Chris@16
|
121 bidir_node_iterator<node_type>,
|
Chris@16
|
122 safe_ctr_proxy<
|
Chris@16
|
123 bidir_node_iterator<node_type> > > iterator;
|
Chris@16
|
124 #else
|
Chris@16
|
125 typedef safe_mode::safe_iterator<
|
Chris@16
|
126 bidir_node_iterator<node_type>,
|
Chris@16
|
127 sequenced_index> iterator;
|
Chris@16
|
128 #endif
|
Chris@16
|
129 #else
|
Chris@16
|
130 typedef bidir_node_iterator<node_type> iterator;
|
Chris@16
|
131 #endif
|
Chris@16
|
132
|
Chris@16
|
133 typedef iterator const_iterator;
|
Chris@16
|
134
|
Chris@16
|
135 typedef std::size_t size_type;
|
Chris@16
|
136 typedef std::ptrdiff_t difference_type;
|
Chris@16
|
137 typedef typename allocator_type::pointer pointer;
|
Chris@16
|
138 typedef typename allocator_type::const_pointer const_pointer;
|
Chris@16
|
139 typedef typename
|
Chris@16
|
140 boost::reverse_iterator<iterator> reverse_iterator;
|
Chris@16
|
141 typedef typename
|
Chris@16
|
142 boost::reverse_iterator<const_iterator> const_reverse_iterator;
|
Chris@16
|
143 typedef TagList tag_list;
|
Chris@16
|
144
|
Chris@16
|
145 protected:
|
Chris@16
|
146 typedef typename super::final_node_type final_node_type;
|
Chris@16
|
147 typedef tuples::cons<
|
Chris@16
|
148 ctor_args,
|
Chris@16
|
149 typename super::ctor_args_list> ctor_args_list;
|
Chris@16
|
150 typedef typename mpl::push_front<
|
Chris@16
|
151 typename super::index_type_list,
|
Chris@16
|
152 sequenced_index>::type index_type_list;
|
Chris@16
|
153 typedef typename mpl::push_front<
|
Chris@16
|
154 typename super::iterator_type_list,
|
Chris@16
|
155 iterator>::type iterator_type_list;
|
Chris@16
|
156 typedef typename mpl::push_front<
|
Chris@16
|
157 typename super::const_iterator_type_list,
|
Chris@16
|
158 const_iterator>::type const_iterator_type_list;
|
Chris@16
|
159 typedef typename super::copy_map_type copy_map_type;
|
Chris@16
|
160
|
Chris@16
|
161 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
Chris@16
|
162 typedef typename super::index_saver_type index_saver_type;
|
Chris@16
|
163 typedef typename super::index_loader_type index_loader_type;
|
Chris@16
|
164 #endif
|
Chris@16
|
165
|
Chris@16
|
166 private:
|
Chris@16
|
167 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
168 #if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
Chris@16
|
169 typedef safe_ctr_proxy_impl<
|
Chris@16
|
170 bidir_node_iterator<node_type>,
|
Chris@16
|
171 sequenced_index> safe_super;
|
Chris@16
|
172 #else
|
Chris@16
|
173 typedef safe_mode::safe_container<
|
Chris@16
|
174 sequenced_index> safe_super;
|
Chris@16
|
175 #endif
|
Chris@16
|
176 #endif
|
Chris@16
|
177
|
Chris@16
|
178 typedef typename call_traits<value_type>::param_type value_param_type;
|
Chris@16
|
179
|
Chris@16
|
180 /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
|
Chris@16
|
181 * expansion.
|
Chris@16
|
182 */
|
Chris@16
|
183
|
Chris@16
|
184 typedef std::pair<iterator,bool> emplace_return_type;
|
Chris@16
|
185
|
Chris@16
|
186 public:
|
Chris@16
|
187
|
Chris@16
|
188 /* construct/copy/destroy
|
Chris@16
|
189 * Default and copy ctors are in the protected section as indices are
|
Chris@16
|
190 * not supposed to be created on their own. No range ctor either.
|
Chris@16
|
191 */
|
Chris@16
|
192
|
Chris@16
|
193 sequenced_index<SuperMeta,TagList>& operator=(
|
Chris@16
|
194 const sequenced_index<SuperMeta,TagList>& x)
|
Chris@16
|
195 {
|
Chris@16
|
196 this->final()=x.final();
|
Chris@16
|
197 return *this;
|
Chris@16
|
198 }
|
Chris@16
|
199
|
Chris@16
|
200 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
Chris@16
|
201 sequenced_index<SuperMeta,TagList>& operator=(
|
Chris@16
|
202 std::initializer_list<value_type> list)
|
Chris@16
|
203 {
|
Chris@16
|
204 this->final()=list;
|
Chris@16
|
205 return *this;
|
Chris@16
|
206 }
|
Chris@16
|
207 #endif
|
Chris@16
|
208
|
Chris@16
|
209 template <class InputIterator>
|
Chris@16
|
210 void assign(InputIterator first,InputIterator last)
|
Chris@16
|
211 {
|
Chris@16
|
212 assign_iter(first,last,mpl::not_<is_integral<InputIterator> >());
|
Chris@16
|
213 }
|
Chris@16
|
214
|
Chris@16
|
215 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
Chris@16
|
216 void assign(std::initializer_list<value_type> list)
|
Chris@16
|
217 {
|
Chris@16
|
218 assign(list.begin(),list.end());
|
Chris@16
|
219 }
|
Chris@16
|
220 #endif
|
Chris@16
|
221
|
Chris@16
|
222 void assign(size_type n,value_param_type value)
|
Chris@16
|
223 {
|
Chris@16
|
224 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
225 clear();
|
Chris@16
|
226 for(size_type i=0;i<n;++i)push_back(value);
|
Chris@16
|
227 }
|
Chris@16
|
228
|
Chris@16
|
229 allocator_type get_allocator()const
|
Chris@16
|
230 {
|
Chris@16
|
231 return this->final().get_allocator();
|
Chris@16
|
232 }
|
Chris@16
|
233
|
Chris@16
|
234 /* iterators */
|
Chris@16
|
235
|
Chris@16
|
236 iterator begin()
|
Chris@16
|
237 {return make_iterator(node_type::from_impl(header()->next()));}
|
Chris@16
|
238 const_iterator begin()const
|
Chris@16
|
239 {return make_iterator(node_type::from_impl(header()->next()));}
|
Chris@16
|
240 iterator end(){return make_iterator(header());}
|
Chris@16
|
241 const_iterator end()const{return make_iterator(header());}
|
Chris@16
|
242 reverse_iterator rbegin(){return make_reverse_iterator(end());}
|
Chris@16
|
243 const_reverse_iterator rbegin()const{return make_reverse_iterator(end());}
|
Chris@16
|
244 reverse_iterator rend(){return make_reverse_iterator(begin());}
|
Chris@16
|
245 const_reverse_iterator rend()const{return make_reverse_iterator(begin());}
|
Chris@16
|
246 const_iterator cbegin()const{return begin();}
|
Chris@16
|
247 const_iterator cend()const{return end();}
|
Chris@16
|
248 const_reverse_iterator crbegin()const{return rbegin();}
|
Chris@16
|
249 const_reverse_iterator crend()const{return rend();}
|
Chris@16
|
250
|
Chris@16
|
251 iterator iterator_to(const value_type& x)
|
Chris@16
|
252 {
|
Chris@16
|
253 return make_iterator(node_from_value<node_type>(&x));
|
Chris@16
|
254 }
|
Chris@16
|
255
|
Chris@16
|
256 const_iterator iterator_to(const value_type& x)const
|
Chris@16
|
257 {
|
Chris@16
|
258 return make_iterator(node_from_value<node_type>(&x));
|
Chris@16
|
259 }
|
Chris@16
|
260
|
Chris@16
|
261 /* capacity */
|
Chris@16
|
262
|
Chris@16
|
263 bool empty()const{return this->final_empty_();}
|
Chris@16
|
264 size_type size()const{return this->final_size_();}
|
Chris@16
|
265 size_type max_size()const{return this->final_max_size_();}
|
Chris@16
|
266
|
Chris@16
|
267 void resize(size_type n)
|
Chris@16
|
268 {
|
Chris@16
|
269 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
270 if(n>size()){
|
Chris@16
|
271 for(size_type m=n-size();m--;)
|
Chris@16
|
272 this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK);
|
Chris@16
|
273 }
|
Chris@16
|
274 else if(n<size()){for(size_type m=size()-n;m--;)pop_back();}
|
Chris@16
|
275 }
|
Chris@16
|
276
|
Chris@16
|
277 void resize(size_type n,value_param_type x)
|
Chris@16
|
278 {
|
Chris@16
|
279 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
280 if(n>size())insert(end(),n-size(),x);
|
Chris@16
|
281 else if(n<size())for(size_type m=size()-n;m--;)pop_back();
|
Chris@16
|
282 }
|
Chris@16
|
283
|
Chris@16
|
284 /* access: no non-const versions provided as sequenced_index
|
Chris@16
|
285 * handles const elements.
|
Chris@16
|
286 */
|
Chris@16
|
287
|
Chris@16
|
288 const_reference front()const{return *begin();}
|
Chris@16
|
289 const_reference back()const{return *--end();}
|
Chris@16
|
290
|
Chris@16
|
291 /* modifiers */
|
Chris@16
|
292
|
Chris@16
|
293 BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
Chris@16
|
294 emplace_return_type,emplace_front,emplace_front_impl)
|
Chris@16
|
295
|
Chris@16
|
296 std::pair<iterator,bool> push_front(const value_type& x)
|
Chris@16
|
297 {return insert(begin(),x);}
|
Chris@16
|
298 std::pair<iterator,bool> push_front(BOOST_RV_REF(value_type) x)
|
Chris@16
|
299 {return insert(begin(),boost::move(x));}
|
Chris@16
|
300 void pop_front(){erase(begin());}
|
Chris@16
|
301
|
Chris@16
|
302 BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
|
Chris@16
|
303 emplace_return_type,emplace_back,emplace_back_impl)
|
Chris@16
|
304
|
Chris@16
|
305 std::pair<iterator,bool> push_back(const value_type& x)
|
Chris@16
|
306 {return insert(end(),x);}
|
Chris@16
|
307 std::pair<iterator,bool> push_back(BOOST_RV_REF(value_type) x)
|
Chris@16
|
308 {return insert(end(),boost::move(x));}
|
Chris@16
|
309 void pop_back(){erase(--end());}
|
Chris@16
|
310
|
Chris@16
|
311 BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
|
Chris@16
|
312 emplace_return_type,emplace,emplace_impl,iterator,position)
|
Chris@16
|
313
|
Chris@16
|
314 std::pair<iterator,bool> insert(iterator position,const value_type& x)
|
Chris@16
|
315 {
|
Chris@16
|
316 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
317 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
318 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
319 std::pair<final_node_type*,bool> p=this->final_insert_(x);
|
Chris@16
|
320 if(p.second&&position.get_node()!=header()){
|
Chris@16
|
321 relink(position.get_node(),p.first);
|
Chris@16
|
322 }
|
Chris@16
|
323 return std::pair<iterator,bool>(make_iterator(p.first),p.second);
|
Chris@16
|
324 }
|
Chris@16
|
325
|
Chris@16
|
326 std::pair<iterator,bool> insert(iterator position,BOOST_RV_REF(value_type) x)
|
Chris@16
|
327 {
|
Chris@16
|
328 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
329 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
330 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
331 std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
|
Chris@16
|
332 if(p.second&&position.get_node()!=header()){
|
Chris@16
|
333 relink(position.get_node(),p.first);
|
Chris@16
|
334 }
|
Chris@16
|
335 return std::pair<iterator,bool>(make_iterator(p.first),p.second);
|
Chris@16
|
336 }
|
Chris@16
|
337
|
Chris@16
|
338 void insert(iterator position,size_type n,value_param_type x)
|
Chris@16
|
339 {
|
Chris@16
|
340 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
341 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
342 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
343 for(size_type i=0;i<n;++i)insert(position,x);
|
Chris@16
|
344 }
|
Chris@16
|
345
|
Chris@16
|
346 template<typename InputIterator>
|
Chris@16
|
347 void insert(iterator position,InputIterator first,InputIterator last)
|
Chris@16
|
348 {
|
Chris@16
|
349 insert_iter(position,first,last,mpl::not_<is_integral<InputIterator> >());
|
Chris@16
|
350 }
|
Chris@16
|
351
|
Chris@16
|
352 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
Chris@16
|
353 void insert(iterator position,std::initializer_list<value_type> list)
|
Chris@16
|
354 {
|
Chris@16
|
355 insert(position,list.begin(),list.end());
|
Chris@16
|
356 }
|
Chris@16
|
357 #endif
|
Chris@16
|
358
|
Chris@16
|
359 iterator erase(iterator position)
|
Chris@16
|
360 {
|
Chris@16
|
361 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
362 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
|
Chris@16
|
363 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
364 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
365 this->final_erase_(static_cast<final_node_type*>(position++.get_node()));
|
Chris@16
|
366 return position;
|
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_SEQ_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_SEQ_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_SEQ_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_SEQ_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@16
|
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_SEQ_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@16
|
442 mod,back,static_cast<final_node_type*>(position.get_node()));
|
Chris@16
|
443 }
|
Chris@16
|
444
|
Chris@16
|
445 void swap(sequenced_index<SuperMeta,TagList>& x)
|
Chris@16
|
446 {
|
Chris@16
|
447 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
448 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x);
|
Chris@16
|
449 this->final_swap_(x.final());
|
Chris@16
|
450 }
|
Chris@16
|
451
|
Chris@16
|
452 void clear()
|
Chris@16
|
453 {
|
Chris@16
|
454 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
455 this->final_clear_();
|
Chris@16
|
456 }
|
Chris@16
|
457
|
Chris@16
|
458 /* list operations */
|
Chris@16
|
459
|
Chris@16
|
460 void splice(iterator position,sequenced_index<SuperMeta,TagList>& x)
|
Chris@16
|
461 {
|
Chris@16
|
462 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
463 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
464 BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(*this,x);
|
Chris@16
|
465 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
466 iterator first=x.begin(),last=x.end();
|
Chris@16
|
467 while(first!=last){
|
Chris@16
|
468 if(insert(position,*first).second)first=x.erase(first);
|
Chris@16
|
469 else ++first;
|
Chris@16
|
470 }
|
Chris@16
|
471 }
|
Chris@16
|
472
|
Chris@16
|
473 void splice(iterator position,sequenced_index<SuperMeta,TagList>& x,iterator i)
|
Chris@16
|
474 {
|
Chris@16
|
475 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
476 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
477 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i);
|
Chris@16
|
478 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
|
Chris@16
|
479 BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x);
|
Chris@16
|
480 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
481 if(&x==this){
|
Chris@16
|
482 if(position!=i)relink(position.get_node(),i.get_node());
|
Chris@16
|
483 }
|
Chris@16
|
484 else{
|
Chris@16
|
485 if(insert(position,*i).second){
|
Chris@16
|
486
|
Chris@16
|
487 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
488 /* MSVC++ 6.0 optimizer has a hard time with safe mode, and the following
|
Chris@16
|
489 * workaround is needed. Left it for all compilers as it does no
|
Chris@16
|
490 * harm.
|
Chris@16
|
491 */
|
Chris@16
|
492 i.detach();
|
Chris@16
|
493 x.erase(x.make_iterator(i.get_node()));
|
Chris@16
|
494 #else
|
Chris@16
|
495 x.erase(i);
|
Chris@16
|
496 #endif
|
Chris@16
|
497
|
Chris@16
|
498 }
|
Chris@16
|
499 }
|
Chris@16
|
500 }
|
Chris@16
|
501
|
Chris@16
|
502 void splice(
|
Chris@16
|
503 iterator position,sequenced_index<SuperMeta,TagList>& x,
|
Chris@16
|
504 iterator first,iterator last)
|
Chris@16
|
505 {
|
Chris@16
|
506 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
507 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
508 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
|
Chris@16
|
509 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
|
Chris@16
|
510 BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x);
|
Chris@16
|
511 BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x);
|
Chris@16
|
512 BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
|
Chris@16
|
513 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
514 if(&x==this){
|
Chris@16
|
515 BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last);
|
Chris@16
|
516 if(position!=last)relink(
|
Chris@16
|
517 position.get_node(),first.get_node(),last.get_node());
|
Chris@16
|
518 }
|
Chris@16
|
519 else{
|
Chris@16
|
520 while(first!=last){
|
Chris@16
|
521 if(insert(position,*first).second)first=x.erase(first);
|
Chris@16
|
522 else ++first;
|
Chris@16
|
523 }
|
Chris@16
|
524 }
|
Chris@16
|
525 }
|
Chris@16
|
526
|
Chris@16
|
527 void remove(value_param_type value)
|
Chris@16
|
528 {
|
Chris@16
|
529 sequenced_index_remove(
|
Chris@16
|
530 *this,std::bind2nd(std::equal_to<value_type>(),value));
|
Chris@16
|
531 }
|
Chris@16
|
532
|
Chris@16
|
533 template<typename Predicate>
|
Chris@16
|
534 void remove_if(Predicate pred)
|
Chris@16
|
535 {
|
Chris@16
|
536 sequenced_index_remove(*this,pred);
|
Chris@16
|
537 }
|
Chris@16
|
538
|
Chris@16
|
539 void unique()
|
Chris@16
|
540 {
|
Chris@16
|
541 sequenced_index_unique(*this,std::equal_to<value_type>());
|
Chris@16
|
542 }
|
Chris@16
|
543
|
Chris@16
|
544 template <class BinaryPredicate>
|
Chris@16
|
545 void unique(BinaryPredicate binary_pred)
|
Chris@16
|
546 {
|
Chris@16
|
547 sequenced_index_unique(*this,binary_pred);
|
Chris@16
|
548 }
|
Chris@16
|
549
|
Chris@16
|
550 void merge(sequenced_index<SuperMeta,TagList>& x)
|
Chris@16
|
551 {
|
Chris@16
|
552 sequenced_index_merge(*this,x,std::less<value_type>());
|
Chris@16
|
553 }
|
Chris@16
|
554
|
Chris@16
|
555 template <typename Compare>
|
Chris@16
|
556 void merge(sequenced_index<SuperMeta,TagList>& x,Compare comp)
|
Chris@16
|
557 {
|
Chris@16
|
558 sequenced_index_merge(*this,x,comp);
|
Chris@16
|
559 }
|
Chris@16
|
560
|
Chris@16
|
561 void sort()
|
Chris@16
|
562 {
|
Chris@16
|
563 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
564 sequenced_index_sort(header(),std::less<value_type>());
|
Chris@16
|
565 }
|
Chris@16
|
566
|
Chris@16
|
567 template <typename Compare>
|
Chris@16
|
568 void sort(Compare comp)
|
Chris@16
|
569 {
|
Chris@16
|
570 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
571 sequenced_index_sort(header(),comp);
|
Chris@16
|
572 }
|
Chris@16
|
573
|
Chris@16
|
574 void reverse()
|
Chris@16
|
575 {
|
Chris@16
|
576 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
577 node_impl_type::reverse(header()->impl());
|
Chris@16
|
578 }
|
Chris@16
|
579
|
Chris@16
|
580 /* rearrange operations */
|
Chris@16
|
581
|
Chris@16
|
582 void relocate(iterator position,iterator i)
|
Chris@16
|
583 {
|
Chris@16
|
584 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
585 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
586 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i);
|
Chris@16
|
587 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
|
Chris@16
|
588 BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,*this);
|
Chris@16
|
589 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
590 if(position!=i)relink(position.get_node(),i.get_node());
|
Chris@16
|
591 }
|
Chris@16
|
592
|
Chris@16
|
593 void relocate(iterator position,iterator first,iterator last)
|
Chris@16
|
594 {
|
Chris@16
|
595 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
596 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
597 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
|
Chris@16
|
598 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
|
Chris@16
|
599 BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
|
Chris@16
|
600 BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
|
Chris@16
|
601 BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
|
Chris@16
|
602 BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last);
|
Chris@16
|
603 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
604 if(position!=last)relink(
|
Chris@16
|
605 position.get_node(),first.get_node(),last.get_node());
|
Chris@16
|
606 }
|
Chris@16
|
607
|
Chris@16
|
608 template<typename InputIterator>
|
Chris@16
|
609 void rearrange(InputIterator first)
|
Chris@16
|
610 {
|
Chris@16
|
611 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
612 node_type* pos=header();
|
Chris@16
|
613 for(size_type s=size();s--;){
|
Chris@16
|
614 const value_type& v=*first++;
|
Chris@16
|
615 relink(pos,node_from_value<node_type>(&v));
|
Chris@16
|
616 }
|
Chris@16
|
617 }
|
Chris@16
|
618
|
Chris@16
|
619 BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
|
Chris@16
|
620 sequenced_index(const ctor_args_list& args_list,const allocator_type& al):
|
Chris@16
|
621 super(args_list.get_tail(),al)
|
Chris@16
|
622 {
|
Chris@16
|
623 empty_initialize();
|
Chris@16
|
624 }
|
Chris@16
|
625
|
Chris@16
|
626 sequenced_index(const sequenced_index<SuperMeta,TagList>& x):
|
Chris@16
|
627 super(x)
|
Chris@16
|
628
|
Chris@16
|
629 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
630 ,safe_super()
|
Chris@16
|
631 #endif
|
Chris@16
|
632
|
Chris@16
|
633 {
|
Chris@16
|
634 /* the actual copying takes place in subsequent call to copy_() */
|
Chris@16
|
635 }
|
Chris@16
|
636
|
Chris@16
|
637 sequenced_index(
|
Chris@16
|
638 const sequenced_index<SuperMeta,TagList>& x,do_not_copy_elements_tag):
|
Chris@16
|
639 super(x,do_not_copy_elements_tag())
|
Chris@16
|
640
|
Chris@16
|
641 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
642 ,safe_super()
|
Chris@16
|
643 #endif
|
Chris@16
|
644
|
Chris@16
|
645 {
|
Chris@16
|
646 empty_initialize();
|
Chris@16
|
647 }
|
Chris@16
|
648
|
Chris@16
|
649 ~sequenced_index()
|
Chris@16
|
650 {
|
Chris@16
|
651 /* the container is guaranteed to be empty by now */
|
Chris@16
|
652 }
|
Chris@16
|
653
|
Chris@16
|
654 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
655 iterator make_iterator(node_type* node){return iterator(node,this);}
|
Chris@16
|
656 const_iterator make_iterator(node_type* node)const
|
Chris@16
|
657 {return const_iterator(node,const_cast<sequenced_index*>(this));}
|
Chris@16
|
658 #else
|
Chris@16
|
659 iterator make_iterator(node_type* node){return iterator(node);}
|
Chris@16
|
660 const_iterator make_iterator(node_type* node)const
|
Chris@16
|
661 {return const_iterator(node);}
|
Chris@16
|
662 #endif
|
Chris@16
|
663
|
Chris@16
|
664 void copy_(
|
Chris@16
|
665 const sequenced_index<SuperMeta,TagList>& x,const copy_map_type& map)
|
Chris@16
|
666 {
|
Chris@16
|
667 node_type* org=x.header();
|
Chris@16
|
668 node_type* cpy=header();
|
Chris@16
|
669 do{
|
Chris@16
|
670 node_type* next_org=node_type::from_impl(org->next());
|
Chris@16
|
671 node_type* next_cpy=map.find(static_cast<final_node_type*>(next_org));
|
Chris@16
|
672 cpy->next()=next_cpy->impl();
|
Chris@16
|
673 next_cpy->prior()=cpy->impl();
|
Chris@16
|
674 org=next_org;
|
Chris@16
|
675 cpy=next_cpy;
|
Chris@16
|
676 }while(org!=x.header());
|
Chris@16
|
677
|
Chris@16
|
678 super::copy_(x,map);
|
Chris@16
|
679 }
|
Chris@16
|
680
|
Chris@16
|
681 template<typename Variant>
|
Chris@16
|
682 node_type* insert_(value_param_type v,node_type* x,Variant variant)
|
Chris@16
|
683 {
|
Chris@16
|
684 node_type* res=static_cast<node_type*>(super::insert_(v,x,variant));
|
Chris@16
|
685 if(res==x)link(x);
|
Chris@16
|
686 return res;
|
Chris@16
|
687 }
|
Chris@16
|
688
|
Chris@16
|
689 template<typename Variant>
|
Chris@16
|
690 node_type* insert_(
|
Chris@16
|
691 value_param_type v,node_type* position,node_type* x,Variant variant)
|
Chris@16
|
692 {
|
Chris@16
|
693 node_type* res=
|
Chris@16
|
694 static_cast<node_type*>(super::insert_(v,position,x,variant));
|
Chris@16
|
695 if(res==x)link(x);
|
Chris@16
|
696 return res;
|
Chris@16
|
697 }
|
Chris@16
|
698
|
Chris@16
|
699 void erase_(node_type* x)
|
Chris@16
|
700 {
|
Chris@16
|
701 unlink(x);
|
Chris@16
|
702 super::erase_(x);
|
Chris@16
|
703
|
Chris@16
|
704 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
705 detach_iterators(x);
|
Chris@16
|
706 #endif
|
Chris@16
|
707 }
|
Chris@16
|
708
|
Chris@16
|
709 void delete_all_nodes_()
|
Chris@16
|
710 {
|
Chris@16
|
711 for(node_type* x=node_type::from_impl(header()->next());x!=header();){
|
Chris@16
|
712 node_type* y=node_type::from_impl(x->next());
|
Chris@16
|
713 this->final_delete_node_(static_cast<final_node_type*>(x));
|
Chris@16
|
714 x=y;
|
Chris@16
|
715 }
|
Chris@16
|
716 }
|
Chris@16
|
717
|
Chris@16
|
718 void clear_()
|
Chris@16
|
719 {
|
Chris@16
|
720 super::clear_();
|
Chris@16
|
721 empty_initialize();
|
Chris@16
|
722
|
Chris@16
|
723 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
724 safe_super::detach_dereferenceable_iterators();
|
Chris@16
|
725 #endif
|
Chris@16
|
726 }
|
Chris@16
|
727
|
Chris@16
|
728 void swap_(sequenced_index<SuperMeta,TagList>& x)
|
Chris@16
|
729 {
|
Chris@16
|
730 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
731 safe_super::swap(x);
|
Chris@16
|
732 #endif
|
Chris@16
|
733
|
Chris@16
|
734 super::swap_(x);
|
Chris@16
|
735 }
|
Chris@16
|
736
|
Chris@16
|
737 void swap_elements_(sequenced_index<SuperMeta,TagList>& x)
|
Chris@16
|
738 {
|
Chris@16
|
739 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
740 safe_super::swap(x);
|
Chris@16
|
741 #endif
|
Chris@16
|
742
|
Chris@16
|
743 super::swap_elements_(x);
|
Chris@16
|
744 }
|
Chris@16
|
745
|
Chris@16
|
746 template<typename Variant>
|
Chris@16
|
747 bool replace_(value_param_type v,node_type* x,Variant variant)
|
Chris@16
|
748 {
|
Chris@16
|
749 return super::replace_(v,x,variant);
|
Chris@16
|
750 }
|
Chris@16
|
751
|
Chris@16
|
752 bool modify_(node_type* x)
|
Chris@16
|
753 {
|
Chris@16
|
754 BOOST_TRY{
|
Chris@16
|
755 if(!super::modify_(x)){
|
Chris@16
|
756 unlink(x);
|
Chris@16
|
757
|
Chris@16
|
758 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
759 detach_iterators(x);
|
Chris@16
|
760 #endif
|
Chris@16
|
761
|
Chris@16
|
762 return false;
|
Chris@16
|
763 }
|
Chris@16
|
764 else return true;
|
Chris@16
|
765 }
|
Chris@16
|
766 BOOST_CATCH(...){
|
Chris@16
|
767 unlink(x);
|
Chris@16
|
768
|
Chris@16
|
769 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
770 detach_iterators(x);
|
Chris@16
|
771 #endif
|
Chris@16
|
772
|
Chris@16
|
773 BOOST_RETHROW;
|
Chris@16
|
774 }
|
Chris@16
|
775 BOOST_CATCH_END
|
Chris@16
|
776 }
|
Chris@16
|
777
|
Chris@16
|
778 bool modify_rollback_(node_type* x)
|
Chris@16
|
779 {
|
Chris@16
|
780 return super::modify_rollback_(x);
|
Chris@16
|
781 }
|
Chris@16
|
782
|
Chris@16
|
783 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
Chris@16
|
784 /* serialization */
|
Chris@16
|
785
|
Chris@16
|
786 template<typename Archive>
|
Chris@16
|
787 void save_(
|
Chris@16
|
788 Archive& ar,const unsigned int version,const index_saver_type& sm)const
|
Chris@16
|
789 {
|
Chris@16
|
790 sm.save(begin(),end(),ar,version);
|
Chris@16
|
791 super::save_(ar,version,sm);
|
Chris@16
|
792 }
|
Chris@16
|
793
|
Chris@16
|
794 template<typename Archive>
|
Chris@16
|
795 void load_(
|
Chris@16
|
796 Archive& ar,const unsigned int version,const index_loader_type& lm)
|
Chris@16
|
797 {
|
Chris@16
|
798 lm.load(
|
Chris@16
|
799 ::boost::bind(&sequenced_index::rearranger,this,_1,_2),
|
Chris@16
|
800 ar,version);
|
Chris@16
|
801 super::load_(ar,version,lm);
|
Chris@16
|
802 }
|
Chris@16
|
803 #endif
|
Chris@16
|
804
|
Chris@16
|
805 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
|
Chris@16
|
806 /* invariant stuff */
|
Chris@16
|
807
|
Chris@16
|
808 bool invariant_()const
|
Chris@16
|
809 {
|
Chris@16
|
810 if(size()==0||begin()==end()){
|
Chris@16
|
811 if(size()!=0||begin()!=end()||
|
Chris@16
|
812 header()->next()!=header()->impl()||
|
Chris@16
|
813 header()->prior()!=header()->impl())return false;
|
Chris@16
|
814 }
|
Chris@16
|
815 else{
|
Chris@16
|
816 size_type s=0;
|
Chris@16
|
817 for(const_iterator it=begin(),it_end=end();it!=it_end;++it,++s){
|
Chris@16
|
818 if(it.get_node()->next()->prior()!=it.get_node()->impl())return false;
|
Chris@16
|
819 if(it.get_node()->prior()->next()!=it.get_node()->impl())return false;
|
Chris@16
|
820 }
|
Chris@16
|
821 if(s!=size())return false;
|
Chris@16
|
822 }
|
Chris@16
|
823
|
Chris@16
|
824 return super::invariant_();
|
Chris@16
|
825 }
|
Chris@16
|
826
|
Chris@16
|
827 /* This forwarding function eases things for the boost::mem_fn construct
|
Chris@16
|
828 * in BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT. Actually,
|
Chris@16
|
829 * final_check_invariant is already an inherited member function of index.
|
Chris@16
|
830 */
|
Chris@16
|
831 void check_invariant_()const{this->final_check_invariant_();}
|
Chris@16
|
832 #endif
|
Chris@16
|
833
|
Chris@16
|
834 private:
|
Chris@16
|
835 node_type* header()const{return this->final_header();}
|
Chris@16
|
836
|
Chris@16
|
837 void empty_initialize()
|
Chris@16
|
838 {
|
Chris@16
|
839 header()->prior()=header()->next()=header()->impl();
|
Chris@16
|
840 }
|
Chris@16
|
841
|
Chris@16
|
842 void link(node_type* x)
|
Chris@16
|
843 {
|
Chris@16
|
844 node_impl_type::link(x->impl(),header()->impl());
|
Chris@16
|
845 };
|
Chris@16
|
846
|
Chris@16
|
847 static void unlink(node_type* x)
|
Chris@16
|
848 {
|
Chris@16
|
849 node_impl_type::unlink(x->impl());
|
Chris@16
|
850 }
|
Chris@16
|
851
|
Chris@16
|
852 static void relink(node_type* position,node_type* x)
|
Chris@16
|
853 {
|
Chris@16
|
854 node_impl_type::relink(position->impl(),x->impl());
|
Chris@16
|
855 }
|
Chris@16
|
856
|
Chris@16
|
857 static void relink(node_type* position,node_type* first,node_type* last)
|
Chris@16
|
858 {
|
Chris@16
|
859 node_impl_type::relink(
|
Chris@16
|
860 position->impl(),first->impl(),last->impl());
|
Chris@16
|
861 }
|
Chris@16
|
862
|
Chris@16
|
863 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
|
Chris@16
|
864 void rearranger(node_type* position,node_type *x)
|
Chris@16
|
865 {
|
Chris@16
|
866 if(!position)position=header();
|
Chris@16
|
867 node_type::increment(position);
|
Chris@16
|
868 if(position!=x)relink(position,x);
|
Chris@16
|
869 }
|
Chris@16
|
870 #endif
|
Chris@16
|
871
|
Chris@16
|
872 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
|
Chris@16
|
873 void detach_iterators(node_type* x)
|
Chris@16
|
874 {
|
Chris@16
|
875 iterator it=make_iterator(x);
|
Chris@16
|
876 safe_mode::detach_equivalent_iterators(it);
|
Chris@16
|
877 }
|
Chris@16
|
878 #endif
|
Chris@16
|
879
|
Chris@16
|
880 template <class InputIterator>
|
Chris@16
|
881 void assign_iter(InputIterator first,InputIterator last,mpl::true_)
|
Chris@16
|
882 {
|
Chris@16
|
883 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
884 clear();
|
Chris@16
|
885 for(;first!=last;++first)this->final_insert_ref_(*first);
|
Chris@16
|
886 }
|
Chris@16
|
887
|
Chris@16
|
888 void assign_iter(size_type n,value_param_type value,mpl::false_)
|
Chris@16
|
889 {
|
Chris@16
|
890 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
891 clear();
|
Chris@16
|
892 for(size_type i=0;i<n;++i)push_back(value);
|
Chris@16
|
893 }
|
Chris@16
|
894
|
Chris@16
|
895 template<typename InputIterator>
|
Chris@16
|
896 void insert_iter(
|
Chris@16
|
897 iterator position,InputIterator first,InputIterator last,mpl::true_)
|
Chris@16
|
898 {
|
Chris@16
|
899 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
900 for(;first!=last;++first){
|
Chris@16
|
901 std::pair<final_node_type*,bool> p=
|
Chris@16
|
902 this->final_insert_ref_(*first);
|
Chris@16
|
903 if(p.second&&position.get_node()!=header()){
|
Chris@16
|
904 relink(position.get_node(),p.first);
|
Chris@16
|
905 }
|
Chris@16
|
906 }
|
Chris@16
|
907 }
|
Chris@16
|
908
|
Chris@16
|
909 void insert_iter(
|
Chris@16
|
910 iterator position,size_type n,value_param_type x,mpl::false_)
|
Chris@16
|
911 {
|
Chris@16
|
912 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
913 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
914 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
915 for(size_type i=0;i<n;++i)insert(position,x);
|
Chris@16
|
916 }
|
Chris@16
|
917
|
Chris@16
|
918 template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
|
Chris@16
|
919 std::pair<iterator,bool> emplace_front_impl(
|
Chris@16
|
920 BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
|
Chris@16
|
921 {
|
Chris@16
|
922 return emplace_impl(begin(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
|
Chris@16
|
923 }
|
Chris@16
|
924
|
Chris@16
|
925 template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
|
Chris@16
|
926 std::pair<iterator,bool> emplace_back_impl(
|
Chris@16
|
927 BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
|
Chris@16
|
928 {
|
Chris@16
|
929 return emplace_impl(end(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
|
Chris@16
|
930 }
|
Chris@16
|
931
|
Chris@16
|
932 template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
|
Chris@16
|
933 std::pair<iterator,bool> emplace_impl(
|
Chris@16
|
934 iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
|
Chris@16
|
935 {
|
Chris@16
|
936 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
|
Chris@16
|
937 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
|
Chris@16
|
938 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
|
Chris@16
|
939 std::pair<final_node_type*,bool> p=
|
Chris@16
|
940 this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
|
Chris@16
|
941 if(p.second&&position.get_node()!=header()){
|
Chris@16
|
942 relink(position.get_node(),p.first);
|
Chris@16
|
943 }
|
Chris@16
|
944 return std::pair<iterator,bool>(make_iterator(p.first),p.second);
|
Chris@16
|
945 }
|
Chris@16
|
946
|
Chris@16
|
947 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
|
Chris@16
|
948 BOOST_WORKAROUND(__MWERKS__,<=0x3003)
|
Chris@16
|
949 #pragma parse_mfunc_templ reset
|
Chris@16
|
950 #endif
|
Chris@16
|
951 };
|
Chris@16
|
952
|
Chris@16
|
953 /* comparison */
|
Chris@16
|
954
|
Chris@16
|
955 template<
|
Chris@16
|
956 typename SuperMeta1,typename TagList1,
|
Chris@16
|
957 typename SuperMeta2,typename TagList2
|
Chris@16
|
958 >
|
Chris@16
|
959 bool operator==(
|
Chris@16
|
960 const sequenced_index<SuperMeta1,TagList1>& x,
|
Chris@16
|
961 const sequenced_index<SuperMeta2,TagList2>& y)
|
Chris@16
|
962 {
|
Chris@16
|
963 return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
|
Chris@16
|
964 }
|
Chris@16
|
965
|
Chris@16
|
966 template<
|
Chris@16
|
967 typename SuperMeta1,typename TagList1,
|
Chris@16
|
968 typename SuperMeta2,typename TagList2
|
Chris@16
|
969 >
|
Chris@16
|
970 bool operator<(
|
Chris@16
|
971 const sequenced_index<SuperMeta1,TagList1>& x,
|
Chris@16
|
972 const sequenced_index<SuperMeta2,TagList2>& y)
|
Chris@16
|
973 {
|
Chris@16
|
974 return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
|
Chris@16
|
975 }
|
Chris@16
|
976
|
Chris@16
|
977 template<
|
Chris@16
|
978 typename SuperMeta1,typename TagList1,
|
Chris@16
|
979 typename SuperMeta2,typename TagList2
|
Chris@16
|
980 >
|
Chris@16
|
981 bool operator!=(
|
Chris@16
|
982 const sequenced_index<SuperMeta1,TagList1>& x,
|
Chris@16
|
983 const sequenced_index<SuperMeta2,TagList2>& y)
|
Chris@16
|
984 {
|
Chris@16
|
985 return !(x==y);
|
Chris@16
|
986 }
|
Chris@16
|
987
|
Chris@16
|
988 template<
|
Chris@16
|
989 typename SuperMeta1,typename TagList1,
|
Chris@16
|
990 typename SuperMeta2,typename TagList2
|
Chris@16
|
991 >
|
Chris@16
|
992 bool operator>(
|
Chris@16
|
993 const sequenced_index<SuperMeta1,TagList1>& x,
|
Chris@16
|
994 const sequenced_index<SuperMeta2,TagList2>& y)
|
Chris@16
|
995 {
|
Chris@16
|
996 return y<x;
|
Chris@16
|
997 }
|
Chris@16
|
998
|
Chris@16
|
999 template<
|
Chris@16
|
1000 typename SuperMeta1,typename TagList1,
|
Chris@16
|
1001 typename SuperMeta2,typename TagList2
|
Chris@16
|
1002 >
|
Chris@16
|
1003 bool operator>=(
|
Chris@16
|
1004 const sequenced_index<SuperMeta1,TagList1>& x,
|
Chris@16
|
1005 const sequenced_index<SuperMeta2,TagList2>& y)
|
Chris@16
|
1006 {
|
Chris@16
|
1007 return !(x<y);
|
Chris@16
|
1008 }
|
Chris@16
|
1009
|
Chris@16
|
1010 template<
|
Chris@16
|
1011 typename SuperMeta1,typename TagList1,
|
Chris@16
|
1012 typename SuperMeta2,typename TagList2
|
Chris@16
|
1013 >
|
Chris@16
|
1014 bool operator<=(
|
Chris@16
|
1015 const sequenced_index<SuperMeta1,TagList1>& x,
|
Chris@16
|
1016 const sequenced_index<SuperMeta2,TagList2>& y)
|
Chris@16
|
1017 {
|
Chris@16
|
1018 return !(x>y);
|
Chris@16
|
1019 }
|
Chris@16
|
1020
|
Chris@16
|
1021 /* specialized algorithms */
|
Chris@16
|
1022
|
Chris@16
|
1023 template<typename SuperMeta,typename TagList>
|
Chris@16
|
1024 void swap(
|
Chris@16
|
1025 sequenced_index<SuperMeta,TagList>& x,
|
Chris@16
|
1026 sequenced_index<SuperMeta,TagList>& y)
|
Chris@16
|
1027 {
|
Chris@16
|
1028 x.swap(y);
|
Chris@16
|
1029 }
|
Chris@16
|
1030
|
Chris@16
|
1031 } /* namespace multi_index::detail */
|
Chris@16
|
1032
|
Chris@16
|
1033 /* sequenced index specifier */
|
Chris@16
|
1034
|
Chris@16
|
1035 template <typename TagList>
|
Chris@16
|
1036 struct sequenced
|
Chris@16
|
1037 {
|
Chris@16
|
1038 BOOST_STATIC_ASSERT(detail::is_tag<TagList>::value);
|
Chris@16
|
1039
|
Chris@16
|
1040 template<typename Super>
|
Chris@16
|
1041 struct node_class
|
Chris@16
|
1042 {
|
Chris@16
|
1043 typedef detail::sequenced_index_node<Super> type;
|
Chris@16
|
1044 };
|
Chris@16
|
1045
|
Chris@16
|
1046 template<typename SuperMeta>
|
Chris@16
|
1047 struct index_class
|
Chris@16
|
1048 {
|
Chris@16
|
1049 typedef detail::sequenced_index<SuperMeta,typename TagList::type> type;
|
Chris@16
|
1050 };
|
Chris@16
|
1051 };
|
Chris@16
|
1052
|
Chris@16
|
1053 } /* namespace multi_index */
|
Chris@16
|
1054
|
Chris@16
|
1055 } /* namespace boost */
|
Chris@16
|
1056
|
Chris@16
|
1057 /* Boost.Foreach compatibility */
|
Chris@16
|
1058
|
Chris@16
|
1059 template<typename SuperMeta,typename TagList>
|
Chris@16
|
1060 inline boost::mpl::true_* boost_foreach_is_noncopyable(
|
Chris@16
|
1061 boost::multi_index::detail::sequenced_index<SuperMeta,TagList>*&,
|
Chris@16
|
1062 boost::foreach::tag)
|
Chris@16
|
1063 {
|
Chris@16
|
1064 return 0;
|
Chris@16
|
1065 }
|
Chris@16
|
1066
|
Chris@16
|
1067 #undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT
|
Chris@16
|
1068 #undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF
|
Chris@16
|
1069
|
Chris@16
|
1070 #endif
|