epoc32/include/stdapis/boost/multi_index/random_access_index.hpp
author William Roberts <williamr@symbian.org>
Tue, 16 Mar 2010 16:12:26 +0000
branchSymbian2
changeset 2 2fe1408b6811
permissions -rw-r--r--
Final list of Symbian^2 public API header files
williamr@2
     1
/* Copyright 2003-2007 Joaquín M López Muñoz.
williamr@2
     2
 * Distributed under the Boost Software License, Version 1.0.
williamr@2
     3
 * (See accompanying file LICENSE_1_0.txt or copy at
williamr@2
     4
 * http://www.boost.org/LICENSE_1_0.txt)
williamr@2
     5
 *
williamr@2
     6
 * See http://www.boost.org/libs/multi_index for library home page.
williamr@2
     7
 */
williamr@2
     8
williamr@2
     9
#ifndef BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_HPP
williamr@2
    10
#define BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_HPP
williamr@2
    11
williamr@2
    12
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
williamr@2
    13
#pragma once
williamr@2
    14
#endif
williamr@2
    15
williamr@2
    16
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
williamr@2
    17
#include <algorithm>
williamr@2
    18
#include <boost/call_traits.hpp>
williamr@2
    19
#include <boost/detail/no_exceptions_support.hpp>
williamr@2
    20
#include <boost/detail/workaround.hpp>
williamr@2
    21
#include <boost/iterator/reverse_iterator.hpp>
williamr@2
    22
#include <boost/mpl/push_front.hpp>
williamr@2
    23
#include <boost/multi_index/detail/access_specifier.hpp>
williamr@2
    24
#include <boost/multi_index/detail/index_node_base.hpp>
williamr@2
    25
#include <boost/multi_index/detail/rnd_node_iterator.hpp>
williamr@2
    26
#include <boost/multi_index/detail/rnd_index_node.hpp>
williamr@2
    27
#include <boost/multi_index/detail/rnd_index_ops.hpp>
williamr@2
    28
#include <boost/multi_index/detail/rnd_index_ptr_array.hpp>
williamr@2
    29
#include <boost/multi_index/detail/safe_ctr_proxy.hpp>
williamr@2
    30
#include <boost/multi_index/detail/safe_mode.hpp>
williamr@2
    31
#include <boost/multi_index/detail/scope_guard.hpp>
williamr@2
    32
#include <boost/multi_index/random_access_index_fwd.hpp>
williamr@2
    33
#include <boost/throw_exception.hpp> 
williamr@2
    34
#include <boost/tuple/tuple.hpp>
williamr@2
    35
#include <cstddef>
williamr@2
    36
#include <functional>
williamr@2
    37
#include <stdexcept> 
williamr@2
    38
#include <utility>
williamr@2
    39
williamr@2
    40
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
williamr@2
    41
#include <boost/bind.hpp>
williamr@2
    42
#include <boost/multi_index/detail/rnd_index_loader.hpp>
williamr@2
    43
#endif
williamr@2
    44
williamr@2
    45
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
williamr@2
    46
#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT                          \
williamr@2
    47
  detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)=                 \
williamr@2
    48
    detail::make_obj_guard(*this,&random_access_index::check_invariant_);    \
williamr@2
    49
  BOOST_JOIN(check_invariant_,__LINE__).touch();
williamr@2
    50
#else
williamr@2
    51
#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT
williamr@2
    52
#endif
williamr@2
    53
williamr@2
    54
namespace boost{
williamr@2
    55
williamr@2
    56
namespace multi_index{
williamr@2
    57
williamr@2
    58
namespace detail{
williamr@2
    59
williamr@2
    60
/* random_access_index adds a layer of random access indexing
williamr@2
    61
 * to a given Super
williamr@2
    62
 */
williamr@2
    63
williamr@2
    64
template<typename SuperMeta,typename TagList>
williamr@2
    65
class random_access_index:
williamr@2
    66
  BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type
williamr@2
    67
williamr@2
    68
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
williamr@2
    69
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
williamr@2
    70
  ,public safe_ctr_proxy_impl<
williamr@2
    71
    rnd_node_iterator<
williamr@2
    72
      random_access_index_node<typename SuperMeta::type::node_type> >,
williamr@2
    73
    random_access_index<SuperMeta,TagList> >
williamr@2
    74
#else
williamr@2
    75
  ,public safe_mode::safe_container<
williamr@2
    76
    random_access_index<SuperMeta,TagList> >
williamr@2
    77
#endif
williamr@2
    78
#endif
williamr@2
    79
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
  typedef typename SuperMeta::type                 super;
williamr@2
    92
williamr@2
    93
protected:
williamr@2
    94
  typedef random_access_index_node<
williamr@2
    95
    typename super::node_type>                     node_type;
williamr@2
    96
williamr@2
    97
public:
williamr@2
    98
  /* types */
williamr@2
    99
williamr@2
   100
  typedef typename node_type::value_type           value_type;
williamr@2
   101
  typedef tuples::null_type                        ctor_args;
williamr@2
   102
  typedef typename super::final_allocator_type     allocator_type;
williamr@2
   103
  typedef typename allocator_type::reference       reference;
williamr@2
   104
  typedef typename allocator_type::const_reference const_reference;
williamr@2
   105
williamr@2
   106
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
williamr@2
   107
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
williamr@2
   108
  typedef safe_mode::safe_iterator<
williamr@2
   109
    rnd_node_iterator<node_type>,
williamr@2
   110
    safe_ctr_proxy<
williamr@2
   111
      rnd_node_iterator<node_type> > >             iterator;
williamr@2
   112
#else
williamr@2
   113
  typedef safe_mode::safe_iterator<
williamr@2
   114
    rnd_node_iterator<node_type>,
williamr@2
   115
    random_access_index>                           iterator;
williamr@2
   116
#endif
williamr@2
   117
#else
williamr@2
   118
  typedef rnd_node_iterator<node_type>             iterator;
williamr@2
   119
#endif
williamr@2
   120
williamr@2
   121
  typedef iterator                                 const_iterator;
williamr@2
   122
williamr@2
   123
  typedef std::size_t                              size_type;      
williamr@2
   124
  typedef std::ptrdiff_t                           difference_type;
williamr@2
   125
  typedef typename allocator_type::pointer         pointer;
williamr@2
   126
  typedef typename allocator_type::const_pointer   const_pointer;
williamr@2
   127
  typedef typename
williamr@2
   128
    boost::reverse_iterator<iterator>              reverse_iterator;
williamr@2
   129
  typedef typename
williamr@2
   130
    boost::reverse_iterator<const_iterator>        const_reverse_iterator;
williamr@2
   131
  typedef TagList                                  tag_list;
williamr@2
   132
williamr@2
   133
protected:
williamr@2
   134
  typedef typename super::final_node_type     final_node_type;
williamr@2
   135
  typedef tuples::cons<
williamr@2
   136
    ctor_args, 
williamr@2
   137
    typename super::ctor_args_list>           ctor_args_list;
williamr@2
   138
  typedef typename mpl::push_front<
williamr@2
   139
    typename super::index_type_list,
williamr@2
   140
    random_access_index>::type                index_type_list;
williamr@2
   141
  typedef typename mpl::push_front<
williamr@2
   142
    typename super::iterator_type_list,
williamr@2
   143
    iterator>::type                           iterator_type_list;
williamr@2
   144
  typedef typename mpl::push_front<
williamr@2
   145
    typename super::const_iterator_type_list,
williamr@2
   146
    const_iterator>::type                     const_iterator_type_list;
williamr@2
   147
  typedef typename super::copy_map_type       copy_map_type;
williamr@2
   148
williamr@2
   149
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
williamr@2
   150
  typedef typename super::index_saver_type    index_saver_type;
williamr@2
   151
  typedef typename super::index_loader_type   index_loader_type;
williamr@2
   152
#endif
williamr@2
   153
williamr@2
   154
private:
williamr@2
   155
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
williamr@2
   156
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
williamr@2
   157
  typedef safe_ctr_proxy_impl<
williamr@2
   158
    rnd_node_iterator<node_type>,
williamr@2
   159
    random_access_index>                      safe_super;
williamr@2
   160
#else
williamr@2
   161
  typedef safe_mode::safe_container<
williamr@2
   162
    random_access_index>                      safe_super;
williamr@2
   163
#endif
williamr@2
   164
#endif
williamr@2
   165
williamr@2
   166
  typedef typename call_traits<
williamr@2
   167
    value_type>::param_type                   value_param_type;
williamr@2
   168
williamr@2
   169
public:
williamr@2
   170
williamr@2
   171
  /* construct/copy/destroy
williamr@2
   172
   * Default and copy ctors are in the protected section as indices are
williamr@2
   173
   * not supposed to be created on their own. No range ctor either.
williamr@2
   174
   */
williamr@2
   175
williamr@2
   176
  random_access_index<SuperMeta,TagList>& operator=(
williamr@2
   177
    const random_access_index<SuperMeta,TagList>& x)
williamr@2
   178
  {
williamr@2
   179
    this->final()=x.final();
williamr@2
   180
    return *this;
williamr@2
   181
  }
williamr@2
   182
williamr@2
   183
  template <class InputIterator>
williamr@2
   184
  void assign(InputIterator first,InputIterator last)
williamr@2
   185
  {
williamr@2
   186
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   187
    clear();
williamr@2
   188
    for(;first!=last;++first)push_back(*first);
williamr@2
   189
  }
williamr@2
   190
williamr@2
   191
  void assign(size_type n,value_param_type value)
williamr@2
   192
  {
williamr@2
   193
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   194
    clear();
williamr@2
   195
    for(size_type i=0;i<n;++i)push_back(value);
williamr@2
   196
  }
williamr@2
   197
    
williamr@2
   198
  allocator_type get_allocator()const
williamr@2
   199
  {
williamr@2
   200
    return this->final().get_allocator();
williamr@2
   201
  }
williamr@2
   202
williamr@2
   203
  /* iterators */
williamr@2
   204
williamr@2
   205
  iterator               begin()
williamr@2
   206
    {return make_iterator(node_type::from_impl(*ptrs.begin()));}
williamr@2
   207
  const_iterator         begin()const
williamr@2
   208
    {return make_iterator(node_type::from_impl(*ptrs.begin()));}
williamr@2
   209
  iterator               end(){return make_iterator(header());}
williamr@2
   210
  const_iterator         end()const{return make_iterator(header());}
williamr@2
   211
  reverse_iterator       rbegin(){return make_reverse_iterator(end());}
williamr@2
   212
  const_reverse_iterator rbegin()const{return make_reverse_iterator(end());}
williamr@2
   213
  reverse_iterator       rend(){return make_reverse_iterator(begin());}
williamr@2
   214
  const_reverse_iterator rend()const{return make_reverse_iterator(begin());}
williamr@2
   215
williamr@2
   216
  /* capacity */
williamr@2
   217
williamr@2
   218
  bool      empty()const{return this->final_empty_();}
williamr@2
   219
  size_type size()const{return this->final_size_();}
williamr@2
   220
  size_type max_size()const{return this->final_max_size_();}
williamr@2
   221
  size_type capacity()const{return ptrs.capacity();}
williamr@2
   222
  void      reserve(size_type n){ptrs.reserve(n);}
williamr@2
   223
williamr@2
   224
  void resize(size_type n,value_param_type x=value_type())
williamr@2
   225
  {
williamr@2
   226
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   227
    if(n>size())insert(end(),n-size(),x);
williamr@2
   228
    else if(n<size())erase(begin()+n,end());
williamr@2
   229
  }
williamr@2
   230
williamr@2
   231
  /* access: no non-const versions provided as random_access_index
williamr@2
   232
   * handles const elements.
williamr@2
   233
   */
williamr@2
   234
williamr@2
   235
  const_reference operator[](size_type n)const
williamr@2
   236
  {
williamr@2
   237
    BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(n<size(),safe_mode::out_of_bounds);
williamr@2
   238
    return node_type::from_impl(*ptrs.at(n))->value();
williamr@2
   239
  }
williamr@2
   240
williamr@2
   241
  const_reference at(size_type n)const
williamr@2
   242
  {
williamr@2
   243
    if(n>=size())throw_exception(std::out_of_range("random access index"));
williamr@2
   244
    return node_type::from_impl(*ptrs.at(n))->value();
williamr@2
   245
  }
williamr@2
   246
williamr@2
   247
  const_reference front()const{return operator[](0);}
williamr@2
   248
  const_reference back()const{return operator[](size()-1);}
williamr@2
   249
williamr@2
   250
  /* modifiers */
williamr@2
   251
williamr@2
   252
  std::pair<iterator,bool> push_front(value_param_type x)
williamr@2
   253
                             {return insert(begin(),x);}
williamr@2
   254
  void                     pop_front(){erase(begin());}
williamr@2
   255
  std::pair<iterator,bool> push_back(value_param_type x)
williamr@2
   256
                             {return insert(end(),x);}
williamr@2
   257
  void                     pop_back(){erase(--end());}
williamr@2
   258
williamr@2
   259
  std::pair<iterator,bool> insert(iterator position,value_param_type x)
williamr@2
   260
  {
williamr@2
   261
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
williamr@2
   262
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
williamr@2
   263
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   264
    std::pair<final_node_type*,bool> p=this->final_insert_(x);
williamr@2
   265
    if(p.second&&position.get_node()!=header()){
williamr@2
   266
      relocate(position.get_node(),p.first);
williamr@2
   267
    }
williamr@2
   268
    return std::pair<iterator,bool>(make_iterator(p.first),p.second);
williamr@2
   269
  }
williamr@2
   270
williamr@2
   271
  void insert(iterator position,size_type n,value_param_type x)
williamr@2
   272
  {
williamr@2
   273
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
williamr@2
   274
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
williamr@2
   275
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   276
    size_type s=0;
williamr@2
   277
    BOOST_TRY{
williamr@2
   278
      while(n--){
williamr@2
   279
        if(push_back(x).second)++s;
williamr@2
   280
      }
williamr@2
   281
    }
williamr@2
   282
    BOOST_CATCH(...){
williamr@2
   283
      relocate(position,end()-s,end());
williamr@2
   284
      BOOST_RETHROW;
williamr@2
   285
    }
williamr@2
   286
    BOOST_CATCH_END
williamr@2
   287
    relocate(position,end()-s,end());
williamr@2
   288
  }
williamr@2
   289
 
williamr@2
   290
  template<typename InputIterator>
williamr@2
   291
  void insert(iterator position,InputIterator first,InputIterator last)
williamr@2
   292
  {
williamr@2
   293
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   294
    size_type s=0;
williamr@2
   295
    BOOST_TRY{
williamr@2
   296
      for(;first!=last;++first){
williamr@2
   297
        if(push_back(*first).second)++s;
williamr@2
   298
      }
williamr@2
   299
    }
williamr@2
   300
    BOOST_CATCH(...){
williamr@2
   301
      relocate(position,end()-s,end());
williamr@2
   302
      BOOST_RETHROW;
williamr@2
   303
    }
williamr@2
   304
    BOOST_CATCH_END
williamr@2
   305
    relocate(position,end()-s,end());
williamr@2
   306
  }
williamr@2
   307
williamr@2
   308
  iterator erase(iterator position)
williamr@2
   309
  {
williamr@2
   310
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
williamr@2
   311
    BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
williamr@2
   312
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
williamr@2
   313
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   314
    this->final_erase_(static_cast<final_node_type*>(position++.get_node()));
williamr@2
   315
    return position;
williamr@2
   316
  }
williamr@2
   317
  
williamr@2
   318
  iterator erase(iterator first,iterator last)
williamr@2
   319
  {
williamr@2
   320
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
williamr@2
   321
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
williamr@2
   322
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
williamr@2
   323
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
williamr@2
   324
    BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
williamr@2
   325
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   326
    difference_type n=last-first;
williamr@2
   327
    relocate(end(),first,last);
williamr@2
   328
    while(n--)pop_back();
williamr@2
   329
    return last;
williamr@2
   330
  }
williamr@2
   331
williamr@2
   332
  bool replace(iterator position,value_param_type x)
williamr@2
   333
  {
williamr@2
   334
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
williamr@2
   335
    BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
williamr@2
   336
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
williamr@2
   337
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   338
    return this->final_replace_(
williamr@2
   339
      x,static_cast<final_node_type*>(position.get_node()));
williamr@2
   340
  }
williamr@2
   341
williamr@2
   342
  template<typename Modifier>
williamr@2
   343
  bool modify(iterator position,Modifier mod)
williamr@2
   344
  {
williamr@2
   345
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
williamr@2
   346
    BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
williamr@2
   347
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
williamr@2
   348
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   349
williamr@2
   350
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
williamr@2
   351
    /* MSVC++ 6.0 optimizer on safe mode code chokes if this
williamr@2
   352
     * this is not added. Left it for all compilers as it does no
williamr@2
   353
     * harm.
williamr@2
   354
     */
williamr@2
   355
williamr@2
   356
    position.detach();
williamr@2
   357
#endif
williamr@2
   358
williamr@2
   359
    return this->final_modify_(
williamr@2
   360
      mod,static_cast<final_node_type*>(position.get_node()));
williamr@2
   361
  }
williamr@2
   362
williamr@2
   363
  void swap(random_access_index<SuperMeta,TagList>& x)
williamr@2
   364
  {
williamr@2
   365
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   366
    this->final_swap_(x.final());
williamr@2
   367
  }
williamr@2
   368
williamr@2
   369
  void clear()
williamr@2
   370
  {
williamr@2
   371
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   372
    this->final_clear_();
williamr@2
   373
  }
williamr@2
   374
williamr@2
   375
  /* list operations */
williamr@2
   376
williamr@2
   377
  void splice(iterator position,random_access_index<SuperMeta,TagList>& x)
williamr@2
   378
  {
williamr@2
   379
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
williamr@2
   380
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
williamr@2
   381
    BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(*this,x);
williamr@2
   382
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   383
    iterator  first=x.begin(),last=x.end();
williamr@2
   384
    size_type n=0;
williamr@2
   385
    BOOST_TRY{
williamr@2
   386
      while(first!=last){
williamr@2
   387
        if(push_back(*first).second){
williamr@2
   388
          first=x.erase(first);
williamr@2
   389
          ++n;
williamr@2
   390
        }
williamr@2
   391
        else ++first;
williamr@2
   392
      }
williamr@2
   393
    }
williamr@2
   394
    BOOST_CATCH(...){
williamr@2
   395
      relocate(position,end()-n,end());
williamr@2
   396
      BOOST_RETHROW;
williamr@2
   397
    }
williamr@2
   398
    BOOST_CATCH_END
williamr@2
   399
    relocate(position,end()-n,end());
williamr@2
   400
  }
williamr@2
   401
williamr@2
   402
  void splice(
williamr@2
   403
    iterator position,random_access_index<SuperMeta,TagList>& x,iterator i)
williamr@2
   404
  {
williamr@2
   405
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
williamr@2
   406
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
williamr@2
   407
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i);
williamr@2
   408
    BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
williamr@2
   409
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x);
williamr@2
   410
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   411
    if(&x==this)relocate(position,i);
williamr@2
   412
    else{
williamr@2
   413
      if(insert(position,*i).second){
williamr@2
   414
williamr@2
   415
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
williamr@2
   416
    /* MSVC++ 6.0 optimizer has a hard time with safe mode, and the following
williamr@2
   417
     * workaround is needed. Left it for all compilers as it does no
williamr@2
   418
     * harm.
williamr@2
   419
     */
williamr@2
   420
        i.detach();
williamr@2
   421
        x.erase(x.make_iterator(i.get_node()));
williamr@2
   422
#else
williamr@2
   423
        x.erase(i);
williamr@2
   424
#endif
williamr@2
   425
williamr@2
   426
      }
williamr@2
   427
    }
williamr@2
   428
  }
williamr@2
   429
williamr@2
   430
  void splice(
williamr@2
   431
    iterator position,random_access_index<SuperMeta,TagList>& x,
williamr@2
   432
    iterator first,iterator last)
williamr@2
   433
  {
williamr@2
   434
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
williamr@2
   435
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
williamr@2
   436
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
williamr@2
   437
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
williamr@2
   438
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x);
williamr@2
   439
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x);
williamr@2
   440
    BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
williamr@2
   441
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   442
    if(&x==this)relocate(position,first,last);
williamr@2
   443
    else{
williamr@2
   444
      size_type n=0;
williamr@2
   445
      BOOST_TRY{
williamr@2
   446
        while(first!=last){
williamr@2
   447
          if(push_back(*first).second){
williamr@2
   448
            first=x.erase(first);
williamr@2
   449
            ++n;
williamr@2
   450
          }
williamr@2
   451
          else ++first;
williamr@2
   452
        }
williamr@2
   453
      }
williamr@2
   454
      BOOST_CATCH(...){
williamr@2
   455
        relocate(position,end()-n,end());
williamr@2
   456
        BOOST_RETHROW;
williamr@2
   457
      }
williamr@2
   458
      BOOST_CATCH_END
williamr@2
   459
      relocate(position,end()-n,end());
williamr@2
   460
    }
williamr@2
   461
  }
williamr@2
   462
williamr@2
   463
  void remove(value_param_type value)
williamr@2
   464
  {
williamr@2
   465
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   466
    difference_type n=
williamr@2
   467
      end()-make_iterator(
williamr@2
   468
        random_access_index_remove<node_type>(
williamr@2
   469
          ptrs,std::bind2nd(std::equal_to<value_type>(),value)));
williamr@2
   470
    while(n--)pop_back();
williamr@2
   471
  }
williamr@2
   472
williamr@2
   473
  template<typename Predicate>
williamr@2
   474
  void remove_if(Predicate pred)
williamr@2
   475
  {
williamr@2
   476
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   477
    difference_type n=
williamr@2
   478
      end()-make_iterator(random_access_index_remove<node_type>(ptrs,pred));
williamr@2
   479
    while(n--)pop_back();
williamr@2
   480
  }
williamr@2
   481
williamr@2
   482
  void unique()
williamr@2
   483
  {
williamr@2
   484
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   485
    difference_type n=
williamr@2
   486
      end()-make_iterator(
williamr@2
   487
        random_access_index_unique<node_type>(
williamr@2
   488
          ptrs,std::equal_to<value_type>()));
williamr@2
   489
    while(n--)pop_back();
williamr@2
   490
  }
williamr@2
   491
williamr@2
   492
  template <class BinaryPredicate>
williamr@2
   493
  void unique(BinaryPredicate binary_pred)
williamr@2
   494
  {
williamr@2
   495
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   496
    difference_type n=
williamr@2
   497
      end()-make_iterator(
williamr@2
   498
        random_access_index_unique<node_type>(ptrs,binary_pred));
williamr@2
   499
    while(n--)pop_back();
williamr@2
   500
  }
williamr@2
   501
williamr@2
   502
  void merge(random_access_index<SuperMeta,TagList>& x)
williamr@2
   503
  {
williamr@2
   504
    if(this!=&x){
williamr@2
   505
      BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   506
      size_type s=size();
williamr@2
   507
      splice(end(),x);
williamr@2
   508
      random_access_index_inplace_merge<node_type>(
williamr@2
   509
        get_allocator(),ptrs,ptrs.at(s),std::less<value_type>());
williamr@2
   510
    }
williamr@2
   511
  }
williamr@2
   512
williamr@2
   513
  template <typename Compare>
williamr@2
   514
  void merge(random_access_index<SuperMeta,TagList>& x,Compare comp)
williamr@2
   515
  {
williamr@2
   516
    if(this!=&x){
williamr@2
   517
      BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   518
      size_type s=size();
williamr@2
   519
      splice(end(),x);
williamr@2
   520
      random_access_index_inplace_merge<node_type>(
williamr@2
   521
        get_allocator(),ptrs,ptrs.at(s),comp);
williamr@2
   522
    }
williamr@2
   523
  }
williamr@2
   524
williamr@2
   525
  void sort()
williamr@2
   526
  {
williamr@2
   527
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   528
    random_access_index_sort<node_type>(
williamr@2
   529
      get_allocator(),ptrs,std::less<value_type>());
williamr@2
   530
  }
williamr@2
   531
williamr@2
   532
  template <typename Compare>
williamr@2
   533
  void sort(Compare comp)
williamr@2
   534
  {
williamr@2
   535
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   536
    random_access_index_sort<node_type>(
williamr@2
   537
      get_allocator(),ptrs,comp);
williamr@2
   538
  }
williamr@2
   539
williamr@2
   540
  void reverse()
williamr@2
   541
  {
williamr@2
   542
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   543
    random_access_index_node_impl::reverse(ptrs.begin(),ptrs.end());
williamr@2
   544
  }
williamr@2
   545
williamr@2
   546
  /* rearrange operations */
williamr@2
   547
williamr@2
   548
  void relocate(iterator position,iterator i)
williamr@2
   549
  {
williamr@2
   550
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
williamr@2
   551
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
williamr@2
   552
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i);
williamr@2
   553
    BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i);
williamr@2
   554
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,*this);
williamr@2
   555
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   556
    if(position!=i)relocate(position.get_node(),i.get_node());
williamr@2
   557
  }
williamr@2
   558
williamr@2
   559
  void relocate(iterator position,iterator first,iterator last)
williamr@2
   560
  {
williamr@2
   561
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
williamr@2
   562
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
williamr@2
   563
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
williamr@2
   564
    BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
williamr@2
   565
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
williamr@2
   566
    BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
williamr@2
   567
    BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
williamr@2
   568
    BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last);
williamr@2
   569
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   570
    if(position!=last)relocate(
williamr@2
   571
      position.get_node(),first.get_node(),last.get_node());
williamr@2
   572
  }
williamr@2
   573
williamr@2
   574
  template<typename InputIterator>
williamr@2
   575
  void rearrange(InputIterator first)
williamr@2
   576
  {
williamr@2
   577
    BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
williamr@2
   578
    for(random_access_index_node_impl** p0=ptrs.begin(),** p0_end=ptrs.end();
williamr@2
   579
        p0!=p0_end;++first,++p0){
williamr@2
   580
      const value_type&               v1=*first;
williamr@2
   581
      random_access_index_node_impl** p1=node_from_value<node_type>(&v1)->up();
williamr@2
   582
williamr@2
   583
      std::swap(*p0,*p1);
williamr@2
   584
      (*p0)->up()=p0;
williamr@2
   585
      (*p1)->up()=p1;
williamr@2
   586
    }
williamr@2
   587
  }
williamr@2
   588
    
williamr@2
   589
BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
williamr@2
   590
  random_access_index(
williamr@2
   591
    const ctor_args_list& args_list,const allocator_type& al):
williamr@2
   592
    super(args_list.get_tail(),al),
williamr@2
   593
    ptrs(al,header()->impl(),0)
williamr@2
   594
  {
williamr@2
   595
  }
williamr@2
   596
williamr@2
   597
  random_access_index(const random_access_index<SuperMeta,TagList>& x):
williamr@2
   598
    super(x),
williamr@2
   599
williamr@2
   600
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
williamr@2
   601
    safe_super(),
williamr@2
   602
#endif
williamr@2
   603
williamr@2
   604
    ptrs(x.get_allocator(),header()->impl(),x.size())
williamr@2
   605
  {
williamr@2
   606
    /* The actual copying takes place in subsequent call to copy_().
williamr@2
   607
     */
williamr@2
   608
  }
williamr@2
   609
williamr@2
   610
  ~random_access_index()
williamr@2
   611
  {
williamr@2
   612
    /* the container is guaranteed to be empty by now */
williamr@2
   613
  }
williamr@2
   614
williamr@2
   615
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
williamr@2
   616
  iterator       make_iterator(node_type* node){return iterator(node,this);}
williamr@2
   617
  const_iterator make_iterator(node_type* node)const
williamr@2
   618
    {return const_iterator(node,const_cast<random_access_index*>(this));}
williamr@2
   619
#else
williamr@2
   620
  iterator       make_iterator(node_type* node){return iterator(node);}
williamr@2
   621
  const_iterator make_iterator(node_type* node)const
williamr@2
   622
                   {return const_iterator(node);}
williamr@2
   623
#endif
williamr@2
   624
williamr@2
   625
  void copy_(
williamr@2
   626
    const random_access_index<SuperMeta,TagList>& x,const copy_map_type& map)
williamr@2
   627
  {
williamr@2
   628
    for(random_access_index_node_impl** begin_org=x.ptrs.begin(),
williamr@2
   629
                                     ** begin_cpy=ptrs.begin(),
williamr@2
   630
                                     ** end_org=x.ptrs.end();
williamr@2
   631
        begin_org!=end_org;++begin_org,++begin_cpy){
williamr@2
   632
      *begin_cpy=
williamr@2
   633
         static_cast<node_type*>(
williamr@2
   634
           map.find(
williamr@2
   635
             static_cast<final_node_type*>(
williamr@2
   636
               node_type::from_impl(*begin_org))))->impl();
williamr@2
   637
      (*begin_cpy)->up()=begin_cpy;
williamr@2
   638
    }
williamr@2
   639
williamr@2
   640
    super::copy_(x,map);
williamr@2
   641
  }
williamr@2
   642
williamr@2
   643
  node_type* insert_(value_param_type v,node_type* x)
williamr@2
   644
  {
williamr@2
   645
    ptrs.room_for_one();
williamr@2
   646
    node_type* res=static_cast<node_type*>(super::insert_(v,x));
williamr@2
   647
    if(res==x)ptrs.push_back(x->impl());
williamr@2
   648
    return res;
williamr@2
   649
  }
williamr@2
   650
williamr@2
   651
  node_type* insert_(value_param_type v,node_type* position,node_type* x)
williamr@2
   652
  {
williamr@2
   653
    ptrs.room_for_one();
williamr@2
   654
    node_type* res=static_cast<node_type*>(super::insert_(v,position,x));
williamr@2
   655
    if(res==x)ptrs.push_back(x->impl());
williamr@2
   656
    return res;
williamr@2
   657
  }
williamr@2
   658
williamr@2
   659
  void erase_(node_type* x)
williamr@2
   660
  {
williamr@2
   661
    ptrs.erase(x->impl());
williamr@2
   662
    super::erase_(x);
williamr@2
   663
williamr@2
   664
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
williamr@2
   665
    detach_iterators(x);
williamr@2
   666
#endif
williamr@2
   667
  }
williamr@2
   668
williamr@2
   669
  void delete_all_nodes_()
williamr@2
   670
  {
williamr@2
   671
    for(random_access_index_node_impl** x=ptrs.begin(),**x_end=ptrs.end();
williamr@2
   672
        x!=x_end;++x){
williamr@2
   673
      this->final_delete_node_(
williamr@2
   674
        static_cast<final_node_type*>(node_type::from_impl(*x)));
williamr@2
   675
    }
williamr@2
   676
  }
williamr@2
   677
williamr@2
   678
  void clear_()
williamr@2
   679
  {
williamr@2
   680
    super::clear_();
williamr@2
   681
    ptrs.clear();
williamr@2
   682
williamr@2
   683
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
williamr@2
   684
    safe_super::detach_dereferenceable_iterators();
williamr@2
   685
#endif
williamr@2
   686
  }
williamr@2
   687
williamr@2
   688
  void swap_(random_access_index<SuperMeta,TagList>& x)
williamr@2
   689
  {
williamr@2
   690
    ptrs.swap(x.ptrs);
williamr@2
   691
williamr@2
   692
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
williamr@2
   693
    safe_super::swap(x);
williamr@2
   694
#endif
williamr@2
   695
williamr@2
   696
    super::swap_(x);
williamr@2
   697
  }
williamr@2
   698
williamr@2
   699
  bool replace_(value_param_type v,node_type* x)
williamr@2
   700
  {
williamr@2
   701
    return super::replace_(v,x);
williamr@2
   702
  }
williamr@2
   703
williamr@2
   704
  bool modify_(node_type* x)
williamr@2
   705
  {
williamr@2
   706
    BOOST_TRY{
williamr@2
   707
      if(!super::modify_(x)){
williamr@2
   708
        ptrs.erase(x->impl());
williamr@2
   709
williamr@2
   710
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
williamr@2
   711
        detach_iterators(x);
williamr@2
   712
#endif
williamr@2
   713
williamr@2
   714
        return false;
williamr@2
   715
      }
williamr@2
   716
      else return true;
williamr@2
   717
    }
williamr@2
   718
    BOOST_CATCH(...){
williamr@2
   719
      ptrs.erase(x->impl());
williamr@2
   720
williamr@2
   721
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
williamr@2
   722
      detach_iterators(x);
williamr@2
   723
#endif
williamr@2
   724
williamr@2
   725
      BOOST_RETHROW;
williamr@2
   726
    }
williamr@2
   727
    BOOST_CATCH_END
williamr@2
   728
  }
williamr@2
   729
williamr@2
   730
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
williamr@2
   731
  /* serialization */
williamr@2
   732
williamr@2
   733
  template<typename Archive>
williamr@2
   734
  void save_(
williamr@2
   735
    Archive& ar,const unsigned int version,const index_saver_type& sm)const
williamr@2
   736
  {
williamr@2
   737
    sm.save(begin(),end(),ar,version);
williamr@2
   738
    super::save_(ar,version,sm);
williamr@2
   739
  }
williamr@2
   740
williamr@2
   741
  template<typename Archive>
williamr@2
   742
  void load_(
williamr@2
   743
    Archive& ar,const unsigned int version,const index_loader_type& lm)
williamr@2
   744
  {
williamr@2
   745
    {
williamr@2
   746
      typedef random_access_index_loader<node_type,allocator_type> loader;
williamr@2
   747
williamr@2
   748
      loader ld(get_allocator(),ptrs);
williamr@2
   749
      lm.load(::boost::bind(&loader::rearrange,&ld,_1,_2),ar,version);
williamr@2
   750
    } /* exit scope so that ld frees its resources */
williamr@2
   751
    super::load_(ar,version,lm);
williamr@2
   752
  }
williamr@2
   753
#endif
williamr@2
   754
williamr@2
   755
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
williamr@2
   756
  /* invariant stuff */
williamr@2
   757
williamr@2
   758
  bool invariant_()const
williamr@2
   759
  {
williamr@2
   760
    if(size()>capacity())return false;
williamr@2
   761
    if(size()==0||begin()==end()){
williamr@2
   762
      if(size()!=0||begin()!=end())return false;
williamr@2
   763
    }
williamr@2
   764
    else{
williamr@2
   765
      size_type s=0;
williamr@2
   766
      for(const_iterator it=begin(),it_end=end();;++it,++s){
williamr@2
   767
        if(*(it.get_node()->up())!=it.get_node()->impl())return false;
williamr@2
   768
        if(it==it_end)break;
williamr@2
   769
      }
williamr@2
   770
      if(s!=size())return false;
williamr@2
   771
    }
williamr@2
   772
williamr@2
   773
    return super::invariant_();
williamr@2
   774
  }
williamr@2
   775
williamr@2
   776
  /* This forwarding function eases things for the boost::mem_fn construct
williamr@2
   777
   * in BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT. Actually,
williamr@2
   778
   * final_check_invariant is already an inherited member function of index.
williamr@2
   779
   */
williamr@2
   780
  void check_invariant_()const{this->final_check_invariant_();}
williamr@2
   781
#endif
williamr@2
   782
williamr@2
   783
private:
williamr@2
   784
  node_type* header()const{return this->final_header();}
williamr@2
   785
williamr@2
   786
  static void relocate(node_type* position,node_type* x)
williamr@2
   787
  {
williamr@2
   788
    random_access_index_node_impl::relocate(position->up(),x->up());
williamr@2
   789
  }
williamr@2
   790
williamr@2
   791
  static void relocate(node_type* position,node_type* first,node_type* last)
williamr@2
   792
  {
williamr@2
   793
    random_access_index_node_impl::relocate(
williamr@2
   794
      position->up(),first->up(),last->up());
williamr@2
   795
  }
williamr@2
   796
williamr@2
   797
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
williamr@2
   798
  void detach_iterators(node_type* x)
williamr@2
   799
  {
williamr@2
   800
    iterator it=make_iterator(x);
williamr@2
   801
    safe_mode::detach_equivalent_iterators(it);
williamr@2
   802
  }
williamr@2
   803
#endif
williamr@2
   804
williamr@2
   805
  random_access_index_ptr_array<typename super::final_allocator_type> ptrs;
williamr@2
   806
williamr@2
   807
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
williamr@2
   808
    BOOST_WORKAROUND(__MWERKS__,<=0x3003)
williamr@2
   809
#pragma parse_mfunc_templ reset
williamr@2
   810
#endif
williamr@2
   811
};
williamr@2
   812
williamr@2
   813
/* comparison */
williamr@2
   814
williamr@2
   815
template<
williamr@2
   816
  typename SuperMeta1,typename TagList1,
williamr@2
   817
  typename SuperMeta2,typename TagList2
williamr@2
   818
>
williamr@2
   819
bool operator==(
williamr@2
   820
  const random_access_index<SuperMeta1,TagList1>& x,
williamr@2
   821
  const random_access_index<SuperMeta2,TagList2>& y)
williamr@2
   822
{
williamr@2
   823
  return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
williamr@2
   824
}
williamr@2
   825
williamr@2
   826
template<
williamr@2
   827
  typename SuperMeta1,typename TagList1,
williamr@2
   828
  typename SuperMeta2,typename TagList2
williamr@2
   829
>
williamr@2
   830
bool operator<(
williamr@2
   831
  const random_access_index<SuperMeta1,TagList1>& x,
williamr@2
   832
  const random_access_index<SuperMeta2,TagList2>& y)
williamr@2
   833
{
williamr@2
   834
  return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
williamr@2
   835
}
williamr@2
   836
williamr@2
   837
template<
williamr@2
   838
  typename SuperMeta1,typename TagList1,
williamr@2
   839
  typename SuperMeta2,typename TagList2
williamr@2
   840
>
williamr@2
   841
bool operator!=(
williamr@2
   842
  const random_access_index<SuperMeta1,TagList1>& x,
williamr@2
   843
  const random_access_index<SuperMeta2,TagList2>& y)
williamr@2
   844
{
williamr@2
   845
  return !(x==y);
williamr@2
   846
}
williamr@2
   847
williamr@2
   848
template<
williamr@2
   849
  typename SuperMeta1,typename TagList1,
williamr@2
   850
  typename SuperMeta2,typename TagList2
williamr@2
   851
>
williamr@2
   852
bool operator>(
williamr@2
   853
  const random_access_index<SuperMeta1,TagList1>& x,
williamr@2
   854
  const random_access_index<SuperMeta2,TagList2>& y)
williamr@2
   855
{
williamr@2
   856
  return y<x;
williamr@2
   857
}
williamr@2
   858
williamr@2
   859
template<
williamr@2
   860
  typename SuperMeta1,typename TagList1,
williamr@2
   861
  typename SuperMeta2,typename TagList2
williamr@2
   862
>
williamr@2
   863
bool operator>=(
williamr@2
   864
  const random_access_index<SuperMeta1,TagList1>& x,
williamr@2
   865
  const random_access_index<SuperMeta2,TagList2>& y)
williamr@2
   866
{
williamr@2
   867
  return !(x<y);
williamr@2
   868
}
williamr@2
   869
williamr@2
   870
template<
williamr@2
   871
  typename SuperMeta1,typename TagList1,
williamr@2
   872
  typename SuperMeta2,typename TagList2
williamr@2
   873
>
williamr@2
   874
bool operator<=(
williamr@2
   875
  const random_access_index<SuperMeta1,TagList1>& x,
williamr@2
   876
  const random_access_index<SuperMeta2,TagList2>& y)
williamr@2
   877
{
williamr@2
   878
  return !(x>y);
williamr@2
   879
}
williamr@2
   880
williamr@2
   881
/*  specialized algorithms */
williamr@2
   882
williamr@2
   883
template<typename SuperMeta,typename TagList>
williamr@2
   884
void swap(
williamr@2
   885
  random_access_index<SuperMeta,TagList>& x,
williamr@2
   886
  random_access_index<SuperMeta,TagList>& y)
williamr@2
   887
{
williamr@2
   888
  x.swap(y);
williamr@2
   889
}
williamr@2
   890
williamr@2
   891
} /* namespace multi_index::detail */
williamr@2
   892
williamr@2
   893
/* random access index specifier */
williamr@2
   894
williamr@2
   895
template <typename TagList>
williamr@2
   896
struct random_access
williamr@2
   897
{
williamr@2
   898
  BOOST_STATIC_ASSERT(detail::is_tag<TagList>::value);
williamr@2
   899
williamr@2
   900
  template<typename Super>
williamr@2
   901
  struct node_class
williamr@2
   902
  {
williamr@2
   903
    typedef detail::random_access_index_node<Super> type;
williamr@2
   904
  };
williamr@2
   905
williamr@2
   906
  template<typename SuperMeta>
williamr@2
   907
  struct index_class
williamr@2
   908
  {
williamr@2
   909
    typedef detail::random_access_index<
williamr@2
   910
      SuperMeta,typename TagList::type>  type;
williamr@2
   911
  };
williamr@2
   912
};
williamr@2
   913
williamr@2
   914
} /* namespace multi_index */
williamr@2
   915
williamr@2
   916
} /* namespace boost */
williamr@2
   917
williamr@2
   918
#undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT
williamr@2
   919
williamr@2
   920
#endif