diff --git a/counting_iterator.htm b/counting_iterator.htm index 3224785..81a662c 100644 --- a/counting_iterator.htm +++ b/counting_iterator.htm @@ -18,16 +18,15 @@ Defined in header boost/counting_iterator.hpp
-Sometimes it would be nice if one could treat an integer like an -iterator, for example, to fill up a vector with the numbers zero +How would you fill up a vector with the numbers zero through one hundred using std::copy(). The +href="http://www.sgi.com/tech/stl/copy.html">std::copy()? The only iterator operation missing from builtin integer types is an -operator*(), which we would want to just return the current -value of the integer. The counting iterator adaptor provides this -functionality, though it is a bit more generalized. One can use the +operator*() that returns the current +value of the integer. The counting iterator adaptor adds this crucial piece of +functionality to whatever type it wraps. One can use the counting iterator adaptor not only with integer types, but with any -type that is incrementable (see type requirements below). The +type that is Incrementable (see type requirements below). The following pseudo-code shows the general idea of how the counting iterator is implemented.
@@ -41,63 +40,30 @@ counting iterator is implemented. All of the other operators of the counting iterator behave in the same -fashion as the incrementable base type. +fashion as the Incrementable base type.namespace boost { template <class Incrementable> - struct counting_iterator_traits; + struct counting_iterator_traits; template <class Incrementable> - struct counting_iterator_generator; + struct counting_iterator_generator; template <class Incrementable> typename counting_iterator_generator<Incrementable>::type - make_counting_iterator(Incrementable x); + make_counting_iterator(Incrementable x); }
-template <class Incrementable> -struct counting_iterator_traits -{ - if (numeric_limits<Incrementable>::is_specialized == true) { - typedef detail::numeric_traits<Incrementable>::difference_type difference_type; - typedef std::random_access_iterator_tag iterator_category; - } else { - typedef std::iterator_traits<Incrementable>::difference_type difference_type; - typedef std::iterator_traits<Incrementable>::iterator_category iterator_category; - } -}; -- -
template <class Incrementable> @@ -159,7 +125,7 @@ Access Iterator. If the Incrementable type has less functionality, then the counting iterator will have correspondingly less functionality. -+Type Requirements
+Type Requirements
The Incrementable type must be Default @@ -183,7 +149,7 @@ If you wish to create a counting iterator that is a Random Access Iterator, then these additional expressions are also required:-counting_iterator_traits<Incrementable>::difference_type n; +counting_iterator_traits<Incrementable>::difference_type n; i += n n = i - j i < j @@ -214,7 +180,11 @@ typename counting_iterator_generator<Incrementable>::type make_counting_iterator(Incrementable base);-This function provides a convenient way to create counting iterators. +An object +generator function that provides a convenient way to create counting +iterators.+ +
Example
@@ -280,9 +250,56 @@ indirectly printing out the numbers from 0 to 7 0 1 2 3 4 5 6
The following pseudocode describes how the counting_iterator_traits are determined: + +
+template <class Incrementable> +struct counting_iterator_traits +{ + if (numeric_limits<Incrementable>::is_specialized) { + if (!numeric_limits<Incrementable>::is_integral) + COMPILE_TIME_ERROR; + + if (!numeric_limits<Incrementable>::is_bounded + && numeric_limits<Incrementable>::is_signed) { + typedef Incrementable difference_type; + } + else if (numeric_limits<Incrementable>::is_integral) { + typedef next-larger-signed-type-or-intmax_t difference_type; + } + typedef std::random_access_iterator_tag iterator_category; + } else { + typedef std::iterator_traits<Incrementable>::difference_type difference_type; + typedef std::iterator_traits<Incrementable>::iterator_category iterator_category; + } +}; ++ +
The italicized sections above are implementation details, but it is important +to know that the difference_type for integral types is selected so that +it can always represent the difference between two values if such a built-in +integer exists. On platforms with a working std::numeric_limits +implementation, the difference_type for any variable-length signed +integer type T is T itself.
Revised 10 Feb 2001
+Revised 15 Feb 2001
© Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" @@ -296,3 +313,4 @@ any purpose.
--> +