1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/boost/iterator/counting_iterator.hpp Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,215 @@
1.4 +// Copyright David Abrahams 2003.
1.5 +// Distributed under the Boost Software License, Version 1.0. (See
1.6 +// accompanying file LICENSE_1_0.txt or copy at
1.7 +// http://www.boost.org/LICENSE_1_0.txt)
1.8 +#ifndef COUNTING_ITERATOR_DWA200348_HPP
1.9 +# define COUNTING_ITERATOR_DWA200348_HPP
1.10 +
1.11 +# include <boost/iterator/iterator_adaptor.hpp>
1.12 +# include <boost/detail/numeric_traits.hpp>
1.13 +# include <boost/mpl/bool.hpp>
1.14 +# include <boost/mpl/if.hpp>
1.15 +# include <boost/mpl/identity.hpp>
1.16 +# include <boost/mpl/eval_if.hpp>
1.17 +
1.18 +namespace boost {
1.19 +
1.20 +template <
1.21 + class Incrementable
1.22 + , class CategoryOrTraversal
1.23 + , class Difference
1.24 +>
1.25 +class counting_iterator;
1.26 +
1.27 +namespace detail
1.28 +{
1.29 + // Try to detect numeric types at compile time in ways compatible
1.30 + // with the limitations of the compiler and library.
1.31 + template <class T>
1.32 + struct is_numeric_impl
1.33 + {
1.34 + // For a while, this wasn't true, but we rely on it below. This is a regression assert.
1.35 + BOOST_STATIC_ASSERT(::boost::is_integral<char>::value);
1.36 +
1.37 +# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
1.38 +
1.39 + BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized);
1.40 +
1.41 +# else
1.42 +
1.43 +# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
1.44 + BOOST_STATIC_CONSTANT(
1.45 + bool, value = (
1.46 + boost::is_convertible<int,T>::value
1.47 + && boost::is_convertible<T,int>::value
1.48 + ));
1.49 +# else
1.50 + BOOST_STATIC_CONSTANT(bool, value = ::boost::is_arithmetic<T>::value);
1.51 +# endif
1.52 +
1.53 +# endif
1.54 + };
1.55 +
1.56 + template <class T>
1.57 + struct is_numeric
1.58 + : mpl::bool_<(::boost::detail::is_numeric_impl<T>::value)>
1.59 + {};
1.60 +
1.61 +# if defined(BOOST_HAS_LONG_LONG)
1.62 + template <>
1.63 + struct is_numeric< ::boost::long_long_type>
1.64 + : mpl::true_ {};
1.65 +
1.66 + template <>
1.67 + struct is_numeric< ::boost::ulong_long_type>
1.68 + : mpl::true_ {};
1.69 +# endif
1.70 +
1.71 + // Some compilers fail to have a numeric_limits specialization
1.72 + template <>
1.73 + struct is_numeric<wchar_t>
1.74 + : mpl::true_ {};
1.75 +
1.76 + template <class T>
1.77 + struct numeric_difference
1.78 + {
1.79 + typedef typename boost::detail::numeric_traits<T>::difference_type type;
1.80 + };
1.81 +
1.82 + BOOST_STATIC_ASSERT(is_numeric<int>::value);
1.83 +
1.84 + template <class Incrementable, class CategoryOrTraversal, class Difference>
1.85 + struct counting_iterator_base
1.86 + {
1.87 + typedef typename detail::ia_dflt_help<
1.88 + CategoryOrTraversal
1.89 + , mpl::eval_if<
1.90 + is_numeric<Incrementable>
1.91 + , mpl::identity<random_access_traversal_tag>
1.92 + , iterator_traversal<Incrementable>
1.93 + >
1.94 + >::type traversal;
1.95 +
1.96 + typedef typename detail::ia_dflt_help<
1.97 + Difference
1.98 + , mpl::eval_if<
1.99 + is_numeric<Incrementable>
1.100 + , numeric_difference<Incrementable>
1.101 + , iterator_difference<Incrementable>
1.102 + >
1.103 + >::type difference;
1.104 +
1.105 + typedef iterator_adaptor<
1.106 + counting_iterator<Incrementable, CategoryOrTraversal, Difference> // self
1.107 + , Incrementable // Base
1.108 + , Incrementable // Value
1.109 +# ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
1.110 + const // MSVC won't strip this. Instead we enable Thomas'
1.111 + // criterion (see boost/iterator/detail/facade_iterator_category.hpp)
1.112 +# endif
1.113 + , traversal
1.114 + , Incrementable const& // reference
1.115 + , difference
1.116 + > type;
1.117 + };
1.118 +
1.119 + // Template class distance_policy_select -- choose a policy for computing the
1.120 + // distance between counting_iterators at compile-time based on whether or not
1.121 + // the iterator wraps an integer or an iterator, using "poor man's partial
1.122 + // specialization".
1.123 +
1.124 + template <bool is_integer> struct distance_policy_select;
1.125 +
1.126 + // A policy for wrapped iterators
1.127 + template <class Difference, class Incrementable1, class Incrementable2>
1.128 + struct iterator_distance
1.129 + {
1.130 + static Difference distance(Incrementable1 x, Incrementable2 y)
1.131 + {
1.132 + return y - x;
1.133 + }
1.134 + };
1.135 +
1.136 + // A policy for wrapped numbers
1.137 + template <class Difference, class Incrementable1, class Incrementable2>
1.138 + struct number_distance
1.139 + {
1.140 + static Difference distance(Incrementable1 x, Incrementable2 y)
1.141 + {
1.142 + return numeric_distance(x, y);
1.143 + }
1.144 + };
1.145 +}
1.146 +
1.147 +template <
1.148 + class Incrementable
1.149 + , class CategoryOrTraversal = use_default
1.150 + , class Difference = use_default
1.151 +>
1.152 +class counting_iterator
1.153 + : public detail::counting_iterator_base<
1.154 + Incrementable, CategoryOrTraversal, Difference
1.155 + >::type
1.156 +{
1.157 + typedef typename detail::counting_iterator_base<
1.158 + Incrementable, CategoryOrTraversal, Difference
1.159 + >::type super_t;
1.160 +
1.161 + friend class iterator_core_access;
1.162 +
1.163 + public:
1.164 + typedef typename super_t::difference_type difference_type;
1.165 +
1.166 + counting_iterator() { }
1.167 +
1.168 + counting_iterator(counting_iterator const& rhs) : super_t(rhs.base()) {}
1.169 +
1.170 + counting_iterator(Incrementable x)
1.171 + : super_t(x)
1.172 + {
1.173 + }
1.174 +
1.175 +# if 0
1.176 + template<class OtherIncrementable>
1.177 + counting_iterator(
1.178 + counting_iterator<OtherIncrementable, CategoryOrTraversal, Difference> const& t
1.179 + , typename enable_if_convertible<OtherIncrementable, Incrementable>::type* = 0
1.180 + )
1.181 + : super_t(t.base())
1.182 + {}
1.183 +# endif
1.184 +
1.185 + private:
1.186 +
1.187 + typename super_t::reference dereference() const
1.188 + {
1.189 + return this->base_reference();
1.190 + }
1.191 +
1.192 + template <class OtherIncrementable>
1.193 + difference_type
1.194 + distance_to(counting_iterator<OtherIncrementable, CategoryOrTraversal, Difference> const& y) const
1.195 + {
1.196 + typedef typename mpl::if_<
1.197 + detail::is_numeric<Incrementable>
1.198 + , detail::number_distance<difference_type, Incrementable, OtherIncrementable>
1.199 + , detail::iterator_distance<difference_type, Incrementable, OtherIncrementable>
1.200 + >::type d;
1.201 +
1.202 + return d::distance(this->base(), y.base());
1.203 + }
1.204 +};
1.205 +
1.206 +// Manufacture a counting iterator for an arbitrary incrementable type
1.207 +template <class Incrementable>
1.208 +inline counting_iterator<Incrementable>
1.209 +make_counting_iterator(Incrementable x)
1.210 +{
1.211 + typedef counting_iterator<Incrementable> result_t;
1.212 + return result_t(x);
1.213 +}
1.214 +
1.215 +
1.216 +} // namespace boost::iterator
1.217 +
1.218 +#endif // COUNTING_ITERATOR_DWA200348_HPP