LCOV - code coverage report
Current view: top level - opt/homebrew/include/boost/multi_index - sequenced_index.hpp (source / functions) Hit Total Coverage
Test: test_dash_coverage.info Lines: 27 37 73.0 %
Date: 2026-06-25 07:23:51 Functions: 12 15 80.0 %

          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         404 :   iterator  begin()BOOST_NOEXCEPT
     222         404 :     {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          17 :     end()BOOST_NOEXCEPT{return make_iterator(header());}
     227             :   const_iterator
     228             :     end()const BOOST_NOEXCEPT{return make_iterator(header());}
     229             :   reverse_iterator
     230          17 :     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         404 :     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           0 :   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           0 :     this->final_erase_(static_cast<final_node_type*>(position++.get_node()));
     386           0 :     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       24311 :   sequenced_index(const ctor_args_list& args_list,const allocator_type& al):
     672       24311 :     super(args_list.get_tail(),al)
     673             : 
     674             : #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
     675             :     ,safe(*this)
     676             : #endif
     677             : 
     678             :   {
     679       24311 :     empty_initialize();
     680       24311 :   }
     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       24311 :   ~sequenced_index()
     706             :   {
     707             :     /* the container is guaranteed to be empty by now */
     708       24311 :   }
     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         421 :   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         387 :   final_node_type* insert_(
     741             :     value_param_type v,final_node_type*& x,Variant variant)
     742             :   {
     743         387 :     final_node_type* res=super::insert_(v,x,variant);
     744         387 :     if(res==x)link(static_cast<index_node_type*>(x));
     745         387 :     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           0 :   void extract_(index_node_type* x,Dst dst)
     760             :   {
     761           0 :     unlink(x);
     762           0 :     super::extract_(x,dst.next());
     763             : 
     764             : #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
     765             :     transfer_iterators(dst.get(),x);
     766             : #endif
     767           0 :   }
     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          17 :   void clear_()
     780             :   {
     781          17 :     super::clear_();
     782          17 :     empty_initialize();
     783             : 
     784             : #if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
     785             :     safe.detach_dereferenceable_iterators();
     786             : #endif
     787          17 :   }
     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       73792 :   index_node_type* header()const{return this->final_header();}
     905             : 
     906       24328 :   void empty_initialize()
     907             :   {
     908       24328 :     header()->prior()=header()->next()=header()->impl();
     909       24328 :   }
     910             : 
     911         387 :   void link(index_node_type* x)
     912             :   {
     913         387 :     node_impl_type::link(x->impl(),header()->impl());
     914         387 :   }
     915             : 
     916           0 :   static void unlink(index_node_type* x)
     917             :   {
     918           0 :     node_impl_type::unlink(x->impl());
     919           0 :   }
     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

Generated by: LCOV version 1.16