diff --git a/include/boost/counting_iterator.hpp b/include/boost/counting_iterator.hpp new file mode 100644 index 0000000..2279c93 --- /dev/null +++ b/include/boost/counting_iterator.hpp @@ -0,0 +1,178 @@ +// (C) Copyright David Abrahams and Jeremy Siek 2000-2001. Permission to copy, +// use, modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided "as is" +// without express or implied warranty, and with no claim as to its suitability +// for any purpose. +// +// See http://www.boost.org for most recent version including documentation. +// +// Supplies: +// +// template class counting_iterator_traits; +// template class counting_iterator_policies; +// +// Iterator traits and policies for adapted iterators whose dereferenced +// value progresses through consecutive values of Incrementable when the +// iterator is derferenced. +// +// template +// iterator_adaptor, +// counting_iterator_traits > +// counting_iterator(Incrementable); +// +// A function which produces an adapted counting iterator over values of +// Incrementable. +// +// Revision History +// 24 Jan 2001 initial revision, based on Jeremy Siek's +// boost/pending/integer_range.hpp (David Abrahams) + +#ifndef BOOST_COUNTING_ITERATOR_HPP_DWA20000119 +# define BOOST_COUNTING_ITERATOR_HPP_DWA20000119 + +# include +# include +# include +# include +# include +# ifndef BOOST_NO_LIMITS +# include +# endif + +namespace boost { + +namespace detail { + + // Template class counting_iterator_traits_select -- choose an + // iterator_category and difference_type for a counting_iterator at + // compile-time based on whether or not it wraps an integer or an iterator, + // using "poor man's partial specialization". + template struct counting_iterator_traits_select; + + // Incrementable is an iterator type + template <> + struct counting_iterator_traits_select + { + template + struct traits + { + private: + typedef boost::detail::iterator_traits x; + public: + typedef typename x::iterator_category iterator_category; + typedef typename x::difference_type difference_type; + }; + }; + + // Incrementable is a numeric type + template <> + struct counting_iterator_traits_select + { + template + struct traits + { + typedef typename + boost::detail::numeric_traits::difference_type + difference_type; + typedef std::random_access_iterator_tag iterator_category; + }; + }; + + // Template class distance_policy_select -- choose a policy for computing the + // distance between counting_iterators at compile-time based on whether or not + // the iterator wraps an integer or an iterator, using "poor man's partial + // specialization". + + template struct distance_policy_select; + + // A policy for wrapped iterators + template <> + struct distance_policy_select + { + template + struct policy { + static Distance distance(Incrementable x, Incrementable y) + { return boost::detail::distance(x, y); } + }; + }; + + // A policy for wrapped numbers + template <> + struct distance_policy_select + { + template + struct policy { + static Distance distance(Incrementable x, Incrementable y) + { return numeric_distance(x, y); } + }; + }; + + // Compute the distance over arbitrary numeric and/or iterator types + template + Distance any_distance(Incrementable start, Incrementable finish, Distance* = 0) + { + return distance_policy_select< +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + std::numeric_limits::is_specialized +#else + // Causes warnings with GCC, but how else can I detect numeric types + // at compile-time? + (boost::is_convertible::value && + boost::is_convertible::value) +#endif + >::template policy::distance(start, finish); + } + +} // namespace detail + +template +struct counting_iterator_traits { + private: + typedef typename detail::counting_iterator_traits_select<( +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + std::numeric_limits::is_specialized +#else + // Causes warnings with GCC, but how else can I detect numeric types at + // compile-time? + (boost::is_convertible::value && + boost::is_convertible::value) +#endif + )>::template traits traits; + public: + typedef Incrementable value_type; + typedef const Incrementable& reference; + typedef const value_type* pointer; + typedef typename traits::difference_type difference_type; + typedef typename traits::iterator_category iterator_category; +}; + +template +struct counting_iterator_policies : public default_iterator_policies +{ + const Incrementable& dereference(type, const Incrementable& i) const + { return i; } + + template + Difference distance(type, const Iterator1& x, + const Iterator2& y) const + { + return boost::detail::any_distance(x, y);//,(Difference*)()); + } +}; + +// Manufacture a counting iterator for an arbitrary incrementable type +template +inline iterator_adaptor, + counting_iterator_traits > +counting_iterator(Incrementable x) +{ + return iterator_adaptor, + counting_iterator_traits >(x); +} + +} // namespace boost + +#endif // BOOST_COUNTING_ITERATOR_HPP_DWA20000119