epoc32/include/stdapis/boost/multi_index/sequenced_index.hpp
author William Roberts <williamr@symbian.org>
Tue, 16 Mar 2010 16:12:26 +0000
branchSymbian2
changeset 2 2fe1408b6811
permissions -rw-r--r--
Final list of Symbian^2 public API header files
     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)
     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/no_exceptions_support.hpp>
    19 #include <boost/detail/workaround.hpp>
    20 #include <boost/iterator/reverse_iterator.hpp>
    21 #include <boost/mpl/push_front.hpp>
    22 #include <boost/multi_index/detail/access_specifier.hpp>
    23 #include <boost/multi_index/detail/bidir_node_iterator.hpp>
    24 #include <boost/multi_index/detail/index_node_base.hpp>
    25 #include <boost/multi_index/detail/safe_ctr_proxy.hpp>
    26 #include <boost/multi_index/detail/safe_mode.hpp>
    27 #include <boost/multi_index/detail/scope_guard.hpp>
    28 #include <boost/multi_index/detail/seq_index_node.hpp>
    29 #include <boost/multi_index/detail/seq_index_ops.hpp>
    30 #include <boost/multi_index/sequenced_index_fwd.hpp>
    31 #include <boost/tuple/tuple.hpp>
    32 #include <cstddef>
    33 #include <functional>
    34 #include <utility>
    35 
    36 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
    37 #include <boost/bind.hpp>
    38 #endif
    39 
    40 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
    41 #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT                          \
    42   detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)=                 \
    43     detail::make_obj_guard(*this,&sequenced_index::check_invariant_);        \
    44   BOOST_JOIN(check_invariant_,__LINE__).touch();
    45 #else
    46 #define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT
    47 #endif
    48 
    49 namespace boost{
    50 
    51 namespace multi_index{
    52 
    53 namespace detail{
    54 
    55 /* sequenced_index adds a layer of sequenced indexing to a given Super */
    56 
    57 template<typename SuperMeta,typename TagList>
    58 class sequenced_index:
    59   BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
    60 
    61 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
    62 #if BOOST_WORKAROUND(BOOST_MSVC,<1300)
    63   ,public safe_ctr_proxy_impl<
    64     bidir_node_iterator<
    65       sequenced_index_node<typename SuperMeta::type::node_type> >,
    66     sequenced_index<SuperMeta,TagList> >
    67 #else
    68   ,public safe_mode::safe_container<
    69     sequenced_index<SuperMeta,TagList> >
    70 #endif
    71 #endif
    72 
    73 { 
    74 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
    75     BOOST_WORKAROUND(__MWERKS__,<=0x3003)
    76 /* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
    77  * lifetime of const references bound to temporaries --precisely what
    78  * scopeguards are.
    79  */
    80 
    81 #pragma parse_mfunc_templ off
    82 #endif
    83 
    84   typedef typename SuperMeta::type                   super;
    85 
    86 protected:
    87   typedef sequenced_index_node<
    88     typename super::node_type>                       node_type;
    89 
    90 public:
    91   /* types */
    92 
    93   typedef typename node_type::value_type             value_type;
    94   typedef tuples::null_type                          ctor_args;
    95   typedef typename super::final_allocator_type       allocator_type;
    96   typedef typename allocator_type::reference         reference;
    97   typedef typename allocator_type::const_reference   const_reference;
    98 
    99 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
   100 #if BOOST_WORKAROUND(BOOST_MSVC,<1300)
   101   typedef safe_mode::safe_iterator<
   102     bidir_node_iterator<node_type>,
   103     safe_ctr_proxy<
   104       bidir_node_iterator<node_type> > >             iterator;
   105 #else
   106   typedef safe_mode::safe_iterator<
   107     bidir_node_iterator<node_type>,
   108     sequenced_index>                                 iterator;
   109 #endif
   110 #else
   111   typedef bidir_node_iterator<node_type>             iterator;
   112 #endif
   113 
   114   typedef iterator                                   const_iterator;
   115 
   116   typedef std::size_t                                size_type;      
   117   typedef std::ptrdiff_t                             difference_type;
   118   typedef typename allocator_type::pointer           pointer;
   119   typedef typename allocator_type::const_pointer     const_pointer;
   120   typedef typename
   121     boost::reverse_iterator<iterator>                reverse_iterator;
   122   typedef typename
   123     boost::reverse_iterator<const_iterator>          const_reverse_iterator;
   124   typedef TagList                                    tag_list;
   125 
   126 protected:
   127   typedef typename super::final_node_type     final_node_type;
   128   typedef tuples::cons<
   129     ctor_args, 
   130     typename super::ctor_args_list>           ctor_args_list;
   131   typedef typename mpl::push_front<
   132     typename super::index_type_list,
   133     sequenced_index>::type                    index_type_list;
   134   typedef typename mpl::push_front<
   135     typename super::iterator_type_list,
   136     iterator>::type                           iterator_type_list;
   137   typedef typename mpl::push_front<
   138     typename super::const_iterator_type_list,
   139     const_iterator>::type                     const_iterator_type_list;
   140   typedef typename super::copy_map_type       copy_map_type;
   141 
   142 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
   143   typedef typename super::index_saver_type    index_saver_type;
   144   typedef typename super::index_loader_type   index_loader_type;
   145 #endif
   146 
   147 private:
   148 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
   149 #if BOOST_WORKAROUND(BOOST_MSVC,<1300)
   150   typedef safe_ctr_proxy_impl<
   151     bidir_node_iterator<node_type>,
   152     sequenced_index>                          safe_super;
   153 #else
   154   typedef safe_mode::safe_container<
   155     sequenced_index>                          safe_super;
   156 #endif
   157 #endif
   158 
   159   typedef typename call_traits<value_type>::param_type value_param_type;
   160 
   161 public:
   162 
   163   /* construct/copy/destroy
   164    * Default and copy ctors are in the protected section as indices are
   165    * not supposed to be created on their own. No range ctor either.
   166    */
   167 
   168   sequenced_index<SuperMeta,TagList>& operator=(
   169     const sequenced_index<SuperMeta,TagList>& x)
   170   {
   171     this->final()=x.final();
   172     return *this;
   173   }
   174 
   175   template <class InputIterator>
   176   void assign(InputIterator first,InputIterator last)
   177   {
   178     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   179     clear();
   180     for(;first!=last;++first)push_back(*first);
   181   }
   182 
   183   void assign(size_type n,value_param_type value)
   184   {
   185     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   186     clear();
   187     for(size_type i=0;i<n;++i)push_back(value);
   188   }
   189     
   190   allocator_type get_allocator()const
   191   {
   192     return this->final().get_allocator();
   193   }
   194 
   195   /* iterators */
   196 
   197   iterator               begin()
   198     {return make_iterator(node_type::from_impl(header()->next()));}
   199   const_iterator         begin()const
   200     {return make_iterator(node_type::from_impl(header()->next()));}
   201   iterator               end(){return make_iterator(header());}
   202   const_iterator         end()const{return make_iterator(header());}
   203   reverse_iterator       rbegin(){return make_reverse_iterator(end());}
   204   const_reverse_iterator rbegin()const{return make_reverse_iterator(end());}
   205   reverse_iterator       rend(){return make_reverse_iterator(begin());}
   206   const_reverse_iterator rend()const{return make_reverse_iterator(begin());}
   207 
   208   /* capacity */
   209 
   210   bool      empty()const{return this->final_empty_();}
   211   size_type size()const{return this->final_size_();}
   212   size_type max_size()const{return this->final_max_size_();}
   213 
   214   void resize(size_type n,value_param_type x=value_type())
   215   {
   216     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   217     if(n>size())insert(end(),n-size(),x);
   218     else if(n<size()){
   219       iterator it=begin();
   220       std::advance(it,n);
   221       erase(it,end());
   222     }   
   223   }
   224 
   225   /* access: no non-const versions provided as sequenced_index
   226    * handles const elements.
   227    */
   228 
   229   const_reference front()const{return *begin();}
   230   const_reference back()const{return *--end();}
   231 
   232   /* modifiers */
   233 
   234   std::pair<iterator,bool> push_front(value_param_type x)
   235                              {return insert(begin(),x);}
   236   void                     pop_front(){erase(begin());}
   237   std::pair<iterator,bool> push_back(value_param_type x)
   238                              {return insert(end(),x);}
   239   void                     pop_back(){erase(--end());}
   240 
   241   std::pair<iterator,bool> insert(iterator position,value_param_type x)
   242   {
   243     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
   244     BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
   245     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   246     std::pair<final_node_type*,bool> p=this->final_insert_(x);
   247     if(p.second&&position.get_node()!=header()){
   248       relink(position.get_node(),p.first);
   249     }
   250     return std::pair<iterator,bool>(make_iterator(p.first),p.second);
   251   }
   252 
   253   void insert(iterator position,size_type n,value_param_type x)
   254   {
   255     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
   256     BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
   257     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   258     for(size_type i=0;i<n;++i)insert(position,x);
   259   }
   260  
   261   template<typename InputIterator>
   262   void insert(iterator position,InputIterator first,InputIterator last)
   263   {
   264     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   265     for(;first!=last;++first)insert(position,*first);
   266   }
   267 
   268   iterator erase(iterator position)
   269   {
   270     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
   271     BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
   272     BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
   273     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   274     this->final_erase_(static_cast<final_node_type*>(position++.get_node()));
   275     return position;
   276   }
   277   
   278   iterator erase(iterator first,iterator last)
   279   {
   280     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
   281     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
   282     BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
   283     BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
   284     BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
   285     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   286     while(first!=last){
   287       first=erase(first);
   288     }
   289     return first;
   290   }
   291 
   292   bool replace(iterator position,value_param_type x)
   293   {
   294     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
   295     BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
   296     BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
   297     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   298     return this->final_replace_(
   299       x,static_cast<final_node_type*>(position.get_node()));
   300   }
   301 
   302   template<typename Modifier>
   303   bool modify(iterator position,Modifier mod)
   304   {
   305     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
   306     BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
   307     BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
   308     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   309 
   310 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
   311     /* MSVC++ 6.0 optimizer on safe mode code chokes if this
   312      * this is not added. Left it for all compilers as it does no
   313      * harm.
   314      */
   315 
   316     position.detach();
   317 #endif
   318 
   319     return this->final_modify_(
   320       mod,static_cast<final_node_type*>(position.get_node()));
   321   }
   322 
   323   void swap(sequenced_index<SuperMeta,TagList>& x)
   324   {
   325     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   326     this->final_swap_(x.final());
   327   }
   328 
   329   void clear()
   330   {
   331     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   332     this->final_clear_();
   333   }
   334 
   335   /* list operations */
   336 
   337   void splice(iterator position,sequenced_index<SuperMeta,TagList>& x)
   338   {
   339     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
   340     BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
   341     BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(*this,x);
   342     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   343     iterator first=x.begin(),last=x.end();
   344     while(first!=last){
   345       if(insert(position,*first).second)first=x.erase(first);
   346       else ++first;
   347     }
   348   }
   349 
   350   void splice(iterator position,sequenced_index<SuperMeta,TagList>& x,iterator i)
   351   {
   352     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
   353     BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
   354     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i);
   355     BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
   356     BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x);
   357     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   358     if(&x==this){
   359       if(position!=i)relink(position.get_node(),i.get_node());
   360     }
   361     else{
   362       if(insert(position,*i).second){
   363 
   364 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
   365     /* MSVC++ 6.0 optimizer has a hard time with safe mode, and the following
   366      * workaround is needed. Left it for all compilers as it does no
   367      * harm.
   368      */
   369         i.detach();
   370         x.erase(x.make_iterator(i.get_node()));
   371 #else
   372         x.erase(i);
   373 #endif
   374 
   375       }
   376     }
   377   }
   378 
   379   void splice(
   380     iterator position,sequenced_index<SuperMeta,TagList>& x,
   381     iterator first,iterator last)
   382   {
   383     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
   384     BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
   385     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
   386     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
   387     BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x);
   388     BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x);
   389     BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
   390     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   391     if(&x==this){
   392       BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last);
   393       if(position!=last)relink(
   394         position.get_node(),first.get_node(),last.get_node());
   395     }
   396     else{
   397       while(first!=last){
   398         if(insert(position,*first).second)first=x.erase(first);
   399         else ++first;
   400       }
   401     }
   402   }
   403 
   404   void remove(value_param_type value)
   405   {
   406     sequenced_index_remove(
   407       *this,std::bind2nd(std::equal_to<value_type>(),value));
   408   }
   409 
   410   template<typename Predicate>
   411   void remove_if(Predicate pred)
   412   {
   413     sequenced_index_remove(*this,pred);
   414   }
   415 
   416   void unique()
   417   {
   418     sequenced_index_unique(*this,std::equal_to<value_type>());
   419   }
   420 
   421   template <class BinaryPredicate>
   422   void unique(BinaryPredicate binary_pred)
   423   {
   424     sequenced_index_unique(*this,binary_pred);
   425   }
   426 
   427   void merge(sequenced_index<SuperMeta,TagList>& x)
   428   {
   429     sequenced_index_merge(*this,x,std::less<value_type>());
   430   }
   431 
   432   template <typename Compare>
   433   void merge(sequenced_index<SuperMeta,TagList>& x,Compare comp)
   434   {
   435     sequenced_index_merge(*this,x,comp);
   436   }
   437 
   438   void sort()
   439   {
   440     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   441     sequenced_index_sort(header(),std::less<value_type>());
   442   }
   443 
   444   template <typename Compare>
   445   void sort(Compare comp)
   446   {
   447     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   448     sequenced_index_sort(header(),comp);
   449   }
   450 
   451   void reverse()
   452   {
   453     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   454     sequenced_index_node_impl::reverse(header()->impl());
   455   }
   456 
   457   /* rearrange operations */
   458 
   459   void relocate(iterator position,iterator i)
   460   {
   461     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
   462     BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
   463     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i);
   464     BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
   465     BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,*this);
   466     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   467     if(position!=i)relink(position.get_node(),i.get_node());
   468   }
   469 
   470   void relocate(iterator position,iterator first,iterator last)
   471   {
   472     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
   473     BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
   474     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
   475     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
   476     BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
   477     BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
   478     BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
   479     BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last);
   480     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   481     if(position!=last)relink(
   482       position.get_node(),first.get_node(),last.get_node());
   483   }
   484     
   485   template<typename InputIterator>
   486   void rearrange(InputIterator first)
   487   {
   488     BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
   489     node_type* pos=header();
   490     for(size_type s=size();s--;){
   491       const value_type& v=*first++;
   492       relink(pos,node_from_value<node_type>(&v));
   493     }
   494   }
   495 
   496 BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
   497   sequenced_index(const ctor_args_list& args_list,const allocator_type& al):
   498     super(args_list.get_tail(),al)
   499   {
   500     empty_initialize();
   501   }
   502 
   503   sequenced_index(const sequenced_index<SuperMeta,TagList>& x):
   504     super(x)
   505 
   506 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
   507     ,safe_super()
   508 #endif
   509 
   510   {
   511     /* The actual copying takes place in subsequent call to copy_().
   512      */
   513   }
   514 
   515   ~sequenced_index()
   516   {
   517     /* the container is guaranteed to be empty by now */
   518   }
   519 
   520 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
   521   iterator       make_iterator(node_type* node){return iterator(node,this);}
   522   const_iterator make_iterator(node_type* node)const
   523     {return const_iterator(node,const_cast<sequenced_index*>(this));}
   524 #else
   525   iterator       make_iterator(node_type* node){return iterator(node);}
   526   const_iterator make_iterator(node_type* node)const
   527                    {return const_iterator(node);}
   528 #endif
   529 
   530   void copy_(
   531     const sequenced_index<SuperMeta,TagList>& x,const copy_map_type& map)
   532   {
   533     node_type* org=x.header();
   534     node_type* cpy=header();
   535     do{
   536       node_type* next_org=node_type::from_impl(org->next());
   537       node_type* next_cpy=map.find(static_cast<final_node_type*>(next_org));
   538       cpy->next()=next_cpy->impl();
   539       next_cpy->prior()=cpy->impl();
   540       org=next_org;
   541       cpy=next_cpy;
   542     }while(org!=x.header());
   543 
   544     super::copy_(x,map);
   545   }
   546 
   547   node_type* insert_(value_param_type v,node_type* x)
   548   {
   549     node_type* res=static_cast<node_type*>(super::insert_(v,x));
   550     if(res==x)link(x);
   551     return res;
   552   }
   553 
   554   node_type* insert_(value_param_type v,node_type* position,node_type* x)
   555   {
   556     node_type* res=static_cast<node_type*>(super::insert_(v,position,x));
   557     if(res==x)link(x);
   558     return res;
   559   }
   560 
   561   void erase_(node_type* x)
   562   {
   563     unlink(x);
   564     super::erase_(x);
   565 
   566 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
   567     detach_iterators(x);
   568 #endif
   569   }
   570 
   571   void delete_all_nodes_()
   572   {
   573     for(node_type* x=node_type::from_impl(header()->next());x!=header();){
   574       node_type* y=node_type::from_impl(x->next());
   575       this->final_delete_node_(static_cast<final_node_type*>(x));
   576       x=y;
   577     }
   578   }
   579 
   580   void clear_()
   581   {
   582     super::clear_();
   583     empty_initialize();
   584 
   585 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
   586     safe_super::detach_dereferenceable_iterators();
   587 #endif
   588   }
   589 
   590   void swap_(sequenced_index<SuperMeta,TagList>& x)
   591   {
   592 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
   593     safe_super::swap(x);
   594 #endif
   595 
   596     super::swap_(x);
   597   }
   598 
   599   bool replace_(value_param_type v,node_type* x)
   600   {
   601     return super::replace_(v,x);
   602   }
   603 
   604   bool modify_(node_type* x)
   605   {
   606     BOOST_TRY{
   607       if(!super::modify_(x)){
   608         unlink(x);
   609 
   610 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
   611         detach_iterators(x);
   612 #endif
   613 
   614         return false;
   615       }
   616       else return true;
   617     }
   618     BOOST_CATCH(...){
   619       unlink(x);
   620 
   621 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
   622       detach_iterators(x);
   623 #endif
   624 
   625       BOOST_RETHROW;
   626     }
   627     BOOST_CATCH_END
   628   }
   629 
   630 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
   631   /* serialization */
   632 
   633   template<typename Archive>
   634   void save_(
   635     Archive& ar,const unsigned int version,const index_saver_type& sm)const
   636   {
   637     sm.save(begin(),end(),ar,version);
   638     super::save_(ar,version,sm);
   639   }
   640 
   641   template<typename Archive>
   642   void load_(
   643     Archive& ar,const unsigned int version,const index_loader_type& lm)
   644   {
   645     lm.load(
   646       ::boost::bind(&sequenced_index::rearranger,this,_1,_2),
   647       ar,version);
   648     super::load_(ar,version,lm);
   649   }
   650 #endif
   651 
   652 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
   653   /* invariant stuff */
   654 
   655   bool invariant_()const
   656   {
   657     if(size()==0||begin()==end()){
   658       if(size()!=0||begin()!=end()||
   659          header()->next()!=header()->impl()||
   660          header()->prior()!=header()->impl())return false;
   661     }
   662     else{
   663       size_type s=0;
   664       for(const_iterator it=begin(),it_end=end();it!=it_end;++it,++s){
   665         if(it.get_node()->next()->prior()!=it.get_node()->impl())return false;
   666         if(it.get_node()->prior()->next()!=it.get_node()->impl())return false;
   667       }
   668       if(s!=size())return false;
   669     }
   670 
   671     return super::invariant_();
   672   }
   673 
   674   /* This forwarding function eases things for the boost::mem_fn construct
   675    * in BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT. Actually,
   676    * final_check_invariant is already an inherited member function of index.
   677    */
   678   void check_invariant_()const{this->final_check_invariant_();}
   679 #endif
   680 
   681 private:
   682   node_type* header()const{return this->final_header();}
   683 
   684   void empty_initialize()
   685   {
   686     header()->prior()=header()->next()=header()->impl();
   687   }
   688 
   689   void link(node_type* x)
   690   {
   691     sequenced_index_node_impl::link(x->impl(),header()->impl());
   692   };
   693 
   694   static void unlink(node_type* x)
   695   {
   696     sequenced_index_node_impl::unlink(x->impl());
   697   }
   698 
   699   static void relink(node_type* position,node_type* x)
   700   {
   701     sequenced_index_node_impl::relink(position->impl(),x->impl());
   702   }
   703 
   704   static void relink(node_type* position,node_type* first,node_type* last)
   705   {
   706     sequenced_index_node_impl::relink(
   707       position->impl(),first->impl(),last->impl());
   708   }
   709 
   710 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
   711   void rearranger(node_type* position,node_type *x)
   712   {
   713     if(!position)position=header();
   714     node_type::increment(position);
   715     if(position!=x)relink(position,x);
   716   }
   717 #endif
   718 
   719 #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
   720   void detach_iterators(node_type* x)
   721   {
   722     iterator it=make_iterator(x);
   723     safe_mode::detach_equivalent_iterators(it);
   724   }
   725 #endif
   726 
   727 #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
   728     BOOST_WORKAROUND(__MWERKS__,<=0x3003)
   729 #pragma parse_mfunc_templ reset
   730 #endif
   731 };
   732 
   733 /* comparison */
   734 
   735 template<
   736   typename SuperMeta1,typename TagList1,
   737   typename SuperMeta2,typename TagList2
   738 >
   739 bool operator==(
   740   const sequenced_index<SuperMeta1,TagList1>& x,
   741   const sequenced_index<SuperMeta2,TagList2>& y)
   742 {
   743   return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
   744 }
   745 
   746 template<
   747   typename SuperMeta1,typename TagList1,
   748   typename SuperMeta2,typename TagList2
   749 >
   750 bool operator<(
   751   const sequenced_index<SuperMeta1,TagList1>& x,
   752   const sequenced_index<SuperMeta2,TagList2>& y)
   753 {
   754   return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
   755 }
   756 
   757 template<
   758   typename SuperMeta1,typename TagList1,
   759   typename SuperMeta2,typename TagList2
   760 >
   761 bool operator!=(
   762   const sequenced_index<SuperMeta1,TagList1>& x,
   763   const sequenced_index<SuperMeta2,TagList2>& y)
   764 {
   765   return !(x==y);
   766 }
   767 
   768 template<
   769   typename SuperMeta1,typename TagList1,
   770   typename SuperMeta2,typename TagList2
   771 >
   772 bool operator>(
   773   const sequenced_index<SuperMeta1,TagList1>& x,
   774   const sequenced_index<SuperMeta2,TagList2>& y)
   775 {
   776   return y<x;
   777 }
   778 
   779 template<
   780   typename SuperMeta1,typename TagList1,
   781   typename SuperMeta2,typename TagList2
   782 >
   783 bool operator>=(
   784   const sequenced_index<SuperMeta1,TagList1>& x,
   785   const sequenced_index<SuperMeta2,TagList2>& y)
   786 {
   787   return !(x<y);
   788 }
   789 
   790 template<
   791   typename SuperMeta1,typename TagList1,
   792   typename SuperMeta2,typename TagList2
   793 >
   794 bool operator<=(
   795   const sequenced_index<SuperMeta1,TagList1>& x,
   796   const sequenced_index<SuperMeta2,TagList2>& y)
   797 {
   798   return !(x>y);
   799 }
   800 
   801 /*  specialized algorithms */
   802 
   803 template<typename SuperMeta,typename TagList>
   804 void swap(
   805   sequenced_index<SuperMeta,TagList>& x,
   806   sequenced_index<SuperMeta,TagList>& y)
   807 {
   808   x.swap(y);
   809 }
   810 
   811 } /* namespace multi_index::detail */
   812 
   813 /* sequenced index specifier */
   814 
   815 template <typename TagList>
   816 struct sequenced
   817 {
   818   BOOST_STATIC_ASSERT(detail::is_tag<TagList>::value);
   819 
   820   template<typename Super>
   821   struct node_class
   822   {
   823     typedef detail::sequenced_index_node<Super> type;
   824   };
   825 
   826   template<typename SuperMeta>
   827   struct index_class
   828   {
   829     typedef detail::sequenced_index<SuperMeta,typename TagList::type> type;
   830   };
   831 };
   832 
   833 } /* namespace multi_index */
   834 
   835 } /* namespace boost */
   836 
   837 #undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT
   838 
   839 #endif