1 /* Copyright 2003-2007 Joaquín M López Muñoz.
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)
6 * See http://www.boost.org/libs/multi_index for library home page.
9 #ifndef BOOST_MULTI_INDEX_SEQUENCED_INDEX_HPP
10 #define BOOST_MULTI_INDEX_SEQUENCED_INDEX_HPP
12 #if defined(_MSC_VER)&&(_MSC_VER>=1200)
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/iterator/reverse_iterator.hpp>
22 #include <boost/mpl/bool.hpp>
23 #include <boost/mpl/not.hpp>
24 #include <boost/mpl/push_front.hpp>
25 #include <boost/multi_index/detail/access_specifier.hpp>
26 #include <boost/multi_index/detail/bidir_node_iterator.hpp>
27 #include <boost/multi_index/detail/index_node_base.hpp>
28 #include <boost/multi_index/detail/safe_ctr_proxy.hpp>
29 #include <boost/multi_index/detail/safe_mode.hpp>
30 #include <boost/multi_index/detail/scope_guard.hpp>
31 #include <boost/multi_index/detail/seq_index_node.hpp>
32 #include <boost/multi_index/detail/seq_index_ops.hpp>
33 #include <boost/multi_index/sequenced_index_fwd.hpp>
34 #include <boost/tuple/tuple.hpp>
35 #include <boost/type_traits/is_integral.hpp>
40 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
41 #include <boost/bind.hpp>
44 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
45 #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT \
46 detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
47 detail::make_obj_guard(*this,&sequenced_index::check_invariant_); \
48 BOOST_JOIN(check_invariant_,__LINE__).touch();
50 #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT
55 namespace multi_index{
59 /* sequenced_index adds a layer of sequenced indexing to a given Super */
61 template<typename SuperMeta,typename TagList>
62 class sequenced_index:
63 BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
65 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
66 #if BOOST_WORKAROUND(BOOST_MSVC,<1300)
67 ,public safe_ctr_proxy_impl<
69 sequenced_index_node<typename SuperMeta::type::node_type> >,
70 sequenced_index<SuperMeta,TagList> >
72 ,public safe_mode::safe_container<
73 sequenced_index<SuperMeta,TagList> >
78 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
79 BOOST_WORKAROUND(__MWERKS__,<=0x3003)
80 /* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
81 * lifetime of const references bound to temporaries --precisely what
85 #pragma parse_mfunc_templ off
88 typedef typename SuperMeta::type super;
91 typedef sequenced_index_node<
92 typename super::node_type> node_type;
95 typedef typename node_type::impl_type node_impl_type;
100 typedef typename node_type::value_type value_type;
101 typedef tuples::null_type ctor_args;
102 typedef typename super::final_allocator_type allocator_type;
103 typedef typename allocator_type::reference reference;
104 typedef typename allocator_type::const_reference const_reference;
106 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
107 #if BOOST_WORKAROUND(BOOST_MSVC,<1300)
108 typedef safe_mode::safe_iterator<
109 bidir_node_iterator<node_type>,
111 bidir_node_iterator<node_type> > > iterator;
113 typedef safe_mode::safe_iterator<
114 bidir_node_iterator<node_type>,
115 sequenced_index> iterator;
118 typedef bidir_node_iterator<node_type> iterator;
121 typedef iterator const_iterator;
123 typedef std::size_t size_type;
124 typedef std::ptrdiff_t difference_type;
125 typedef typename allocator_type::pointer pointer;
126 typedef typename allocator_type::const_pointer const_pointer;
128 boost::reverse_iterator<iterator> reverse_iterator;
130 boost::reverse_iterator<const_iterator> const_reverse_iterator;
131 typedef TagList tag_list;
134 typedef typename super::final_node_type final_node_type;
135 typedef tuples::cons<
137 typename super::ctor_args_list> ctor_args_list;
138 typedef typename mpl::push_front<
139 typename super::index_type_list,
140 sequenced_index>::type index_type_list;
141 typedef typename mpl::push_front<
142 typename super::iterator_type_list,
143 iterator>::type iterator_type_list;
144 typedef typename mpl::push_front<
145 typename super::const_iterator_type_list,
146 const_iterator>::type const_iterator_type_list;
147 typedef typename super::copy_map_type copy_map_type;
149 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
150 typedef typename super::index_saver_type index_saver_type;
151 typedef typename super::index_loader_type index_loader_type;
155 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
156 #if BOOST_WORKAROUND(BOOST_MSVC,<1300)
157 typedef safe_ctr_proxy_impl<
158 bidir_node_iterator<node_type>,
159 sequenced_index> safe_super;
161 typedef safe_mode::safe_container<
162 sequenced_index> safe_super;
166 typedef typename call_traits<value_type>::param_type value_param_type;
170 /* construct/copy/destroy
171 * Default and copy ctors are in the protected section as indices are
172 * not supposed to be created on their own. No range ctor either.
175 sequenced_index<SuperMeta,TagList>& operator=(
176 const sequenced_index<SuperMeta,TagList>& x)
178 this->final()=x.final();
182 template <class InputIterator>
183 void assign(InputIterator first,InputIterator last)
185 assign_iter(first,last,mpl::not_<is_integral<InputIterator> >());
188 void assign(size_type n,value_param_type value)
190 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
192 for(size_type i=0;i<n;++i)push_back(value);
195 allocator_type get_allocator()const
197 return this->final().get_allocator();
203 {return make_iterator(node_type::from_impl(header()->next()));}
204 const_iterator begin()const
205 {return make_iterator(node_type::from_impl(header()->next()));}
206 iterator end(){return make_iterator(header());}
207 const_iterator end()const{return make_iterator(header());}
208 reverse_iterator rbegin(){return make_reverse_iterator(end());}
209 const_reverse_iterator rbegin()const{return make_reverse_iterator(end());}
210 reverse_iterator rend(){return make_reverse_iterator(begin());}
211 const_reverse_iterator rend()const{return make_reverse_iterator(begin());}
212 const_iterator cbegin()const{return begin();}
213 const_iterator cend()const{return end();}
214 const_reverse_iterator crbegin()const{return rbegin();}
215 const_reverse_iterator crend()const{return rend();}
217 iterator iterator_to(const value_type& x)
219 return make_iterator(node_from_value<node_type>(&x));
222 const_iterator iterator_to(const value_type& x)const
224 return make_iterator(node_from_value<node_type>(&x));
229 bool empty()const{return this->final_empty_();}
230 size_type size()const{return this->final_size_();}
231 size_type max_size()const{return this->final_max_size_();}
233 void resize(size_type n,value_param_type x=value_type())
235 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
236 if(n>size())insert(end(),n-size(),x);
245 for(size_type m=size()-n;m--;--it){}
251 /* access: no non-const versions provided as sequenced_index
252 * handles const elements.
255 const_reference front()const{return *begin();}
256 const_reference back()const{return *--end();}
260 std::pair<iterator,bool> push_front(value_param_type x)
261 {return insert(begin(),x);}
262 void pop_front(){erase(begin());}
263 std::pair<iterator,bool> push_back(value_param_type x)
264 {return insert(end(),x);}
265 void pop_back(){erase(--end());}
267 std::pair<iterator,bool> insert(iterator position,value_param_type x)
269 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
270 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
271 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
272 std::pair<final_node_type*,bool> p=this->final_insert_(x);
273 if(p.second&&position.get_node()!=header()){
274 relink(position.get_node(),p.first);
276 return std::pair<iterator,bool>(make_iterator(p.first),p.second);
279 void insert(iterator position,size_type n,value_param_type x)
281 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
282 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
283 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
284 for(size_type i=0;i<n;++i)insert(position,x);
287 template<typename InputIterator>
288 void insert(iterator position,InputIterator first,InputIterator last)
290 insert_iter(position,first,last,mpl::not_<is_integral<InputIterator> >());
293 iterator erase(iterator position)
295 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
296 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
297 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
298 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
299 this->final_erase_(static_cast<final_node_type*>(position++.get_node()));
303 iterator erase(iterator first,iterator last)
305 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
306 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
307 BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
308 BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
309 BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
310 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
317 bool replace(iterator position,value_param_type x)
319 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
320 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
321 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
322 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
323 return this->final_replace_(
324 x,static_cast<final_node_type*>(position.get_node()));
327 template<typename Modifier>
328 bool modify(iterator position,Modifier mod)
330 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
331 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
332 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
333 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
335 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
336 /* MSVC++ 6.0 optimizer on safe mode code chokes if this
337 * this is not added. Left it for all compilers as it does no
344 return this->final_modify_(
345 mod,static_cast<final_node_type*>(position.get_node()));
348 template<typename Modifier,typename Rollback>
349 bool modify(iterator position,Modifier mod,Rollback back)
351 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
352 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
353 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
354 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
356 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
357 /* MSVC++ 6.0 optimizer on safe mode code chokes if this
358 * this is not added. Left it for all compilers as it does no
365 return this->final_modify_(
366 mod,back,static_cast<final_node_type*>(position.get_node()));
369 void swap(sequenced_index<SuperMeta,TagList>& x)
371 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
372 this->final_swap_(x.final());
377 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
378 this->final_clear_();
381 /* list operations */
383 void splice(iterator position,sequenced_index<SuperMeta,TagList>& x)
385 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
386 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
387 BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(*this,x);
388 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
389 iterator first=x.begin(),last=x.end();
391 if(insert(position,*first).second)first=x.erase(first);
396 void splice(iterator position,sequenced_index<SuperMeta,TagList>& x,iterator i)
398 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
399 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
400 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i);
401 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
402 BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x);
403 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
405 if(position!=i)relink(position.get_node(),i.get_node());
408 if(insert(position,*i).second){
410 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
411 /* MSVC++ 6.0 optimizer has a hard time with safe mode, and the following
412 * workaround is needed. Left it for all compilers as it does no
416 x.erase(x.make_iterator(i.get_node()));
426 iterator position,sequenced_index<SuperMeta,TagList>& x,
427 iterator first,iterator last)
429 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
430 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
431 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
432 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
433 BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x);
434 BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x);
435 BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
436 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
438 BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last);
439 if(position!=last)relink(
440 position.get_node(),first.get_node(),last.get_node());
444 if(insert(position,*first).second)first=x.erase(first);
450 void remove(value_param_type value)
452 sequenced_index_remove(
453 *this,std::bind2nd(std::equal_to<value_type>(),value));
456 template<typename Predicate>
457 void remove_if(Predicate pred)
459 sequenced_index_remove(*this,pred);
464 sequenced_index_unique(*this,std::equal_to<value_type>());
467 template <class BinaryPredicate>
468 void unique(BinaryPredicate binary_pred)
470 sequenced_index_unique(*this,binary_pred);
473 void merge(sequenced_index<SuperMeta,TagList>& x)
475 sequenced_index_merge(*this,x,std::less<value_type>());
478 template <typename Compare>
479 void merge(sequenced_index<SuperMeta,TagList>& x,Compare comp)
481 sequenced_index_merge(*this,x,comp);
486 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
487 sequenced_index_sort(header(),std::less<value_type>());
490 template <typename Compare>
491 void sort(Compare comp)
493 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
494 sequenced_index_sort(header(),comp);
499 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
500 node_impl_type::reverse(header()->impl());
503 /* rearrange operations */
505 void relocate(iterator position,iterator i)
507 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
508 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
509 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i);
510 BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
511 BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,*this);
512 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
513 if(position!=i)relink(position.get_node(),i.get_node());
516 void relocate(iterator position,iterator first,iterator last)
518 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
519 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
520 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
521 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
522 BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
523 BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
524 BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
525 BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last);
526 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
527 if(position!=last)relink(
528 position.get_node(),first.get_node(),last.get_node());
531 template<typename InputIterator>
532 void rearrange(InputIterator first)
534 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
535 node_type* pos=header();
536 for(size_type s=size();s--;){
537 const value_type& v=*first++;
538 relink(pos,node_from_value<node_type>(&v));
542 BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
543 sequenced_index(const ctor_args_list& args_list,const allocator_type& al):
544 super(args_list.get_tail(),al)
549 sequenced_index(const sequenced_index<SuperMeta,TagList>& x):
552 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
557 /* The actual copying takes place in subsequent call to copy_().
563 /* the container is guaranteed to be empty by now */
566 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
567 iterator make_iterator(node_type* node){return iterator(node,this);}
568 const_iterator make_iterator(node_type* node)const
569 {return const_iterator(node,const_cast<sequenced_index*>(this));}
571 iterator make_iterator(node_type* node){return iterator(node);}
572 const_iterator make_iterator(node_type* node)const
573 {return const_iterator(node);}
577 const sequenced_index<SuperMeta,TagList>& x,const copy_map_type& map)
579 node_type* org=x.header();
580 node_type* cpy=header();
582 node_type* next_org=node_type::from_impl(org->next());
583 node_type* next_cpy=map.find(static_cast<final_node_type*>(next_org));
584 cpy->next()=next_cpy->impl();
585 next_cpy->prior()=cpy->impl();
588 }while(org!=x.header());
593 node_type* insert_(value_param_type v,node_type* x)
595 node_type* res=static_cast<node_type*>(super::insert_(v,x));
600 node_type* insert_(value_param_type v,node_type* position,node_type* x)
602 node_type* res=static_cast<node_type*>(super::insert_(v,position,x));
607 void erase_(node_type* x)
612 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
617 void delete_all_nodes_()
619 for(node_type* x=node_type::from_impl(header()->next());x!=header();){
620 node_type* y=node_type::from_impl(x->next());
621 this->final_delete_node_(static_cast<final_node_type*>(x));
631 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
632 safe_super::detach_dereferenceable_iterators();
636 void swap_(sequenced_index<SuperMeta,TagList>& x)
638 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
645 bool replace_(value_param_type v,node_type* x)
647 return super::replace_(v,x);
650 bool modify_(node_type* x)
653 if(!super::modify_(x)){
656 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
667 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
676 bool modify_rollback_(node_type* x)
678 return super::modify_rollback_(x);
681 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
684 template<typename Archive>
686 Archive& ar,const unsigned int version,const index_saver_type& sm)const
688 sm.save(begin(),end(),ar,version);
689 super::save_(ar,version,sm);
692 template<typename Archive>
694 Archive& ar,const unsigned int version,const index_loader_type& lm)
697 ::boost::bind(&sequenced_index::rearranger,this,_1,_2),
699 super::load_(ar,version,lm);
703 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
704 /* invariant stuff */
706 bool invariant_()const
708 if(size()==0||begin()==end()){
709 if(size()!=0||begin()!=end()||
710 header()->next()!=header()->impl()||
711 header()->prior()!=header()->impl())return false;
715 for(const_iterator it=begin(),it_end=end();it!=it_end;++it,++s){
716 if(it.get_node()->next()->prior()!=it.get_node()->impl())return false;
717 if(it.get_node()->prior()->next()!=it.get_node()->impl())return false;
719 if(s!=size())return false;
722 return super::invariant_();
725 /* This forwarding function eases things for the boost::mem_fn construct
726 * in BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT. Actually,
727 * final_check_invariant is already an inherited member function of index.
729 void check_invariant_()const{this->final_check_invariant_();}
733 node_type* header()const{return this->final_header();}
735 void empty_initialize()
737 header()->prior()=header()->next()=header()->impl();
740 void link(node_type* x)
742 node_impl_type::link(x->impl(),header()->impl());
745 static void unlink(node_type* x)
747 node_impl_type::unlink(x->impl());
750 static void relink(node_type* position,node_type* x)
752 node_impl_type::relink(position->impl(),x->impl());
755 static void relink(node_type* position,node_type* first,node_type* last)
757 node_impl_type::relink(
758 position->impl(),first->impl(),last->impl());
761 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
762 void rearranger(node_type* position,node_type *x)
764 if(!position)position=header();
765 node_type::increment(position);
766 if(position!=x)relink(position,x);
770 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
771 void detach_iterators(node_type* x)
773 iterator it=make_iterator(x);
774 safe_mode::detach_equivalent_iterators(it);
778 template <class InputIterator>
779 void assign_iter(InputIterator first,InputIterator last,mpl::true_)
781 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
783 for(;first!=last;++first)push_back(*first);
786 void assign_iter(size_type n,value_param_type value,mpl::false_)
788 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
790 for(size_type i=0;i<n;++i)push_back(value);
793 template<typename InputIterator>
795 iterator position,InputIterator first,InputIterator last,mpl::true_)
797 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
798 for(;first!=last;++first)insert(position,*first);
802 iterator position,size_type n,value_param_type x,mpl::false_)
804 BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
805 BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
806 BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
807 for(size_type i=0;i<n;++i)insert(position,x);
810 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
811 BOOST_WORKAROUND(__MWERKS__,<=0x3003)
812 #pragma parse_mfunc_templ reset
819 typename SuperMeta1,typename TagList1,
820 typename SuperMeta2,typename TagList2
823 const sequenced_index<SuperMeta1,TagList1>& x,
824 const sequenced_index<SuperMeta2,TagList2>& y)
826 return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
830 typename SuperMeta1,typename TagList1,
831 typename SuperMeta2,typename TagList2
834 const sequenced_index<SuperMeta1,TagList1>& x,
835 const sequenced_index<SuperMeta2,TagList2>& y)
837 return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
841 typename SuperMeta1,typename TagList1,
842 typename SuperMeta2,typename TagList2
845 const sequenced_index<SuperMeta1,TagList1>& x,
846 const sequenced_index<SuperMeta2,TagList2>& y)
852 typename SuperMeta1,typename TagList1,
853 typename SuperMeta2,typename TagList2
856 const sequenced_index<SuperMeta1,TagList1>& x,
857 const sequenced_index<SuperMeta2,TagList2>& y)
863 typename SuperMeta1,typename TagList1,
864 typename SuperMeta2,typename TagList2
867 const sequenced_index<SuperMeta1,TagList1>& x,
868 const sequenced_index<SuperMeta2,TagList2>& y)
874 typename SuperMeta1,typename TagList1,
875 typename SuperMeta2,typename TagList2
878 const sequenced_index<SuperMeta1,TagList1>& x,
879 const sequenced_index<SuperMeta2,TagList2>& y)
884 /* specialized algorithms */
886 template<typename SuperMeta,typename TagList>
888 sequenced_index<SuperMeta,TagList>& x,
889 sequenced_index<SuperMeta,TagList>& y)
894 } /* namespace multi_index::detail */
896 /* sequenced index specifier */
898 template <typename TagList>
901 BOOST_STATIC_ASSERT(detail::is_tag<TagList>::value);
903 template<typename Super>
906 typedef detail::sequenced_index_node<Super> type;
909 template<typename SuperMeta>
912 typedef detail::sequenced_index<SuperMeta,typename TagList::type> type;
916 } /* namespace multi_index */
918 } /* namespace boost */
920 #undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT