epoc32/include/stdapis/boost/iterator/iterator_facade.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_FACADE_23022003THW_HPP
williamr@2
     8
#define BOOST_ITERATOR_FACADE_23022003THW_HPP
williamr@2
     9
williamr@2
    10
#include <boost/iterator.hpp>
williamr@2
    11
#include <boost/iterator/interoperable.hpp>
williamr@2
    12
#include <boost/iterator/iterator_traits.hpp>
williamr@2
    13
williamr@2
    14
#include <boost/iterator/detail/facade_iterator_category.hpp>
williamr@2
    15
#include <boost/iterator/detail/enable_if.hpp>
williamr@2
    16
williamr@2
    17
#include <boost/implicit_cast.hpp>
williamr@2
    18
#include <boost/static_assert.hpp>
williamr@2
    19
williamr@2
    20
#include <boost/type_traits/is_same.hpp>
williamr@2
    21
#include <boost/type_traits/add_const.hpp>
williamr@2
    22
#include <boost/type_traits/add_pointer.hpp>
williamr@2
    23
#include <boost/type_traits/remove_const.hpp>
williamr@2
    24
#include <boost/type_traits/remove_reference.hpp>
williamr@2
    25
#include <boost/type_traits/is_convertible.hpp>
williamr@2
    26
#include <boost/type_traits/is_pod.hpp>
williamr@2
    27
williamr@2
    28
#include <boost/mpl/eval_if.hpp>
williamr@2
    29
#include <boost/mpl/if.hpp>
williamr@2
    30
#include <boost/mpl/or.hpp>
williamr@2
    31
#include <boost/mpl/and.hpp>
williamr@2
    32
#include <boost/mpl/not.hpp>
williamr@2
    33
#include <boost/mpl/always.hpp>
williamr@2
    34
#include <boost/mpl/apply.hpp>
williamr@2
    35
#include <boost/mpl/identity.hpp>
williamr@2
    36
williamr@2
    37
#include <boost/iterator/detail/config_def.hpp> // this goes last
williamr@2
    38
williamr@2
    39
namespace boost
williamr@2
    40
{
williamr@2
    41
  // This forward declaration is required for the friend declaration
williamr@2
    42
  // in iterator_core_access
williamr@2
    43
  template <class I, class V, class TC, class R, class D> class iterator_facade;
williamr@2
    44
williamr@2
    45
  namespace detail
williamr@2
    46
  {
williamr@2
    47
    // A binary metafunction class that always returns bool.  VC6
williamr@2
    48
    // ICEs on mpl::always<bool>, probably because of the default
williamr@2
    49
    // parameters.
williamr@2
    50
    struct always_bool2
williamr@2
    51
    {
williamr@2
    52
        template <class T, class U>
williamr@2
    53
        struct apply
williamr@2
    54
        {
williamr@2
    55
            typedef bool type;
williamr@2
    56
        };
williamr@2
    57
    };
williamr@2
    58
williamr@2
    59
    //
williamr@2
    60
    // enable if for use in operator implementation.
williamr@2
    61
    //
williamr@2
    62
    template <
williamr@2
    63
        class Facade1
williamr@2
    64
      , class Facade2
williamr@2
    65
      , class Return
williamr@2
    66
    >
williamr@2
    67
    struct enable_if_interoperable
williamr@2
    68
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
williamr@2
    69
    {
williamr@2
    70
        typedef typename mpl::if_<
williamr@2
    71
            mpl::or_<
williamr@2
    72
                is_convertible<Facade1, Facade2>
williamr@2
    73
              , is_convertible<Facade2, Facade1>
williamr@2
    74
            >
williamr@2
    75
          , Return
williamr@2
    76
          , int[3]
williamr@2
    77
        >::type type;
williamr@2
    78
    };        
williamr@2
    79
#else
williamr@2
    80
      : ::boost::iterators::enable_if<
williamr@2
    81
           mpl::or_<
williamr@2
    82
               is_convertible<Facade1, Facade2>
williamr@2
    83
             , is_convertible<Facade2, Facade1>
williamr@2
    84
           >
williamr@2
    85
         , Return
williamr@2
    86
        >
williamr@2
    87
    {};
williamr@2
    88
#endif 
williamr@2
    89
williamr@2
    90
    //
williamr@2
    91
    // Generates associated types for an iterator_facade with the
williamr@2
    92
    // given parameters.
williamr@2
    93
    //
williamr@2
    94
    template <
williamr@2
    95
        class ValueParam
williamr@2
    96
      , class CategoryOrTraversal
williamr@2
    97
      , class Reference 
williamr@2
    98
      , class Difference
williamr@2
    99
    >
williamr@2
   100
    struct iterator_facade_types
williamr@2
   101
    {
williamr@2
   102
        typedef typename facade_iterator_category<
williamr@2
   103
            CategoryOrTraversal, ValueParam, Reference
williamr@2
   104
        >::type iterator_category;
williamr@2
   105
        
williamr@2
   106
        typedef typename remove_const<ValueParam>::type value_type;
williamr@2
   107
        
williamr@2
   108
        typedef typename mpl::eval_if<
williamr@2
   109
            detail::iterator_writability_disabled<ValueParam,Reference>
williamr@2
   110
          , add_pointer<const value_type>
williamr@2
   111
          , add_pointer<value_type>
williamr@2
   112
        >::type pointer;
williamr@2
   113
      
williamr@2
   114
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)                          \
williamr@2
   115
    && (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452))              \
williamr@2
   116
        || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310)))     \
williamr@2
   117
    || BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101))              \
williamr@2
   118
    || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 310)
williamr@2
   119
williamr@2
   120
        // To interoperate with some broken library/compiler
williamr@2
   121
        // combinations, user-defined iterators must be derived from
williamr@2
   122
        // std::iterator.  It is possible to implement a standard
williamr@2
   123
        // library for broken compilers without this limitation.
williamr@2
   124
#  define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1
williamr@2
   125
williamr@2
   126
        typedef
williamr@2
   127
           iterator<iterator_category, value_type, Difference, pointer, Reference>
williamr@2
   128
        base;
williamr@2
   129
# endif
williamr@2
   130
    };
williamr@2
   131
williamr@2
   132
    // iterators whose dereference operators reference the same value
williamr@2
   133
    // for all iterators into the same sequence (like many input
williamr@2
   134
    // iterators) need help with their postfix ++: the referenced
williamr@2
   135
    // value must be read and stored away before the increment occurs
williamr@2
   136
    // so that *a++ yields the originally referenced element and not
williamr@2
   137
    // the next one.
williamr@2
   138
    template <class Iterator>
williamr@2
   139
    class postfix_increment_proxy
williamr@2
   140
    {
williamr@2
   141
        typedef typename iterator_value<Iterator>::type value_type;
williamr@2
   142
     public:
williamr@2
   143
        explicit postfix_increment_proxy(Iterator const& x)
williamr@2
   144
          : stored_value(*x)
williamr@2
   145
        {}
williamr@2
   146
williamr@2
   147
        // Returning a mutable reference allows nonsense like
williamr@2
   148
        // (*r++).mutate(), but it imposes fewer assumptions about the
williamr@2
   149
        // behavior of the value_type.  In particular, recall taht
williamr@2
   150
        // (*r).mutate() is legal if operator* returns by value.
williamr@2
   151
        value_type&
williamr@2
   152
        operator*() const
williamr@2
   153
        {
williamr@2
   154
            return this->stored_value;
williamr@2
   155
        }
williamr@2
   156
     private:
williamr@2
   157
        mutable value_type stored_value;
williamr@2
   158
    };
williamr@2
   159
    
williamr@2
   160
    //
williamr@2
   161
    // In general, we can't determine that such an iterator isn't
williamr@2
   162
    // writable -- we also need to store a copy of the old iterator so
williamr@2
   163
    // that it can be written into.
williamr@2
   164
    template <class Iterator>
williamr@2
   165
    class writable_postfix_increment_proxy
williamr@2
   166
    {
williamr@2
   167
        typedef typename iterator_value<Iterator>::type value_type;
williamr@2
   168
     public:
williamr@2
   169
        explicit writable_postfix_increment_proxy(Iterator const& x)
williamr@2
   170
          : stored_value(*x)
williamr@2
   171
          , stored_iterator(x)
williamr@2
   172
        {}
williamr@2
   173
williamr@2
   174
        // Dereferencing must return a proxy so that both *r++ = o and
williamr@2
   175
        // value_type(*r++) can work.  In this case, *r is the same as
williamr@2
   176
        // *r++, and the conversion operator below is used to ensure
williamr@2
   177
        // readability.
williamr@2
   178
        writable_postfix_increment_proxy const&
williamr@2
   179
        operator*() const
williamr@2
   180
        {
williamr@2
   181
            return *this;
williamr@2
   182
        }
williamr@2
   183
williamr@2
   184
        // Provides readability of *r++
williamr@2
   185
        operator value_type&() const
williamr@2
   186
        {
williamr@2
   187
            return stored_value;
williamr@2
   188
        }
williamr@2
   189
williamr@2
   190
        // Provides writability of *r++
williamr@2
   191
        template <class T>
williamr@2
   192
        T const& operator=(T const& x) const
williamr@2
   193
        {
williamr@2
   194
            *this->stored_iterator = x;
williamr@2
   195
            return x;
williamr@2
   196
        }
williamr@2
   197
williamr@2
   198
        // This overload just in case only non-const objects are writable
williamr@2
   199
        template <class T>
williamr@2
   200
        T& operator=(T& x) const
williamr@2
   201
        {
williamr@2
   202
            *this->stored_iterator = x;
williamr@2
   203
            return x;
williamr@2
   204
        }
williamr@2
   205
williamr@2
   206
        // Provides X(r++)
williamr@2
   207
        operator Iterator const&() const
williamr@2
   208
        {
williamr@2
   209
            return stored_iterator;
williamr@2
   210
        }
williamr@2
   211
        
williamr@2
   212
     private:
williamr@2
   213
        mutable value_type stored_value;
williamr@2
   214
        Iterator stored_iterator;
williamr@2
   215
    };
williamr@2
   216
williamr@2
   217
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
williamr@2
   218
williamr@2
   219
    template <class Reference, class Value>
williamr@2
   220
    struct is_non_proxy_reference_impl
williamr@2
   221
    {
williamr@2
   222
        static Reference r;
williamr@2
   223
        
williamr@2
   224
        template <class R>
williamr@2
   225
        static typename mpl::if_<
williamr@2
   226
            is_convertible<
williamr@2
   227
                R const volatile*
williamr@2
   228
              , Value const volatile*
williamr@2
   229
            >
williamr@2
   230
          , char[1]
williamr@2
   231
          , char[2]
williamr@2
   232
        >::type& helper(R const&);
williamr@2
   233
        
williamr@2
   234
        BOOST_STATIC_CONSTANT(bool, value = sizeof(helper(r)) == 1);
williamr@2
   235
    };
williamr@2
   236
        
williamr@2
   237
    template <class Reference, class Value>
williamr@2
   238
    struct is_non_proxy_reference
williamr@2
   239
      : mpl::bool_<
williamr@2
   240
            is_non_proxy_reference_impl<Reference, Value>::value
williamr@2
   241
        >
williamr@2
   242
    {};
williamr@2
   243
# else 
williamr@2
   244
    template <class Reference, class Value>
williamr@2
   245
    struct is_non_proxy_reference
williamr@2
   246
      : is_convertible<
williamr@2
   247
            typename remove_reference<Reference>::type
williamr@2
   248
            const volatile*
williamr@2
   249
          , Value const volatile*
williamr@2
   250
        >
williamr@2
   251
    {};
williamr@2
   252
# endif 
williamr@2
   253
        
williamr@2
   254
    // A metafunction to choose the result type of postfix ++
williamr@2
   255
    //
williamr@2
   256
    // Because the C++98 input iterator requirements say that *r++ has
williamr@2
   257
    // type T (value_type), implementations of some standard
williamr@2
   258
    // algorithms like lexicographical_compare may use constructions
williamr@2
   259
    // like:
williamr@2
   260
    //
williamr@2
   261
    //          *r++ < *s++
williamr@2
   262
    //
williamr@2
   263
    // If *r++ returns a proxy (as required if r is writable but not
williamr@2
   264
    // multipass), this sort of expression will fail unless the proxy
williamr@2
   265
    // supports the operator<.  Since there are any number of such
williamr@2
   266
    // operations, we're not going to try to support them.  Therefore,
williamr@2
   267
    // even if r++ returns a proxy, *r++ will only return a proxy if
williamr@2
   268
    // *r also returns a proxy.
williamr@2
   269
    template <class Iterator, class Value, class Reference, class CategoryOrTraversal>
williamr@2
   270
    struct postfix_increment_result
williamr@2
   271
      : mpl::eval_if<
williamr@2
   272
            mpl::and_<
williamr@2
   273
                // A proxy is only needed for readable iterators
williamr@2
   274
                is_convertible<Reference,Value const&>
williamr@2
   275
                
williamr@2
   276
                // No multipass iterator can have values that disappear
williamr@2
   277
                // before positions can be re-visited
williamr@2
   278
              , mpl::not_<
williamr@2
   279
                    is_convertible<
williamr@2
   280
                        typename iterator_category_to_traversal<CategoryOrTraversal>::type
williamr@2
   281
                      , forward_traversal_tag
williamr@2
   282
                    >
williamr@2
   283
                >
williamr@2
   284
            >
williamr@2
   285
          , mpl::if_<
williamr@2
   286
                is_non_proxy_reference<Reference,Value>
williamr@2
   287
              , postfix_increment_proxy<Iterator>
williamr@2
   288
              , writable_postfix_increment_proxy<Iterator>
williamr@2
   289
            >
williamr@2
   290
          , mpl::identity<Iterator>
williamr@2
   291
        >
williamr@2
   292
    {};
williamr@2
   293
williamr@2
   294
    // operator->() needs special support for input iterators to strictly meet the
williamr@2
   295
    // standard's requirements. If *i is not a reference type, we must still
williamr@2
   296
    // produce a lvalue to which a pointer can be formed. We do that by
williamr@2
   297
    // returning an instantiation of this special proxy class template.
williamr@2
   298
    template <class T>
williamr@2
   299
    struct operator_arrow_proxy
williamr@2
   300
    {
williamr@2
   301
        operator_arrow_proxy(T const* px) : m_value(*px) {}
williamr@2
   302
        T* operator->() const { return &m_value; }
williamr@2
   303
        // This function is needed for MWCW and BCC, which won't call operator->
williamr@2
   304
        // again automatically per 13.3.1.2 para 8
williamr@2
   305
        operator T*() const { return &m_value; }
williamr@2
   306
        mutable T m_value;
williamr@2
   307
    };
williamr@2
   308
williamr@2
   309
    // A metafunction that gets the result type for operator->.  Also
williamr@2
   310
    // has a static function make() which builds the result from a
williamr@2
   311
    // Reference
williamr@2
   312
    template <class ValueType, class Reference, class Pointer>
williamr@2
   313
    struct operator_arrow_result
williamr@2
   314
    {
williamr@2
   315
        // CWPro8.3 won't accept "operator_arrow_result::type", and we
williamr@2
   316
        // need that type below, so metafunction forwarding would be a
williamr@2
   317
        // losing proposition here.
williamr@2
   318
        typedef typename mpl::if_<
williamr@2
   319
            is_reference<Reference>
williamr@2
   320
          , Pointer
williamr@2
   321
          , operator_arrow_proxy<ValueType>
williamr@2
   322
        >::type type;
williamr@2
   323
williamr@2
   324
        static type make(Reference x)
williamr@2
   325
        {
williamr@2
   326
            return implicit_cast<type>(&x);
williamr@2
   327
        }
williamr@2
   328
    };
williamr@2
   329
williamr@2
   330
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
williamr@2
   331
    // Deal with ETI
williamr@2
   332
    template<>
williamr@2
   333
    struct operator_arrow_result<int, int, int>
williamr@2
   334
    {
williamr@2
   335
        typedef int type;
williamr@2
   336
    };
williamr@2
   337
# endif
williamr@2
   338
williamr@2
   339
    // A proxy return type for operator[], needed to deal with
williamr@2
   340
    // iterators that may invalidate referents upon destruction.
williamr@2
   341
    // Consider the temporary iterator in *(a + n)
williamr@2
   342
    template <class Iterator>
williamr@2
   343
    class operator_brackets_proxy
williamr@2
   344
    {
williamr@2
   345
        // Iterator is actually an iterator_facade, so we do not have to
williamr@2
   346
        // go through iterator_traits to access the traits.
williamr@2
   347
        typedef typename Iterator::reference  reference;
williamr@2
   348
        typedef typename Iterator::value_type value_type;
williamr@2
   349
williamr@2
   350
     public:
williamr@2
   351
        operator_brackets_proxy(Iterator const& iter)
williamr@2
   352
          : m_iter(iter)
williamr@2
   353
        {}
williamr@2
   354
williamr@2
   355
        operator reference() const
williamr@2
   356
        {
williamr@2
   357
            return *m_iter;
williamr@2
   358
        }
williamr@2
   359
williamr@2
   360
        operator_brackets_proxy& operator=(value_type const& val)
williamr@2
   361
        {
williamr@2
   362
            *m_iter = val;
williamr@2
   363
            return *this;
williamr@2
   364
        }
williamr@2
   365
williamr@2
   366
     private:
williamr@2
   367
        Iterator m_iter;
williamr@2
   368
    };
williamr@2
   369
williamr@2
   370
    // A metafunction that determines whether operator[] must return a
williamr@2
   371
    // proxy, or whether it can simply return a copy of the value_type.
williamr@2
   372
    template <class ValueType, class Reference>
williamr@2
   373
    struct use_operator_brackets_proxy
williamr@2
   374
      : mpl::not_<
williamr@2
   375
            mpl::and_<
williamr@2
   376
                // Really we want an is_copy_constructible trait here,
williamr@2
   377
                // but is_POD will have to suffice in the meantime.
williamr@2
   378
                boost::is_POD<ValueType>
williamr@2
   379
              , iterator_writability_disabled<ValueType,Reference>
williamr@2
   380
            >
williamr@2
   381
        >
williamr@2
   382
    {};
williamr@2
   383
        
williamr@2
   384
    template <class Iterator, class Value, class Reference>
williamr@2
   385
    struct operator_brackets_result
williamr@2
   386
    {
williamr@2
   387
        typedef typename mpl::if_<
williamr@2
   388
            use_operator_brackets_proxy<Value,Reference>
williamr@2
   389
          , operator_brackets_proxy<Iterator>
williamr@2
   390
          , Value
williamr@2
   391
        >::type type;
williamr@2
   392
    };
williamr@2
   393
williamr@2
   394
    template <class Iterator>
williamr@2
   395
    operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::true_)
williamr@2
   396
    {
williamr@2
   397
        return operator_brackets_proxy<Iterator>(iter);
williamr@2
   398
    }
williamr@2
   399
williamr@2
   400
    template <class Iterator>
williamr@2
   401
    typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_)
williamr@2
   402
    {
williamr@2
   403
      return *iter;
williamr@2
   404
    }
williamr@2
   405
williamr@2
   406
    struct choose_difference_type
williamr@2
   407
    {
williamr@2
   408
        template <class I1, class I2>
williamr@2
   409
        struct apply
williamr@2
   410
          :
williamr@2
   411
# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
williamr@2
   412
          iterator_difference<I1>
williamr@2
   413
# elif BOOST_WORKAROUND(BOOST_MSVC, < 1300)
williamr@2
   414
          mpl::if_<
williamr@2
   415
              is_convertible<I2,I1>
williamr@2
   416
            , typename I1::difference_type
williamr@2
   417
            , typename I2::difference_type
williamr@2
   418
          >
williamr@2
   419
# else 
williamr@2
   420
          mpl::eval_if<
williamr@2
   421
              is_convertible<I2,I1>
williamr@2
   422
            , iterator_difference<I1>
williamr@2
   423
            , iterator_difference<I2>
williamr@2
   424
          >
williamr@2
   425
# endif 
williamr@2
   426
        {};
williamr@2
   427
williamr@2
   428
    };
williamr@2
   429
  } // namespace detail
williamr@2
   430
williamr@2
   431
williamr@2
   432
  // Macros which describe the declarations of binary operators
williamr@2
   433
# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
williamr@2
   434
#  define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type)       \
williamr@2
   435
    template <                                                              \
williamr@2
   436
        class Derived1, class V1, class TC1, class R1, class D1             \
williamr@2
   437
      , class Derived2, class V2, class TC2, class R2, class D2             \
williamr@2
   438
    >                                                                       \
williamr@2
   439
    prefix typename mpl::apply2<result_type,Derived1,Derived2>::type \
williamr@2
   440
    operator op(                                                            \
williamr@2
   441
        iterator_facade<Derived1, V1, TC1, R1, D1> const& lhs               \
williamr@2
   442
      , iterator_facade<Derived2, V2, TC2, R2, D2> const& rhs)
williamr@2
   443
# else 
williamr@2
   444
#  define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type)   \
williamr@2
   445
    template <                                                          \
williamr@2
   446
        class Derived1, class V1, class TC1, class R1, class D1         \
williamr@2
   447
      , class Derived2, class V2, class TC2, class R2, class D2         \
williamr@2
   448
    >                                                                   \
williamr@2
   449
    prefix typename detail::enable_if_interoperable<             \
williamr@2
   450
        Derived1, Derived2                                              \
williamr@2
   451
      , typename mpl::apply2<result_type,Derived1,Derived2>::type       \
williamr@2
   452
    >::type                                                             \
williamr@2
   453
    operator op(                                                        \
williamr@2
   454
        iterator_facade<Derived1, V1, TC1, R1, D1> const& lhs           \
williamr@2
   455
      , iterator_facade<Derived2, V2, TC2, R2, D2> const& rhs)
williamr@2
   456
# endif 
williamr@2
   457
williamr@2
   458
#  define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args)              \
williamr@2
   459
    template <class Derived, class V, class TC, class R, class D>   \
williamr@2
   460
    prefix Derived operator+ args
williamr@2
   461
williamr@2
   462
  //
williamr@2
   463
  // Helper class for granting access to the iterator core interface.
williamr@2
   464
  //
williamr@2
   465
  // The simple core interface is used by iterator_facade. The core
williamr@2
   466
  // interface of a user/library defined iterator type should not be made public
williamr@2
   467
  // so that it does not clutter the public interface. Instead iterator_core_access
williamr@2
   468
  // should be made friend so that iterator_facade can access the core
williamr@2
   469
  // interface through iterator_core_access.
williamr@2
   470
  //
williamr@2
   471
  class iterator_core_access
williamr@2
   472
  {
williamr@2
   473
# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)                  \
williamr@2
   474
    || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
williamr@2
   475
      // Tasteless as this may seem, making all members public allows member templates
williamr@2
   476
      // to work in the absence of member template friends.
williamr@2
   477
   public:
williamr@2
   478
# else
williamr@2
   479
      
williamr@2
   480
      template <class I, class V, class TC, class R, class D> friend class iterator_facade;
williamr@2
   481
williamr@2
   482
#  define BOOST_ITERATOR_FACADE_RELATION(op)                                \
williamr@2
   483
      BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, detail::always_bool2);
williamr@2
   484
williamr@2
   485
      BOOST_ITERATOR_FACADE_RELATION(==)
williamr@2
   486
      BOOST_ITERATOR_FACADE_RELATION(!=)
williamr@2
   487
williamr@2
   488
      BOOST_ITERATOR_FACADE_RELATION(<)
williamr@2
   489
      BOOST_ITERATOR_FACADE_RELATION(>)
williamr@2
   490
      BOOST_ITERATOR_FACADE_RELATION(<=)
williamr@2
   491
      BOOST_ITERATOR_FACADE_RELATION(>=)
williamr@2
   492
#  undef BOOST_ITERATOR_FACADE_RELATION
williamr@2
   493
williamr@2
   494
      BOOST_ITERATOR_FACADE_INTEROP_HEAD(
williamr@2
   495
          friend, -, detail::choose_difference_type)
williamr@2
   496
      ;
williamr@2
   497
williamr@2
   498
      BOOST_ITERATOR_FACADE_PLUS_HEAD(
williamr@2
   499
          friend inline
williamr@2
   500
          , (iterator_facade<Derived, V, TC, R, D> const&
williamr@2
   501
           , typename Derived::difference_type)
williamr@2
   502
      )
williamr@2
   503
      ;
williamr@2
   504
williamr@2
   505
      BOOST_ITERATOR_FACADE_PLUS_HEAD(
williamr@2
   506
          friend inline
williamr@2
   507
        , (typename Derived::difference_type
williamr@2
   508
           , iterator_facade<Derived, V, TC, R, D> const&)
williamr@2
   509
      )
williamr@2
   510
      ;
williamr@2
   511
williamr@2
   512
# endif
williamr@2
   513
williamr@2
   514
      template <class Facade>
williamr@2
   515
      static typename Facade::reference dereference(Facade const& f)
williamr@2
   516
      {
williamr@2
   517
          return f.dereference();
williamr@2
   518
      }
williamr@2
   519
williamr@2
   520
      template <class Facade>
williamr@2
   521
      static void increment(Facade& f)
williamr@2
   522
      {
williamr@2
   523
          f.increment();
williamr@2
   524
      }
williamr@2
   525
williamr@2
   526
      template <class Facade>
williamr@2
   527
      static void decrement(Facade& f)
williamr@2
   528
      {
williamr@2
   529
          f.decrement();
williamr@2
   530
      }
williamr@2
   531
williamr@2
   532
      template <class Facade1, class Facade2>
williamr@2
   533
      static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::true_)
williamr@2
   534
      {
williamr@2
   535
          return f1.equal(f2);
williamr@2
   536
      }
williamr@2
   537
williamr@2
   538
      template <class Facade1, class Facade2>
williamr@2
   539
      static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::false_)
williamr@2
   540
      {
williamr@2
   541
          return f2.equal(f1);
williamr@2
   542
      }
williamr@2
   543
williamr@2
   544
      template <class Facade>
williamr@2
   545
      static void advance(Facade& f, typename Facade::difference_type n)
williamr@2
   546
      {
williamr@2
   547
          f.advance(n);
williamr@2
   548
      }
williamr@2
   549
williamr@2
   550
      template <class Facade1, class Facade2>
williamr@2
   551
      static typename Facade1::difference_type distance_from(
williamr@2
   552
          Facade1 const& f1, Facade2 const& f2, mpl::true_)
williamr@2
   553
      {
williamr@2
   554
          return -f1.distance_to(f2);
williamr@2
   555
      }
williamr@2
   556
williamr@2
   557
      template <class Facade1, class Facade2>
williamr@2
   558
      static typename Facade2::difference_type distance_from(
williamr@2
   559
          Facade1 const& f1, Facade2 const& f2, mpl::false_)
williamr@2
   560
      {
williamr@2
   561
          return f2.distance_to(f1);
williamr@2
   562
      }
williamr@2
   563
williamr@2
   564
      //
williamr@2
   565
      // Curiously Recurring Template interface.
williamr@2
   566
      //
williamr@2
   567
      template <class I, class V, class TC, class R, class D>
williamr@2
   568
      static I& derived(iterator_facade<I,V,TC,R,D>& facade)
williamr@2
   569
      {
williamr@2
   570
          return *static_cast<I*>(&facade);
williamr@2
   571
      }
williamr@2
   572
williamr@2
   573
      template <class I, class V, class TC, class R, class D>
williamr@2
   574
      static I const& derived(iterator_facade<I,V,TC,R,D> const& facade)
williamr@2
   575
      {
williamr@2
   576
          return *static_cast<I const*>(&facade);
williamr@2
   577
      }
williamr@2
   578
williamr@2
   579
   private:
williamr@2
   580
      // objects of this class are useless
williamr@2
   581
      iterator_core_access(); //undefined
williamr@2
   582
  };
williamr@2
   583
williamr@2
   584
  //
williamr@2
   585
  // iterator_facade - use as a public base class for defining new
williamr@2
   586
  // standard-conforming iterators.
williamr@2
   587
  //
williamr@2
   588
  template <
williamr@2
   589
      class Derived             // The derived iterator type being constructed
williamr@2
   590
    , class Value
williamr@2
   591
    , class CategoryOrTraversal
williamr@2
   592
    , class Reference   = Value&
williamr@2
   593
    , class Difference  = std::ptrdiff_t
williamr@2
   594
  >
williamr@2
   595
  class iterator_facade
williamr@2
   596
# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
williamr@2
   597
    : public detail::iterator_facade_types<
williamr@2
   598
         Value, CategoryOrTraversal, Reference, Difference
williamr@2
   599
      >::base
williamr@2
   600
#  undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
williamr@2
   601
# endif
williamr@2
   602
  {
williamr@2
   603
   private:
williamr@2
   604
      //
williamr@2
   605
      // Curiously Recurring Template interface.
williamr@2
   606
      //
williamr@2
   607
      Derived& derived()
williamr@2
   608
      {
williamr@2
   609
          return *static_cast<Derived*>(this);
williamr@2
   610
      }
williamr@2
   611
williamr@2
   612
      Derived const& derived() const
williamr@2
   613
      {
williamr@2
   614
          return *static_cast<Derived const*>(this);
williamr@2
   615
      }
williamr@2
   616
williamr@2
   617
      typedef detail::iterator_facade_types<
williamr@2
   618
         Value, CategoryOrTraversal, Reference, Difference
williamr@2
   619
      > associated_types;
williamr@2
   620
williamr@2
   621
   protected:
williamr@2
   622
      // For use by derived classes
williamr@2
   623
      typedef iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference> iterator_facade_;
williamr@2
   624
      
williamr@2
   625
   public:
williamr@2
   626
williamr@2
   627
      typedef typename associated_types::value_type value_type;
williamr@2
   628
      typedef Reference reference;
williamr@2
   629
      typedef Difference difference_type;
williamr@2
   630
      typedef typename associated_types::pointer pointer;
williamr@2
   631
      typedef typename associated_types::iterator_category iterator_category;
williamr@2
   632
williamr@2
   633
      reference operator*() const
williamr@2
   634
      {
williamr@2
   635
          return iterator_core_access::dereference(this->derived());
williamr@2
   636
      }
williamr@2
   637
williamr@2
   638
      typename detail::operator_arrow_result<
williamr@2
   639
          value_type
williamr@2
   640
        , reference
williamr@2
   641
        , pointer
williamr@2
   642
      >::type
williamr@2
   643
      operator->() const
williamr@2
   644
      {
williamr@2
   645
          return detail::operator_arrow_result<
williamr@2
   646
              value_type
williamr@2
   647
            , reference
williamr@2
   648
            , pointer
williamr@2
   649
          >::make(*this->derived());
williamr@2
   650
      }
williamr@2
   651
        
williamr@2
   652
      typename detail::operator_brackets_result<Derived,Value,reference>::type
williamr@2
   653
      operator[](difference_type n) const
williamr@2
   654
      {
williamr@2
   655
          typedef detail::use_operator_brackets_proxy<Value,Reference> use_proxy;
williamr@2
   656
          
williamr@2
   657
          return detail::make_operator_brackets_result<Derived>(
williamr@2
   658
              this->derived() + n
williamr@2
   659
            , use_proxy()
williamr@2
   660
          );
williamr@2
   661
      }
williamr@2
   662
williamr@2
   663
      Derived& operator++()
williamr@2
   664
      {
williamr@2
   665
          iterator_core_access::increment(this->derived());
williamr@2
   666
          return this->derived();
williamr@2
   667
      }
williamr@2
   668
williamr@2
   669
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
williamr@2
   670
      typename detail::postfix_increment_result<Derived,Value,Reference,CategoryOrTraversal>::type
williamr@2
   671
      operator++(int)
williamr@2
   672
      {
williamr@2
   673
          typename detail::postfix_increment_result<Derived,Value,Reference,CategoryOrTraversal>::type
williamr@2
   674
          tmp(this->derived());
williamr@2
   675
          ++*this;
williamr@2
   676
          return tmp;
williamr@2
   677
      }
williamr@2
   678
# endif
williamr@2
   679
      
williamr@2
   680
      Derived& operator--()
williamr@2
   681
      {
williamr@2
   682
          iterator_core_access::decrement(this->derived());
williamr@2
   683
          return this->derived();
williamr@2
   684
      }
williamr@2
   685
williamr@2
   686
      Derived operator--(int)
williamr@2
   687
      {
williamr@2
   688
          Derived tmp(this->derived());
williamr@2
   689
          --*this;
williamr@2
   690
          return tmp;
williamr@2
   691
      }
williamr@2
   692
williamr@2
   693
      Derived& operator+=(difference_type n)
williamr@2
   694
      {
williamr@2
   695
          iterator_core_access::advance(this->derived(), n);
williamr@2
   696
          return this->derived();
williamr@2
   697
      }
williamr@2
   698
williamr@2
   699
      Derived& operator-=(difference_type n)
williamr@2
   700
      {
williamr@2
   701
          iterator_core_access::advance(this->derived(), -n);
williamr@2
   702
          return this->derived();
williamr@2
   703
      }
williamr@2
   704
williamr@2
   705
      Derived operator-(difference_type x) const
williamr@2
   706
      {
williamr@2
   707
          Derived result(this->derived());
williamr@2
   708
          return result -= x;
williamr@2
   709
      }
williamr@2
   710
williamr@2
   711
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
williamr@2
   712
      // There appears to be a bug which trashes the data of classes
williamr@2
   713
      // derived from iterator_facade when they are assigned unless we
williamr@2
   714
      // define this assignment operator.  This bug is only revealed
williamr@2
   715
      // (so far) in STLPort debug mode, but it's clearly a codegen
williamr@2
   716
      // problem so we apply the workaround for all MSVC6.
williamr@2
   717
      iterator_facade& operator=(iterator_facade const&)
williamr@2
   718
      {
williamr@2
   719
          return *this;
williamr@2
   720
      }
williamr@2
   721
# endif
williamr@2
   722
  };
williamr@2
   723
williamr@2
   724
# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
williamr@2
   725
  template <class I, class V, class TC, class R, class D>
williamr@2
   726
  inline typename detail::postfix_increment_result<I,V,R,TC>::type
williamr@2
   727
  operator++(
williamr@2
   728
      iterator_facade<I,V,TC,R,D>& i
williamr@2
   729
    , int
williamr@2
   730
  )
williamr@2
   731
  {
williamr@2
   732
      typename detail::postfix_increment_result<I,V,R,TC>::type
williamr@2
   733
          tmp(*static_cast<I*>(&i));
williamr@2
   734
      
williamr@2
   735
      ++i;
williamr@2
   736
      
williamr@2
   737
      return tmp;
williamr@2
   738
  }
williamr@2
   739
# endif 
williamr@2
   740
williamr@2
   741
  
williamr@2
   742
  //
williamr@2
   743
  // Comparison operator implementation. The library supplied operators
williamr@2
   744
  // enables the user to provide fully interoperable constant/mutable
williamr@2
   745
  // iterator types. I.e. the library provides all operators
williamr@2
   746
  // for all mutable/constant iterator combinations.
williamr@2
   747
  //
williamr@2
   748
  // Note though that this kind of interoperability for constant/mutable
williamr@2
   749
  // iterators is not required by the standard for container iterators.
williamr@2
   750
  // All the standard asks for is a conversion mutable -> constant.
williamr@2
   751
  // Most standard library implementations nowadays provide fully interoperable
williamr@2
   752
  // iterator implementations, but there are still heavily used implementations
williamr@2
   753
  // that do not provide them. (Actually it's even worse, they do not provide
williamr@2
   754
  // them for only a few iterators.)
williamr@2
   755
  //
williamr@2
   756
  // ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should
williamr@2
   757
  //    enable the user to turn off mixed type operators
williamr@2
   758
  //
williamr@2
   759
  // The library takes care to provide only the right operator overloads.
williamr@2
   760
  // I.e.
williamr@2
   761
  //
williamr@2
   762
  // bool operator==(Iterator,      Iterator);
williamr@2
   763
  // bool operator==(ConstIterator, Iterator);
williamr@2
   764
  // bool operator==(Iterator,      ConstIterator);
williamr@2
   765
  // bool operator==(ConstIterator, ConstIterator);
williamr@2
   766
  //
williamr@2
   767
  //   ...
williamr@2
   768
  //
williamr@2
   769
  // In order to do so it uses c++ idioms that are not yet widely supported
williamr@2
   770
  // by current compiler releases. The library is designed to degrade gracefully
williamr@2
   771
  // in the face of compiler deficiencies. In general compiler
williamr@2
   772
  // deficiencies result in less strict error checking and more obscure
williamr@2
   773
  // error messages, functionality is not affected.
williamr@2
   774
  //
williamr@2
   775
  // For full operation compiler support for "Substitution Failure Is Not An Error"
williamr@2
   776
  // (aka. enable_if) and boost::is_convertible is required.
williamr@2
   777
  //
williamr@2
   778
  // The following problems occur if support is lacking.
williamr@2
   779
  //
williamr@2
   780
  // Pseudo code
williamr@2
   781
  //
williamr@2
   782
  // ---------------
williamr@2
   783
  // AdaptorA<Iterator1> a1;
williamr@2
   784
  // AdaptorA<Iterator2> a2;
williamr@2
   785
  //
williamr@2
   786
  // // This will result in a no such overload error in full operation
williamr@2
   787
  // // If enable_if or is_convertible is not supported
williamr@2
   788
  // // The instantiation will fail with an error hopefully indicating that
williamr@2
   789
  // // there is no operator== for Iterator1, Iterator2
williamr@2
   790
  // // The same will happen if no enable_if is used to remove
williamr@2
   791
  // // false overloads from the templated conversion constructor
williamr@2
   792
  // // of AdaptorA.
williamr@2
   793
  //
williamr@2
   794
  // a1 == a2;
williamr@2
   795
  // ----------------
williamr@2
   796
  //
williamr@2
   797
  // AdaptorA<Iterator> a;
williamr@2
   798
  // AdaptorB<Iterator> b;
williamr@2
   799
  //
williamr@2
   800
  // // This will result in a no such overload error in full operation
williamr@2
   801
  // // If enable_if is not supported the static assert used
williamr@2
   802
  // // in the operator implementation will fail.
williamr@2
   803
  // // This will accidently work if is_convertible is not supported.
williamr@2
   804
  //
williamr@2
   805
  // a == b;
williamr@2
   806
  // ----------------
williamr@2
   807
  //
williamr@2
   808
williamr@2
   809
# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
williamr@2
   810
#  define BOOST_ITERATOR_CONVERTIBLE(a,b) mpl::true_()
williamr@2
   811
# else
williamr@2
   812
#  define BOOST_ITERATOR_CONVERTIBLE(a,b) is_convertible<a,b>()
williamr@2
   813
# endif
williamr@2
   814
williamr@2
   815
# define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, return_prefix, base_op) \
williamr@2
   816
  BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type)                   \
williamr@2
   817
  {                                                                             \
williamr@2
   818
      /* For those compilers that do not support enable_if */                   \
williamr@2
   819
      BOOST_STATIC_ASSERT((                                                     \
williamr@2
   820
          is_interoperable< Derived1, Derived2 >::value                         \
williamr@2
   821
      ));                                                                       \
williamr@2
   822
      return_prefix iterator_core_access::base_op(                              \
williamr@2
   823
          *static_cast<Derived1 const*>(&lhs)                                   \
williamr@2
   824
        , *static_cast<Derived2 const*>(&rhs)                                   \
williamr@2
   825
        , BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1)                         \
williamr@2
   826
      );                                                                        \
williamr@2
   827
  }
williamr@2
   828
williamr@2
   829
# define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
williamr@2
   830
  BOOST_ITERATOR_FACADE_INTEROP(                                    \
williamr@2
   831
      op                                                            \
williamr@2
   832
    , detail::always_bool2                                          \
williamr@2
   833
    , return_prefix                                                 \
williamr@2
   834
    , base_op                                                       \
williamr@2
   835
  )
williamr@2
   836
williamr@2
   837
  BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
williamr@2
   838
  BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
williamr@2
   839
williamr@2
   840
  BOOST_ITERATOR_FACADE_RELATION(<, return 0 >, distance_from)
williamr@2
   841
  BOOST_ITERATOR_FACADE_RELATION(>, return 0 <, distance_from)
williamr@2
   842
  BOOST_ITERATOR_FACADE_RELATION(<=, return 0 >=, distance_from)
williamr@2
   843
  BOOST_ITERATOR_FACADE_RELATION(>=, return 0 <=, distance_from)
williamr@2
   844
# undef BOOST_ITERATOR_FACADE_RELATION
williamr@2
   845
williamr@2
   846
  // operator- requires an additional part in the static assertion
williamr@2
   847
  BOOST_ITERATOR_FACADE_INTEROP(
williamr@2
   848
      -
williamr@2
   849
    , detail::choose_difference_type
williamr@2
   850
    , return
williamr@2
   851
    , distance_from
williamr@2
   852
  )
williamr@2
   853
# undef BOOST_ITERATOR_FACADE_INTEROP
williamr@2
   854
# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
williamr@2
   855
williamr@2
   856
# define BOOST_ITERATOR_FACADE_PLUS(args)           \
williamr@2
   857
  BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args)     \
williamr@2
   858
  {                                                 \
williamr@2
   859
      Derived tmp(static_cast<Derived const&>(i));  \
williamr@2
   860
      return tmp += n;                              \
williamr@2
   861
  }
williamr@2
   862
williamr@2
   863
BOOST_ITERATOR_FACADE_PLUS((
williamr@2
   864
  iterator_facade<Derived, V, TC, R, D> const& i
williamr@2
   865
  , typename Derived::difference_type n
williamr@2
   866
))
williamr@2
   867
williamr@2
   868
BOOST_ITERATOR_FACADE_PLUS((
williamr@2
   869
    typename Derived::difference_type n
williamr@2
   870
    , iterator_facade<Derived, V, TC, R, D> const& i
williamr@2
   871
))
williamr@2
   872
# undef BOOST_ITERATOR_FACADE_PLUS
williamr@2
   873
# undef BOOST_ITERATOR_FACADE_PLUS_HEAD
williamr@2
   874
williamr@2
   875
} // namespace boost
williamr@2
   876
williamr@2
   877
#include <boost/iterator/detail/config_undef.hpp>
williamr@2
   878
williamr@2
   879
#endif // BOOST_ITERATOR_FACADE_23022003THW_HPP