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