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