imgtools/imglib/boostlibrary/boost/iterator/counting_iterator.hpp
changeset 2 39c28ec933dd
equal deleted inserted replaced
1:820b22e13ff1 2:39c28ec933dd
       
     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