LCOV - code coverage report
Current view: top level - usr/include/boost - multi_index_container.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 28 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 2 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14