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