epoc32/include/stdapis/boost/iterator/counting_iterator.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 David Abrahams 2003.
williamr@2
     2
// Distributed under the Boost Software License, Version 1.0. (See
williamr@2
     3
// accompanying file LICENSE_1_0.txt or copy at
williamr@2
     4
// http://www.boost.org/LICENSE_1_0.txt)
williamr@2
     5
#ifndef COUNTING_ITERATOR_DWA200348_HPP
williamr@2
     6
# define COUNTING_ITERATOR_DWA200348_HPP
williamr@2
     7
williamr@2
     8
# include <boost/iterator/iterator_adaptor.hpp>
williamr@2
     9
# include <boost/detail/numeric_traits.hpp>
williamr@2
    10
# include <boost/mpl/bool.hpp>
williamr@2
    11
# include <boost/mpl/if.hpp>
williamr@2
    12
# include <boost/mpl/identity.hpp>
williamr@2
    13
# include <boost/mpl/eval_if.hpp>
williamr@2
    14
williamr@2
    15
namespace boost {
williamr@2
    16
williamr@2
    17
template <
williamr@2
    18
    class Incrementable
williamr@2
    19
  , class CategoryOrTraversal
williamr@2
    20
  , class Difference
williamr@2
    21
>
williamr@2
    22
class counting_iterator;
williamr@2
    23
williamr@2
    24
namespace detail
williamr@2
    25
{
williamr@2
    26
  // Try to detect numeric types at compile time in ways compatible
williamr@2
    27
  // with the limitations of the compiler and library.
williamr@2
    28
  template <class T>
williamr@2
    29
  struct is_numeric_impl
williamr@2
    30
  {
williamr@2
    31
      // For a while, this wasn't true, but we rely on it below. This is a regression assert.
williamr@2
    32
      BOOST_STATIC_ASSERT(::boost::is_integral<char>::value);
williamr@2
    33
      
williamr@2
    34
# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
williamr@2
    35
      
williamr@2
    36
      BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized);
williamr@2
    37
      
williamr@2
    38
# else
williamr@2
    39
      
williamr@2
    40
#  if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
williamr@2
    41
      BOOST_STATIC_CONSTANT(
williamr@2
    42
          bool, value = (
williamr@2
    43
              boost::is_convertible<int,T>::value
williamr@2
    44
           && boost::is_convertible<T,int>::value
williamr@2
    45
      ));
williamr@2
    46
#  else
williamr@2
    47
    BOOST_STATIC_CONSTANT(bool, value = ::boost::is_arithmetic<T>::value);
williamr@2
    48
#  endif
williamr@2
    49
      
williamr@2
    50
# endif
williamr@2
    51
  };
williamr@2
    52
williamr@2
    53
  template <class T>
williamr@2
    54
  struct is_numeric
williamr@2
    55
    : mpl::bool_<(::boost::detail::is_numeric_impl<T>::value)>
williamr@2
    56
  {};
williamr@2
    57
williamr@2
    58
#  if defined(BOOST_HAS_LONG_LONG)
williamr@2
    59
  template <>
williamr@2
    60
  struct is_numeric< ::boost::long_long_type>
williamr@2
    61
    : mpl::true_ {};
williamr@2
    62
  
williamr@2
    63
  template <>
williamr@2
    64
  struct is_numeric< ::boost::ulong_long_type>
williamr@2
    65
    : mpl::true_ {};
williamr@2
    66
#  endif
williamr@2
    67
williamr@2
    68
  // Some compilers fail to have a numeric_limits specialization
williamr@2
    69
  template <>
williamr@2
    70
  struct is_numeric<wchar_t>
williamr@2
    71
    : mpl::true_ {};
williamr@2
    72
  
williamr@2
    73
  template <class T>
williamr@2
    74
  struct numeric_difference
williamr@2
    75
  {
williamr@2
    76
      typedef typename boost::detail::numeric_traits<T>::difference_type type;
williamr@2
    77
  };
williamr@2
    78
williamr@2
    79
  BOOST_STATIC_ASSERT(is_numeric<int>::value);
williamr@2
    80
  
williamr@2
    81
  template <class Incrementable, class CategoryOrTraversal, class Difference>
williamr@2
    82
  struct counting_iterator_base
williamr@2
    83
  {
williamr@2
    84
      typedef typename detail::ia_dflt_help<
williamr@2
    85
          CategoryOrTraversal
williamr@2
    86
        , mpl::eval_if<
williamr@2
    87
              is_numeric<Incrementable>
williamr@2
    88
            , mpl::identity<random_access_traversal_tag>
williamr@2
    89
            , iterator_traversal<Incrementable>
williamr@2
    90
          >
williamr@2
    91
      >::type traversal;
williamr@2
    92
      
williamr@2
    93
      typedef typename detail::ia_dflt_help<
williamr@2
    94
          Difference
williamr@2
    95
        , mpl::eval_if<
williamr@2
    96
              is_numeric<Incrementable>
williamr@2
    97
            , numeric_difference<Incrementable>
williamr@2
    98
            , iterator_difference<Incrementable>
williamr@2
    99
          >
williamr@2
   100
      >::type difference;
williamr@2
   101
      
williamr@2
   102
      typedef iterator_adaptor<
williamr@2
   103
          counting_iterator<Incrementable, CategoryOrTraversal, Difference> // self
williamr@2
   104
        , Incrementable                                           // Base
williamr@2
   105
        , Incrementable                                           // Value
williamr@2
   106
# ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
williamr@2
   107
          const  // MSVC won't strip this.  Instead we enable Thomas'
williamr@2
   108
                 // criterion (see boost/iterator/detail/facade_iterator_category.hpp)
williamr@2
   109
# endif 
williamr@2
   110
        , traversal
williamr@2
   111
        , Incrementable const&                                    // reference
williamr@2
   112
        , difference
williamr@2
   113
      > type;
williamr@2
   114
  };
williamr@2
   115
williamr@2
   116
  // Template class distance_policy_select -- choose a policy for computing the
williamr@2
   117
  // distance between counting_iterators at compile-time based on whether or not
williamr@2
   118
  // the iterator wraps an integer or an iterator, using "poor man's partial
williamr@2
   119
  // specialization".
williamr@2
   120
williamr@2
   121
  template <bool is_integer> struct distance_policy_select;
williamr@2
   122
williamr@2
   123
  // A policy for wrapped iterators
williamr@2
   124
  template <class Difference, class Incrementable1, class Incrementable2>
williamr@2
   125
  struct iterator_distance
williamr@2
   126
  {
williamr@2
   127
      static Difference distance(Incrementable1 x, Incrementable2 y)
williamr@2
   128
      {
williamr@2
   129
          return y - x;
williamr@2
   130
      }
williamr@2
   131
  };
williamr@2
   132
williamr@2
   133
  // A policy for wrapped numbers
williamr@2
   134
  template <class Difference, class Incrementable1, class Incrementable2>
williamr@2
   135
  struct number_distance
williamr@2
   136
  {
williamr@2
   137
      static Difference distance(Incrementable1 x, Incrementable2 y)
williamr@2
   138
      {
williamr@2
   139
          return numeric_distance(x, y);
williamr@2
   140
      }
williamr@2
   141
  };
williamr@2
   142
}
williamr@2
   143
williamr@2
   144
template <
williamr@2
   145
    class Incrementable
williamr@2
   146
  , class CategoryOrTraversal = use_default
williamr@2
   147
  , class Difference = use_default
williamr@2
   148
>
williamr@2
   149
class counting_iterator
williamr@2
   150
  : public detail::counting_iterator_base<
williamr@2
   151
        Incrementable, CategoryOrTraversal, Difference
williamr@2
   152
    >::type
williamr@2
   153
{
williamr@2
   154
    typedef typename detail::counting_iterator_base<
williamr@2
   155
        Incrementable, CategoryOrTraversal, Difference
williamr@2
   156
    >::type super_t;
williamr@2
   157
    
williamr@2
   158
    friend class iterator_core_access;
williamr@2
   159
williamr@2
   160
 public:
williamr@2
   161
    typedef typename super_t::difference_type difference_type;
williamr@2
   162
williamr@2
   163
    counting_iterator() { }
williamr@2
   164
    
williamr@2
   165
    counting_iterator(counting_iterator const& rhs) : super_t(rhs.base()) {}
williamr@2
   166
williamr@2
   167
    counting_iterator(Incrementable x)
williamr@2
   168
      : super_t(x)
williamr@2
   169
    {
williamr@2
   170
    }
williamr@2
   171
williamr@2
   172
# if 0
williamr@2
   173
    template<class OtherIncrementable>
williamr@2
   174
    counting_iterator(
williamr@2
   175
        counting_iterator<OtherIncrementable, CategoryOrTraversal, Difference> const& t
williamr@2
   176
      , typename enable_if_convertible<OtherIncrementable, Incrementable>::type* = 0
williamr@2
   177
    )
williamr@2
   178
      : super_t(t.base())
williamr@2
   179
    {}
williamr@2
   180
# endif 
williamr@2
   181
williamr@2
   182
 private:
williamr@2
   183
    
williamr@2
   184
    typename super_t::reference dereference() const
williamr@2
   185
    {
williamr@2
   186
        return this->base_reference();
williamr@2
   187
    }
williamr@2
   188
williamr@2
   189
    template <class OtherIncrementable>
williamr@2
   190
    difference_type
williamr@2
   191
    distance_to(counting_iterator<OtherIncrementable, CategoryOrTraversal, Difference> const& y) const
williamr@2
   192
    {
williamr@2
   193
      typedef typename mpl::if_<
williamr@2
   194
          detail::is_numeric<Incrementable>
williamr@2
   195
        , detail::number_distance<difference_type, Incrementable, OtherIncrementable>
williamr@2
   196
        , detail::iterator_distance<difference_type, Incrementable, OtherIncrementable>
williamr@2
   197
      >::type d;
williamr@2
   198
williamr@2
   199
      return d::distance(this->base(), y.base());
williamr@2
   200
    }
williamr@2
   201
};
williamr@2
   202
williamr@2
   203
// Manufacture a counting iterator for an arbitrary incrementable type
williamr@2
   204
template <class Incrementable>
williamr@2
   205
inline counting_iterator<Incrementable>
williamr@2
   206
make_counting_iterator(Incrementable x)
williamr@2
   207
{
williamr@2
   208
  typedef counting_iterator<Incrementable> result_t;
williamr@2
   209
  return result_t(x);
williamr@2
   210
}
williamr@2
   211
williamr@2
   212
williamr@2
   213
} // namespace boost::iterator
williamr@2
   214
williamr@2
   215
#endif // COUNTING_ITERATOR_DWA200348_HPP