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