epoc32/include/stdapis/boost/iterator/iterator_adaptor.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
// (C) Copyright David Abrahams 2002.
williamr@2
     2
// (C) Copyright Jeremy Siek    2002.
williamr@2
     3
// (C) Copyright Thomas Witt    2002.
williamr@2
     4
// Distributed under the Boost Software License, Version 1.0. (See
williamr@2
     5
// accompanying file LICENSE_1_0.txt or copy at
williamr@2
     6
// http://www.boost.org/LICENSE_1_0.txt)
williamr@2
     7
#ifndef BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
williamr@2
     8
#define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
williamr@2
     9
williamr@2
    10
#include <boost/static_assert.hpp>
williamr@2
    11
#include <boost/iterator.hpp>
williamr@2
    12
#include <boost/detail/iterator.hpp>
williamr@2
    13
williamr@2
    14
#include <boost/iterator/iterator_categories.hpp>
williamr@2
    15
#include <boost/iterator/iterator_facade.hpp>
williamr@2
    16
#include <boost/iterator/detail/enable_if.hpp>
williamr@2
    17
williamr@2
    18
#include <boost/mpl/and.hpp>
williamr@2
    19
#include <boost/mpl/not.hpp>
williamr@2
    20
#include <boost/mpl/or.hpp>
williamr@2
    21
williamr@2
    22
#include <boost/type_traits/is_same.hpp>
williamr@2
    23
#include <boost/type_traits/is_convertible.hpp>
williamr@2
    24
williamr@2
    25
#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
williamr@2
    26
# include <boost/type_traits/remove_reference.hpp>
williamr@2
    27
#else 
williamr@2
    28
# include <boost/type_traits/add_reference.hpp>
williamr@2
    29
#endif 
williamr@2
    30
williamr@2
    31
#include <boost/iterator/detail/config_def.hpp>
williamr@2
    32
williamr@2
    33
#include <boost/iterator/iterator_traits.hpp>
williamr@2
    34
williamr@2
    35
namespace boost
williamr@2
    36
{
williamr@2
    37
  // Used as a default template argument internally, merely to
williamr@2
    38
  // indicate "use the default", this can also be passed by users
williamr@2
    39
  // explicitly in order to specify that the default should be used.
williamr@2
    40
  struct use_default;
williamr@2
    41
  
williamr@2
    42
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
williamr@2
    43
  // the incompleteness of use_default causes massive problems for
williamr@2
    44
  // is_convertible (naturally).  This workaround is fortunately not
williamr@2
    45
  // needed for vc6/vc7.
williamr@2
    46
  template<class To>
williamr@2
    47
  struct is_convertible<use_default,To>
williamr@2
    48
    : mpl::false_ {};
williamr@2
    49
# endif 
williamr@2
    50
  
williamr@2
    51
  namespace detail
williamr@2
    52
  {
williamr@2
    53
williamr@2
    54
    // 
williamr@2
    55
    // Result type used in enable_if_convertible meta function.
williamr@2
    56
    // This can be an incomplete type, as only pointers to 
williamr@2
    57
    // enable_if_convertible< ... >::type are used.
williamr@2
    58
    // We could have used void for this, but conversion to
williamr@2
    59
    // void* is just to easy.
williamr@2
    60
    //
williamr@2
    61
    struct enable_type;
williamr@2
    62
  }
williamr@2
    63
williamr@2
    64
williamr@2
    65
  //
williamr@2
    66
  // enable_if for use in adapted iterators constructors.
williamr@2
    67
  //
williamr@2
    68
  // In order to provide interoperability between adapted constant and
williamr@2
    69
  // mutable iterators, adapted iterators will usually provide templated
williamr@2
    70
  // conversion constructors of the following form
williamr@2
    71
  //
williamr@2
    72
  // template <class BaseIterator>
williamr@2
    73
  // class adapted_iterator :
williamr@2
    74
  //   public iterator_adaptor< adapted_iterator<Iterator>, Iterator >
williamr@2
    75
  // {
williamr@2
    76
  // public:
williamr@2
    77
  //   
williamr@2
    78
  //   ...
williamr@2
    79
  //
williamr@2
    80
  //   template <class OtherIterator>
williamr@2
    81
  //   adapted_iterator(
williamr@2
    82
  //       OtherIterator const& it
williamr@2
    83
  //     , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0);
williamr@2
    84
  //
williamr@2
    85
  //   ...
williamr@2
    86
  // };
williamr@2
    87
  //
williamr@2
    88
  // enable_if_convertible is used to remove those overloads from the overload
williamr@2
    89
  // set that cannot be instantiated. For all practical purposes only overloads
williamr@2
    90
  // for constant/mutable interaction will remain. This has the advantage that
williamr@2
    91
  // meta functions like boost::is_convertible do not return false positives,
williamr@2
    92
  // as they can only look at the signature of the conversion constructor
williamr@2
    93
  // and not at the actual instantiation.
williamr@2
    94
  //
williamr@2
    95
  // enable_if_interoperable can be safely used in user code. It falls back to
williamr@2
    96
  // always enabled for compilers that don't support enable_if or is_convertible. 
williamr@2
    97
  // There is no need for compiler specific workarounds in user code. 
williamr@2
    98
  //
williamr@2
    99
  // The operators implementation relies on boost::is_convertible not returning
williamr@2
   100
  // false positives for user/library defined iterator types. See comments
williamr@2
   101
  // on operator implementation for consequences.
williamr@2
   102
  //
williamr@2
   103
#  if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
williamr@2
   104
  
williamr@2
   105
  template<typename From, typename To>
williamr@2
   106
  struct enable_if_convertible
williamr@2
   107
  {
williamr@2
   108
     typedef typename mpl::if_<
williamr@2
   109
         mpl::or_<
williamr@2
   110
             is_same<From,To>
williamr@2
   111
           , is_convertible<From, To>
williamr@2
   112
         >
williamr@2
   113
      , detail::enable_type
williamr@2
   114
      , int&
williamr@2
   115
     >::type type;
williamr@2
   116
  };
williamr@2
   117
  
williamr@2
   118
#  elif defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE)
williamr@2
   119
  
williamr@2
   120
  template <class From, class To>
williamr@2
   121
  struct enable_if_convertible
williamr@2
   122
  {
williamr@2
   123
      typedef detail::enable_type type;
williamr@2
   124
  };
williamr@2
   125
  
williamr@2
   126
#  elif BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) && BOOST_MSVC > 1300
williamr@2
   127
  
williamr@2
   128
  // For some reason vc7.1 needs us to "cut off" instantiation
williamr@2
   129
  // of is_convertible in a few cases.
williamr@2
   130
  template<typename From, typename To>
williamr@2
   131
  struct enable_if_convertible
williamr@2
   132
    : iterators::enable_if<
williamr@2
   133
        mpl::or_<
williamr@2
   134
            is_same<From,To>
williamr@2
   135
          , is_convertible<From, To>
williamr@2
   136
        >
williamr@2
   137
      , detail::enable_type
williamr@2
   138
    >
williamr@2
   139
  {};
williamr@2
   140
  
williamr@2
   141
#  else 
williamr@2
   142
  
williamr@2
   143
  template<typename From, typename To>
williamr@2
   144
  struct enable_if_convertible
williamr@2
   145
    : iterators::enable_if<
williamr@2
   146
          is_convertible<From, To>
williamr@2
   147
        , detail::enable_type
williamr@2
   148
      >
williamr@2
   149
  {};
williamr@2
   150
      
williamr@2
   151
# endif
williamr@2
   152
  
williamr@2
   153
  //
williamr@2
   154
  // Default template argument handling for iterator_adaptor
williamr@2
   155
  //
williamr@2
   156
  namespace detail
williamr@2
   157
  {
williamr@2
   158
    // If T is use_default, return the result of invoking
williamr@2
   159
    // DefaultNullaryFn, otherwise return T.
williamr@2
   160
    template <class T, class DefaultNullaryFn>
williamr@2
   161
    struct ia_dflt_help
williamr@2
   162
      : mpl::eval_if<
williamr@2
   163
            is_same<T, use_default>
williamr@2
   164
          , DefaultNullaryFn
williamr@2
   165
          , mpl::identity<T>
williamr@2
   166
        >
williamr@2
   167
    {
williamr@2
   168
    };
williamr@2
   169
williamr@2
   170
    // A metafunction which computes an iterator_adaptor's base class,
williamr@2
   171
    // a specialization of iterator_facade.
williamr@2
   172
    template <
williamr@2
   173
        class Derived
williamr@2
   174
      , class Base
williamr@2
   175
      , class Value
williamr@2
   176
      , class Traversal
williamr@2
   177
      , class Reference
williamr@2
   178
      , class Difference
williamr@2
   179
    >
williamr@2
   180
    struct iterator_adaptor_base
williamr@2
   181
    {
williamr@2
   182
        typedef iterator_facade<
williamr@2
   183
            Derived
williamr@2
   184
            
williamr@2
   185
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
williamr@2
   186
          , typename detail::ia_dflt_help<
williamr@2
   187
                Value
williamr@2
   188
              , mpl::eval_if<
williamr@2
   189
                    is_same<Reference,use_default>
williamr@2
   190
                  , iterator_value<Base>
williamr@2
   191
                  , remove_reference<Reference>
williamr@2
   192
                >
williamr@2
   193
            >::type
williamr@2
   194
# else
williamr@2
   195
          , typename detail::ia_dflt_help<
williamr@2
   196
                Value, iterator_value<Base>
williamr@2
   197
            >::type
williamr@2
   198
# endif
williamr@2
   199
            
williamr@2
   200
          , typename detail::ia_dflt_help<
williamr@2
   201
                Traversal
williamr@2
   202
              , iterator_traversal<Base>
williamr@2
   203
            >::type
williamr@2
   204
williamr@2
   205
          , typename detail::ia_dflt_help<
williamr@2
   206
                Reference
williamr@2
   207
              , mpl::eval_if<
williamr@2
   208
                    is_same<Value,use_default>
williamr@2
   209
                  , iterator_reference<Base>
williamr@2
   210
                  , add_reference<Value>
williamr@2
   211
                >
williamr@2
   212
            >::type
williamr@2
   213
williamr@2
   214
          , typename detail::ia_dflt_help<
williamr@2
   215
                Difference, iterator_difference<Base>
williamr@2
   216
            >::type
williamr@2
   217
        >
williamr@2
   218
        type;
williamr@2
   219
    };
williamr@2
   220
  
williamr@2
   221
    // workaround for aC++ CR JAGaf33512
williamr@2
   222
    template <class Tr1, class Tr2>
williamr@2
   223
    inline void iterator_adaptor_assert_traversal ()
williamr@2
   224
    {
williamr@2
   225
      BOOST_STATIC_ASSERT((is_convertible<Tr1, Tr2>::value));
williamr@2
   226
    }
williamr@2
   227
  }
williamr@2
   228
  
williamr@2
   229
  //
williamr@2
   230
  // Iterator Adaptor
williamr@2
   231
  //
williamr@2
   232
  // The parameter ordering changed slightly with respect to former
williamr@2
   233
  // versions of iterator_adaptor The idea is that when the user needs
williamr@2
   234
  // to fiddle with the reference type it is highly likely that the
williamr@2
   235
  // iterator category has to be adjusted as well.  Any of the
williamr@2
   236
  // following four template arguments may be ommitted or explicitly
williamr@2
   237
  // replaced by use_default.
williamr@2
   238
  //
williamr@2
   239
  //   Value - if supplied, the value_type of the resulting iterator, unless
williamr@2
   240
  //      const. If const, a conforming compiler strips constness for the
williamr@2
   241
  //      value_type. If not supplied, iterator_traits<Base>::value_type is used
williamr@2
   242
  //
williamr@2
   243
  //   Category - the traversal category of the resulting iterator. If not
williamr@2
   244
  //      supplied, iterator_traversal<Base>::type is used.
williamr@2
   245
  //
williamr@2
   246
  //   Reference - the reference type of the resulting iterator, and in
williamr@2
   247
  //      particular, the result type of operator*(). If not supplied but
williamr@2
   248
  //      Value is supplied, Value& is used. Otherwise
williamr@2
   249
  //      iterator_traits<Base>::reference is used.
williamr@2
   250
  //
williamr@2
   251
  //   Difference - the difference_type of the resulting iterator. If not
williamr@2
   252
  //      supplied, iterator_traits<Base>::difference_type is used.
williamr@2
   253
  //
williamr@2
   254
  template <
williamr@2
   255
      class Derived
williamr@2
   256
    , class Base
williamr@2
   257
    , class Value        = use_default
williamr@2
   258
    , class Traversal    = use_default
williamr@2
   259
    , class Reference    = use_default
williamr@2
   260
    , class Difference   = use_default
williamr@2
   261
  >
williamr@2
   262
  class iterator_adaptor
williamr@2
   263
    : public detail::iterator_adaptor_base<
williamr@2
   264
        Derived, Base, Value, Traversal, Reference, Difference
williamr@2
   265
      >::type
williamr@2
   266
  {
williamr@2
   267
      friend class iterator_core_access;
williamr@2
   268
williamr@2
   269
   protected:
williamr@2
   270
      typedef typename detail::iterator_adaptor_base<
williamr@2
   271
          Derived, Base, Value, Traversal, Reference, Difference
williamr@2
   272
      >::type super_t;
williamr@2
   273
   public:
williamr@2
   274
      iterator_adaptor() {}
williamr@2
   275
williamr@2
   276
      explicit iterator_adaptor(Base const &iter)
williamr@2
   277
          : m_iterator(iter)
williamr@2
   278
      {
williamr@2
   279
      }
williamr@2
   280
williamr@2
   281
      typedef Base base_type;
williamr@2
   282
williamr@2
   283
      Base const& base() const
williamr@2
   284
        { return m_iterator; }
williamr@2
   285
williamr@2
   286
   protected:
williamr@2
   287
      // for convenience in derived classes
williamr@2
   288
      typedef iterator_adaptor<Derived,Base,Value,Traversal,Reference,Difference> iterator_adaptor_;
williamr@2
   289
      
williamr@2
   290
      //
williamr@2
   291
      // lvalue access to the Base object for Derived
williamr@2
   292
      //
williamr@2
   293
      Base const& base_reference() const
williamr@2
   294
        { return m_iterator; }
williamr@2
   295
williamr@2
   296
      Base& base_reference()
williamr@2
   297
        { return m_iterator; }
williamr@2
   298
williamr@2
   299
   private:
williamr@2
   300
      //
williamr@2
   301
      // Core iterator interface for iterator_facade.  This is private
williamr@2
   302
      // to prevent temptation for Derived classes to use it, which
williamr@2
   303
      // will often result in an error.  Derived classes should use
williamr@2
   304
      // base_reference(), above, to get direct access to m_iterator.
williamr@2
   305
      // 
williamr@2
   306
      typename super_t::reference dereference() const
williamr@2
   307
        { return *m_iterator; }
williamr@2
   308
williamr@2
   309
      template <
williamr@2
   310
      class OtherDerived, class OtherIterator, class V, class C, class R, class D
williamr@2
   311
      >   
williamr@2
   312
      bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const
williamr@2
   313
      {
williamr@2
   314
        // Maybe readd with same_distance
williamr@2
   315
        //           BOOST_STATIC_ASSERT(
williamr@2
   316
        //               (detail::same_category_and_difference<Derived,OtherDerived>::value)
williamr@2
   317
        //               );
williamr@2
   318
          return m_iterator == x.base();
williamr@2
   319
      }
williamr@2
   320
williamr@2
   321
      typedef typename iterator_category_to_traversal<
williamr@2
   322
          typename super_t::iterator_category
williamr@2
   323
      >::type my_traversal;
williamr@2
   324
williamr@2
   325
# define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \
williamr@2
   326
      detail::iterator_adaptor_assert_traversal<my_traversal, cat>();
williamr@2
   327
williamr@2
   328
      void advance(typename super_t::difference_type n)
williamr@2
   329
      {
williamr@2
   330
          BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
williamr@2
   331
          m_iterator += n;
williamr@2
   332
      }
williamr@2
   333
  
williamr@2
   334
      void increment() { ++m_iterator; }
williamr@2
   335
williamr@2
   336
      void decrement() 
williamr@2
   337
      {
williamr@2
   338
          BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag)
williamr@2
   339
           --m_iterator;
williamr@2
   340
      }
williamr@2
   341
williamr@2
   342
      template <
williamr@2
   343
          class OtherDerived, class OtherIterator, class V, class C, class R, class D
williamr@2
   344
      >   
williamr@2
   345
      typename super_t::difference_type distance_to(
williamr@2
   346
          iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const
williamr@2
   347
      {
williamr@2
   348
          BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
williamr@2
   349
          // Maybe readd with same_distance
williamr@2
   350
          //           BOOST_STATIC_ASSERT(
williamr@2
   351
          //               (detail::same_category_and_difference<Derived,OtherDerived>::value)
williamr@2
   352
          //               );
williamr@2
   353
          return y.base() - m_iterator;
williamr@2
   354
      }
williamr@2
   355
williamr@2
   356
# undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL
williamr@2
   357
      
williamr@2
   358
   private: // data members
williamr@2
   359
      Base m_iterator;
williamr@2
   360
  };
williamr@2
   361
williamr@2
   362
} // namespace boost
williamr@2
   363
williamr@2
   364
#include <boost/iterator/detail/config_undef.hpp>
williamr@2
   365
williamr@2
   366
#endif // BOOST_ITERATOR_ADAPTOR_23022003THW_HPP