Blame boost/multi_index_container.hpp

Packit 58578d
/* Multiply indexed container.
Packit 58578d
 *
Packit 58578d
 * Copyright 2003-2017 Joaquin M Lopez Munoz.
Packit 58578d
 * Distributed under the Boost Software License, Version 1.0.
Packit 58578d
 * (See accompanying file LICENSE_1_0.txt or copy at
Packit 58578d
 * http://www.boost.org/LICENSE_1_0.txt)
Packit 58578d
 *
Packit 58578d
 * See http://www.boost.org/libs/multi_index for library home page.
Packit 58578d
 */
Packit 58578d
Packit 58578d
#ifndef BOOST_MULTI_INDEX_HPP
Packit 58578d
#define BOOST_MULTI_INDEX_HPP
Packit 58578d
Packit 58578d
#if defined(_MSC_VER)
Packit 58578d
#pragma once
Packit 58578d
#endif
Packit 58578d
Packit 58578d
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
Packit 58578d
#include <algorithm>
Packit 58578d
#include <boost/detail/allocator_utilities.hpp>
Packit 58578d
#include <boost/detail/no_exceptions_support.hpp>
Packit 58578d
#include <boost/detail/workaround.hpp>
Packit 58578d
#include <boost/move/core.hpp>
Packit 58578d
#include <boost/mpl/at.hpp>
Packit 58578d
#include <boost/mpl/contains.hpp>
Packit 58578d
#include <boost/mpl/find_if.hpp>
Packit 58578d
#include <boost/mpl/identity.hpp>
Packit 58578d
#include <boost/mpl/int.hpp>
Packit 58578d
#include <boost/mpl/size.hpp>
Packit 58578d
#include <boost/mpl/deref.hpp>
Packit 58578d
#include <boost/multi_index_container_fwd.hpp>
Packit 58578d
#include <boost/multi_index/detail/access_specifier.hpp>
Packit 58578d
#include <boost/multi_index/detail/adl_swap.hpp>
Packit 58578d
#include <boost/multi_index/detail/base_type.hpp>
Packit 58578d
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
Packit 58578d
#include <boost/multi_index/detail/converter.hpp>
Packit 58578d
#include <boost/multi_index/detail/header_holder.hpp>
Packit 58578d
#include <boost/multi_index/detail/has_tag.hpp>
Packit 58578d
#include <boost/multi_index/detail/no_duplicate_tags.hpp>
Packit 58578d
#include <boost/multi_index/detail/safe_mode.hpp>
Packit 58578d
#include <boost/multi_index/detail/scope_guard.hpp>
Packit 58578d
#include <boost/multi_index/detail/vartempl_support.hpp>
Packit 58578d
#include <boost/static_assert.hpp>
Packit 58578d
#include <boost/type_traits/is_same.hpp>
Packit 58578d
#include <boost/utility/base_from_member.hpp>
Packit 58578d
Packit 58578d
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
Packit 58578d
#include <initializer_list>
Packit 58578d
#endif
Packit 58578d
Packit 58578d
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
Packit 58578d
#include <boost/multi_index/detail/archive_constructed.hpp>
Packit 58578d
#include <boost/multi_index/detail/serialization_version.hpp>
Packit 58578d
#include <boost/serialization/collection_size_type.hpp>
Packit 58578d
#include <boost/serialization/nvp.hpp>
Packit 58578d
#include <boost/serialization/split_member.hpp>
Packit 58578d
#include <boost/serialization/version.hpp>
Packit 58578d
#include <boost/throw_exception.hpp> 
Packit 58578d
#endif
Packit 58578d
Packit 58578d
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
Packit 58578d
#include <boost/multi_index/detail/invariant_assert.hpp>
Packit 58578d
#define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x)                              \
Packit 58578d
  detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)=                 \
Packit 58578d
    detail::make_obj_guard(x,&multi_index_container::check_invariant_);      \
Packit 58578d
  BOOST_JOIN(check_invariant_,__LINE__).touch();
Packit 58578d
#define BOOST_MULTI_INDEX_CHECK_INVARIANT                                    \
Packit 58578d
  BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(*this)
Packit 58578d
#else
Packit 58578d
#define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x)
Packit 58578d
#define BOOST_MULTI_INDEX_CHECK_INVARIANT
Packit 58578d
#endif
Packit 58578d
Packit 58578d
namespace boost{
Packit 58578d
Packit 58578d
namespace multi_index{
Packit 58578d
Packit 58578d
#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
Packit 58578d
#pragma warning(push)
Packit 58578d
#pragma warning(disable:4522) /* spurious warning on multiple operator=()'s */
Packit 58578d
#endif
Packit 58578d
Packit 58578d
template<typename Value,typename IndexSpecifierList,typename Allocator>
Packit 58578d
class multi_index_container:
Packit 58578d
  private ::boost::base_from_member<
Packit 58578d
    typename boost::detail::allocator::rebind_to<
Packit 58578d
      Allocator,
Packit 58578d
      typename detail::multi_index_node_type<
Packit 58578d
        Value,IndexSpecifierList,Allocator>::type
Packit 58578d
    >::type>,
Packit 58578d
  BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS detail::header_holder<
Packit 58578d
    typename boost::detail::allocator::rebind_to<
Packit 58578d
      Allocator,
Packit 58578d
      typename detail::multi_index_node_type<
Packit 58578d
        Value,IndexSpecifierList,Allocator>::type
Packit 58578d
    >::type::pointer,
Packit 58578d
    multi_index_container<Value,IndexSpecifierList,Allocator> >,
Packit 58578d
  public detail::multi_index_base_type<
Packit 58578d
    Value,IndexSpecifierList,Allocator>::type
Packit 58578d
{
Packit 58578d
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
Packit 58578d
    BOOST_WORKAROUND(__MWERKS__,<=0x3003)
Packit 58578d
/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
Packit 58578d
 * lifetime of const references bound to temporaries --precisely what
Packit 58578d
 * scopeguards are.
Packit 58578d
 */
Packit 58578d
Packit 58578d
#pragma parse_mfunc_templ off
Packit 58578d
#endif
Packit 58578d
Packit 58578d
private:
Packit 58578d
  BOOST_COPYABLE_AND_MOVABLE(multi_index_container)
Packit 58578d
Packit 58578d
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
Packit 58578d
  template <typename,typename,typename> friend class  detail::index_base;
Packit 58578d
  template <typename,typename>          friend struct detail::header_holder;
Packit 58578d
  template <typename,typename>          friend struct detail::converter;
Packit 58578d
#endif
Packit 58578d
Packit 58578d
  typedef typename detail::multi_index_base_type<
Packit 58578d
      Value,IndexSpecifierList,Allocator>::type   super;
Packit 58578d
  typedef typename
Packit 58578d
  boost::detail::allocator::rebind_to<
Packit 58578d
    Allocator,
Packit 58578d
    typename super::node_type
Packit 58578d
  >::type                                         node_allocator;
Packit 58578d
  typedef ::boost::base_from_member<
Packit 58578d
    node_allocator>                               bfm_allocator;
Packit 58578d
  typedef detail::header_holder<
Packit 58578d
    typename node_allocator::pointer,
Packit 58578d
    multi_index_container>                        bfm_header;
Packit 58578d
Packit 58578d
Packit 58578d
public:
Packit 58578d
  /* All types are inherited from super, a few are explicitly
Packit 58578d
   * brought forward here to save us some typename's.
Packit 58578d
   */
Packit 58578d
Packit 58578d
  typedef typename super::ctor_args_list           ctor_args_list;
Packit 58578d
  typedef IndexSpecifierList                       index_specifier_type_list;
Packit 58578d
 
Packit 58578d
  typedef typename super::index_type_list          index_type_list;
Packit 58578d
Packit 58578d
  typedef typename super::iterator_type_list       iterator_type_list;
Packit 58578d
  typedef typename super::const_iterator_type_list const_iterator_type_list;
Packit 58578d
  typedef typename super::value_type               value_type;
Packit 58578d
  typedef typename super::final_allocator_type     allocator_type;
Packit 58578d
  typedef typename super::iterator                 iterator;
Packit 58578d
  typedef typename super::const_iterator           const_iterator;
Packit 58578d
Packit 58578d
  BOOST_STATIC_ASSERT(
Packit 58578d
    detail::no_duplicate_tags_in_index_list<index_type_list>::value);
Packit 58578d
Packit 58578d
  /* global project() needs to see this publicly */
Packit 58578d
Packit 58578d
  typedef typename super::node_type node_type;
Packit 58578d
Packit 58578d
  /* construct/copy/destroy */
Packit 58578d
Packit 58578d
  explicit multi_index_container(
Packit 58578d
Packit 58578d
#if BOOST_WORKAROUND(__IBMCPP__,<=600)
Packit 58578d
    /* VisualAge seems to have an ETI issue with the default values
Packit 58578d
     * for arguments args_list and al.
Packit 58578d
     */
Packit 58578d
Packit 58578d
    const ctor_args_list& args_list=
Packit 58578d
      typename mpl::identity<multi_index_container>::type::
Packit 58578d
        ctor_args_list(),
Packit 58578d
    const allocator_type& al=
Packit 58578d
      typename mpl::identity<multi_index_container>::type::
Packit 58578d
        allocator_type()):
Packit 58578d
#else
Packit 58578d
    const ctor_args_list& args_list=ctor_args_list(),
Packit 58578d
    const allocator_type& al=allocator_type()):
Packit 58578d
#endif
Packit 58578d
Packit 58578d
    bfm_allocator(al),
Packit 58578d
    super(args_list,bfm_allocator::member),
Packit 58578d
    node_count(0)
Packit 58578d
  {
Packit 58578d
    BOOST_MULTI_INDEX_CHECK_INVARIANT;
Packit 58578d
  }
Packit 58578d
Packit 58578d
  explicit multi_index_container(const allocator_type& al):
Packit 58578d
    bfm_allocator(al),
Packit 58578d
    super(ctor_args_list(),bfm_allocator::member),
Packit 58578d
    node_count(0)
Packit 58578d
  {
Packit 58578d
    BOOST_MULTI_INDEX_CHECK_INVARIANT;
Packit 58578d
  }
Packit 58578d
  
Packit 58578d
  template<typename InputIterator>
Packit 58578d
  multi_index_container(
Packit 58578d
    InputIterator first,InputIterator last,
Packit 58578d
Packit 58578d
#if BOOST_WORKAROUND(__IBMCPP__,<=600)
Packit 58578d
    /* VisualAge seems to have an ETI issue with the default values
Packit 58578d
     * for arguments args_list and al.
Packit 58578d
     */
Packit 58578d
Packit 58578d
    const ctor_args_list& args_list=
Packit 58578d
      typename mpl::identity<multi_index_container>::type::
Packit 58578d
        ctor_args_list(),
Packit 58578d
    const allocator_type& al=
Packit 58578d
      typename mpl::identity<multi_index_container>::type::
Packit 58578d
        allocator_type()):
Packit 58578d
#else
Packit 58578d
    const ctor_args_list& args_list=ctor_args_list(),
Packit 58578d
    const allocator_type& al=allocator_type()):
Packit 58578d
#endif
Packit 58578d
Packit 58578d
    bfm_allocator(al),
Packit 58578d
    super(args_list,bfm_allocator::member),
Packit 58578d
    node_count(0)
Packit 58578d
  {
Packit 58578d
    BOOST_MULTI_INDEX_CHECK_INVARIANT;
Packit 58578d
    BOOST_TRY{
Packit 58578d
      iterator hint=super::end();
Packit 58578d
      for(;first!=last;++first){
Packit 58578d
        hint=super::make_iterator(
Packit 58578d
          insert_ref_(*first,hint.get_node()).first);
Packit 58578d
        ++hint;
Packit 58578d
      }
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH(...){
Packit 58578d
      clear_();
Packit 58578d
      BOOST_RETHROW;
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH_END
Packit 58578d
  }
Packit 58578d
Packit 58578d
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
Packit 58578d
  multi_index_container(
Packit 58578d
    std::initializer_list<Value> list,
Packit 58578d
    const ctor_args_list& args_list=ctor_args_list(),
Packit 58578d
    const allocator_type& al=allocator_type()):
Packit 58578d
    bfm_allocator(al),
Packit 58578d
    super(args_list,bfm_allocator::member),
Packit 58578d
    node_count(0)
Packit 58578d
  {
Packit 58578d
    BOOST_MULTI_INDEX_CHECK_INVARIANT;
Packit 58578d
    BOOST_TRY{
Packit 58578d
      typedef const Value* init_iterator;
Packit 58578d
Packit 58578d
      iterator hint=super::end();
Packit 58578d
      for(init_iterator first=list.begin(),last=list.end();
Packit 58578d
          first!=last;++first){
Packit 58578d
        hint=super::make_iterator(insert_(*first,hint.get_node()).first);
Packit 58578d
        ++hint;
Packit 58578d
      }
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH(...){
Packit 58578d
      clear_();
Packit 58578d
      BOOST_RETHROW;
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH_END
Packit 58578d
  }
Packit 58578d
#endif
Packit 58578d
Packit 58578d
  multi_index_container(
Packit 58578d
    const multi_index_container<Value,IndexSpecifierList,Allocator>& x):
Packit 58578d
    bfm_allocator(x.bfm_allocator::member),
Packit 58578d
    bfm_header(),
Packit 58578d
    super(x),
Packit 58578d
    node_count(0)
Packit 58578d
  {
Packit 58578d
    copy_map_type map(bfm_allocator::member,x.size(),x.header(),header());
Packit 58578d
    for(const_iterator it=x.begin(),it_end=x.end();it!=it_end;++it){
Packit 58578d
      map.clone(it.get_node());
Packit 58578d
    }
Packit 58578d
    super::copy_(x,map);
Packit 58578d
    map.release();
Packit 58578d
    node_count=x.size();
Packit 58578d
Packit 58578d
    /* Not until this point are the indices required to be consistent,
Packit 58578d
     * hence the position of the invariant checker.
Packit 58578d
     */
Packit 58578d
Packit 58578d
    BOOST_MULTI_INDEX_CHECK_INVARIANT;
Packit 58578d
  }
Packit 58578d
Packit 58578d
  multi_index_container(BOOST_RV_REF(multi_index_container) x):
Packit 58578d
    bfm_allocator(x.bfm_allocator::member),
Packit 58578d
    bfm_header(),
Packit 58578d
    super(x,detail::do_not_copy_elements_tag()),
Packit 58578d
    node_count(0)
Packit 58578d
  {
Packit 58578d
    BOOST_MULTI_INDEX_CHECK_INVARIANT;
Packit 58578d
    BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x);
Packit 58578d
    swap_elements_(x);
Packit 58578d
  }
Packit 58578d
Packit 58578d
  ~multi_index_container()
Packit 58578d
  {
Packit 58578d
    delete_all_nodes_();
Packit 58578d
  }
Packit 58578d
Packit 58578d
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
Packit 58578d
  /* As per http://www.boost.org/doc/html/move/emulation_limitations.html
Packit 58578d
   * #move.emulation_limitations.assignment_operator
Packit 58578d
   */
Packit 58578d
Packit 58578d
  multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
Packit 58578d
    const multi_index_container<Value,IndexSpecifierList,Allocator>& x)
Packit 58578d
  {
Packit 58578d
    multi_index_container y(x);
Packit 58578d
    this->swap(y);
Packit 58578d
    return *this;
Packit 58578d
  }
Packit 58578d
#endif
Packit 58578d
Packit 58578d
  multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
Packit 58578d
    BOOST_COPY_ASSIGN_REF(multi_index_container) x)
Packit 58578d
  {
Packit 58578d
    multi_index_container y(x);
Packit 58578d
    this->swap(y);
Packit 58578d
    return *this;
Packit 58578d
  }
Packit 58578d
Packit 58578d
  multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
Packit 58578d
    BOOST_RV_REF(multi_index_container) x)
Packit 58578d
  {
Packit 58578d
    this->swap(x);
Packit 58578d
    return *this;
Packit 58578d
  }
Packit 58578d
Packit 58578d
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
Packit 58578d
  multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
Packit 58578d
    std::initializer_list<Value> list)
Packit 58578d
  {
Packit 58578d
    BOOST_MULTI_INDEX_CHECK_INVARIANT;
Packit 58578d
    typedef const Value* init_iterator;
Packit 58578d
Packit 58578d
    multi_index_container x(*this,detail::do_not_copy_elements_tag());    
Packit 58578d
    iterator hint=x.end();
Packit 58578d
    for(init_iterator first=list.begin(),last=list.end();
Packit 58578d
        first!=last;++first){
Packit 58578d
      hint=x.make_iterator(x.insert_(*first,hint.get_node()).first);
Packit 58578d
      ++hint;
Packit 58578d
    }
Packit 58578d
    x.swap_elements_(*this);
Packit 58578d
    return*this;
Packit 58578d
  }
Packit 58578d
#endif
Packit 58578d
Packit 58578d
  allocator_type get_allocator()const BOOST_NOEXCEPT
Packit 58578d
  {
Packit 58578d
    return allocator_type(bfm_allocator::member);
Packit 58578d
  }
Packit 58578d
Packit 58578d
  /* retrieval of indices by number */
Packit 58578d
Packit 58578d
#if !defined(BOOST_NO_MEMBER_TEMPLATES)
Packit 58578d
  template<int N>
Packit 58578d
  struct nth_index
Packit 58578d
  {
Packit 58578d
    BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
Packit 58578d
    typedef typename mpl::at_c<index_type_list,N>::type type;
Packit 58578d
  };
Packit 58578d
Packit 58578d
  template<int N>
Packit 58578d
  typename nth_index<N>::type& get()BOOST_NOEXCEPT
Packit 58578d
  {
Packit 58578d
    BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
Packit 58578d
    return *this;
Packit 58578d
  }
Packit 58578d
Packit 58578d
  template<int N>
Packit 58578d
  const typename nth_index<N>::type& get()const BOOST_NOEXCEPT
Packit 58578d
  {
Packit 58578d
    BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
Packit 58578d
    return *this;
Packit 58578d
  }
Packit 58578d
#endif
Packit 58578d
Packit 58578d
  /* retrieval of indices by tag */
Packit 58578d
Packit 58578d
#if !defined(BOOST_NO_MEMBER_TEMPLATES)
Packit 58578d
  template<typename Tag>
Packit 58578d
  struct index
Packit 58578d
  {
Packit 58578d
    typedef typename mpl::find_if<
Packit 58578d
      index_type_list,
Packit 58578d
      detail::has_tag<Tag>
Packit 58578d
    >::type                                    iter;
Packit 58578d
Packit 58578d
    BOOST_STATIC_CONSTANT(
Packit 58578d
      bool,index_found=!(is_same<iter,typename mpl::end<index_type_list>::type >::value));
Packit 58578d
    BOOST_STATIC_ASSERT(index_found);
Packit 58578d
Packit 58578d
    typedef typename mpl::deref<iter>::type    type;
Packit 58578d
  };
Packit 58578d
Packit 58578d
  template<typename Tag>
Packit 58578d
  typename index<Tag>::type& get()BOOST_NOEXCEPT
Packit 58578d
  {
Packit 58578d
    return *this;
Packit 58578d
  }
Packit 58578d
Packit 58578d
  template<typename Tag>
Packit 58578d
  const typename index<Tag>::type& get()const BOOST_NOEXCEPT
Packit 58578d
  {
Packit 58578d
    return *this;
Packit 58578d
  }
Packit 58578d
#endif
Packit 58578d
Packit 58578d
  /* projection of iterators by number */
Packit 58578d
Packit 58578d
#if !defined(BOOST_NO_MEMBER_TEMPLATES)
Packit 58578d
  template<int N>
Packit 58578d
  struct nth_index_iterator
Packit 58578d
  {
Packit 58578d
    typedef typename nth_index<N>::type::iterator type;
Packit 58578d
  };
Packit 58578d
Packit 58578d
  template<int N>
Packit 58578d
  struct nth_index_const_iterator
Packit 58578d
  {
Packit 58578d
    typedef typename nth_index<N>::type::const_iterator type;
Packit 58578d
  };
Packit 58578d
Packit 58578d
  template<int N,typename IteratorType>
Packit 58578d
  typename nth_index_iterator<N>::type project(IteratorType it)
Packit 58578d
  {
Packit 58578d
    typedef typename nth_index<N>::type index_type;
Packit 58578d
Packit 58578d
#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
Packit 58578d
    BOOST_STATIC_ASSERT(
Packit 58578d
      (mpl::contains<iterator_type_list,IteratorType>::value));
Packit 58578d
#endif
Packit 58578d
Packit 58578d
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
Packit 58578d
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(
Packit 58578d
      it,static_cast<typename IteratorType::container_type&>(*this));
Packit 58578d
Packit 58578d
    return index_type::make_iterator(static_cast<node_type*>(it.get_node()));
Packit 58578d
  }
Packit 58578d
Packit 58578d
  template<int N,typename IteratorType>
Packit 58578d
  typename nth_index_const_iterator<N>::type project(IteratorType it)const
Packit 58578d
  {
Packit 58578d
    typedef typename nth_index<N>::type index_type;
Packit 58578d
Packit 58578d
#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
Packit 58578d
    BOOST_STATIC_ASSERT((
Packit 58578d
      mpl::contains<iterator_type_list,IteratorType>::value||
Packit 58578d
      mpl::contains<const_iterator_type_list,IteratorType>::value));
Packit 58578d
#endif
Packit 58578d
Packit 58578d
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
Packit 58578d
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(
Packit 58578d
      it,static_cast<const typename IteratorType::container_type&>(*this));
Packit 58578d
    return index_type::make_iterator(static_cast<node_type*>(it.get_node()));
Packit 58578d
  }
Packit 58578d
#endif
Packit 58578d
Packit 58578d
  /* projection of iterators by tag */
Packit 58578d
Packit 58578d
#if !defined(BOOST_NO_MEMBER_TEMPLATES)
Packit 58578d
  template<typename Tag>
Packit 58578d
  struct index_iterator
Packit 58578d
  {
Packit 58578d
    typedef typename index<Tag>::type::iterator type;
Packit 58578d
  };
Packit 58578d
Packit 58578d
  template<typename Tag>
Packit 58578d
  struct index_const_iterator
Packit 58578d
  {
Packit 58578d
    typedef typename index<Tag>::type::const_iterator type;
Packit 58578d
  };
Packit 58578d
Packit 58578d
  template<typename Tag,typename IteratorType>
Packit 58578d
  typename index_iterator<Tag>::type project(IteratorType it)
Packit 58578d
  {
Packit 58578d
    typedef typename index<Tag>::type index_type;
Packit 58578d
Packit 58578d
#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
Packit 58578d
    BOOST_STATIC_ASSERT(
Packit 58578d
      (mpl::contains<iterator_type_list,IteratorType>::value));
Packit 58578d
#endif
Packit 58578d
Packit 58578d
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
Packit 58578d
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(
Packit 58578d
      it,static_cast<typename IteratorType::container_type&>(*this));
Packit 58578d
    return index_type::make_iterator(static_cast<node_type*>(it.get_node()));
Packit 58578d
  }
Packit 58578d
Packit 58578d
  template<typename Tag,typename IteratorType>
Packit 58578d
  typename index_const_iterator<Tag>::type project(IteratorType it)const
Packit 58578d
  {
Packit 58578d
    typedef typename index<Tag>::type index_type;
Packit 58578d
Packit 58578d
#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */
Packit 58578d
    BOOST_STATIC_ASSERT((
Packit 58578d
      mpl::contains<iterator_type_list,IteratorType>::value||
Packit 58578d
      mpl::contains<const_iterator_type_list,IteratorType>::value));
Packit 58578d
#endif
Packit 58578d
Packit 58578d
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
Packit 58578d
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(
Packit 58578d
      it,static_cast<const typename IteratorType::container_type&>(*this));
Packit 58578d
    return index_type::make_iterator(static_cast<node_type*>(it.get_node()));
Packit 58578d
  }
Packit 58578d
#endif
Packit 58578d
Packit 58578d
BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
Packit 58578d
  typedef typename super::copy_map_type copy_map_type;
Packit 58578d
Packit 58578d
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
Packit 58578d
  multi_index_container(
Packit 58578d
    const multi_index_container<Value,IndexSpecifierList,Allocator>& x,
Packit 58578d
    detail::do_not_copy_elements_tag):
Packit 58578d
    bfm_allocator(x.bfm_allocator::member),
Packit 58578d
    bfm_header(),
Packit 58578d
    super(x,detail::do_not_copy_elements_tag()),
Packit 58578d
    node_count(0)
Packit 58578d
  {
Packit 58578d
    BOOST_MULTI_INDEX_CHECK_INVARIANT;
Packit 58578d
  }
Packit 58578d
#endif
Packit 58578d
Packit 58578d
  node_type* header()const
Packit 58578d
  {
Packit 58578d
    return &*bfm_header::member;
Packit 58578d
  }
Packit 58578d
Packit 58578d
  node_type* allocate_node()
Packit 58578d
  {
Packit 58578d
    return &*bfm_allocator::member.allocate(1);
Packit 58578d
  }
Packit 58578d
Packit 58578d
  void deallocate_node(node_type* x)
Packit 58578d
  {
Packit 58578d
    typedef typename node_allocator::pointer node_pointer;
Packit 58578d
    bfm_allocator::member.deallocate(static_cast<node_pointer>(x),1);
Packit 58578d
  }
Packit 58578d
Packit 58578d
  bool empty_()const
Packit 58578d
  {
Packit 58578d
    return node_count==0;
Packit 58578d
  }
Packit 58578d
Packit 58578d
  std::size_t size_()const
Packit 58578d
  {
Packit 58578d
    return node_count;
Packit 58578d
  }
Packit 58578d
Packit 58578d
  std::size_t max_size_()const
Packit 58578d
  {
Packit 58578d
    return static_cast<std::size_t >(-1);
Packit 58578d
  }
Packit 58578d
Packit 58578d
  template<typename Variant>
Packit 58578d
  std::pair<node_type*,bool> insert_(const Value& v,Variant variant)
Packit 58578d
  {
Packit 58578d
    node_type* x=0;
Packit 58578d
    node_type* res=super::insert_(v,x,variant);
Packit 58578d
    if(res==x){
Packit 58578d
      ++node_count;
Packit 58578d
      return std::pair<node_type*,bool>(res,true);
Packit 58578d
    }
Packit 58578d
    else{
Packit 58578d
      return std::pair<node_type*,bool>(res,false);
Packit 58578d
    }
Packit 58578d
  }
Packit 58578d
Packit 58578d
  std::pair<node_type*,bool> insert_(const Value& v)
Packit 58578d
  {
Packit 58578d
    return insert_(v,detail::lvalue_tag());
Packit 58578d
  }
Packit 58578d
Packit 58578d
  std::pair<node_type*,bool> insert_rv_(const Value& v)
Packit 58578d
  {
Packit 58578d
    return insert_(v,detail::rvalue_tag());
Packit 58578d
  }
Packit 58578d
Packit 58578d
  template<typename T>
Packit 58578d
  std::pair<node_type*,bool> insert_ref_(T& t)
Packit 58578d
  {
Packit 58578d
    node_type* x=allocate_node();
Packit 58578d
    BOOST_TRY{
Packit 58578d
      new(&x->value()) value_type(t);
Packit 58578d
      BOOST_TRY{
Packit 58578d
        node_type* res=super::insert_(x->value(),x,detail::emplaced_tag());
Packit 58578d
        if(res==x){
Packit 58578d
          ++node_count;
Packit 58578d
          return std::pair<node_type*,bool>(res,true);
Packit 58578d
        }
Packit 58578d
        else{
Packit 58578d
          boost::detail::allocator::destroy(&x->value());
Packit 58578d
          deallocate_node(x);
Packit 58578d
          return std::pair<node_type*,bool>(res,false);
Packit 58578d
        }
Packit 58578d
      }
Packit 58578d
      BOOST_CATCH(...){
Packit 58578d
        boost::detail::allocator::destroy(&x->value());
Packit 58578d
        BOOST_RETHROW;
Packit 58578d
      }
Packit 58578d
      BOOST_CATCH_END
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH(...){
Packit 58578d
      deallocate_node(x);
Packit 58578d
      BOOST_RETHROW;
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH_END
Packit 58578d
  }
Packit 58578d
Packit 58578d
  std::pair<node_type*,bool> insert_ref_(const value_type& x)
Packit 58578d
  {
Packit 58578d
    return insert_(x);
Packit 58578d
  }
Packit 58578d
Packit 58578d
  std::pair<node_type*,bool> insert_ref_(value_type& x)
Packit 58578d
  {
Packit 58578d
    return insert_(x);
Packit 58578d
  }
Packit 58578d
Packit 58578d
  template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
Packit 58578d
  std::pair<node_type*,bool> emplace_(
Packit 58578d
    BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
Packit 58578d
  {
Packit 58578d
    node_type* x=allocate_node();
Packit 58578d
    BOOST_TRY{
Packit 58578d
      detail::vartempl_placement_new(
Packit 58578d
        &x->value(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
Packit 58578d
      BOOST_TRY{
Packit 58578d
        node_type* res=super::insert_(x->value(),x,detail::emplaced_tag());
Packit 58578d
        if(res==x){
Packit 58578d
          ++node_count;
Packit 58578d
          return std::pair<node_type*,bool>(res,true);
Packit 58578d
        }
Packit 58578d
        else{
Packit 58578d
          boost::detail::allocator::destroy(&x->value());
Packit 58578d
          deallocate_node(x);
Packit 58578d
          return std::pair<node_type*,bool>(res,false);
Packit 58578d
        }
Packit 58578d
      }
Packit 58578d
      BOOST_CATCH(...){
Packit 58578d
        boost::detail::allocator::destroy(&x->value());
Packit 58578d
        BOOST_RETHROW;
Packit 58578d
      }
Packit 58578d
      BOOST_CATCH_END
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH(...){
Packit 58578d
      deallocate_node(x);
Packit 58578d
      BOOST_RETHROW;
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH_END
Packit 58578d
  }
Packit 58578d
Packit 58578d
  template<typename Variant>
Packit 58578d
  std::pair<node_type*,bool> insert_(
Packit 58578d
    const Value& v,node_type* position,Variant variant)
Packit 58578d
  {
Packit 58578d
    node_type* x=0;
Packit 58578d
    node_type* res=super::insert_(v,position,x,variant);
Packit 58578d
    if(res==x){
Packit 58578d
      ++node_count;
Packit 58578d
      return std::pair<node_type*,bool>(res,true);
Packit 58578d
    }
Packit 58578d
    else{
Packit 58578d
      return std::pair<node_type*,bool>(res,false);
Packit 58578d
    }
Packit 58578d
  }
Packit 58578d
Packit 58578d
  std::pair<node_type*,bool> insert_(const Value& v,node_type* position)
Packit 58578d
  {
Packit 58578d
    return insert_(v,position,detail::lvalue_tag());
Packit 58578d
  }
Packit 58578d
Packit 58578d
  std::pair<node_type*,bool> insert_rv_(const Value& v,node_type* position)
Packit 58578d
  {
Packit 58578d
    return insert_(v,position,detail::rvalue_tag());
Packit 58578d
  }
Packit 58578d
Packit 58578d
  template<typename T>
Packit 58578d
  std::pair<node_type*,bool> insert_ref_(
Packit 58578d
    T& t,node_type* position)
Packit 58578d
  {
Packit 58578d
    node_type* x=allocate_node();
Packit 58578d
    BOOST_TRY{
Packit 58578d
      new(&x->value()) value_type(t);
Packit 58578d
      BOOST_TRY{
Packit 58578d
        node_type* res=super::insert_(
Packit 58578d
          x->value(),position,x,detail::emplaced_tag());
Packit 58578d
        if(res==x){
Packit 58578d
          ++node_count;
Packit 58578d
          return std::pair<node_type*,bool>(res,true);
Packit 58578d
        }
Packit 58578d
        else{
Packit 58578d
          boost::detail::allocator::destroy(&x->value());
Packit 58578d
          deallocate_node(x);
Packit 58578d
          return std::pair<node_type*,bool>(res,false);
Packit 58578d
        }
Packit 58578d
      }
Packit 58578d
      BOOST_CATCH(...){
Packit 58578d
        boost::detail::allocator::destroy(&x->value());
Packit 58578d
        BOOST_RETHROW;
Packit 58578d
      }
Packit 58578d
      BOOST_CATCH_END
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH(...){
Packit 58578d
      deallocate_node(x);
Packit 58578d
      BOOST_RETHROW;
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH_END
Packit 58578d
  }
Packit 58578d
Packit 58578d
  std::pair<node_type*,bool> insert_ref_(
Packit 58578d
    const value_type& x,node_type* position)
Packit 58578d
  {
Packit 58578d
    return insert_(x,position);
Packit 58578d
  }
Packit 58578d
Packit 58578d
  std::pair<node_type*,bool> insert_ref_(
Packit 58578d
    value_type& x,node_type* position)
Packit 58578d
  {
Packit 58578d
    return insert_(x,position);
Packit 58578d
  }
Packit 58578d
Packit 58578d
  template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
Packit 58578d
  std::pair<node_type*,bool> emplace_hint_(
Packit 58578d
    node_type* position,
Packit 58578d
    BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
Packit 58578d
  {
Packit 58578d
    node_type* x=allocate_node();
Packit 58578d
    BOOST_TRY{
Packit 58578d
      detail::vartempl_placement_new(
Packit 58578d
        &x->value(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
Packit 58578d
      BOOST_TRY{
Packit 58578d
        node_type* res=super::insert_(
Packit 58578d
          x->value(),position,x,detail::emplaced_tag());
Packit 58578d
        if(res==x){
Packit 58578d
          ++node_count;
Packit 58578d
          return std::pair<node_type*,bool>(res,true);
Packit 58578d
        }
Packit 58578d
        else{
Packit 58578d
          boost::detail::allocator::destroy(&x->value());
Packit 58578d
          deallocate_node(x);
Packit 58578d
          return std::pair<node_type*,bool>(res,false);
Packit 58578d
        }
Packit 58578d
      }
Packit 58578d
      BOOST_CATCH(...){
Packit 58578d
        boost::detail::allocator::destroy(&x->value());
Packit 58578d
        BOOST_RETHROW;
Packit 58578d
      }
Packit 58578d
      BOOST_CATCH_END
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH(...){
Packit 58578d
      deallocate_node(x);
Packit 58578d
      BOOST_RETHROW;
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH_END
Packit 58578d
  }
Packit 58578d
Packit 58578d
  void erase_(node_type* x)
Packit 58578d
  {
Packit 58578d
    --node_count;
Packit 58578d
    super::erase_(x);
Packit 58578d
    deallocate_node(x);
Packit 58578d
  }
Packit 58578d
Packit 58578d
  void delete_node_(node_type* x)
Packit 58578d
  {
Packit 58578d
    super::delete_node_(x);
Packit 58578d
    deallocate_node(x);
Packit 58578d
  }
Packit 58578d
Packit 58578d
  void delete_all_nodes_()
Packit 58578d
  {
Packit 58578d
    super::delete_all_nodes_();
Packit 58578d
  }
Packit 58578d
Packit 58578d
  void clear_()
Packit 58578d
  {
Packit 58578d
    delete_all_nodes_();
Packit 58578d
    super::clear_();
Packit 58578d
    node_count=0;
Packit 58578d
  }
Packit 58578d
Packit 58578d
  void swap_(multi_index_container<Value,IndexSpecifierList,Allocator>& x)
Packit 58578d
  {
Packit 58578d
    if(bfm_allocator::member!=x.bfm_allocator::member){
Packit 58578d
      detail::adl_swap(bfm_allocator::member,x.bfm_allocator::member);
Packit 58578d
    }
Packit 58578d
    std::swap(bfm_header::member,x.bfm_header::member);
Packit 58578d
    super::swap_(x);
Packit 58578d
    std::swap(node_count,x.node_count);
Packit 58578d
  }
Packit 58578d
Packit 58578d
  void swap_elements_(
Packit 58578d
    multi_index_container<Value,IndexSpecifierList,Allocator>& x)
Packit 58578d
  {
Packit 58578d
    std::swap(bfm_header::member,x.bfm_header::member);
Packit 58578d
    super::swap_elements_(x);
Packit 58578d
    std::swap(node_count,x.node_count);
Packit 58578d
  }
Packit 58578d
Packit 58578d
  bool replace_(const Value& k,node_type* x)
Packit 58578d
  {
Packit 58578d
    return super::replace_(k,x,detail::lvalue_tag());
Packit 58578d
  }
Packit 58578d
Packit 58578d
  bool replace_rv_(const Value& k,node_type* x)
Packit 58578d
  {
Packit 58578d
    return super::replace_(k,x,detail::rvalue_tag());
Packit 58578d
  }
Packit 58578d
Packit 58578d
  template<typename Modifier>
Packit 58578d
  bool modify_(Modifier& mod,node_type* x)
Packit 58578d
  {
Packit 58578d
    BOOST_TRY{
Packit 58578d
      mod(const_cast<value_type&>(x->value()));
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH(...){
Packit 58578d
      this->erase_(x);
Packit 58578d
      BOOST_RETHROW;
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH_END
Packit 58578d
Packit 58578d
    BOOST_TRY{
Packit 58578d
      if(!super::modify_(x)){
Packit 58578d
        deallocate_node(x);
Packit 58578d
        --node_count;
Packit 58578d
        return false;
Packit 58578d
      }
Packit 58578d
      else return true;
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH(...){
Packit 58578d
      deallocate_node(x);
Packit 58578d
      --node_count;
Packit 58578d
      BOOST_RETHROW;
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH_END
Packit 58578d
  }
Packit 58578d
Packit 58578d
  template<typename Modifier,typename Rollback>
Packit 58578d
  bool modify_(Modifier& mod,Rollback& back_,node_type* x)
Packit 58578d
  {
Packit 58578d
    BOOST_TRY{
Packit 58578d
      mod(const_cast<value_type&>(x->value()));
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH(...){
Packit 58578d
      this->erase_(x);
Packit 58578d
      BOOST_RETHROW;
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH_END
Packit 58578d
Packit 58578d
    bool b;
Packit 58578d
    BOOST_TRY{
Packit 58578d
      b=super::modify_rollback_(x);
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH(...){
Packit 58578d
      BOOST_TRY{
Packit 58578d
        back_(const_cast<value_type&>(x->value()));
Packit 58578d
        if(!super::check_rollback_(x))this->erase_(x);
Packit 58578d
        BOOST_RETHROW;
Packit 58578d
      }
Packit 58578d
      BOOST_CATCH(...){
Packit 58578d
        this->erase_(x);
Packit 58578d
        BOOST_RETHROW;
Packit 58578d
      }
Packit 58578d
      BOOST_CATCH_END
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH_END
Packit 58578d
Packit 58578d
    BOOST_TRY{
Packit 58578d
      if(!b){
Packit 58578d
        back_(const_cast<value_type&>(x->value()));
Packit 58578d
        if(!super::check_rollback_(x))this->erase_(x);
Packit 58578d
        return false;
Packit 58578d
      }
Packit 58578d
      else return true;
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH(...){
Packit 58578d
      this->erase_(x);
Packit 58578d
      BOOST_RETHROW;
Packit 58578d
    }
Packit 58578d
    BOOST_CATCH_END
Packit 58578d
  }
Packit 58578d
Packit 58578d
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
Packit 58578d
  /* serialization */
Packit 58578d
Packit 58578d
  friend class boost::serialization::access;
Packit 58578d
Packit 58578d
  BOOST_SERIALIZATION_SPLIT_MEMBER()
Packit 58578d
Packit 58578d
  typedef typename super::index_saver_type        index_saver_type;
Packit 58578d
  typedef typename super::index_loader_type       index_loader_type;
Packit 58578d
Packit 58578d
  template<class Archive>
Packit 58578d
  void save(Archive& ar,const unsigned int version)const
Packit 58578d
  {
Packit 58578d
    const serialization::collection_size_type       s(size_());
Packit 58578d
    const detail::serialization_version<value_type> value_version;
Packit 58578d
    ar<
Packit 58578d
    ar<
Packit 58578d
Packit 58578d
    index_saver_type sm(bfm_allocator::member,s);
Packit 58578d
Packit 58578d
    for(iterator it=super::begin(),it_end=super::end();it!=it_end;++it){
Packit 58578d
      serialization::save_construct_data_adl(ar,&*it,value_version);
Packit 58578d
      ar<
Packit 58578d
      sm.add(it.get_node(),ar,version);
Packit 58578d
    }
Packit 58578d
    sm.add_track(header(),ar,version);
Packit 58578d
Packit 58578d
    super::save_(ar,version,sm);
Packit 58578d
  }
Packit 58578d
Packit 58578d
  template<class Archive>
Packit 58578d
  void load(Archive& ar,const unsigned int version)
Packit 58578d
  {
Packit 58578d
    BOOST_MULTI_INDEX_CHECK_INVARIANT;
Packit 58578d
Packit 58578d
    clear_(); 
Packit 58578d
    serialization::collection_size_type       s;
Packit 58578d
    detail::serialization_version<value_type> value_version;
Packit 58578d
    if(version<1){
Packit 58578d
      std::size_t sz;
Packit 58578d
      ar>>serialization::make_nvp("count",sz);
Packit 58578d
      s=static_cast<serialization::collection_size_type>(sz);
Packit 58578d
    }
Packit 58578d
    else{
Packit 58578d
      ar>>serialization::make_nvp("count",s);
Packit 58578d
    }
Packit 58578d
    if(version<2){
Packit 58578d
      value_version=0;
Packit 58578d
    }
Packit 58578d
    else{
Packit 58578d
      ar>>serialization::make_nvp("value_version",value_version);
Packit 58578d
    }
Packit 58578d
Packit 58578d
    index_loader_type lm(bfm_allocator::member,s);
Packit 58578d
Packit 58578d
    for(std::size_t n=0;n
Packit 58578d
      detail::archive_constructed<Value> value("item",ar,value_version);
Packit 58578d
      std::pair<node_type*,bool> p=insert_(
Packit 58578d
        value.get(),super::end().get_node());
Packit 58578d
      if(!p.second)throw_exception(
Packit 58578d
        archive::archive_exception(
Packit 58578d
          archive::archive_exception::other_exception));
Packit 58578d
      ar.reset_object_address(&p.first->value(),&value.get());
Packit 58578d
      lm.add(p.first,ar,version);
Packit 58578d
    }
Packit 58578d
    lm.add_track(header(),ar,version);
Packit 58578d
Packit 58578d
    super::load_(ar,version,lm);
Packit 58578d
  }
Packit 58578d
#endif
Packit 58578d
Packit 58578d
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
Packit 58578d
  /* invariant stuff */
Packit 58578d
Packit 58578d
  bool invariant_()const
Packit 58578d
  {
Packit 58578d
    return super::invariant_();
Packit 58578d
  }
Packit 58578d
Packit 58578d
  void check_invariant_()const
Packit 58578d
  {
Packit 58578d
    BOOST_MULTI_INDEX_INVARIANT_ASSERT(invariant_());
Packit 58578d
  }
Packit 58578d
#endif
Packit 58578d
Packit 58578d
private:
Packit 58578d
  std::size_t node_count;
Packit 58578d
Packit 58578d
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
Packit 58578d
    BOOST_WORKAROUND(__MWERKS__,<=0x3003)
Packit 58578d
#pragma parse_mfunc_templ reset
Packit 58578d
#endif
Packit 58578d
};
Packit 58578d
Packit 58578d
#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
Packit 58578d
#pragma warning(pop) /* C4522 */
Packit 58578d
#endif
Packit 58578d
Packit 58578d
/* retrieval of indices by number */
Packit 58578d
Packit 58578d
template<typename MultiIndexContainer,int N>
Packit 58578d
struct nth_index
Packit 58578d
{
Packit 58578d
  BOOST_STATIC_CONSTANT(
Packit 58578d
    int,
Packit 58578d
    M=mpl::size<typename MultiIndexContainer::index_type_list>::type::value);
Packit 58578d
  BOOST_STATIC_ASSERT(N>=0&&N
Packit 58578d
  typedef typename mpl::at_c<
Packit 58578d
    typename MultiIndexContainer::index_type_list,N>::type type;
Packit 58578d
};
Packit 58578d
Packit 58578d
template<int N,typename Value,typename IndexSpecifierList,typename Allocator>
Packit 58578d
typename nth_index<
Packit 58578d
  multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type&
Packit 58578d
get(
Packit 58578d
  multi_index_container<Value,IndexSpecifierList,Allocator>& m)BOOST_NOEXCEPT
Packit 58578d
{
Packit 58578d
  typedef multi_index_container<
Packit 58578d
    Value,IndexSpecifierList,Allocator>    multi_index_type;
Packit 58578d
  typedef typename nth_index<
Packit 58578d
    multi_index_container<
Packit 58578d
      Value,IndexSpecifierList,Allocator>,
Packit 58578d
    N
Packit 58578d
  >::type                                  index_type;
Packit 58578d
Packit 58578d
  BOOST_STATIC_ASSERT(N>=0&&
Packit 58578d
    N<
Packit 58578d
    mpl::size<
Packit 58578d
      BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list
Packit 58578d
    >::type::value);
Packit 58578d
Packit 58578d
  return detail::converter<multi_index_type,index_type>::index(m);
Packit 58578d
}
Packit 58578d
Packit 58578d
template<int N,typename Value,typename IndexSpecifierList,typename Allocator>
Packit 58578d
const typename nth_index<
Packit 58578d
  multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type&
Packit 58578d
get(
Packit 58578d
  const multi_index_container<Value,IndexSpecifierList,Allocator>& m
Packit 58578d
)BOOST_NOEXCEPT
Packit 58578d
{
Packit 58578d
  typedef multi_index_container<
Packit 58578d
    Value,IndexSpecifierList,Allocator>    multi_index_type;
Packit 58578d
  typedef typename nth_index<
Packit 58578d
    multi_index_container<
Packit 58578d
      Value,IndexSpecifierList,Allocator>,
Packit 58578d
    N
Packit 58578d
  >::type                                  index_type;
Packit 58578d
Packit 58578d
  BOOST_STATIC_ASSERT(N>=0&&
Packit 58578d
    N<
Packit 58578d
    mpl::size<
Packit 58578d
      BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list
Packit 58578d
    >::type::value);
Packit 58578d
Packit 58578d
  return detail::converter<multi_index_type,index_type>::index(m);
Packit 58578d
}
Packit 58578d
Packit 58578d
/* retrieval of indices by tag */
Packit 58578d
Packit 58578d
template<typename MultiIndexContainer,typename Tag>
Packit 58578d
struct index
Packit 58578d
{
Packit 58578d
  typedef typename MultiIndexContainer::index_type_list index_type_list;
Packit 58578d
Packit 58578d
  typedef typename mpl::find_if<
Packit 58578d
    index_type_list,
Packit 58578d
    detail::has_tag<Tag>
Packit 58578d
  >::type                                      iter;
Packit 58578d
Packit 58578d
  BOOST_STATIC_CONSTANT(
Packit 58578d
    bool,index_found=!(is_same<iter,typename mpl::end<index_type_list>::type >::value));
Packit 58578d
  BOOST_STATIC_ASSERT(index_found);
Packit 58578d
Packit 58578d
  typedef typename mpl::deref<iter>::type       type;
Packit 58578d
};
Packit 58578d
Packit 58578d
template<
Packit 58578d
  typename Tag,typename Value,typename IndexSpecifierList,typename Allocator
Packit 58578d
>
Packit 58578d
typename ::boost::multi_index::index<
Packit 58578d
  multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type&
Packit 58578d
get(
Packit 58578d
  multi_index_container<Value,IndexSpecifierList,Allocator>& m)BOOST_NOEXCEPT
Packit 58578d
{
Packit 58578d
  typedef multi_index_container<
Packit 58578d
    Value,IndexSpecifierList,Allocator>         multi_index_type;
Packit 58578d
  typedef typename ::boost::multi_index::index<
Packit 58578d
    multi_index_container<
Packit 58578d
      Value,IndexSpecifierList,Allocator>,
Packit 58578d
    Tag
Packit 58578d
  >::type                                       index_type;
Packit 58578d
Packit 58578d
  return detail::converter<multi_index_type,index_type>::index(m);
Packit 58578d
}
Packit 58578d
Packit 58578d
template<
Packit 58578d
  typename Tag,typename Value,typename IndexSpecifierList,typename Allocator
Packit 58578d
>
Packit 58578d
const typename ::boost::multi_index::index<
Packit 58578d
  multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type&
Packit 58578d
get(
Packit 58578d
  const multi_index_container<Value,IndexSpecifierList,Allocator>& m
Packit 58578d
)BOOST_NOEXCEPT
Packit 58578d
{
Packit 58578d
  typedef multi_index_container<
Packit 58578d
    Value,IndexSpecifierList,Allocator>         multi_index_type;
Packit 58578d
  typedef typename ::boost::multi_index::index<
Packit 58578d
    multi_index_container<
Packit 58578d
      Value,IndexSpecifierList,Allocator>,
Packit 58578d
    Tag
Packit 58578d
  >::type                                       index_type;
Packit 58578d
Packit 58578d
  return detail::converter<multi_index_type,index_type>::index(m);
Packit 58578d
}
Packit 58578d
Packit 58578d
/* projection of iterators by number */
Packit 58578d
Packit 58578d
template<typename MultiIndexContainer,int N>
Packit 58578d
struct nth_index_iterator
Packit 58578d
{
Packit 58578d
  typedef typename nth_index<MultiIndexContainer,N>::type::iterator type;
Packit 58578d
};
Packit 58578d
Packit 58578d
template<typename MultiIndexContainer,int N>
Packit 58578d
struct nth_index_const_iterator
Packit 58578d
{
Packit 58578d
  typedef typename nth_index<MultiIndexContainer,N>::type::const_iterator type;
Packit 58578d
};
Packit 58578d
Packit 58578d
template<
Packit 58578d
  int N,typename IteratorType,
Packit 58578d
  typename Value,typename IndexSpecifierList,typename Allocator>
Packit 58578d
typename nth_index_iterator<
Packit 58578d
  multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type
Packit 58578d
project(
Packit 58578d
  multi_index_container<Value,IndexSpecifierList,Allocator>& m,
Packit 58578d
  IteratorType it)
Packit 58578d
{
Packit 58578d
  typedef multi_index_container<
Packit 58578d
    Value,IndexSpecifierList,Allocator>                multi_index_type;
Packit 58578d
  typedef typename nth_index<multi_index_type,N>::type index_type;
Packit 58578d
Packit 58578d
#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */
Packit 58578d
  BOOST_STATIC_ASSERT((
Packit 58578d
    mpl::contains<
Packit 58578d
      BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
Packit 58578d
      IteratorType>::value));
Packit 58578d
#endif
Packit 58578d
Packit 58578d
  BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
Packit 58578d
Packit 58578d
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
Packit 58578d
  typedef detail::converter<
Packit 58578d
    multi_index_type,
Packit 58578d
    BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
Packit 58578d
  BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
Packit 58578d
#endif
Packit 58578d
Packit 58578d
  return detail::converter<multi_index_type,index_type>::iterator(
Packit 58578d
    m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
Packit 58578d
}
Packit 58578d
Packit 58578d
template<
Packit 58578d
  int N,typename IteratorType,
Packit 58578d
  typename Value,typename IndexSpecifierList,typename Allocator>
Packit 58578d
typename nth_index_const_iterator<
Packit 58578d
  multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type
Packit 58578d
project(
Packit 58578d
  const multi_index_container<Value,IndexSpecifierList,Allocator>& m,
Packit 58578d
  IteratorType it)
Packit 58578d
{
Packit 58578d
  typedef multi_index_container<
Packit 58578d
    Value,IndexSpecifierList,Allocator>                multi_index_type;
Packit 58578d
  typedef typename nth_index<multi_index_type,N>::type index_type;
Packit 58578d
Packit 58578d
#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */
Packit 58578d
  BOOST_STATIC_ASSERT((
Packit 58578d
    mpl::contains<
Packit 58578d
      BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
Packit 58578d
      IteratorType>::value||
Packit 58578d
    mpl::contains<
Packit 58578d
      BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list,
Packit 58578d
      IteratorType>::value));
Packit 58578d
#endif
Packit 58578d
Packit 58578d
  BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
Packit 58578d
Packit 58578d
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
Packit 58578d
  typedef detail::converter<
Packit 58578d
    multi_index_type,
Packit 58578d
    BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
Packit 58578d
  BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
Packit 58578d
#endif
Packit 58578d
Packit 58578d
  return detail::converter<multi_index_type,index_type>::const_iterator(
Packit 58578d
    m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
Packit 58578d
}
Packit 58578d
Packit 58578d
/* projection of iterators by tag */
Packit 58578d
Packit 58578d
template<typename MultiIndexContainer,typename Tag>
Packit 58578d
struct index_iterator
Packit 58578d
{
Packit 58578d
  typedef typename ::boost::multi_index::index<
Packit 58578d
    MultiIndexContainer,Tag>::type::iterator    type;
Packit 58578d
};
Packit 58578d
Packit 58578d
template<typename MultiIndexContainer,typename Tag>
Packit 58578d
struct index_const_iterator
Packit 58578d
{
Packit 58578d
  typedef typename ::boost::multi_index::index<
Packit 58578d
    MultiIndexContainer,Tag>::type::const_iterator type;
Packit 58578d
};
Packit 58578d
Packit 58578d
template<
Packit 58578d
  typename Tag,typename IteratorType,
Packit 58578d
  typename Value,typename IndexSpecifierList,typename Allocator>
Packit 58578d
typename index_iterator<
Packit 58578d
  multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type
Packit 58578d
project(
Packit 58578d
  multi_index_container<Value,IndexSpecifierList,Allocator>& m,
Packit 58578d
  IteratorType it)
Packit 58578d
{
Packit 58578d
  typedef multi_index_container<
Packit 58578d
    Value,IndexSpecifierList,Allocator>         multi_index_type;
Packit 58578d
  typedef typename ::boost::multi_index::index<
Packit 58578d
    multi_index_type,Tag>::type                 index_type;
Packit 58578d
Packit 58578d
#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */
Packit 58578d
  BOOST_STATIC_ASSERT((
Packit 58578d
    mpl::contains<
Packit 58578d
      BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
Packit 58578d
      IteratorType>::value));
Packit 58578d
#endif
Packit 58578d
Packit 58578d
  BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
Packit 58578d
Packit 58578d
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
Packit 58578d
  typedef detail::converter<
Packit 58578d
    multi_index_type,
Packit 58578d
    BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
Packit 58578d
  BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
Packit 58578d
#endif
Packit 58578d
Packit 58578d
  return detail::converter<multi_index_type,index_type>::iterator(
Packit 58578d
    m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
Packit 58578d
}
Packit 58578d
Packit 58578d
template<
Packit 58578d
  typename Tag,typename IteratorType,
Packit 58578d
  typename Value,typename IndexSpecifierList,typename Allocator>
Packit 58578d
typename index_const_iterator<
Packit 58578d
  multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type
Packit 58578d
project(
Packit 58578d
  const multi_index_container<Value,IndexSpecifierList,Allocator>& m,
Packit 58578d
  IteratorType it)
Packit 58578d
{
Packit 58578d
  typedef multi_index_container<
Packit 58578d
    Value,IndexSpecifierList,Allocator>         multi_index_type;
Packit 58578d
  typedef typename ::boost::multi_index::index<
Packit 58578d
    multi_index_type,Tag>::type                 index_type;
Packit 58578d
Packit 58578d
#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */
Packit 58578d
  BOOST_STATIC_ASSERT((
Packit 58578d
    mpl::contains<
Packit 58578d
      BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
Packit 58578d
      IteratorType>::value||
Packit 58578d
    mpl::contains<
Packit 58578d
      BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list,
Packit 58578d
      IteratorType>::value));
Packit 58578d
#endif
Packit 58578d
Packit 58578d
  BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
Packit 58578d
Packit 58578d
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
Packit 58578d
  typedef detail::converter<
Packit 58578d
    multi_index_type,
Packit 58578d
    BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
Packit 58578d
  BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
Packit 58578d
#endif
Packit 58578d
Packit 58578d
  return detail::converter<multi_index_type,index_type>::const_iterator(
Packit 58578d
    m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
Packit 58578d
}
Packit 58578d
Packit 58578d
/* Comparison. Simple forward to first index. */
Packit 58578d
Packit 58578d
template<
Packit 58578d
  typename Value1,typename IndexSpecifierList1,typename Allocator1,
Packit 58578d
  typename Value2,typename IndexSpecifierList2,typename Allocator2
Packit 58578d
>
Packit 58578d
bool operator==(
Packit 58578d
  const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
Packit 58578d
  const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
Packit 58578d
{
Packit 58578d
  return get<0>(x)==get<0>(y);
Packit 58578d
}
Packit 58578d
Packit 58578d
template<
Packit 58578d
  typename Value1,typename IndexSpecifierList1,typename Allocator1,
Packit 58578d
  typename Value2,typename IndexSpecifierList2,typename Allocator2
Packit 58578d
>
Packit 58578d
bool operator<(
Packit 58578d
  const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
Packit 58578d
  const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
Packit 58578d
{
Packit 58578d
  return get<0>(x)<get<0>(y);
Packit 58578d
}
Packit 58578d
Packit 58578d
template<
Packit 58578d
  typename Value1,typename IndexSpecifierList1,typename Allocator1,
Packit 58578d
  typename Value2,typename IndexSpecifierList2,typename Allocator2
Packit 58578d
>
Packit 58578d
bool operator!=(
Packit 58578d
  const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
Packit 58578d
  const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
Packit 58578d
{
Packit 58578d
  return get<0>(x)!=get<0>(y);
Packit 58578d
}
Packit 58578d
Packit 58578d
template<
Packit 58578d
  typename Value1,typename IndexSpecifierList1,typename Allocator1,
Packit 58578d
  typename Value2,typename IndexSpecifierList2,typename Allocator2
Packit 58578d
>
Packit 58578d
bool operator>(
Packit 58578d
  const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
Packit 58578d
  const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
Packit 58578d
{
Packit 58578d
  return get<0>(x)>get<0>(y);
Packit 58578d
}
Packit 58578d
Packit 58578d
template<
Packit 58578d
  typename Value1,typename IndexSpecifierList1,typename Allocator1,
Packit 58578d
  typename Value2,typename IndexSpecifierList2,typename Allocator2
Packit 58578d
>
Packit 58578d
bool operator>=(
Packit 58578d
  const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
Packit 58578d
  const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
Packit 58578d
{
Packit 58578d
  return get<0>(x)>=get<0>(y);
Packit 58578d
}
Packit 58578d
Packit 58578d
template<
Packit 58578d
  typename Value1,typename IndexSpecifierList1,typename Allocator1,
Packit 58578d
  typename Value2,typename IndexSpecifierList2,typename Allocator2
Packit 58578d
>
Packit 58578d
bool operator<=(
Packit 58578d
  const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
Packit 58578d
  const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
Packit 58578d
{
Packit 58578d
  return get<0>(x)<=get<0>(y);
Packit 58578d
}
Packit 58578d
Packit 58578d
/*  specialized algorithms */
Packit 58578d
Packit 58578d
template<typename Value,typename IndexSpecifierList,typename Allocator>
Packit 58578d
void swap(
Packit 58578d
  multi_index_container<Value,IndexSpecifierList,Allocator>& x,
Packit 58578d
  multi_index_container<Value,IndexSpecifierList,Allocator>& y)
Packit 58578d
{
Packit 58578d
  x.swap(y);
Packit 58578d
}
Packit 58578d
Packit 58578d
} /* namespace multi_index */
Packit 58578d
Packit 58578d
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
Packit 58578d
/* class version = 1 : we now serialize the size through
Packit 58578d
 * boost::serialization::collection_size_type.
Packit 58578d
 * class version = 2 : proper use of {save|load}_construct_data.
Packit 58578d
 */
Packit 58578d
Packit 58578d
namespace serialization {
Packit 58578d
template<typename Value,typename IndexSpecifierList,typename Allocator>
Packit 58578d
struct version<
Packit 58578d
  boost::multi_index_container<Value,IndexSpecifierList,Allocator>
Packit 58578d
>
Packit 58578d
{
Packit 58578d
  BOOST_STATIC_CONSTANT(int,value=2);
Packit 58578d
};
Packit 58578d
} /* namespace serialization */
Packit 58578d
#endif
Packit 58578d
Packit 58578d
/* Associated global functions are promoted to namespace boost, except
Packit 58578d
 * comparison operators and swap, which are meant to be Koenig looked-up.
Packit 58578d
 */
Packit 58578d
Packit 58578d
using multi_index::get;
Packit 58578d
using multi_index::project;
Packit 58578d
Packit 58578d
} /* namespace boost */
Packit 58578d
Packit 58578d
#undef BOOST_MULTI_INDEX_CHECK_INVARIANT
Packit 58578d
#undef BOOST_MULTI_INDEX_CHECK_INVARIANT_OF
Packit 58578d
Packit 58578d
#endif