epoc32/include/stdapis/boost/multi_index_container.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
williamr@2
     1
/* Multiply indexed container.
williamr@2
     2
 *
williamr@2
     3
 * Copyright 2003-2007 Joaquín M López Muñoz.
williamr@2
     4
 * Distributed under the Boost Software License, Version 1.0.
williamr@2
     5
 * (See accompanying file LICENSE_1_0.txt or copy at
williamr@2
     6
 * http://www.boost.org/LICENSE_1_0.txt)
williamr@2
     7
 *
williamr@2
     8
 * See http://www.boost.org/libs/multi_index for library home page.
williamr@2
     9
 */
williamr@2
    10
williamr@2
    11
#ifndef BOOST_MULTI_INDEX_HPP
williamr@2
    12
#define BOOST_MULTI_INDEX_HPP
williamr@2
    13
williamr@2
    14
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
williamr@2
    15
#pragma once
williamr@2
    16
#endif
williamr@2
    17
williamr@2
    18
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
williamr@2
    19
#include <algorithm>
williamr@2
    20
#include <boost/detail/allocator_utilities.hpp>
williamr@2
    21
#include <boost/detail/no_exceptions_support.hpp>
williamr@2
    22
#include <boost/detail/workaround.hpp>
williamr@2
    23
#include <boost/mpl/at.hpp>
williamr@2
    24
#include <boost/mpl/contains.hpp>
williamr@2
    25
#include <boost/mpl/find_if.hpp>
williamr@2
    26
#include <boost/mpl/identity.hpp>
williamr@2
    27
#include <boost/mpl/int.hpp>
williamr@2
    28
#include <boost/mpl/size.hpp>
williamr@2
    29
#include <boost/mpl/deref.hpp>
williamr@2
    30
#include <boost/multi_index_container_fwd.hpp>
williamr@2
    31
#include <boost/multi_index/detail/access_specifier.hpp>
williamr@2
    32
#include <boost/multi_index/detail/base_type.hpp>
williamr@2
    33
#include <boost/multi_index/detail/converter.hpp>
williamr@2
    34
#include <boost/multi_index/detail/def_ctor_tuple_cons.hpp>
williamr@2
    35
#include <boost/multi_index/detail/header_holder.hpp>
williamr@2
    36
#include <boost/multi_index/detail/has_tag.hpp>
williamr@2
    37
#include <boost/multi_index/detail/no_duplicate_tags.hpp>
williamr@2
    38
#include <boost/multi_index/detail/prevent_eti.hpp>
williamr@2
    39
#include <boost/multi_index/detail/safe_mode.hpp>
williamr@2
    40
#include <boost/multi_index/detail/scope_guard.hpp>
williamr@2
    41
#include <boost/static_assert.hpp>
williamr@2
    42
#include <boost/type_traits/is_same.hpp>
williamr@2
    43
#include <boost/utility/base_from_member.hpp>
williamr@2
    44
williamr@2
    45
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
williamr@2
    46
#include <boost/multi_index/detail/archive_constructed.hpp>
williamr@2
    47
#include <boost/serialization/nvp.hpp>
williamr@2
    48
#include <boost/serialization/split_member.hpp>
williamr@2
    49
#include <boost/throw_exception.hpp> 
williamr@2
    50
#endif
williamr@2
    51
williamr@2
    52
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
williamr@2
    53
#include <boost/multi_index/detail/invariant_assert.hpp>
williamr@2
    54
#define BOOST_MULTI_INDEX_CHECK_INVARIANT                                    \
williamr@2
    55
  detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)=                 \
williamr@2
    56
    detail::make_obj_guard(*this,&multi_index_container::check_invariant_);  \
williamr@2
    57
  BOOST_JOIN(check_invariant_,__LINE__).touch();
williamr@2
    58
#else
williamr@2
    59
#define BOOST_MULTI_INDEX_CHECK_INVARIANT
williamr@2
    60
#endif
williamr@2
    61
williamr@2
    62
namespace boost{
williamr@2
    63
williamr@2
    64
namespace multi_index{
williamr@2
    65
williamr@2
    66
template<typename Value,typename IndexSpecifierList,typename Allocator>
williamr@2
    67
class multi_index_container:
williamr@2
    68
  private ::boost::base_from_member<
williamr@2
    69
    typename boost::detail::allocator::rebind_to<
williamr@2
    70
      Allocator,
williamr@2
    71
      typename detail::multi_index_node_type<
williamr@2
    72
        Value,IndexSpecifierList,Allocator>::type
williamr@2
    73
    >::type>,
williamr@2
    74
  BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS detail::header_holder<
williamr@2
    75
    typename detail::multi_index_node_type<
williamr@2
    76
      Value,IndexSpecifierList,Allocator>::type,
williamr@2
    77
    multi_index_container<Value,IndexSpecifierList,Allocator> >,
williamr@2
    78
  public detail::multi_index_base_type<
williamr@2
    79
    Value,IndexSpecifierList,Allocator>::type
williamr@2
    80
{
williamr@2
    81
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
williamr@2
    82
    BOOST_WORKAROUND(__MWERKS__,<=0x3003)
williamr@2
    83
/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the
williamr@2
    84
 * lifetime of const references bound to temporaries --precisely what
williamr@2
    85
 * scopeguards are.
williamr@2
    86
 */
williamr@2
    87
williamr@2
    88
#pragma parse_mfunc_templ off
williamr@2
    89
#endif
williamr@2
    90
williamr@2
    91
private:
williamr@2
    92
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
williamr@2
    93
  template <typename,typename,typename> friend class  detail::index_base;
williamr@2
    94
  template <typename,typename>          friend class  detail::header_holder;
williamr@2
    95
  template <typename,typename>          friend class  detail::converter;
williamr@2
    96
#endif
williamr@2
    97
williamr@2
    98
  typedef typename detail::multi_index_base_type<
williamr@2
    99
      Value,IndexSpecifierList,Allocator>::type   super;
williamr@2
   100
  typedef ::boost::base_from_member<
williamr@2
   101
    typename boost::detail::allocator::rebind_to<
williamr@2
   102
      Allocator,
williamr@2
   103
      typename super::node_type
williamr@2
   104
    >::type>                                      bfm_allocator;
williamr@2
   105
  typedef detail::header_holder<
williamr@2
   106
    typename super::node_type,
williamr@2
   107
    multi_index_container>                        bfm_header;
williamr@2
   108
williamr@2
   109
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
williamr@2
   110
  /* see definition of index_type_list below */
williamr@2
   111
  typedef typename super::index_type_list         super_index_type_list;
williamr@2
   112
#endif
williamr@2
   113
williamr@2
   114
public:
williamr@2
   115
  /* All types are inherited from super, a few are explicitly
williamr@2
   116
   * brought forward here to save us some typename's.
williamr@2
   117
   */
williamr@2
   118
williamr@2
   119
#if defined(BOOST_MSVC)
williamr@2
   120
  typedef 
williamr@2
   121
    detail::default_constructible_tuple_cons<
williamr@2
   122
      typename super::ctor_args_list>              ctor_args_list;
williamr@2
   123
#else
williamr@2
   124
  typedef typename super::ctor_args_list           ctor_args_list;
williamr@2
   125
#endif
williamr@2
   126
williamr@2
   127
  typedef IndexSpecifierList                       index_specifier_type_list;
williamr@2
   128
 
williamr@2
   129
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
williamr@2
   130
  /* MSVC++ 6.0 chokes on moderately long index lists (around 6 indices
williamr@2
   131
   * or more), with errors ranging from corrupt exes to duplicate
williamr@2
   132
   * comdats. The following type hiding hack alleviates this condition;
williamr@2
   133
   * best results combined with type hiding of the indexed_by construct
williamr@2
   134
   * itself, as explained in the "Compiler specifics" section of
williamr@2
   135
   * the documentation.
williamr@2
   136
   */
williamr@2
   137
williamr@2
   138
  struct index_type_list:super_index_type_list
williamr@2
   139
  {
williamr@2
   140
    typedef index_type_list                      type;
williamr@2
   141
    typedef typename super_index_type_list::back back;
williamr@2
   142
    typedef mpl::v_iter<type,0>                  begin;
williamr@2
   143
    typedef mpl::v_iter<
williamr@2
   144
      type,
williamr@2
   145
      mpl::size<super_index_type_list>::value>   end;
williamr@2
   146
  };
williamr@2
   147
#else
williamr@2
   148
  typedef typename super::index_type_list          index_type_list;
williamr@2
   149
#endif
williamr@2
   150
williamr@2
   151
  typedef typename super::iterator_type_list       iterator_type_list;
williamr@2
   152
  typedef typename super::const_iterator_type_list const_iterator_type_list;
williamr@2
   153
  typedef typename super::value_type               value_type;
williamr@2
   154
  typedef typename super::final_allocator_type     allocator_type;
williamr@2
   155
  typedef typename super::iterator                 iterator;
williamr@2
   156
  typedef typename super::const_iterator           const_iterator;
williamr@2
   157
williamr@2
   158
  BOOST_STATIC_ASSERT(
williamr@2
   159
    detail::no_duplicate_tags_in_index_list<index_type_list>::value);
williamr@2
   160
williamr@2
   161
  /* global project() needs to see this publicly */
williamr@2
   162
williamr@2
   163
  typedef typename super::node_type node_type;
williamr@2
   164
williamr@2
   165
  /* construct/copy/destroy */
williamr@2
   166
williamr@2
   167
  explicit multi_index_container(
williamr@2
   168
williamr@2
   169
#if BOOST_WORKAROUND(__IBMCPP__,<=600)
williamr@2
   170
    /* VisualAge seems to have an ETI issue with the default values
williamr@2
   171
     * for arguments args_list and al.
williamr@2
   172
     */
williamr@2
   173
williamr@2
   174
    const ctor_args_list& args_list=
williamr@2
   175
      typename mpl::identity<multi_index_container>::type::
williamr@2
   176
        ctor_args_list(),
williamr@2
   177
    const allocator_type& al=
williamr@2
   178
      typename mpl::identity<multi_index_container>::type::
williamr@2
   179
        allocator_type()):
williamr@2
   180
#else
williamr@2
   181
    const ctor_args_list& args_list=ctor_args_list(),
williamr@2
   182
    const allocator_type& al=allocator_type()):
williamr@2
   183
#endif
williamr@2
   184
williamr@2
   185
    bfm_allocator(al),
williamr@2
   186
    super(args_list,bfm_allocator::member),
williamr@2
   187
    node_count(0)
williamr@2
   188
  {
williamr@2
   189
    BOOST_MULTI_INDEX_CHECK_INVARIANT;
williamr@2
   190
  }    
williamr@2
   191
williamr@2
   192
  template<typename InputIterator>
williamr@2
   193
  multi_index_container(
williamr@2
   194
    InputIterator first,InputIterator last,
williamr@2
   195
williamr@2
   196
#if BOOST_WORKAROUND(__IBMCPP__,<=600)
williamr@2
   197
    /* VisualAge seems to have an ETI issue with the default values
williamr@2
   198
     * for arguments args_list and al.
williamr@2
   199
     */
williamr@2
   200
williamr@2
   201
    const ctor_args_list& args_list=
williamr@2
   202
      typename mpl::identity<multi_index_container>::type::
williamr@2
   203
        ctor_args_list(),
williamr@2
   204
    const allocator_type& al=
williamr@2
   205
      typename mpl::identity<multi_index_container>::type::
williamr@2
   206
        allocator_type()):
williamr@2
   207
#else
williamr@2
   208
    const ctor_args_list& args_list=ctor_args_list(),
williamr@2
   209
    const allocator_type& al=allocator_type()):
williamr@2
   210
#endif
williamr@2
   211
williamr@2
   212
    bfm_allocator(al),
williamr@2
   213
    super(args_list,bfm_allocator::member),
williamr@2
   214
    node_count(0)
williamr@2
   215
  {
williamr@2
   216
    BOOST_MULTI_INDEX_CHECK_INVARIANT;
williamr@2
   217
    BOOST_TRY{
williamr@2
   218
      iterator hint=super::end();
williamr@2
   219
      for(;first!=last;++first){
williamr@2
   220
        hint=super::make_iterator(insert_(*first,hint.get_node()).first);
williamr@2
   221
      }
williamr@2
   222
    }
williamr@2
   223
    BOOST_CATCH(...){
williamr@2
   224
      clear_();
williamr@2
   225
      BOOST_RETHROW;
williamr@2
   226
    }
williamr@2
   227
    BOOST_CATCH_END
williamr@2
   228
  }
williamr@2
   229
williamr@2
   230
  multi_index_container(
williamr@2
   231
    const multi_index_container<Value,IndexSpecifierList,Allocator>& x):
williamr@2
   232
    bfm_allocator(x.bfm_allocator::member),
williamr@2
   233
    bfm_header(),
williamr@2
   234
    super(x),
williamr@2
   235
    node_count(0)
williamr@2
   236
  {
williamr@2
   237
    copy_map_type map(bfm_allocator::member,x.size(),x.header(),header());
williamr@2
   238
    for(const_iterator it=x.begin(),it_end=x.end();it!=it_end;++it){
williamr@2
   239
      map.clone(it.get_node());
williamr@2
   240
    }
williamr@2
   241
    super::copy_(x,map);
williamr@2
   242
    map.release();
williamr@2
   243
    node_count=x.size();
williamr@2
   244
williamr@2
   245
    /* Not until this point are the indices required to be consistent,
williamr@2
   246
     * hence the position of the invariant checker.
williamr@2
   247
     */
williamr@2
   248
williamr@2
   249
    BOOST_MULTI_INDEX_CHECK_INVARIANT;
williamr@2
   250
  }
williamr@2
   251
williamr@2
   252
  ~multi_index_container()
williamr@2
   253
  {
williamr@2
   254
    delete_all_nodes_();
williamr@2
   255
  }
williamr@2
   256
williamr@2
   257
  multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
williamr@2
   258
    const multi_index_container<Value,IndexSpecifierList,Allocator>& x)
williamr@2
   259
  {
williamr@2
   260
    BOOST_MULTI_INDEX_CHECK_INVARIANT;
williamr@2
   261
    multi_index_container<Value,IndexSpecifierList,Allocator> tmp(x);
williamr@2
   262
    this->swap(tmp);
williamr@2
   263
    return *this;
williamr@2
   264
  }
williamr@2
   265
williamr@2
   266
  allocator_type get_allocator()const
williamr@2
   267
  {
williamr@2
   268
    return allocator_type(bfm_allocator::member);
williamr@2
   269
  }
williamr@2
   270
williamr@2
   271
  /* retrieval of indices by number */
williamr@2
   272
williamr@2
   273
#if !defined(BOOST_NO_MEMBER_TEMPLATES)
williamr@2
   274
  template<int N>
williamr@2
   275
  struct nth_index
williamr@2
   276
  {
williamr@2
   277
    BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
williamr@2
   278
    typedef typename mpl::at_c<index_type_list,N>::type type;
williamr@2
   279
  };
williamr@2
   280
williamr@2
   281
  template<int N>
williamr@2
   282
  typename nth_index<N>::type& get(BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int,N))
williamr@2
   283
  {
williamr@2
   284
    BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
williamr@2
   285
    return *this;
williamr@2
   286
  }
williamr@2
   287
williamr@2
   288
  template<int N>
williamr@2
   289
  const typename nth_index<N>::type& get(
williamr@2
   290
    BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int,N))const
williamr@2
   291
  {
williamr@2
   292
    BOOST_STATIC_ASSERT(N>=0&&N<mpl::size<index_type_list>::type::value);
williamr@2
   293
    return *this;
williamr@2
   294
  }
williamr@2
   295
#endif
williamr@2
   296
williamr@2
   297
  /* retrieval of indices by tag */
williamr@2
   298
williamr@2
   299
#if !defined(BOOST_NO_MEMBER_TEMPLATES)
williamr@2
   300
  template<typename Tag>
williamr@2
   301
  struct index
williamr@2
   302
  {
williamr@2
   303
    typedef typename mpl::find_if<
williamr@2
   304
      index_type_list,
williamr@2
   305
      detail::has_tag<Tag>
williamr@2
   306
    >::type                                    iter;
williamr@2
   307
williamr@2
   308
    BOOST_STATIC_CONSTANT(
williamr@2
   309
      bool,index_found=!(is_same<iter,typename mpl::end<index_type_list>::type >::value));
williamr@2
   310
    BOOST_STATIC_ASSERT(index_found);
williamr@2
   311
williamr@2
   312
    typedef typename mpl::deref<iter>::type    type;
williamr@2
   313
  };
williamr@2
   314
williamr@2
   315
  template<typename Tag>
williamr@2
   316
  typename index<Tag>::type& get(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag))
williamr@2
   317
  {
williamr@2
   318
    return *this;
williamr@2
   319
  }
williamr@2
   320
williamr@2
   321
  template<typename Tag>
williamr@2
   322
  const typename index<Tag>::type& get(
williamr@2
   323
    BOOST_EXPLICIT_TEMPLATE_TYPE(Tag))const
williamr@2
   324
  {
williamr@2
   325
    return *this;
williamr@2
   326
  }
williamr@2
   327
#endif
williamr@2
   328
williamr@2
   329
  /* projection of iterators by number */
williamr@2
   330
williamr@2
   331
#if !defined(BOOST_NO_MEMBER_TEMPLATES)
williamr@2
   332
  template<int N>
williamr@2
   333
  struct nth_index_iterator
williamr@2
   334
  {
williamr@2
   335
    typedef typename nth_index<N>::type::iterator type;
williamr@2
   336
  };
williamr@2
   337
williamr@2
   338
  template<int N>
williamr@2
   339
  struct nth_index_const_iterator
williamr@2
   340
  {
williamr@2
   341
    typedef typename nth_index<N>::type::const_iterator type;
williamr@2
   342
  };
williamr@2
   343
williamr@2
   344
  template<int N,typename IteratorType>
williamr@2
   345
  typename nth_index_iterator<N>::type project(
williamr@2
   346
    IteratorType it
williamr@2
   347
    BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))
williamr@2
   348
  {
williamr@2
   349
    typedef typename nth_index<N>::type index;
williamr@2
   350
williamr@2
   351
    BOOST_STATIC_ASSERT(
williamr@2
   352
      (mpl::contains<iterator_type_list,IteratorType>::value));
williamr@2
   353
williamr@2
   354
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
williamr@2
   355
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(
williamr@2
   356
      it,static_cast<typename IteratorType::container_type&>(*this));
williamr@2
   357
williamr@2
   358
    return index::make_iterator(static_cast<node_type*>(it.get_node()));
williamr@2
   359
  }
williamr@2
   360
williamr@2
   361
  template<int N,typename IteratorType>
williamr@2
   362
  typename nth_index_const_iterator<N>::type project(
williamr@2
   363
    IteratorType it
williamr@2
   364
    BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))const
williamr@2
   365
  {
williamr@2
   366
    typedef typename nth_index<N>::type index;
williamr@2
   367
williamr@2
   368
    BOOST_STATIC_ASSERT((
williamr@2
   369
      mpl::contains<iterator_type_list,IteratorType>::value||
williamr@2
   370
      mpl::contains<const_iterator_type_list,IteratorType>::value));
williamr@2
   371
williamr@2
   372
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
williamr@2
   373
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(
williamr@2
   374
      it,static_cast<const typename IteratorType::container_type&>(*this));
williamr@2
   375
    return index::make_iterator(static_cast<node_type*>(it.get_node()));
williamr@2
   376
  }
williamr@2
   377
#endif
williamr@2
   378
williamr@2
   379
  /* projection of iterators by tag */
williamr@2
   380
williamr@2
   381
#if !defined(BOOST_NO_MEMBER_TEMPLATES)
williamr@2
   382
  template<typename Tag>
williamr@2
   383
  struct index_iterator
williamr@2
   384
  {
williamr@2
   385
    typedef typename index<Tag>::type::iterator type;
williamr@2
   386
  };
williamr@2
   387
williamr@2
   388
  template<typename Tag>
williamr@2
   389
  struct index_const_iterator
williamr@2
   390
  {
williamr@2
   391
    typedef typename index<Tag>::type::const_iterator type;
williamr@2
   392
  };
williamr@2
   393
williamr@2
   394
  template<typename Tag,typename IteratorType>
williamr@2
   395
  typename index_iterator<Tag>::type project(
williamr@2
   396
    IteratorType it
williamr@2
   397
    BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
williamr@2
   398
  {
williamr@2
   399
    typedef typename index<Tag>::type index;
williamr@2
   400
williamr@2
   401
    BOOST_STATIC_ASSERT(
williamr@2
   402
      (mpl::contains<iterator_type_list,IteratorType>::value));
williamr@2
   403
williamr@2
   404
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
williamr@2
   405
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(
williamr@2
   406
      it,static_cast<typename IteratorType::container_type&>(*this));
williamr@2
   407
    return index::make_iterator(static_cast<node_type*>(it.get_node()));
williamr@2
   408
  }
williamr@2
   409
williamr@2
   410
  template<typename Tag,typename IteratorType>
williamr@2
   411
  typename index_const_iterator<Tag>::type project(
williamr@2
   412
    IteratorType it
williamr@2
   413
    BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))const
williamr@2
   414
  {
williamr@2
   415
    typedef typename index<Tag>::type index;
williamr@2
   416
williamr@2
   417
    BOOST_STATIC_ASSERT((
williamr@2
   418
      mpl::contains<iterator_type_list,IteratorType>::value||
williamr@2
   419
      mpl::contains<const_iterator_type_list,IteratorType>::value));
williamr@2
   420
williamr@2
   421
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
williamr@2
   422
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(
williamr@2
   423
      it,static_cast<const typename IteratorType::container_type&>(*this));
williamr@2
   424
    return index::make_iterator(static_cast<node_type*>(it.get_node()));
williamr@2
   425
  }
williamr@2
   426
#endif
williamr@2
   427
williamr@2
   428
BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
williamr@2
   429
  typedef typename super::copy_map_type copy_map_type;
williamr@2
   430
williamr@2
   431
  node_type* header()const
williamr@2
   432
  {
williamr@2
   433
    return bfm_header::member;
williamr@2
   434
  }
williamr@2
   435
williamr@2
   436
  node_type* allocate_node()
williamr@2
   437
  {
williamr@2
   438
    return bfm_allocator::member.allocate(1);
williamr@2
   439
  }
williamr@2
   440
williamr@2
   441
  void deallocate_node(node_type* x)
williamr@2
   442
  {
williamr@2
   443
    bfm_allocator::member.deallocate(x,1);
williamr@2
   444
  }
williamr@2
   445
williamr@2
   446
  bool empty_()const
williamr@2
   447
  {
williamr@2
   448
    return node_count==0;
williamr@2
   449
  }
williamr@2
   450
williamr@2
   451
  std::size_t size_()const
williamr@2
   452
  {
williamr@2
   453
    return node_count;
williamr@2
   454
  }
williamr@2
   455
williamr@2
   456
  std::size_t max_size_()const
williamr@2
   457
  {
williamr@2
   458
    return static_cast<std::size_t >(-1);
williamr@2
   459
  }
williamr@2
   460
williamr@2
   461
  std::pair<node_type*,bool> insert_(const Value& v)
williamr@2
   462
  {
williamr@2
   463
    node_type* x=allocate_node();
williamr@2
   464
    BOOST_TRY{
williamr@2
   465
      node_type* res=super::insert_(v,x);
williamr@2
   466
      if(res==x){
williamr@2
   467
        ++node_count;
williamr@2
   468
        return std::pair<node_type*,bool>(res,true);
williamr@2
   469
      }
williamr@2
   470
      else{
williamr@2
   471
        deallocate_node(x);
williamr@2
   472
        return std::pair<node_type*,bool>(res,false);
williamr@2
   473
      }
williamr@2
   474
    }
williamr@2
   475
    BOOST_CATCH(...){
williamr@2
   476
      deallocate_node(x);
williamr@2
   477
      BOOST_RETHROW;
williamr@2
   478
    }
williamr@2
   479
    BOOST_CATCH_END
williamr@2
   480
  }
williamr@2
   481
williamr@2
   482
  std::pair<node_type*,bool> insert_(const Value& v,node_type* position)
williamr@2
   483
  {
williamr@2
   484
    node_type* x=allocate_node();
williamr@2
   485
    BOOST_TRY{
williamr@2
   486
      node_type* res=super::insert_(v,position,x);
williamr@2
   487
      if(res==x){
williamr@2
   488
        ++node_count;
williamr@2
   489
        return std::pair<node_type*,bool>(res,true);
williamr@2
   490
      }
williamr@2
   491
      else{
williamr@2
   492
        deallocate_node(x);
williamr@2
   493
        return std::pair<node_type*,bool>(res,false);
williamr@2
   494
      }
williamr@2
   495
    }
williamr@2
   496
    BOOST_CATCH(...){
williamr@2
   497
      deallocate_node(x);
williamr@2
   498
      BOOST_RETHROW;
williamr@2
   499
    }
williamr@2
   500
    BOOST_CATCH_END
williamr@2
   501
  }
williamr@2
   502
williamr@2
   503
  void erase_(node_type* x)
williamr@2
   504
  {
williamr@2
   505
    super::erase_(x);
williamr@2
   506
    deallocate_node(x);
williamr@2
   507
    --node_count;
williamr@2
   508
  }
williamr@2
   509
williamr@2
   510
  void delete_node_(node_type* x)
williamr@2
   511
  {
williamr@2
   512
    super::delete_node_(x);
williamr@2
   513
    deallocate_node(x);
williamr@2
   514
  }
williamr@2
   515
williamr@2
   516
  void delete_all_nodes_()
williamr@2
   517
  {
williamr@2
   518
    super::delete_all_nodes_();
williamr@2
   519
  }
williamr@2
   520
williamr@2
   521
  void clear_()
williamr@2
   522
  {
williamr@2
   523
    delete_all_nodes_();
williamr@2
   524
    super::clear_();
williamr@2
   525
    node_count=0;
williamr@2
   526
  }
williamr@2
   527
williamr@2
   528
  void swap_(multi_index_container<Value,IndexSpecifierList,Allocator>& x)
williamr@2
   529
  {
williamr@2
   530
    std::swap(bfm_header::member,x.bfm_header::member);
williamr@2
   531
    super::swap_(x);
williamr@2
   532
    std::swap(node_count,x.node_count);
williamr@2
   533
  }
williamr@2
   534
williamr@2
   535
  bool replace_(const Value& k,node_type* x)
williamr@2
   536
  {
williamr@2
   537
    return super::replace_(k,x);
williamr@2
   538
  }
williamr@2
   539
williamr@2
   540
  template<typename Modifier>
williamr@2
   541
  bool modify_(Modifier mod,node_type* x)
williamr@2
   542
  {
williamr@2
   543
    mod(const_cast<value_type&>(x->value()));
williamr@2
   544
williamr@2
   545
    BOOST_TRY{
williamr@2
   546
      if(!super::modify_(x)){
williamr@2
   547
        deallocate_node(x);
williamr@2
   548
        --node_count;
williamr@2
   549
        return false;
williamr@2
   550
      }
williamr@2
   551
      else return true;
williamr@2
   552
    }
williamr@2
   553
    BOOST_CATCH(...){
williamr@2
   554
      deallocate_node(x);
williamr@2
   555
      --node_count;
williamr@2
   556
      BOOST_RETHROW;
williamr@2
   557
    }
williamr@2
   558
    BOOST_CATCH_END
williamr@2
   559
  }
williamr@2
   560
williamr@2
   561
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
williamr@2
   562
  /* serialization */
williamr@2
   563
williamr@2
   564
  friend class boost::serialization::access;
williamr@2
   565
williamr@2
   566
  BOOST_SERIALIZATION_SPLIT_MEMBER()
williamr@2
   567
williamr@2
   568
  typedef typename super::index_saver_type        index_saver_type;
williamr@2
   569
  typedef typename super::index_loader_type       index_loader_type;
williamr@2
   570
williamr@2
   571
  template<class Archive>
williamr@2
   572
  void save(Archive& ar,const unsigned int version)const
williamr@2
   573
  {
williamr@2
   574
    const std::size_t s=size_();
williamr@2
   575
    ar<<serialization::make_nvp("count",s);
williamr@2
   576
    index_saver_type sm(bfm_allocator::member,s);
williamr@2
   577
williamr@2
   578
    for(iterator it=super::begin(),it_end=super::end();it!=it_end;++it){
williamr@2
   579
      ar<<serialization::make_nvp("item",*it);
williamr@2
   580
      sm.add(it.get_node(),ar,version);
williamr@2
   581
    }
williamr@2
   582
    sm.add_track(header(),ar,version);
williamr@2
   583
williamr@2
   584
    super::save_(ar,version,sm);
williamr@2
   585
  }
williamr@2
   586
williamr@2
   587
  template<class Archive>
williamr@2
   588
  void load(Archive& ar,const unsigned int version)
williamr@2
   589
  {
williamr@2
   590
    BOOST_MULTI_INDEX_CHECK_INVARIANT;
williamr@2
   591
williamr@2
   592
    clear_(); 
williamr@2
   593
williamr@2
   594
    std::size_t s;
williamr@2
   595
    ar>>serialization::make_nvp("count",s);
williamr@2
   596
    index_loader_type lm(bfm_allocator::member,s);
williamr@2
   597
williamr@2
   598
    for(std::size_t n=0;n<s;++n){
williamr@2
   599
      detail::archive_constructed<Value> value("item",ar,version);
williamr@2
   600
      std::pair<node_type*,bool> p=insert_(
williamr@2
   601
        value.get(),super::end().get_node());
williamr@2
   602
      if(!p.second)throw_exception(
williamr@2
   603
        archive::archive_exception(
williamr@2
   604
          archive::archive_exception::other_exception));
williamr@2
   605
      ar.reset_object_address(&p.first->value(),&value.get());
williamr@2
   606
      lm.add(p.first,ar,version);
williamr@2
   607
    }
williamr@2
   608
    lm.add_track(header(),ar,version);
williamr@2
   609
williamr@2
   610
    super::load_(ar,version,lm);
williamr@2
   611
  }
williamr@2
   612
#endif
williamr@2
   613
williamr@2
   614
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
williamr@2
   615
  /* invariant stuff */
williamr@2
   616
williamr@2
   617
  bool invariant_()const
williamr@2
   618
  {
williamr@2
   619
    return super::invariant_();
williamr@2
   620
  }
williamr@2
   621
williamr@2
   622
  void check_invariant_()const
williamr@2
   623
  {
williamr@2
   624
    BOOST_MULTI_INDEX_INVARIANT_ASSERT(invariant_());
williamr@2
   625
  }
williamr@2
   626
#endif
williamr@2
   627
williamr@2
   628
private:
williamr@2
   629
  std::size_t node_count;
williamr@2
   630
williamr@2
   631
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
williamr@2
   632
    BOOST_WORKAROUND(__MWERKS__,<=0x3003)
williamr@2
   633
#pragma parse_mfunc_templ reset
williamr@2
   634
#endif
williamr@2
   635
};
williamr@2
   636
williamr@2
   637
/* retrieval of indices by number */
williamr@2
   638
williamr@2
   639
template<typename MultiIndexContainer,int N>
williamr@2
   640
struct nth_index
williamr@2
   641
{
williamr@2
   642
  BOOST_STATIC_CONSTANT(
williamr@2
   643
    int,
williamr@2
   644
    M=mpl::size<typename MultiIndexContainer::index_type_list>::type::value);
williamr@2
   645
  BOOST_STATIC_ASSERT(N>=0&&N<M);
williamr@2
   646
  typedef typename mpl::at_c<
williamr@2
   647
    typename MultiIndexContainer::index_type_list,N>::type type;
williamr@2
   648
};
williamr@2
   649
williamr@2
   650
template<int N,typename Value,typename IndexSpecifierList,typename Allocator>
williamr@2
   651
typename nth_index<
williamr@2
   652
  multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type&
williamr@2
   653
get(
williamr@2
   654
  multi_index_container<Value,IndexSpecifierList,Allocator>& m
williamr@2
   655
  BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))
williamr@2
   656
{
williamr@2
   657
  typedef multi_index_container<
williamr@2
   658
    Value,IndexSpecifierList,Allocator>    multi_index_type;
williamr@2
   659
  typedef typename nth_index<
williamr@2
   660
    multi_index_container<
williamr@2
   661
      Value,IndexSpecifierList,Allocator>,
williamr@2
   662
    N
williamr@2
   663
  >::type                                  index;
williamr@2
   664
williamr@2
   665
  BOOST_STATIC_ASSERT(N>=0&&
williamr@2
   666
    N<
williamr@2
   667
    mpl::size<
williamr@2
   668
      BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list
williamr@2
   669
    >::type::value);
williamr@2
   670
williamr@2
   671
  return detail::converter<multi_index_type,index>::index(m);
williamr@2
   672
}
williamr@2
   673
williamr@2
   674
template<int N,typename Value,typename IndexSpecifierList,typename Allocator>
williamr@2
   675
const typename nth_index<
williamr@2
   676
  multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type&
williamr@2
   677
get(
williamr@2
   678
  const multi_index_container<Value,IndexSpecifierList,Allocator>& m
williamr@2
   679
  BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))
williamr@2
   680
{
williamr@2
   681
  typedef multi_index_container<
williamr@2
   682
    Value,IndexSpecifierList,Allocator>    multi_index_type;
williamr@2
   683
  typedef typename nth_index<
williamr@2
   684
    multi_index_container<
williamr@2
   685
      Value,IndexSpecifierList,Allocator>,
williamr@2
   686
    N
williamr@2
   687
  >::type                                  index;
williamr@2
   688
williamr@2
   689
  BOOST_STATIC_ASSERT(N>=0&&
williamr@2
   690
    N<
williamr@2
   691
    mpl::size<
williamr@2
   692
      BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list
williamr@2
   693
    >::type::value);
williamr@2
   694
williamr@2
   695
  return detail::converter<multi_index_type,index>::index(m);
williamr@2
   696
}
williamr@2
   697
williamr@2
   698
/* retrieval of indices by tag */
williamr@2
   699
williamr@2
   700
template<typename MultiIndexContainer,typename Tag>
williamr@2
   701
struct index
williamr@2
   702
{
williamr@2
   703
  typedef typename MultiIndexContainer::index_type_list index_type_list;
williamr@2
   704
williamr@2
   705
  typedef typename mpl::find_if<
williamr@2
   706
    index_type_list,
williamr@2
   707
    detail::has_tag<Tag>
williamr@2
   708
  >::type                                      iter;
williamr@2
   709
williamr@2
   710
  BOOST_STATIC_CONSTANT(
williamr@2
   711
    bool,index_found=!(is_same<iter,typename mpl::end<index_type_list>::type >::value));
williamr@2
   712
  BOOST_STATIC_ASSERT(index_found);
williamr@2
   713
williamr@2
   714
  typedef typename mpl::deref<iter>::type       type;
williamr@2
   715
};
williamr@2
   716
williamr@2
   717
template<
williamr@2
   718
  typename Tag,typename Value,typename IndexSpecifierList,typename Allocator
williamr@2
   719
>
williamr@2
   720
typename ::boost::multi_index::index<
williamr@2
   721
  multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type&
williamr@2
   722
get(
williamr@2
   723
  multi_index_container<Value,IndexSpecifierList,Allocator>& m
williamr@2
   724
  BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
williamr@2
   725
{
williamr@2
   726
  typedef multi_index_container<
williamr@2
   727
    Value,IndexSpecifierList,Allocator>         multi_index_type;
williamr@2
   728
  typedef typename ::boost::multi_index::index<
williamr@2
   729
    multi_index_container<
williamr@2
   730
      Value,IndexSpecifierList,Allocator>,
williamr@2
   731
    Tag
williamr@2
   732
  >::type                                       index;
williamr@2
   733
williamr@2
   734
  return detail::converter<multi_index_type,index>::index(m);
williamr@2
   735
}
williamr@2
   736
williamr@2
   737
template<
williamr@2
   738
  typename Tag,typename Value,typename IndexSpecifierList,typename Allocator
williamr@2
   739
>
williamr@2
   740
const typename ::boost::multi_index::index<
williamr@2
   741
  multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type&
williamr@2
   742
get(
williamr@2
   743
  const multi_index_container<Value,IndexSpecifierList,Allocator>& m
williamr@2
   744
  BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
williamr@2
   745
{
williamr@2
   746
  typedef multi_index_container<
williamr@2
   747
    Value,IndexSpecifierList,Allocator>         multi_index_type;
williamr@2
   748
  typedef typename ::boost::multi_index::index<
williamr@2
   749
    multi_index_container<
williamr@2
   750
      Value,IndexSpecifierList,Allocator>,
williamr@2
   751
    Tag
williamr@2
   752
  >::type                                       index;
williamr@2
   753
williamr@2
   754
  return detail::converter<multi_index_type,index>::index(m);
williamr@2
   755
}
williamr@2
   756
williamr@2
   757
/* projection of iterators by number */
williamr@2
   758
williamr@2
   759
template<typename MultiIndexContainer,int N>
williamr@2
   760
struct nth_index_iterator
williamr@2
   761
{
williamr@2
   762
  typedef typename detail::prevent_eti<
williamr@2
   763
    nth_index<MultiIndexContainer,N>,
williamr@2
   764
    typename nth_index<MultiIndexContainer,N>::type>::type::iterator type;
williamr@2
   765
};
williamr@2
   766
williamr@2
   767
template<typename MultiIndexContainer,int N>
williamr@2
   768
struct nth_index_const_iterator
williamr@2
   769
{
williamr@2
   770
  typedef typename detail::prevent_eti<
williamr@2
   771
    nth_index<MultiIndexContainer,N>,
williamr@2
   772
    typename nth_index<MultiIndexContainer,N>::type
williamr@2
   773
  >::type::const_iterator type;
williamr@2
   774
};
williamr@2
   775
williamr@2
   776
template<
williamr@2
   777
  int N,typename IteratorType,
williamr@2
   778
  typename Value,typename IndexSpecifierList,typename Allocator>
williamr@2
   779
typename nth_index_iterator<
williamr@2
   780
  multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type
williamr@2
   781
project(
williamr@2
   782
  multi_index_container<Value,IndexSpecifierList,Allocator>& m,
williamr@2
   783
  IteratorType it
williamr@2
   784
  BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))
williamr@2
   785
{
williamr@2
   786
  typedef multi_index_container<
williamr@2
   787
    Value,IndexSpecifierList,Allocator>                multi_index_type;
williamr@2
   788
  typedef typename nth_index<multi_index_type,N>::type index;
williamr@2
   789
williamr@2
   790
#if !defined(BOOST_MSVC)||!(BOOST_MSVC<1310) /* ain't work in MSVC++ 6.0/7.0 */
williamr@2
   791
  BOOST_STATIC_ASSERT((
williamr@2
   792
    mpl::contains<
williamr@2
   793
      BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
williamr@2
   794
      IteratorType>::value));
williamr@2
   795
#endif
williamr@2
   796
williamr@2
   797
  BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
williamr@2
   798
williamr@2
   799
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
williamr@2
   800
  typedef detail::converter<
williamr@2
   801
    multi_index_type,
williamr@2
   802
    BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
williamr@2
   803
  BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
williamr@2
   804
#endif
williamr@2
   805
williamr@2
   806
  return detail::converter<multi_index_type,index>::iterator(
williamr@2
   807
    m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
williamr@2
   808
}
williamr@2
   809
williamr@2
   810
template<
williamr@2
   811
  int N,typename IteratorType,
williamr@2
   812
  typename Value,typename IndexSpecifierList,typename Allocator>
williamr@2
   813
typename nth_index_const_iterator<
williamr@2
   814
  multi_index_container<Value,IndexSpecifierList,Allocator>,N>::type
williamr@2
   815
project(
williamr@2
   816
  const multi_index_container<Value,IndexSpecifierList,Allocator>& m,
williamr@2
   817
  IteratorType it
williamr@2
   818
  BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int,N))
williamr@2
   819
{
williamr@2
   820
  typedef multi_index_container<
williamr@2
   821
    Value,IndexSpecifierList,Allocator>                multi_index_type;
williamr@2
   822
  typedef typename nth_index<multi_index_type,N>::type index;
williamr@2
   823
williamr@2
   824
#if !defined(BOOST_MSVC)||!(BOOST_MSVC<1310) /* ain't work in MSVC++ 6.0/7.0 */
williamr@2
   825
  BOOST_STATIC_ASSERT((
williamr@2
   826
    mpl::contains<
williamr@2
   827
      BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
williamr@2
   828
      IteratorType>::value||
williamr@2
   829
    mpl::contains<
williamr@2
   830
      BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list,
williamr@2
   831
      IteratorType>::value));
williamr@2
   832
#endif
williamr@2
   833
williamr@2
   834
  BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
williamr@2
   835
williamr@2
   836
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
williamr@2
   837
  typedef detail::converter<
williamr@2
   838
    multi_index_type,
williamr@2
   839
    BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
williamr@2
   840
  BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
williamr@2
   841
#endif
williamr@2
   842
williamr@2
   843
  return detail::converter<multi_index_type,index>::const_iterator(
williamr@2
   844
    m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
williamr@2
   845
}
williamr@2
   846
williamr@2
   847
/* projection of iterators by tag */
williamr@2
   848
williamr@2
   849
template<typename MultiIndexContainer,typename Tag>
williamr@2
   850
struct index_iterator
williamr@2
   851
{
williamr@2
   852
  typedef typename ::boost::multi_index::index<
williamr@2
   853
    MultiIndexContainer,Tag>::type::iterator    type;
williamr@2
   854
};
williamr@2
   855
williamr@2
   856
template<typename MultiIndexContainer,typename Tag>
williamr@2
   857
struct index_const_iterator
williamr@2
   858
{
williamr@2
   859
  typedef typename ::boost::multi_index::index<
williamr@2
   860
    MultiIndexContainer,Tag>::type::const_iterator type;
williamr@2
   861
};
williamr@2
   862
williamr@2
   863
template<
williamr@2
   864
  typename Tag,typename IteratorType,
williamr@2
   865
  typename Value,typename IndexSpecifierList,typename Allocator>
williamr@2
   866
typename index_iterator<
williamr@2
   867
  multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type
williamr@2
   868
project(
williamr@2
   869
  multi_index_container<Value,IndexSpecifierList,Allocator>& m,
williamr@2
   870
  IteratorType it
williamr@2
   871
  BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
williamr@2
   872
{
williamr@2
   873
  typedef multi_index_container<
williamr@2
   874
    Value,IndexSpecifierList,Allocator>         multi_index_type;
williamr@2
   875
  typedef typename ::boost::multi_index::index<
williamr@2
   876
    multi_index_type,Tag>::type                 index;
williamr@2
   877
williamr@2
   878
#if !defined(BOOST_MSVC)||!(BOOST_MSVC<1310) /* ain't work in MSVC++ 6.0/7.0 */
williamr@2
   879
  BOOST_STATIC_ASSERT((
williamr@2
   880
    mpl::contains<
williamr@2
   881
      BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
williamr@2
   882
      IteratorType>::value));
williamr@2
   883
#endif
williamr@2
   884
williamr@2
   885
  BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
williamr@2
   886
williamr@2
   887
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
williamr@2
   888
  typedef detail::converter<
williamr@2
   889
    multi_index_type,
williamr@2
   890
    BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
williamr@2
   891
  BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
williamr@2
   892
#endif
williamr@2
   893
williamr@2
   894
  return detail::converter<multi_index_type,index>::iterator(
williamr@2
   895
    m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
williamr@2
   896
}
williamr@2
   897
williamr@2
   898
template<
williamr@2
   899
  typename Tag,typename IteratorType,
williamr@2
   900
  typename Value,typename IndexSpecifierList,typename Allocator>
williamr@2
   901
typename index_const_iterator<
williamr@2
   902
  multi_index_container<Value,IndexSpecifierList,Allocator>,Tag>::type
williamr@2
   903
project(
williamr@2
   904
  const multi_index_container<Value,IndexSpecifierList,Allocator>& m,
williamr@2
   905
  IteratorType it
williamr@2
   906
  BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Tag))
williamr@2
   907
{
williamr@2
   908
  typedef multi_index_container<
williamr@2
   909
    Value,IndexSpecifierList,Allocator>         multi_index_type;
williamr@2
   910
  typedef typename ::boost::multi_index::index<
williamr@2
   911
    multi_index_type,Tag>::type                 index;
williamr@2
   912
williamr@2
   913
#if !defined(BOOST_MSVC)||!(BOOST_MSVC<1310) /* ain't work in MSVC++ 6.0/7.0 */
williamr@2
   914
  BOOST_STATIC_ASSERT((
williamr@2
   915
    mpl::contains<
williamr@2
   916
      BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list,
williamr@2
   917
      IteratorType>::value||
williamr@2
   918
    mpl::contains<
williamr@2
   919
      BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list,
williamr@2
   920
      IteratorType>::value));
williamr@2
   921
#endif
williamr@2
   922
williamr@2
   923
  BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it);
williamr@2
   924
williamr@2
   925
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
williamr@2
   926
  typedef detail::converter<
williamr@2
   927
    multi_index_type,
williamr@2
   928
    BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter;
williamr@2
   929
  BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m));
williamr@2
   930
#endif
williamr@2
   931
williamr@2
   932
  return detail::converter<multi_index_type,index>::const_iterator(
williamr@2
   933
    m,static_cast<typename multi_index_type::node_type*>(it.get_node()));
williamr@2
   934
}
williamr@2
   935
williamr@2
   936
/* Comparison. Simple forward to first index. */
williamr@2
   937
williamr@2
   938
template<
williamr@2
   939
  typename Value1,typename IndexSpecifierList1,typename Allocator1,
williamr@2
   940
  typename Value2,typename IndexSpecifierList2,typename Allocator2
williamr@2
   941
>
williamr@2
   942
bool operator==(
williamr@2
   943
  const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
williamr@2
   944
  const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
williamr@2
   945
{
williamr@2
   946
  return get<0>(x)==get<0>(y);
williamr@2
   947
}
williamr@2
   948
williamr@2
   949
template<
williamr@2
   950
  typename Value1,typename IndexSpecifierList1,typename Allocator1,
williamr@2
   951
  typename Value2,typename IndexSpecifierList2,typename Allocator2
williamr@2
   952
>
williamr@2
   953
bool operator<(
williamr@2
   954
  const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
williamr@2
   955
  const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
williamr@2
   956
{
williamr@2
   957
  return get<0>(x)<get<0>(y);
williamr@2
   958
}
williamr@2
   959
williamr@2
   960
template<
williamr@2
   961
  typename Value1,typename IndexSpecifierList1,typename Allocator1,
williamr@2
   962
  typename Value2,typename IndexSpecifierList2,typename Allocator2
williamr@2
   963
>
williamr@2
   964
bool operator!=(
williamr@2
   965
  const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
williamr@2
   966
  const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
williamr@2
   967
{
williamr@2
   968
  return get<0>(x)!=get<0>(y);
williamr@2
   969
}
williamr@2
   970
williamr@2
   971
template<
williamr@2
   972
  typename Value1,typename IndexSpecifierList1,typename Allocator1,
williamr@2
   973
  typename Value2,typename IndexSpecifierList2,typename Allocator2
williamr@2
   974
>
williamr@2
   975
bool operator>(
williamr@2
   976
  const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
williamr@2
   977
  const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
williamr@2
   978
{
williamr@2
   979
  return get<0>(x)>get<0>(y);
williamr@2
   980
}
williamr@2
   981
williamr@2
   982
template<
williamr@2
   983
  typename Value1,typename IndexSpecifierList1,typename Allocator1,
williamr@2
   984
  typename Value2,typename IndexSpecifierList2,typename Allocator2
williamr@2
   985
>
williamr@2
   986
bool operator>=(
williamr@2
   987
  const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
williamr@2
   988
  const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
williamr@2
   989
{
williamr@2
   990
  return get<0>(x)>=get<0>(y);
williamr@2
   991
}
williamr@2
   992
williamr@2
   993
template<
williamr@2
   994
  typename Value1,typename IndexSpecifierList1,typename Allocator1,
williamr@2
   995
  typename Value2,typename IndexSpecifierList2,typename Allocator2
williamr@2
   996
>
williamr@2
   997
bool operator<=(
williamr@2
   998
  const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x,
williamr@2
   999
  const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y)
williamr@2
  1000
{
williamr@2
  1001
  return get<0>(x)<=get<0>(y);
williamr@2
  1002
}
williamr@2
  1003
williamr@2
  1004
/*  specialized algorithms */
williamr@2
  1005
williamr@2
  1006
template<typename Value,typename IndexSpecifierList,typename Allocator>
williamr@2
  1007
void swap(
williamr@2
  1008
  multi_index_container<Value,IndexSpecifierList,Allocator>& x,
williamr@2
  1009
  multi_index_container<Value,IndexSpecifierList,Allocator>& y)
williamr@2
  1010
{
williamr@2
  1011
  x.swap(y);
williamr@2
  1012
}
williamr@2
  1013
williamr@2
  1014
} /* namespace multi_index */
williamr@2
  1015
williamr@2
  1016
/* Associated global functions are promoted to namespace boost, except
williamr@2
  1017
 * comparison operators and swap, which are meant to be Koenig looked-up.
williamr@2
  1018
 */
williamr@2
  1019
williamr@2
  1020
using multi_index::get;
williamr@2
  1021
using multi_index::project;
williamr@2
  1022
williamr@2
  1023
} /* namespace boost */
williamr@2
  1024
williamr@2
  1025
#undef BOOST_MULTI_INDEX_CHECK_INVARIANT
williamr@2
  1026
williamr@2
  1027
#endif