LCOV - code coverage report
Current view: top level - opt/homebrew/include/boost - multi_index_container.hpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 89 111 80.2 %
Date: 2026-06-25 07:23:43 Functions: 71 71 100.0 %

          Line data    Source code
       1             : /* Multiply indexed container.
       2             :  *
       3             :  * Copyright 2003-2023 Joaquin M Lopez Munoz.
       4             :  * Distributed under the Boost Software License, Version 1.0.
       5             :  * (See accompanying file LICENSE_1_0.txt or copy at
       6             :  * http://www.boost.org/LICENSE_1_0.txt)
       7             :  *
       8             :  * See http://www.boost.org/libs/multi_index for library home page.
       9             :  */
      10             : 
      11             : #ifndef BOOST_MULTI_INDEX_HPP
      12             : #define BOOST_MULTI_INDEX_HPP
      13             : 
      14             : #if defined(_MSC_VER)
      15             : #pragma once
      16             : #endif
      17             : 
      18             : #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
      19             : #include <algorithm>
      20             : #include <boost/core/addressof.hpp>
      21             : #include <boost/core/no_exceptions_support.hpp>
      22             : #include <boost/detail/workaround.hpp>
      23             : #include <boost/move/core.hpp>
      24             : #include <boost/move/utility_core.hpp>
      25             : #include <boost/mpl/at.hpp>
      26             : #include <boost/mpl/contains.hpp>
      27             : #include <boost/mpl/find_if.hpp>
      28             : #include <boost/mpl/identity.hpp>
      29             : #include <boost/mpl/int.hpp>
      30             : #include <boost/mpl/size.hpp>
      31             : #include <boost/mpl/deref.hpp>
      32             : #include <boost/multi_index_container_fwd.hpp>
      33             : #include <boost/multi_index/detail/access_specifier.hpp>
      34             : #include <boost/multi_index/detail/adl_swap.hpp>
      35             : #include <boost/multi_index/detail/allocator_traits.hpp>
      36             : #include <boost/multi_index/detail/base_type.hpp>
      37             : #include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
      38             : #include <boost/multi_index/detail/converter.hpp>
      39             : #include <boost/multi_index/detail/header_holder.hpp>
      40             : #include <boost/multi_index/detail/has_tag.hpp>
      41             : #include <boost/multi_index/detail/invalidate_iterators.hpp>
      42             : #include <boost/multi_index/detail/no_duplicate_tags.hpp>
      43             : #include <boost/multi_index/detail/safe_mode.hpp>
      44             : #include <boost/multi_index/detail/scope_guard.hpp>
      45             : #include <boost/multi_index/detail/vartempl_support.hpp>
      46             : #include <boost/static_assert.hpp>
      47             : #include <boost/type_traits/integral_constant.hpp>
      48             : #include <boost/type_traits/is_same.hpp>
      49             : #include <boost/utility/base_from_member.hpp>
      50             : 
      51             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
      52             : #include <initializer_list>
      53             : #endif
      54             : 
      55             : #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
      56             : #include <boost/core/serialization.hpp>
      57             : #include <boost/multi_index/detail/archive_constructed.hpp>
      58             : #include <boost/multi_index/detail/bad_archive_exception.hpp>
      59             : #include <boost/multi_index/detail/serialization_version.hpp>
      60             : #include <boost/throw_exception.hpp> 
      61             : 
      62             : #if defined(BOOST_MULTI_INDEX_ENABLE_SERIALIZATION_COMPATIBILITY_V2)
      63             : #define BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER \
      64             :   <boost/serialization/collection_size_type.hpp>
      65             : #include BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
      66             : #undef BOOST_MULTI_INDEX_BLOCK_BOOSTDEP_HEADER
      67             : #endif
      68             : #endif
      69             : 
      70             : #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
      71             : #include <boost/multi_index/detail/invariant_assert.hpp>
      72             : #define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x)                              \
      73             :   detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)=                 \
      74             :     detail::make_obj_guard(x,&multi_index_container::check_invariant_);      \
      75             :   BOOST_JOIN(check_invariant_,__LINE__).touch();
      76             : #define BOOST_MULTI_INDEX_CHECK_INVARIANT                                    \
      77             :   BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(*this)
      78             : #else
      79             : #define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x)
      80             : #define BOOST_MULTI_INDEX_CHECK_INVARIANT
      81             : #endif
      82             : 
      83             : namespace boost{
      84             : 
      85             : namespace multi_index{
      86             : 
      87             : namespace detail{
      88             : 
      89             : struct unequal_alloc_move_ctor_tag{};
      90             : 
      91             : } /* namespace multi_index::detail */
      92             : 
      93             : #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
      94             : #pragma warning(push)
      95             : #pragma warning(disable:4522) /* spurious warning on multiple operator=()'s */
      96             : #endif
      97             : 
      98             : template<typename Value,typename IndexSpecifierList,typename Allocator>
      99             : class multi_index_container:
     100             :   private ::boost::base_from_member<
     101             :     typename detail::rebind_alloc_for<
     102             :       Allocator,
     103             :       typename detail::multi_index_node_type<
     104             :         Value,IndexSpecifierList,Allocator>::type
     105             :     >::type
     106             :   >,
     107             :   BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS detail::header_holder<
     108             :     typename detail::allocator_traits<
     109             :       typename detail::rebind_alloc_for<
     110             :         Allocator,
     111             :         typename detail::multi_index_node_type<
     112             :           Value,IndexSpecifierList,Allocator>::type
     113             :       >::type
     114             :     >::pointer,
     115             :     multi_index_container<Value,IndexSpecifierList,Allocator> >,
     116             :   public detail::multi_index_base_type<
     117             :     Value,IndexSpecifierList,Allocator>::type
     118             : {
     119             : #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
     120             :     BOOST_WORKAROUND(__MWERKS__,<=0x3003)
     121             : /* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
     122             :  * lifetime of const references bound to temporaries --precisely what
     123             :  * scopeguards are.
     124             :  */
     125             : 
     126             : #pragma parse_mfunc_templ off
     127             : #endif
     128             : 
     129             : private:
     130             :   BOOST_COPYABLE_AND_MOVABLE(multi_index_container)
     131             : 
     132             : #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
     133             :   template <typename,typename,typename> friend class  detail::index_base;
     134             :   template <typename,typename>          friend struct detail::header_holder;
     135             :   template <typename,typename>          friend struct detail::converter;
     136             : #endif
     137             : 
     138             :   typedef typename detail::multi_index_base_type<
     139             :       Value,IndexSpecifierList,Allocator>::type    super;
     140             :   typedef typename detail::rebind_alloc_for<
     141             :     Allocator,
     142             :     typename super::index_node_type
     143             :   >::type                                          node_allocator;
     144             :   typedef detail::allocator_traits<node_allocator> node_alloc_traits;
     145             :   typedef typename node_alloc_traits::pointer      node_pointer;
     146             :   typedef ::boost::base_from_member<
     147             :     node_allocator>                                bfm_allocator;
     148             :   typedef detail::header_holder<
     149             :     node_pointer,
     150             :     multi_index_container>                         bfm_header;
     151             : 
     152             : public:
     153             :   /* All types are inherited from super, a few are explicitly
     154             :    * brought forward here to save us some typename's.
     155             :    */
     156             : 
     157             :   typedef typename super::ctor_args_list           ctor_args_list;
     158             :   typedef IndexSpecifierList                       index_specifier_type_list;
     159             :  
     160             :   typedef typename super::index_type_list          index_type_list;
     161             : 
     162             :   typedef typename super::iterator_type_list       iterator_type_list;
     163             :   typedef typename super::const_iterator_type_list const_iterator_type_list;
     164             :   typedef typename super::value_type               value_type;
     165             :   typedef typename super::final_allocator_type     allocator_type;
     166             :   typedef typename super::size_type                size_type;
     167             :   typedef typename super::iterator                 iterator;
     168             :   typedef typename super::const_iterator           const_iterator;
     169             : 
     170             :   BOOST_STATIC_ASSERT(
     171             :     detail::no_duplicate_tags_in_index_list<index_type_list>::value);
     172             : 
     173             :   /* global project() needs to see this publicly */
     174             : 
     175             :   typedef typename super::final_node_type         final_node_type;
     176             : 
     177             :   /* construct/copy/destroy */
     178             : 
     179     1097595 :   multi_index_container():
     180      365865 :     bfm_allocator(allocator_type()),
     181      365865 :     super(ctor_args_list(),bfm_allocator::member),
     182      365865 :     node_count(0)
     183     1097595 :   {
     184             :     BOOST_MULTI_INDEX_CHECK_INVARIANT;
     185      731730 :   }
     186             : 
     187             :   explicit multi_index_container(
     188             :     const ctor_args_list& args_list,
     189             : 
     190             : #if BOOST_WORKAROUND(__IBMCPP__,<=600)
     191             :     /* VisualAge seems to have an ETI issue with the default value for
     192             :      * argument al.
     193             :      */
     194             : 
     195             :     const allocator_type& al=
     196             :       typename mpl::identity<multi_index_container>::type::
     197             :         allocator_type()):
     198             : #else
     199             :     const allocator_type& al=allocator_type()):
     200             : #endif
     201             : 
     202             :     bfm_allocator(al),
     203             :     super(args_list,bfm_allocator::member),
     204             :     node_count(0)
     205             :   {
     206             :     BOOST_MULTI_INDEX_CHECK_INVARIANT;
     207             :   }
     208             : 
     209             :   explicit multi_index_container(const allocator_type& al):
     210             :     bfm_allocator(al),
     211             :     super(ctor_args_list(),bfm_allocator::member),
     212             :     node_count(0)
     213             :   {
     214             :     BOOST_MULTI_INDEX_CHECK_INVARIANT;
     215             :   }
     216             :   
     217             :   template<typename InputIterator>
     218             :   multi_index_container(
     219             :     InputIterator first,InputIterator last,
     220             : 
     221             : #if BOOST_WORKAROUND(__IBMCPP__,<=600)
     222             :     /* VisualAge seems to have an ETI issue with the default values
     223             :      * for arguments args_list and al.
     224             :      */
     225             : 
     226             :     const ctor_args_list& args_list=
     227             :       typename mpl::identity<multi_index_container>::type::
     228             :         ctor_args_list(),
     229             :     const allocator_type& al=
     230             :       typename mpl::identity<multi_index_container>::type::
     231             :         allocator_type()):
     232             : #else
     233             :     const ctor_args_list& args_list=ctor_args_list(),
     234             :     const allocator_type& al=allocator_type()):
     235             : #endif
     236             : 
     237             :     bfm_allocator(al),
     238             :     super(args_list,bfm_allocator::member),
     239             :     node_count(0)
     240             :   {
     241             :     BOOST_MULTI_INDEX_CHECK_INVARIANT;
     242             :     BOOST_TRY{
     243             :       iterator hint=super::end();
     244             :       for(;first!=last;++first){
     245             :         hint=super::make_iterator(
     246             :           insert_ref_(*first,hint.get_node()).first);
     247             :         ++hint;
     248             :       }
     249             :     }
     250             :     BOOST_CATCH(...){
     251             :       clear_();
     252             :       BOOST_RETHROW;
     253             :     }
     254             :     BOOST_CATCH_END
     255             :   }
     256             : 
     257             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
     258             :   multi_index_container(
     259             :     std::initializer_list<Value> list,
     260             :     const ctor_args_list& args_list=ctor_args_list(),
     261             :     const allocator_type& al=allocator_type()):
     262             :     bfm_allocator(al),
     263             :     super(args_list,bfm_allocator::member),
     264             :     node_count(0)
     265             :   {
     266             :     BOOST_MULTI_INDEX_CHECK_INVARIANT;
     267             :     BOOST_TRY{
     268             :       typedef const Value* init_iterator;
     269             : 
     270             :       iterator hint=super::end();
     271             :       for(init_iterator first=list.begin(),last=list.end();
     272             :           first!=last;++first){
     273             :         hint=super::make_iterator(insert_(*first,hint.get_node()).first);
     274             :         ++hint;
     275             :       }
     276             :     }
     277             :     BOOST_CATCH(...){
     278             :       clear_();
     279             :       BOOST_RETHROW;
     280             :     }
     281             :     BOOST_CATCH_END
     282             :   }
     283             : #endif
     284             : 
     285             :   multi_index_container(
     286             :     const multi_index_container<Value,IndexSpecifierList,Allocator>& x):
     287             :     bfm_allocator(
     288             :       node_alloc_traits::select_on_container_copy_construction(
     289             :         x.bfm_allocator::member)),
     290             :     bfm_header(),
     291             :     super(x),
     292             :     node_count(0)
     293             :   {
     294             :     copy_construct_from(x);
     295             :   }
     296             : 
     297             :   multi_index_container(BOOST_RV_REF(multi_index_container) x):
     298             :     bfm_allocator(boost::move(x.bfm_allocator::member)),
     299             :     bfm_header(),
     300             :     super(x,detail::do_not_copy_elements_tag()),
     301             :     node_count(0)
     302             :   {
     303             :     BOOST_MULTI_INDEX_CHECK_INVARIANT;
     304             :     BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x);
     305             :     swap_elements_(x);
     306             :   }
     307             : 
     308             :   multi_index_container(
     309             :     const multi_index_container<Value,IndexSpecifierList,Allocator>& x,
     310             :     const allocator_type& al):
     311             :     bfm_allocator(al),
     312             :     bfm_header(),
     313             :     super(x),
     314             :     node_count(0)
     315             :   {
     316             :     copy_construct_from(x);
     317             :   }
     318             : 
     319             :   multi_index_container(
     320             :     BOOST_RV_REF(multi_index_container) x,const allocator_type& al):
     321             :     bfm_allocator(al),
     322             :     bfm_header(),
     323             :     super(x,detail::do_not_copy_elements_tag()),
     324             :     node_count(0)
     325             :   {
     326             :     BOOST_MULTI_INDEX_CHECK_INVARIANT;
     327             :     BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x);
     328             : 
     329             :     if(al==x.get_allocator()){
     330             :       swap_elements_(x);
     331             :     }
     332             :     else{
     333             :       multi_index_container y(x,al,detail::unequal_alloc_move_ctor_tag());
     334             :       swap_elements_(y);
     335             :     }
     336             :   }
     337             : 
     338      731730 :   ~multi_index_container()
     339      365865 :   {
     340      365865 :     delete_all_nodes_();
     341      731730 :   }
     342             : 
     343             : #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
     344             :   /* As per http://www.boost.org/doc/html/move/emulation_limitations.html
     345             :    * #move.emulation_limitations.assignment_operator
     346             :    */
     347             : 
     348             :   multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
     349             :     const multi_index_container<Value,IndexSpecifierList,Allocator>& x)
     350             :   {
     351             :     multi_index_container y(
     352             :       x,
     353             :       node_alloc_traits::propagate_on_container_copy_assignment::value?
     354             :         x.get_allocator():this->get_allocator());
     355             :     swap_(y,boost::true_type() /* swap_allocators */);
     356             :     return *this;
     357             :   }
     358             : #endif
     359             : 
     360             :   multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
     361             :     BOOST_COPY_ASSIGN_REF(multi_index_container) x)
     362             :   {
     363             :     multi_index_container y(
     364             :       x,
     365             :       node_alloc_traits::propagate_on_container_copy_assignment::value?
     366             :         x.get_allocator():this->get_allocator());
     367             :     swap_(y,boost::true_type() /* swap_allocators */);
     368             :     return *this;
     369             :   }
     370             : 
     371             :   multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
     372             :     BOOST_RV_REF(multi_index_container) x)
     373             :   {
     374             : #include <boost/multi_index/detail/define_if_constexpr_macro.hpp>
     375             : 
     376             :     BOOST_MULTI_INDEX_IF_CONSTEXPR(
     377             :       node_alloc_traits::propagate_on_container_move_assignment::value){
     378             :       swap_(x,boost::true_type() /* swap_allocators */);
     379             :     }
     380             :     else if(this->get_allocator()==x.get_allocator()){
     381             :       swap_(x,boost::false_type() /* swap_allocators */);
     382             :     }
     383             :     else{
     384             :       multi_index_container y(boost::move(x),this->get_allocator());
     385             :       swap_(y,boost::false_type() /* swap_allocators */);
     386             :     }
     387             :     return *this;
     388             : 
     389             : #include <boost/multi_index/detail/undef_if_constexpr_macro.hpp>
     390             :   }
     391             : 
     392             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
     393             :   multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
     394             :     std::initializer_list<Value> list)
     395             :   {
     396             :     BOOST_MULTI_INDEX_CHECK_INVARIANT;
     397             :     typedef const Value* init_iterator;
     398             : 
     399             :     multi_index_container x(*this,detail::do_not_copy_elements_tag());    
     400             :     iterator hint=x.end();
     401             :     for(init_iterator first=list.begin(),last=list.end();
     402             :         first!=last;++first){
     403             :       hint=x.make_iterator(x.insert_(*first,hint.get_node()).first);
     404             :       ++hint;
     405             :     }
     406             :     x.swap_elements_(*this);
     407             :     return*this;
     408             :   }
     409             : #endif
     410             : 
     411         444 :   allocator_type get_allocator()const BOOST_NOEXCEPT
     412             :   {
     413         444 :     return allocator_type(bfm_allocator::member);
     414             :   }
     415             : 
     416             :   /* retrieval of indices by number */
     417             : 
     418             : #if !defined(BOOST_NO_MEMBER_TEMPLATES)
     419             :   template<int N>
     420             :   struct nth_index
     421             :   {
     422             :     BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
     423             :     typedef typename mpl::at_c<index_type_list,N>::type type;
     424             :   };
     425             : 
     426             :   template<int N>
     427             :   typename nth_index<N>::type& get()BOOST_NOEXCEPT
     428             :   {
     429             :     BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
     430             :     return *this;
     431             :   }
     432             : 
     433             :   template<int N>
     434             :   const typename nth_index<N>::type& get()const BOOST_NOEXCEPT
     435             :   {
     436             :     BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
     437             :     return *this;
     438             :   }
     439             : #endif
     440             : 
     441             :   /* retrieval of indices by tag */
     442             : 
     443             : #if !defined(BOOST_NO_MEMBER_TEMPLATES)
     444             :   template<typename Tag>
     445             :   struct index
     446             :   {
     447             :     typedef typename mpl::find_if<
     448             :       index_type_list,
     449             :       detail::has_tag<Tag>
     450             :     >::type                                    iter;
     451             : 
     452             :     BOOST_STATIC_CONSTANT(
     453             :       bool,index_found=!(is_same<iter,typename mpl::end<index_type_list>::type >::value));
     454             :     BOOST_STATIC_ASSERT(index_found);
     455             : 
     456             :     typedef typename mpl::deref<iter>::type    type;
     457             :   };
     458             : 
     459             :   template<typename Tag>
     460      224257 :   typename index<Tag>::type& get()BOOST_NOEXCEPT
     461             :   {
     462      224257 :     return *this;
     463             :   }
     464             : 
     465             :   template<typename Tag>
     466      303538 :   const typename index<Tag>::type& get()const BOOST_NOEXCEPT
     467             :   {
     468      303538 :     return *this;
     469             :   }
     470             : #endif
     471             : 
     472             :   /* projection of iterators by number */
     473             : 
     474             : #if !defined(BOOST_NO_MEMBER_TEMPLATES)
     475             :   template<int N>
     476             :   struct nth_index_iterator
     477             :   {
     478             :     typedef typename nth_index<N>::type::iterator type;
     479             :   };
     480             : 
     481             :   template<int N>
     482             :   struct nth_index_const_iterator
     483             :   {
     484             :     typedef typename nth_index<N>::type::const_iterator type;
     485             :   };
     486             : 
     487             :   template<int N,typename IteratorType>
     488          18 :   typename nth_index_iterator<N>::type project(IteratorType it)
     489             :   {
     490             :     typedef typename nth_index<N>::type index_type;
     491             : 
     492             : #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
     493             :     BOOST_STATIC_ASSERT(
     494             :       (mpl::contains<iterator_type_list,IteratorType>::value));
     495             : #endif
     496             : 
     497             :     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
     498             :     BOOST_MULTI_INDEX_CHECK_BELONGS_IN_SOME_INDEX(it,*this);
     499          36 :     return index_type::make_iterator(
     500          18 :       static_cast<final_node_type*>(it.get_node()));
     501             :   }
     502             : 
     503             :   template<int N,typename IteratorType>
     504       83150 :   typename nth_index_const_iterator<N>::type project(IteratorType it)const
     505             :   {
     506             :     typedef typename nth_index<N>::type index_type;
     507             : 
     508             : #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
     509             :     BOOST_STATIC_ASSERT((
     510             :       mpl::contains<iterator_type_list,IteratorType>::value||
     511             :       mpl::contains<const_iterator_type_list,IteratorType>::value));
     512             : #endif
     513             : 
     514             :     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
     515             :     BOOST_MULTI_INDEX_CHECK_BELONGS_IN_SOME_INDEX(it,*this);
     516      166300 :     return index_type::make_iterator(
     517       83150 :       static_cast<final_node_type*>(it.get_node()));
     518             :   }
     519             : #endif
     520             : 
     521             :   /* projection of iterators by tag */
     522             : 
     523             : #if !defined(BOOST_NO_MEMBER_TEMPLATES)
     524             :   template<typename Tag>
     525             :   struct index_iterator
     526             :   {
     527             :     typedef typename index<Tag>::type::iterator type;
     528             :   };
     529             : 
     530             :   template<typename Tag>
     531             :   struct index_const_iterator
     532             :   {
     533             :     typedef typename index<Tag>::type::const_iterator type;
     534             :   };
     535             : 
     536             :   template<typename Tag,typename IteratorType>
     537             :   typename index_iterator<Tag>::type project(IteratorType it)
     538             :   {
     539             :     typedef typename index<Tag>::type index_type;
     540             : 
     541             : #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
     542             :     BOOST_STATIC_ASSERT(
     543             :       (mpl::contains<iterator_type_list,IteratorType>::value));
     544             : #endif
     545             : 
     546             :     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
     547             :     BOOST_MULTI_INDEX_CHECK_BELONGS_IN_SOME_INDEX(it,*this);
     548             :     return index_type::make_iterator(
     549             :       static_cast<final_node_type*>(it.get_node()));
     550             :   }
     551             : 
     552             :   template<typename Tag,typename IteratorType>
     553             :   typename index_const_iterator<Tag>::type project(IteratorType it)const
     554             :   {
     555             :     typedef typename index<Tag>::type index_type;
     556             : 
     557             : #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
     558             :     BOOST_STATIC_ASSERT((
     559             :       mpl::contains<iterator_type_list,IteratorType>::value||
     560             :       mpl::contains<const_iterator_type_list,IteratorType>::value));
     561             : #endif
     562             : 
     563             :     BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
     564             :     BOOST_MULTI_INDEX_CHECK_BELONGS_IN_SOME_INDEX(it,*this);
     565             :     return index_type::make_iterator(
     566             :       static_cast<final_node_type*>(it.get_node()));
     567             :   }
     568             : #endif
     569             : 
     570             : BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
     571             :   typedef typename super::final_node_handle_type final_node_handle_type;
     572             :   typedef typename super::copy_map_type          copy_map_type;
     573             : 
     574             :   multi_index_container(
     575             :     multi_index_container<Value,IndexSpecifierList,Allocator>& x,
     576             :     const allocator_type& al,
     577             :     detail::unequal_alloc_move_ctor_tag):
     578             :     bfm_allocator(al),
     579             :     bfm_header(),
     580             :     super(x),
     581             :     node_count(0)
     582             :   {
     583             :     BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x);
     584             :     BOOST_TRY{
     585             :       copy_map_type map(bfm_allocator::member,x.size(),x.header(),header());
     586             :       for(const_iterator it=x.begin(),it_end=x.end();it!=it_end;++it){
     587             :         map.move_clone(it.get_node());
     588             :       }
     589             :       super::copy_(x,map);
     590             :       map.release();
     591             :       node_count=x.size();
     592             :       x.clear();
     593             :     }
     594             :     BOOST_CATCH(...){
     595             :       x.clear();
     596             :       BOOST_RETHROW;
     597             :     }
     598             :     BOOST_CATCH_END
     599             : 
     600             :     /* Not until this point are the indices required to be consistent,
     601             :      * hence the position of the invariant checker.
     602             :      */
     603             : 
     604             :     BOOST_MULTI_INDEX_CHECK_INVARIANT;
     605             :   }
     606             : 
     607             : #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
     608             :   multi_index_container(
     609             :     const multi_index_container<Value,IndexSpecifierList,Allocator>& x,
     610             :     detail::do_not_copy_elements_tag):
     611             :     bfm_allocator(x.bfm_allocator::member),
     612             :     bfm_header(),
     613             :     super(x,detail::do_not_copy_elements_tag()),
     614             :     node_count(0)
     615             :   {
     616             :     BOOST_MULTI_INDEX_CHECK_INVARIANT;
     617             :   }
     618             : #endif
     619             : 
     620             :   void copy_construct_from(
     621             :     const multi_index_container<Value,IndexSpecifierList,Allocator>& x)
     622             :   {
     623             :     copy_map_type map(bfm_allocator::member,x.size(),x.header(),header());
     624             :     for(const_iterator it=x.begin(),it_end=x.end();it!=it_end;++it){
     625             :       map.copy_clone(it.get_node());
     626             :     }
     627             :     super::copy_(x,map);
     628             :     map.release();
     629             :     node_count=x.size();
     630             : 
     631             :     /* Not until this point are the indices required to be consistent,
     632             :      * hence the position of the invariant checker.
     633             :      */
     634             : 
     635             :     BOOST_MULTI_INDEX_CHECK_INVARIANT;
     636             :   }
     637             : 
     638    94668728 :   final_node_type* header()const
     639             :   {
     640    94668728 :     return &*bfm_header::member;
     641             :   }
     642             : 
     643      470088 :   final_node_type* allocate_node()
     644             :   {
     645      470088 :     return &*node_alloc_traits::allocate(bfm_allocator::member,1);
     646             :   }
     647             : 
     648      470088 :   void deallocate_node(final_node_type* x)
     649             :   {
     650      470088 :     node_alloc_traits::deallocate(
     651      470088 :       bfm_allocator::member,static_cast<node_pointer>(x),1);
     652      470088 :   }
     653             : 
     654       40507 :   void construct_value(final_node_type* x,const Value& v)
     655             :   {
     656       40507 :     node_alloc_traits::construct(
     657       40507 :       bfm_allocator::member,boost::addressof(x->value()),v);
     658       40507 :   }
     659             : 
     660             :   void construct_value(final_node_type* x,BOOST_RV_REF(Value) v)
     661             :   {
     662             :     node_alloc_traits::construct(
     663             :       bfm_allocator::member,boost::addressof(x->value()),boost::move(v));
     664             :   }
     665             : 
     666       63716 :   BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
     667             :     void,construct_value,vartempl_construct_value_impl,final_node_type*,x)
     668             : 
     669      104223 :   void destroy_value(final_node_type* x)
     670             :   {
     671      104223 :     node_alloc_traits::destroy(
     672      104223 :       bfm_allocator::member,boost::addressof(x->value()));
     673      104223 :   }
     674             : 
     675      635142 :   bool empty_()const
     676             :   {
     677      635142 :     return node_count==0;
     678             :   }
     679             : 
     680    16656327 :   size_type size_()const
     681             :   {
     682    16656327 :     return node_count;
     683             :   }
     684             : 
     685             :   size_type max_size_()const
     686             :   {
     687             :     return static_cast<size_type>(-1);
     688             :   }
     689             : 
     690             :   template<typename Variant>
     691       40507 :   std::pair<final_node_type*,bool> insert_(const Value& v,Variant variant)
     692             :   {
     693       40507 :     final_node_type* x=0;
     694       40507 :     final_node_type* res=super::insert_(v,x,variant);
     695       40507 :     if(res==x){
     696       40507 :       ++node_count;
     697       40507 :       return std::pair<final_node_type*,bool>(res,true);
     698             :     }
     699             :     else{
     700           0 :       return std::pair<final_node_type*,bool>(res,false);
     701             :     }
     702       40507 :   }
     703             : 
     704       40507 :   std::pair<final_node_type*,bool> insert_(const Value& v)
     705             :   {
     706       40507 :     return insert_(v,detail::lvalue_tag());
     707             :   }
     708             : 
     709             :   std::pair<final_node_type*,bool> insert_rv_(const Value& v)
     710             :   {
     711             :     return insert_(v,detail::rvalue_tag());
     712             :   }
     713             : 
     714             :   template<typename T>
     715             :   std::pair<final_node_type*,bool> insert_ref_(T& t)
     716             :   {
     717             :     final_node_type* x=allocate_node();
     718             :     BOOST_TRY{
     719             :       construct_value(x,t);
     720             :       BOOST_TRY{
     721             :         final_node_type* res=super::insert_(
     722             :           x->value(),x,detail::emplaced_tag());
     723             :         if(res==x){
     724             :           ++node_count;
     725             :           return std::pair<final_node_type*,bool>(res,true);
     726             :         }
     727             :         else{
     728             :           delete_node_(x);
     729             :           return std::pair<final_node_type*,bool>(res,false);
     730             :         }
     731             :       }
     732             :       BOOST_CATCH(...){
     733             :         destroy_value(x);
     734             :         BOOST_RETHROW;
     735             :       }
     736             :       BOOST_CATCH_END
     737             :     }
     738             :     BOOST_CATCH(...){
     739             :       deallocate_node(x);
     740             :       BOOST_RETHROW;
     741             :     }
     742             :     BOOST_CATCH_END
     743             :   }
     744             : 
     745             :   std::pair<final_node_type*,bool> insert_ref_(const value_type& x)
     746             :   {
     747             :     return insert_(x);
     748             :   }
     749             : 
     750             :   std::pair<final_node_type*,bool> insert_ref_(value_type& x)
     751             :   {
     752             :     return insert_(x);
     753             :   }
     754             : 
     755             :   std::pair<final_node_type*,bool> insert_nh_(final_node_handle_type& nh)
     756             :   {
     757             :     if(!nh)return std::pair<final_node_type*,bool>(header(),false);
     758             :     else{
     759             :       final_node_type* x=nh.node;
     760             :       final_node_type* res=super::insert_(
     761             :         x->value(),x,detail::emplaced_tag());
     762             :       if(res==x){
     763             :         nh.release_node();
     764             :         ++node_count;
     765             :         return std::pair<final_node_type*,bool>(res,true);
     766             :       }
     767             :       else return std::pair<final_node_type*,bool>(res,false);
     768             :     }
     769             :   }
     770             : 
     771             :   template<typename Index>
     772             :   std::pair<final_node_type*,bool> transfer_(Index& x,final_node_type* n)
     773             :   {
     774             :     final_node_type* res=super::insert_(n->value(),n,&super::final(x));
     775             :     if(res==n){
     776             :       ++node_count;
     777             :       return std::pair<final_node_type*,bool>(res,true);
     778             :     }
     779             :     else{
     780             :       return std::pair<final_node_type*,bool>(res,false);
     781             :     }
     782             :   }
     783             : 
     784             :   template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
     785       63716 :   std::pair<final_node_type*,bool> emplace_(
     786             :     BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
     787             :   {
     788       63716 :     final_node_type* x=allocate_node();
     789             :     BOOST_TRY{
     790       63716 :       construct_value(x,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
     791             :       BOOST_TRY{
     792      127432 :         final_node_type* res=super::insert_(
     793       63716 :           x->value(),x,detail::emplaced_tag());
     794       63716 :         if(res==x){
     795       63716 :           ++node_count;
     796       63716 :           return std::pair<final_node_type*,bool>(res,true);
     797             :         }
     798             :         else{
     799           0 :           delete_node_(x);
     800           0 :           return std::pair<final_node_type*,bool>(res,false);
     801             :         }
     802           0 :       }
     803             :       BOOST_CATCH(...){
     804           0 :         destroy_value(x);
     805           0 :         BOOST_RETHROW;
     806           0 :       }
     807             :       BOOST_CATCH_END
     808           0 :     }
     809             :     BOOST_CATCH(...){
     810           0 :       deallocate_node(x);
     811           0 :       BOOST_RETHROW;
     812           0 :     }
     813             :     BOOST_CATCH_END
     814       63716 :   }
     815             : 
     816             :   template<typename Variant>
     817             :   std::pair<final_node_type*,bool> insert_(
     818             :     const Value& v,final_node_type* position,Variant variant)
     819             :   {
     820             :     final_node_type* x=0;
     821             :     final_node_type* res=super::insert_(v,position,x,variant);
     822             :     if(res==x){
     823             :       ++node_count;
     824             :       return std::pair<final_node_type*,bool>(res,true);
     825             :     }
     826             :     else{
     827             :       return std::pair<final_node_type*,bool>(res,false);
     828             :     }
     829             :   }
     830             : 
     831             :   std::pair<final_node_type*,bool> insert_(
     832             :     const Value& v,final_node_type* position)
     833             :   {
     834             :     return insert_(v,position,detail::lvalue_tag());
     835             :   }
     836             : 
     837             :   std::pair<final_node_type*,bool> insert_rv_(
     838             :     const Value& v,final_node_type* position)
     839             :   {
     840             :     return insert_(v,position,detail::rvalue_tag());
     841             :   }
     842             : 
     843             :   template<typename T>
     844             :   std::pair<final_node_type*,bool> insert_ref_(
     845             :     T& t,final_node_type* position)
     846             :   {
     847             :     final_node_type* x=allocate_node();
     848             :     BOOST_TRY{
     849             :       construct_value(x,t);
     850             :       BOOST_TRY{
     851             :         final_node_type* res=super::insert_(
     852             :           x->value(),position,x,detail::emplaced_tag());
     853             :         if(res==x){
     854             :           ++node_count;
     855             :           return std::pair<final_node_type*,bool>(res,true);
     856             :         }
     857             :         else{
     858             :           delete_node_(x);
     859             :           return std::pair<final_node_type*,bool>(res,false);
     860             :         }
     861             :       }
     862             :       BOOST_CATCH(...){
     863             :         destroy_value(x);
     864             :         BOOST_RETHROW;
     865             :       }
     866             :       BOOST_CATCH_END
     867             :     }
     868             :     BOOST_CATCH(...){
     869             :       deallocate_node(x);
     870             :       BOOST_RETHROW;
     871             :     }
     872             :     BOOST_CATCH_END
     873             :   }
     874             : 
     875             :   std::pair<final_node_type*,bool> insert_ref_(
     876             :     const value_type& x,final_node_type* position)
     877             :   {
     878             :     return insert_(x,position);
     879             :   }
     880             : 
     881             :   std::pair<final_node_type*,bool> insert_ref_(
     882             :     value_type& x,final_node_type* position)
     883             :   {
     884             :     return insert_(x,position);
     885             :   }
     886             : 
     887             :   std::pair<final_node_type*,bool> insert_nh_(
     888             :     final_node_handle_type& nh,final_node_type* position)
     889             :   {
     890             :     if(!nh)return std::pair<final_node_type*,bool>(header(),false);
     891             :     else{
     892             :       final_node_type* x=nh.node;
     893             :       final_node_type* res=super::insert_(
     894             :         x->value(),position,x,detail::emplaced_tag());
     895             :       if(res==x){
     896             :         nh.release_node();
     897             :         ++node_count;
     898             :         return std::pair<final_node_type*,bool>(res,true);
     899             :       }
     900             :       else return std::pair<final_node_type*,bool>(res,false);
     901             :     }
     902             :   }
     903             : 
     904             :   template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
     905             :   std::pair<final_node_type*,bool> emplace_hint_(
     906             :     final_node_type* position,
     907             :     BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
     908             :   {
     909             :     final_node_type* x=allocate_node();
     910             :     BOOST_TRY{
     911             :       construct_value(x,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
     912             :       BOOST_TRY{
     913             :         final_node_type* res=super::insert_(
     914             :           x->value(),position,x,detail::emplaced_tag());
     915             :         if(res==x){
     916             :           ++node_count;
     917             :           return std::pair<final_node_type*,bool>(res,true);
     918             :         }
     919             :         else{
     920             :           delete_node_(x);
     921             :           return std::pair<final_node_type*,bool>(res,false);
     922             :         }
     923             :       }
     924             :       BOOST_CATCH(...){
     925             :         destroy_value(x);
     926             :         BOOST_RETHROW;
     927             :       }
     928             :       BOOST_CATCH_END
     929             :     }
     930             :     BOOST_CATCH(...){
     931             :       deallocate_node(x);
     932             :       BOOST_RETHROW;
     933             :     }
     934             :     BOOST_CATCH_END
     935             :   }
     936             : 
     937             :   final_node_handle_type extract_(final_node_type* x)
     938             :   {
     939             :     --node_count;
     940             :     super::extract_(x,detail::invalidate_iterators());
     941             :     return final_node_handle_type(x,get_allocator());
     942             :   }
     943             : 
     944             :   template<typename Dst>
     945             :   void extract_for_transfer_(final_node_type* x,Dst dst)
     946             :   {
     947             :     --node_count;
     948             :     super::extract_(x,dst);
     949             :   }
     950             : 
     951       72132 :   void erase_(final_node_type* x)
     952             :   {
     953       72132 :     --node_count;
     954       72132 :     super::extract_(x,detail::invalidate_iterators());
     955       72132 :     delete_node_(x);
     956       72132 :   }
     957             : 
     958      104223 :   void delete_node_(final_node_type* x)
     959             :   {
     960      104223 :     destroy_value(x);
     961      104223 :     deallocate_node(x);
     962      104223 :   }
     963             : 
     964      399022 :   void delete_all_nodes_()
     965             :   {
     966      399022 :     super::delete_all_nodes_();
     967      399022 :   }
     968             : 
     969       33157 :   void clear_()
     970             :   {
     971       33157 :     delete_all_nodes_();
     972       33157 :     super::clear_();
     973       33157 :     node_count=0;
     974       33157 :   }
     975             : 
     976             :   template<typename Index>
     977             :   void transfer_range_(
     978             :     Index& x,
     979             :     BOOST_DEDUCED_TYPENAME Index::iterator first,
     980             :     BOOST_DEDUCED_TYPENAME Index::iterator last)
     981             :   {
     982             :     while(first!=last){
     983             :       transfer_(x,static_cast<final_node_type*>((first++).get_node()));
     984             :     }
     985             :   }
     986             : 
     987             :   void swap_(multi_index_container<Value,IndexSpecifierList,Allocator>& x)
     988             :   {
     989             :     swap_(
     990             :       x,
     991             :       boost::integral_constant<
     992             :         bool,node_alloc_traits::propagate_on_container_swap::value>());
     993             :   }
     994             : 
     995             :   void swap_(
     996             :     multi_index_container<Value,IndexSpecifierList,Allocator>& x,
     997             :     boost::true_type swap_allocators)
     998             :   {
     999             :     detail::adl_swap(bfm_allocator::member,x.bfm_allocator::member);
    1000             :     std::swap(bfm_header::member,x.bfm_header::member);
    1001             :     super::swap_(x,swap_allocators);
    1002             :     std::swap(node_count,x.node_count);
    1003             :   }
    1004             : 
    1005             :   void swap_(
    1006             :     multi_index_container<Value,IndexSpecifierList,Allocator>& x,
    1007             :     boost::false_type swap_allocators)
    1008             :   {
    1009             :     std::swap(bfm_header::member,x.bfm_header::member);
    1010             :     super::swap_(x,swap_allocators);
    1011             :     std::swap(node_count,x.node_count);
    1012             :   }
    1013             : 
    1014             :   void swap_elements_(
    1015             :     multi_index_container<Value,IndexSpecifierList,Allocator>& x)
    1016             :   {
    1017             :     std::swap(bfm_header::member,x.bfm_header::member);
    1018             :     super::swap_elements_(x);
    1019             :     std::swap(node_count,x.node_count);
    1020             :   }
    1021             : 
    1022             :   bool replace_(const Value& k,final_node_type* x)
    1023             :   {
    1024             :     return super::replace_(k,x,detail::lvalue_tag());
    1025             :   }
    1026             : 
    1027             :   bool replace_rv_(const Value& k,final_node_type* x)
    1028             :   {
    1029             :     return super::replace_(k,x,detail::rvalue_tag());
    1030             :   }
    1031             : 
    1032             :   template<typename Modifier>
    1033     1848485 :   bool modify_(Modifier& mod,final_node_type* x)
    1034             :   {
    1035             :     BOOST_TRY{
    1036     1848485 :       mod(const_cast<value_type&>(x->value()));
    1037     1848485 :     }
    1038             :     BOOST_CATCH(...){
    1039           0 :       this->erase_(x);
    1040           0 :       BOOST_RETHROW;
    1041           0 :     }
    1042             :     BOOST_CATCH_END
    1043             : 
    1044             :     BOOST_TRY{
    1045     1848485 :       if(!super::modify_(x)){
    1046           0 :         delete_node_(x);
    1047           0 :         --node_count;
    1048           0 :         return false;
    1049             :       }
    1050     1848485 :       else return true;
    1051           0 :     }
    1052             :     BOOST_CATCH(...){
    1053           0 :       delete_node_(x);
    1054           0 :       --node_count;
    1055           0 :       BOOST_RETHROW;
    1056           0 :     }
    1057             :     BOOST_CATCH_END
    1058     1848485 :   }
    1059             : 
    1060             :   template<typename Modifier,typename Rollback>
    1061             :   bool modify_(Modifier& mod,Rollback& back_,final_node_type* x)
    1062             :   {
    1063             :     BOOST_TRY{
    1064             :       mod(const_cast<value_type&>(x->value()));
    1065             :     }
    1066             :     BOOST_CATCH(...){
    1067             :       this->erase_(x);
    1068             :       BOOST_RETHROW;
    1069             :     }
    1070             :     BOOST_CATCH_END
    1071             : 
    1072             :     bool b;
    1073             :     BOOST_TRY{
    1074             :       b=super::modify_rollback_(x);
    1075             :     }
    1076             :     BOOST_CATCH(...){
    1077             :       BOOST_TRY{
    1078             :         back_(const_cast<value_type&>(x->value()));
    1079             :         if(!super::check_rollback_(x))this->erase_(x);
    1080             :         BOOST_RETHROW;
    1081             :       }
    1082             :       BOOST_CATCH(...){
    1083             :         this->erase_(x);
    1084             :         BOOST_RETHROW;
    1085             :       }
    1086             :       BOOST_CATCH_END
    1087             :     }
    1088             :     BOOST_CATCH_END
    1089             : 
    1090             :     BOOST_TRY{
    1091             :       if(!b){
    1092             :         back_(const_cast<value_type&>(x->value()));
    1093             :         if(!super::check_rollback_(x))this->erase_(x);
    1094             :         return false;
    1095             :       }
    1096             :       else return true;
    1097             :     }
    1098             :     BOOST_CATCH(...){
    1099             :       this->erase_(x);
    1100             :       BOOST_RETHROW;
    1101             :     }
    1102             :     BOOST_CATCH_END
    1103             :   }
    1104             : 
    1105             : #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
    1106             :   /* serialization */
    1107             : 
    1108             :   friend class boost::serialization::access;
    1109             : 
    1110             :   template<class Archive>
    1111             :   void serialize(Archive& ar,const unsigned int version)
    1112             :   {
    1113             :     core::split_member(ar,*this,version);
    1114             :   }
    1115             : 
    1116             :   typedef typename super::index_saver_type        index_saver_type;
    1117             :   typedef typename super::index_loader_type       index_loader_type;
    1118             : 
    1119             :   template<class Archive>
    1120             :   void save(Archive& ar,const unsigned int version)const
    1121             :   {
    1122             :     const std::size_t                               s(size_());
    1123             :     const detail::serialization_version<value_type> value_version;
    1124             :     ar<<core::make_nvp("count",s);
    1125             :     ar<<core::make_nvp("value_version",value_version);
    1126             : 
    1127             :     index_saver_type sm(bfm_allocator::member,s);
    1128             : 
    1129             :     for(iterator it=super::begin(),it_end=super::end();it!=it_end;++it){
    1130             :       core::save_construct_data_adl(
    1131             :         ar,boost::addressof(*it),value_version);
    1132             :       ar<<serialization::make_nvp("item",*it);
    1133             :       sm.add(it.get_node(),ar,version);
    1134             :     }
    1135             :     sm.add_track(header(),ar,version);
    1136             : 
    1137             :     super::save_(ar,version,sm);
    1138             :   }
    1139             : 
    1140             :   template<class Archive>
    1141             :   void load(Archive& ar,const unsigned int version)
    1142             :   {
    1143             :     BOOST_MULTI_INDEX_CHECK_INVARIANT;
    1144             : 
    1145             :     clear_(); 
    1146             :     std::size_t                               s;
    1147             :     detail::serialization_version<value_type> value_version;
    1148             :     if(version<1){
    1149             :       std::size_t sz;
    1150             :       ar>>core::make_nvp("count",sz);
    1151             :       s=static_cast<std::size_t>(sz);
    1152             :     }
    1153             :     else if(version<3){
    1154             : #if defined(BOOST_MULTI_INDEX_ENABLE_SERIALIZATION_COMPATIBILITY_V2)
    1155             :       serialization::collection_size_type csz;
    1156             :       ar>>core::make_nvp("count",csz);
    1157             :       s=static_cast<std::size_t>(csz);
    1158             : #else
    1159             :       ar>>core::make_nvp("count",s);
    1160             : #endif
    1161             :     }
    1162             :     else if(version<4){
    1163             :       unsigned long ul;
    1164             :       ar>>core::make_nvp("count",ul);
    1165             :       s=static_cast<std::size_t>(ul);
    1166             :     }
    1167             :     else{
    1168             :       ar>>core::make_nvp("count",s);
    1169             :     }
    1170             : 
    1171             :     if(version<2){
    1172             :       value_version=0;
    1173             :     }
    1174             :     else{
    1175             :       ar>>core::make_nvp("value_version",value_version);
    1176             :     }
    1177             : 
    1178             :     index_loader_type lm(bfm_allocator::member,s);
    1179             : 
    1180             :     for(std::size_t n=0;n<s;++n){
    1181             :       detail::archive_constructed<Value> value("item",ar,value_version);
    1182             :       std::pair<final_node_type*,bool> p=insert_rv_(
    1183             :         value.get(),super::end().get_node());
    1184             :       if(!p.second)throw_exception(detail::bad_archive_exception());
    1185             :       ar.reset_object_address(
    1186             :         boost::addressof(p.first->value()),boost::addressof(value.get()));
    1187             :       lm.add(p.first,ar,version);
    1188             :     }
    1189             :     lm.add_track(header(),ar,version);
    1190             : 
    1191             :     super::load_(ar,version,lm);
    1192             :   }
    1193             : #endif
    1194             : 
    1195             : #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
    1196             :   /* invariant stuff */
    1197             : 
    1198             :   bool invariant_()const
    1199             :   {
    1200             :     return super::invariant_();
    1201             :   }
    1202             : 
    1203             :   void check_invariant_()const
    1204             :   {
    1205             :     BOOST_MULTI_INDEX_INVARIANT_ASSERT(invariant_());
    1206             :   }
    1207             : #endif
    1208             : 
    1209             : private:
    1210             :   template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
    1211       63716 :   void vartempl_construct_value_impl(
    1212             :     final_node_type* x,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
    1213             :   {
    1214       63716 :     node_alloc_traits::construct(
    1215       63716 :       bfm_allocator::member,boost::addressof(x->value()),
    1216       63716 :       BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
    1217       63716 :   }
    1218             : 
    1219             :   size_type node_count;
    1220             : 
    1221             : #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
    1222             :     BOOST_WORKAROUND(__MWERKS__,<=0x3003)
    1223             : #pragma parse_mfunc_templ reset
    1224             : #endif
    1225             : };
    1226             : 
    1227             : #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
    1228             : #pragma warning(pop) /* C4522 */
    1229             : #endif
    1230             : 
    1231             : /* retrieval of indices by number */
    1232             : 
    1233             : template<typename MultiIndexContainer,int N>
    1234             : struct nth_index
    1235             : {
    1236             :   BOOST_STATIC_CONSTANT(
    1237             :     int,
    1238             :     M=mpl::size<typename MultiIndexContainer::index_type_list>::type::value);
    1239             :   BOOST_STATIC_ASSERT(N>=0&&N<M);
    1240             :   typedef typename mpl::at_c<
    1241             :     typename MultiIndexContainer::index_type_list,N>::type type;
    1242             : };
    1243             : 
    1244             : template<int N,typename Value,typename IndexSpecifierList,typename Allocator>
    1245             : typename nth_index<
    1246             :   multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type&
    1247             : get(
    1248             :   multi_index_container<Value,IndexSpecifierList,Allocator>& m)BOOST_NOEXCEPT
    1249             : {
    1250             :   typedef multi_index_container<
    1251             :     Value,IndexSpecifierList,Allocator>    multi_index_type;
    1252             :   typedef typename nth_index<
    1253             :     multi_index_container<
    1254             :       Value,IndexSpecifierList,Allocator>,
    1255             :     N
    1256             :   >::type                                  index_type;
    1257             : 
    1258             :   BOOST_STATIC_ASSERT(N>=0&&
    1259             :     N<
    1260             :     mpl::size<
    1261             :       BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list
    1262             :     >::type::value);
    1263             : 
    1264             :   return detail::converter<multi_index_type,index_type>::index(m);
    1265             : }
    1266             : 
    1267             : template<int N,typename Value,typename IndexSpecifierList,typename Allocator>
    1268             : const typename nth_index<
    1269             :   multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type&
    1270             : get(
    1271             :   const multi_index_container<Value,IndexSpecifierList,Allocator>& m
    1272             : )BOOST_NOEXCEPT
    1273             : {
    1274             :   typedef multi_index_container<
    1275             :     Value,IndexSpecifierList,Allocator>    multi_index_type;
    1276             :   typedef typename nth_index<
    1277             :     multi_index_container<
    1278             :       Value,IndexSpecifierList,Allocator>,
    1279             :     N
    1280             :   >::type                                  index_type;
    1281             : 
    1282             :   BOOST_STATIC_ASSERT(N>=0&&
    1283             :     N<
    1284             :     mpl::size<
    1285             :       BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list
    1286             :     >::type::value);
    1287             : 
    1288             :   return detail::converter<multi_index_type,index_type>::index(m);
    1289             : }
    1290             : 
    1291             : /* retrieval of indices by tag */
    1292             : 
    1293             : template<typename MultiIndexContainer,typename Tag>
    1294             : struct index
    1295             : {
    1296             :   typedef typename MultiIndexContainer::index_type_list index_type_list;
    1297             : 
    1298             :   typedef typename mpl::find_if<
    1299             :     index_type_list,
    1300             :     detail::has_tag<Tag>
    1301             :   >::type                                      iter;
    1302             : 
    1303             :   BOOST_STATIC_CONSTANT(
    1304             :     bool,index_found=!(is_same<iter,typename mpl::end<index_type_list>::type >::value));
    1305             :   BOOST_STATIC_ASSERT(index_found);
    1306             : 
    1307             :   typedef typename mpl::deref<iter>::type       type;
    1308             : };
    1309             : 
    1310             : template<
    1311             :   typename Tag,typename Value,typename IndexSpecifierList,typename Allocator
    1312             : >
    1313             : typename ::boost::multi_index::index<
    1314             :   multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type&
    1315             : get(
    1316             :   multi_index_container<Value,IndexSpecifierList,Allocator>& m)BOOST_NOEXCEPT
    1317             : {
    1318             :   typedef multi_index_container<
    1319             :     Value,IndexSpecifierList,Allocator>         multi_index_type;
    1320             :   typedef typename ::boost::multi_index::index<
    1321             :     multi_index_container<
    1322             :       Value,IndexSpecifierList,Allocator>,
    1323             :     Tag
    1324             :   >::type                                       index_type;
    1325             : 
    1326             :   return detail::converter<multi_index_type,index_type>::index(m);
    1327             : }
    1328             : 
    1329             : template<
    1330             :   typename Tag,typename Value,typename IndexSpecifierList,typename Allocator
    1331             : >
    1332             : const typename ::boost::multi_index::index<
    1333             :   multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type&
    1334             : get(
    1335             :   const multi_index_container<Value,IndexSpecifierList,Allocator>& m
    1336             : )BOOST_NOEXCEPT
    1337             : {
    1338             :   typedef multi_index_container<
    1339             :     Value,IndexSpecifierList,Allocator>         multi_index_type;
    1340             :   typedef typename ::boost::multi_index::index<
    1341             :     multi_index_container<
    1342             :       Value,IndexSpecifierList,Allocator>,
    1343             :     Tag
    1344             :   >::type                                       index_type;
    1345             : 
    1346             :   return detail::converter<multi_index_type,index_type>::index(m);
    1347             : }
    1348             : 
    1349             : /* projection of iterators by number */
    1350             : 
    1351             : template<typename MultiIndexContainer,int N>
    1352             : struct nth_index_iterator
    1353             : {
    1354             :   typedef typename nth_index<MultiIndexContainer,N>::type::iterator type;
    1355             : };
    1356             : 
    1357             : template<typename MultiIndexContainer,int N>
    1358             : struct nth_index_const_iterator
    1359             : {
    1360             :   typedef typename nth_index<MultiIndexContainer,N>::type::const_iterator type;
    1361             : };
    1362             : 
    1363             : template<
    1364             :   int N,typename IteratorType,
    1365             :   typename Value,typename IndexSpecifierList,typename Allocator>
    1366             : typename nth_index_iterator<
    1367             :   multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type
    1368             : project(
    1369             :   multi_index_container<Value,IndexSpecifierList,Allocator>& m,
    1370             :   IteratorType it)
    1371             : {
    1372             :   typedef multi_index_container<
    1373             :     Value,IndexSpecifierList,Allocator>                multi_index_type;
    1374             :   typedef typename nth_index<multi_index_type,N>::type index_type;
    1375             : 
    1376             : #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */
    1377             :   BOOST_STATIC_ASSERT((
    1378             :     mpl::contains<
    1379             :       BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
    1380             :       IteratorType>::value));
    1381             : #endif
    1382             : 
    1383             :   BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
    1384             :   BOOST_MULTI_INDEX_CHECK_BELONGS_IN_SOME_INDEX(it,m);
    1385             :   return detail::converter<multi_index_type,index_type>::iterator(
    1386             :     m,static_cast<typename multi_index_type::final_node_type*>(it.get_node()));
    1387             : }
    1388             : 
    1389             : template<
    1390             :   int N,typename IteratorType,
    1391             :   typename Value,typename IndexSpecifierList,typename Allocator>
    1392             : typename nth_index_const_iterator<
    1393             :   multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type
    1394             : project(
    1395             :   const multi_index_container<Value,IndexSpecifierList,Allocator>& m,
    1396             :   IteratorType it)
    1397             : {
    1398             :   typedef multi_index_container<
    1399             :     Value,IndexSpecifierList,Allocator>                multi_index_type;
    1400             :   typedef typename nth_index<multi_index_type,N>::type index_type;
    1401             : 
    1402             : #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */
    1403             :   BOOST_STATIC_ASSERT((
    1404             :     mpl::contains<
    1405             :       BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
    1406             :       IteratorType>::value||
    1407             :     mpl::contains<
    1408             :       BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list,
    1409             :       IteratorType>::value));
    1410             : #endif
    1411             : 
    1412             :   BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
    1413             :   BOOST_MULTI_INDEX_CHECK_BELONGS_IN_SOME_INDEX(it,m);
    1414             :   return detail::converter<multi_index_type,index_type>::const_iterator(
    1415             :     m,static_cast<typename multi_index_type::final_node_type*>(it.get_node()));
    1416             : }
    1417             : 
    1418             : /* projection of iterators by tag */
    1419             : 
    1420             : template<typename MultiIndexContainer,typename Tag>
    1421             : struct index_iterator
    1422             : {
    1423             :   typedef typename ::boost::multi_index::index<
    1424             :     MultiIndexContainer,Tag>::type::iterator    type;
    1425             : };
    1426             : 
    1427             : template<typename MultiIndexContainer,typename Tag>
    1428             : struct index_const_iterator
    1429             : {
    1430             :   typedef typename ::boost::multi_index::index<
    1431             :     MultiIndexContainer,Tag>::type::const_iterator type;
    1432             : };
    1433             : 
    1434             : template<
    1435             :   typename Tag,typename IteratorType,
    1436             :   typename Value,typename IndexSpecifierList,typename Allocator>
    1437             : typename index_iterator<
    1438             :   multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type
    1439             : project(
    1440             :   multi_index_container<Value,IndexSpecifierList,Allocator>& m,
    1441             :   IteratorType it)
    1442             : {
    1443             :   typedef multi_index_container<
    1444             :     Value,IndexSpecifierList,Allocator>         multi_index_type;
    1445             :   typedef typename ::boost::multi_index::index<
    1446             :     multi_index_type,Tag>::type                 index_type;
    1447             : 
    1448             : #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */
    1449             :   BOOST_STATIC_ASSERT((
    1450             :     mpl::contains<
    1451             :       BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
    1452             :       IteratorType>::value));
    1453             : #endif
    1454             : 
    1455             :   BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
    1456             :   BOOST_MULTI_INDEX_CHECK_BELONGS_IN_SOME_INDEX(it,m);
    1457             :   return detail::converter<multi_index_type,index_type>::iterator(
    1458             :     m,static_cast<typename multi_index_type::final_node_type*>(it.get_node()));
    1459             : }
    1460             : 
    1461             : template<
    1462             :   typename Tag,typename IteratorType,
    1463             :   typename Value,typename IndexSpecifierList,typename Allocator>
    1464             : typename index_const_iterator<
    1465             :   multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type
    1466             : project(
    1467             :   const multi_index_container<Value,IndexSpecifierList,Allocator>& m,
    1468             :   IteratorType it)
    1469             : {
    1470             :   typedef multi_index_container<
    1471             :     Value,IndexSpecifierList,Allocator>         multi_index_type;
    1472             :   typedef typename ::boost::multi_index::index<
    1473             :     multi_index_type,Tag>::type                 index_type;
    1474             : 
    1475             : #if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */
    1476             :   BOOST_STATIC_ASSERT((
    1477             :     mpl::contains<
    1478             :       BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
    1479             :       IteratorType>::value||
    1480             :     mpl::contains<
    1481             :       BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list,
    1482             :       IteratorType>::value));
    1483             : #endif
    1484             : 
    1485             :   BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
    1486             :   BOOST_MULTI_INDEX_CHECK_BELONGS_IN_SOME_INDEX(it,m);
    1487             :   return detail::converter<multi_index_type,index_type>::const_iterator(
    1488             :     m,static_cast<typename multi_index_type::final_node_type*>(it.get_node()));
    1489             : }
    1490             : 
    1491             : /* Comparison. Simple forward to first index. */
    1492             : 
    1493             : template<
    1494             :   typename Value1,typename IndexSpecifierList1,typename Allocator1,
    1495             :   typename Value2,typename IndexSpecifierList2,typename Allocator2
    1496             : >
    1497             : bool operator==(
    1498             :   const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
    1499             :   const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
    1500             : {
    1501             :   return get<0>(x)==get<0>(y);
    1502             : }
    1503             : 
    1504             : template<
    1505             :   typename Value1,typename IndexSpecifierList1,typename Allocator1,
    1506             :   typename Value2,typename IndexSpecifierList2,typename Allocator2
    1507             : >
    1508             : bool operator<(
    1509             :   const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
    1510             :   const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
    1511             : {
    1512             :   return get<0>(x)<get<0>(y);
    1513             : }
    1514             : 
    1515             : template<
    1516             :   typename Value1,typename IndexSpecifierList1,typename Allocator1,
    1517             :   typename Value2,typename IndexSpecifierList2,typename Allocator2
    1518             : >
    1519             : bool operator!=(
    1520             :   const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
    1521             :   const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
    1522             : {
    1523             :   return get<0>(x)!=get<0>(y);
    1524             : }
    1525             : 
    1526             : template<
    1527             :   typename Value1,typename IndexSpecifierList1,typename Allocator1,
    1528             :   typename Value2,typename IndexSpecifierList2,typename Allocator2
    1529             : >
    1530             : bool operator>(
    1531             :   const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
    1532             :   const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
    1533             : {
    1534             :   return get<0>(x)>get<0>(y);
    1535             : }
    1536             : 
    1537             : template<
    1538             :   typename Value1,typename IndexSpecifierList1,typename Allocator1,
    1539             :   typename Value2,typename IndexSpecifierList2,typename Allocator2
    1540             : >
    1541             : bool operator>=(
    1542             :   const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
    1543             :   const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
    1544             : {
    1545             :   return get<0>(x)>=get<0>(y);
    1546             : }
    1547             : 
    1548             : template<
    1549             :   typename Value1,typename IndexSpecifierList1,typename Allocator1,
    1550             :   typename Value2,typename IndexSpecifierList2,typename Allocator2
    1551             : >
    1552             : bool operator<=(
    1553             :   const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
    1554             :   const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
    1555             : {
    1556             :   return get<0>(x)<=get<0>(y);
    1557             : }
    1558             : 
    1559             : /*  specialized algorithms */
    1560             : 
    1561             : template<typename Value,typename IndexSpecifierList,typename Allocator>
    1562             : void swap(
    1563             :   multi_index_container<Value,IndexSpecifierList,Allocator>& x,
    1564             :   multi_index_container<Value,IndexSpecifierList,Allocator>& y)
    1565             : {
    1566             :   x.swap(y);
    1567             : }
    1568             : 
    1569             : } /* namespace multi_index */
    1570             : 
    1571             : #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
    1572             : /* class version = 1 : we now serialize the size through
    1573             :  * boost::serialization::collection_size_type.
    1574             :  * class version = 2 : proper use of {save|load}_construct_data.
    1575             :  * class version = 3 : dropped boost::serialization::collection_size_type
    1576             :  * in favor of unsigned long --this allows us to provide serialization
    1577             :  * support without including any header from Boost.Serialization.
    1578             :  * class version = 4 : uses std::size_t rather than unsigned long (which
    1579             :  * is smaller in LLP64 data models).
    1580             :  */
    1581             : 
    1582             : namespace serialization {
    1583             : template<typename Value,typename IndexSpecifierList,typename Allocator>
    1584             : struct version<
    1585             :   boost::multi_index_container<Value,IndexSpecifierList,Allocator>
    1586             : >
    1587             : {
    1588             :   BOOST_STATIC_CONSTANT(int,value=4);
    1589             : };
    1590             : } /* namespace serialization */
    1591             : #endif
    1592             : 
    1593             : /* Associated global functions are promoted to namespace boost, except
    1594             :  * comparison operators and swap, which are meant to be Koenig looked-up.
    1595             :  */
    1596             : 
    1597             : using multi_index::get;
    1598             : using multi_index::project;
    1599             : 
    1600             : } /* namespace boost */
    1601             : 
    1602             : #undef BOOST_MULTI_INDEX_CHECK_INVARIANT
    1603             : #undef BOOST_MULTI_INDEX_CHECK_INVARIANT_OF
    1604             : 
    1605             : #endif

Generated by: LCOV version 1.16