From fda44ca17d3309b0c798877d0343d0a930b31a83 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 15 Feb 2001 16:39:55 +0000 Subject: [PATCH] General edits for clarity; some reorganization. [SVN r9213] --- counting_iterator.htm | 116 ++++++++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 49 deletions(-) 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.

Synopsis

 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);
 }
 

-

Counting Iterator Traits

- -The counting iterator adaptor needs to know the appropriate -difference_type and iterator_category to use -depending on the Incrementable type supplied by the user. -The counting_iterator_traits class provides these types. If -the Incrementable type is a numeric type or is an iterator -then these types will be correctly deduced by the below counting -iterator traits. Otherwise, the user must specialize -counting_iterator_traits for their type, or add nested -typedefs to their type to fulfill the needs of - -std::iterator_traits. - -
-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;
-  }    
-};
-
- -
-

The Counting Iterator Type Generator

-The class counting_iterator_generator is a helper class whose -purpose is to construct a counting iterator type. The template -parameters for this class is the Incrementable type that is -being wrapped. +The class template counting_iterator_generator<Incrementable> is a type generator for counting iterators.
 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
+
+ +

Counting Iterator Traits

+ +The counting iterator adaptor needs to determine the appropriate +difference_type and iterator_category to use based on the +Incrementable type supplied by the user. The +counting_iterator_traits class provides these types. If the +Incrementable type is an integral type or an iterator, these types +will be correctly deduced by the counting_iterator_traits provided by +the library. Otherwise, the user must specialize +counting_iterator_traits for her type or add nested typedefs to +her type to fulfill the needs of + +std::iterator_traits. + +

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.

--> +