epoc32/include/stdapis/boost/multi_index/detail/iter_adaptor.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:27:01 +0100
branchSymbian2
changeset 3 e1b950c65cb4
permissions -rw-r--r--
Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
williamr@2
     1
/* Copyright 2003-2005 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_DETAIL_ITER_ADAPTOR_HPP
williamr@2
    10
#define BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_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/mpl/apply.hpp>
williamr@2
    18
#include <boost/multi_index/detail/prevent_eti.hpp>
williamr@2
    19
#include <boost/operators.hpp>
williamr@2
    20
williamr@2
    21
namespace boost{
williamr@2
    22
williamr@2
    23
namespace multi_index{
williamr@2
    24
williamr@2
    25
namespace detail{
williamr@2
    26
williamr@2
    27
/* Poor man's version of boost::iterator_adaptor. Used instead of the
williamr@2
    28
 * original as compile times for the latter are significantly higher.
williamr@2
    29
 * The interface is not replicated exactly, only to the extent necessary
williamr@2
    30
 * for internal consumption.
williamr@2
    31
 */
williamr@2
    32
williamr@2
    33
class iter_adaptor_access
williamr@2
    34
{
williamr@2
    35
public:
williamr@2
    36
  template<class Class>
williamr@2
    37
    static typename Class::reference dereference(const Class& x)
williamr@2
    38
  {
williamr@2
    39
    return x.dereference();
williamr@2
    40
  }
williamr@2
    41
williamr@2
    42
  template<class Class>
williamr@2
    43
  static bool equal(const Class& x,const Class& y)
williamr@2
    44
  {
williamr@2
    45
    return x.equal(y);
williamr@2
    46
  }
williamr@2
    47
williamr@2
    48
  template<class Class>
williamr@2
    49
  static void increment(Class& x)
williamr@2
    50
  {
williamr@2
    51
    x.increment();
williamr@2
    52
  }
williamr@2
    53
williamr@2
    54
  template<class Class>
williamr@2
    55
  static void decrement(Class& x)
williamr@2
    56
  {
williamr@2
    57
    x.decrement();
williamr@2
    58
  }
williamr@2
    59
williamr@2
    60
  template<class Class>
williamr@2
    61
  static void advance(Class& x,typename Class::difference_type n)
williamr@2
    62
  {
williamr@2
    63
    x.advance(n);
williamr@2
    64
  }
williamr@2
    65
williamr@2
    66
  template<class Class>
williamr@2
    67
  static typename Class::difference_type distance_to(
williamr@2
    68
    const Class& x,const Class& y)
williamr@2
    69
  {
williamr@2
    70
    return x.distance_to(y);
williamr@2
    71
  }
williamr@2
    72
};
williamr@2
    73
williamr@2
    74
template<typename Category>
williamr@2
    75
struct iter_adaptor_selector;
williamr@2
    76
williamr@2
    77
template<class Derived,class Base>
williamr@2
    78
class forward_iter_adaptor_base:
williamr@2
    79
  public forward_iterator_helper<
williamr@2
    80
    Derived,
williamr@2
    81
    typename Base::value_type,
williamr@2
    82
    typename Base::difference_type,
williamr@2
    83
    typename Base::pointer,
williamr@2
    84
    typename Base::reference>
williamr@2
    85
{
williamr@2
    86
public:
williamr@2
    87
  typedef typename Base::reference reference;
williamr@2
    88
williamr@2
    89
  reference operator*()const
williamr@2
    90
  {
williamr@2
    91
    return iter_adaptor_access::dereference(final());
williamr@2
    92
  }
williamr@2
    93
williamr@2
    94
  friend bool operator==(const Derived& x,const Derived& y)
williamr@2
    95
  {
williamr@2
    96
    return iter_adaptor_access::equal(x,y);
williamr@2
    97
  }
williamr@2
    98
williamr@2
    99
  Derived& operator++()
williamr@2
   100
  {
williamr@2
   101
    iter_adaptor_access::increment(final());
williamr@2
   102
    return final();
williamr@2
   103
  }
williamr@2
   104
williamr@2
   105
private:
williamr@2
   106
  Derived& final(){return *static_cast<Derived*>(this);}
williamr@2
   107
  const Derived& final()const{return *static_cast<const Derived*>(this);}
williamr@2
   108
};
williamr@2
   109
williamr@2
   110
template<>
williamr@2
   111
struct iter_adaptor_selector<std::forward_iterator_tag>
williamr@2
   112
{
williamr@2
   113
  template<class Derived,class Base>
williamr@2
   114
  struct apply
williamr@2
   115
  {
williamr@2
   116
    typedef forward_iter_adaptor_base<Derived,Base> type;
williamr@2
   117
  };
williamr@2
   118
};
williamr@2
   119
williamr@2
   120
template<class Derived,class Base>
williamr@2
   121
class bidirectional_iter_adaptor_base:
williamr@2
   122
  public bidirectional_iterator_helper<
williamr@2
   123
    Derived,
williamr@2
   124
    typename Base::value_type,
williamr@2
   125
    typename Base::difference_type,
williamr@2
   126
    typename Base::pointer,
williamr@2
   127
    typename Base::reference>
williamr@2
   128
{
williamr@2
   129
public:
williamr@2
   130
  typedef typename Base::reference reference;
williamr@2
   131
williamr@2
   132
  reference operator*()const
williamr@2
   133
  {
williamr@2
   134
    return iter_adaptor_access::dereference(final());
williamr@2
   135
  }
williamr@2
   136
williamr@2
   137
  friend bool operator==(const Derived& x,const Derived& y)
williamr@2
   138
  {
williamr@2
   139
    return iter_adaptor_access::equal(x,y);
williamr@2
   140
  }
williamr@2
   141
williamr@2
   142
  Derived& operator++()
williamr@2
   143
  {
williamr@2
   144
    iter_adaptor_access::increment(final());
williamr@2
   145
    return final();
williamr@2
   146
  }
williamr@2
   147
williamr@2
   148
  Derived& operator--()
williamr@2
   149
  {
williamr@2
   150
    iter_adaptor_access::decrement(final());
williamr@2
   151
    return final();
williamr@2
   152
  }
williamr@2
   153
williamr@2
   154
private:
williamr@2
   155
  Derived& final(){return *static_cast<Derived*>(this);}
williamr@2
   156
  const Derived& final()const{return *static_cast<const Derived*>(this);}
williamr@2
   157
};
williamr@2
   158
williamr@2
   159
template<>
williamr@2
   160
struct iter_adaptor_selector<std::bidirectional_iterator_tag>
williamr@2
   161
{
williamr@2
   162
  template<class Derived,class Base>
williamr@2
   163
  struct apply
williamr@2
   164
  {
williamr@2
   165
    typedef bidirectional_iter_adaptor_base<Derived,Base> type;
williamr@2
   166
  };
williamr@2
   167
};
williamr@2
   168
williamr@2
   169
template<class Derived,class Base>
williamr@2
   170
class random_access_iter_adaptor_base:
williamr@2
   171
  public random_access_iterator_helper<
williamr@2
   172
    Derived,
williamr@2
   173
    typename Base::value_type,
williamr@2
   174
    typename Base::difference_type,
williamr@2
   175
    typename Base::pointer,
williamr@2
   176
    typename Base::reference>
williamr@2
   177
{
williamr@2
   178
public:
williamr@2
   179
  typedef typename Base::reference       reference;
williamr@2
   180
  typedef typename Base::difference_type difference_type;
williamr@2
   181
williamr@2
   182
  reference operator*()const
williamr@2
   183
  {
williamr@2
   184
    return iter_adaptor_access::dereference(final());
williamr@2
   185
  }
williamr@2
   186
williamr@2
   187
  friend bool operator==(const Derived& x,const Derived& y)
williamr@2
   188
  {
williamr@2
   189
    return iter_adaptor_access::equal(x,y);
williamr@2
   190
  }
williamr@2
   191
williamr@2
   192
  friend bool operator<(const Derived& x,const Derived& y)
williamr@2
   193
  {
williamr@2
   194
    return iter_adaptor_access::distance_to(x,y)>0;
williamr@2
   195
  }
williamr@2
   196
williamr@2
   197
  Derived& operator++()
williamr@2
   198
  {
williamr@2
   199
    iter_adaptor_access::increment(final());
williamr@2
   200
    return final();
williamr@2
   201
  }
williamr@2
   202
williamr@2
   203
  Derived& operator--()
williamr@2
   204
  {
williamr@2
   205
    iter_adaptor_access::decrement(final());
williamr@2
   206
    return final();
williamr@2
   207
  }
williamr@2
   208
williamr@2
   209
  Derived& operator+=(difference_type n)
williamr@2
   210
  {
williamr@2
   211
    iter_adaptor_access::advance(final(),n);
williamr@2
   212
    return final();
williamr@2
   213
  }
williamr@2
   214
williamr@2
   215
  Derived& operator-=(difference_type n)
williamr@2
   216
  {
williamr@2
   217
    iter_adaptor_access::advance(final(),-n);
williamr@2
   218
    return final();
williamr@2
   219
  }
williamr@2
   220
williamr@2
   221
  friend difference_type operator-(const Derived& x,const Derived& y)
williamr@2
   222
  {
williamr@2
   223
    return iter_adaptor_access::distance_to(y,x);
williamr@2
   224
  }
williamr@2
   225
williamr@2
   226
private:
williamr@2
   227
  Derived& final(){return *static_cast<Derived*>(this);}
williamr@2
   228
  const Derived& final()const{return *static_cast<const Derived*>(this);}
williamr@2
   229
};
williamr@2
   230
williamr@2
   231
template<>
williamr@2
   232
struct iter_adaptor_selector<std::random_access_iterator_tag>
williamr@2
   233
{
williamr@2
   234
  template<class Derived,class Base>
williamr@2
   235
  struct apply
williamr@2
   236
  {
williamr@2
   237
    typedef random_access_iter_adaptor_base<Derived,Base> type;
williamr@2
   238
  };
williamr@2
   239
};
williamr@2
   240
williamr@2
   241
template<class Derived,class Base>
williamr@2
   242
struct iter_adaptor_base
williamr@2
   243
{
williamr@2
   244
  typedef iter_adaptor_selector<
williamr@2
   245
    typename Base::iterator_category>        selector;
williamr@2
   246
  typedef typename prevent_eti<
williamr@2
   247
    selector,
williamr@2
   248
    typename mpl::apply2<
williamr@2
   249
      selector,Derived,Base>::type
williamr@2
   250
  >::type                                    type;
williamr@2
   251
};
williamr@2
   252
williamr@2
   253
template<class Derived,class Base>
williamr@2
   254
class iter_adaptor:public iter_adaptor_base<Derived,Base>::type
williamr@2
   255
{
williamr@2
   256
protected:
williamr@2
   257
  iter_adaptor(){}
williamr@2
   258
  explicit iter_adaptor(const Base& b_):b(b_){}
williamr@2
   259
williamr@2
   260
  const Base& base_reference()const{return b;}
williamr@2
   261
  Base&       base_reference(){return b;}
williamr@2
   262
williamr@2
   263
private:
williamr@2
   264
  Base b;
williamr@2
   265
};
williamr@2
   266
williamr@2
   267
} /* namespace multi_index::detail */
williamr@2
   268
williamr@2
   269
} /* namespace multi_index */
williamr@2
   270
williamr@2
   271
} /* namespace boost */
williamr@2
   272
williamr@2
   273
#endif