Counting Iterator

Author: David Abrahams, Jeremy Siek, Thomas Witt
Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
Organization: Boost Consulting, Indiana University Open Systems Lab, University of Hanover Institute for Transport Railway Operation and Construction
Date: 2004-01-12
Copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved
abstract:

counting_iterator adapts an arithmetic type, such as int, by adding an operator* that returns the current value of the object.

Table of Contents

template <
    class Incrementable
  , class CategoryOrTraversal = use_default
  , class Difference = use_default
>
class counting_iterator
{
 public:
    counting_iterator();
    counting_iterator(counting_iterator const& rhs);
    explicit counting_iterator(Incrementable x);
    Incrementable base() const;
 private:
    Incrementable current; // exposition
  };
[Note: implementers are encouraged to provide an implementation of
distance_to and a difference_type that avoids overflows in the cases when the Incrementable type is a numeric type.]

counting_iterator requirements

The Incrementable type must be Default Constructible, Copy Constructible, and Assignable. The default distance is an implementation defined signed integral type.

counting_iterator models

counting_iterator models Readable Lvalue Iterator.

Furthermore, if you wish to create a counting iterator that is a Forward Traversal Iterator, then the following expressions must be valid:

Incrementable i, j;
++i         // pre-increment
i == j      // operator equal

If you wish to create a counting iterator that is a Bidirectional Traversal Iterator, then pre-decrement is also required:

--i

If you wish to create a counting iterator that is a Random Access Traversal Iterator, then these additional expressions are also required:

counting_iterator::difference_type n;
i += n
n = i - j
i < j

counting_iterator operations

counting_iterator();

Returns:A default constructed instance of counting_iterator.

counting_iterator(counting_iterator const& rhs);

Returns:An instance of counting_iterator that is a copy of rhs.

explicit counting_iterator(Incrementable x);

Returns:An instance of counting_iterator with current constructed from x.

reference operator*() const;

Returns:current

counting_iterator& operator++();

Effects:++current

Incrementable base() const;

Returns:current
template <class Incrementable>
counting_iterator<Incrementable> make_counting_iterator(Incrementable x);
Returns:An instance of counting_iterator<Incrementable> with current constructed from x.

Example

This example fills an array with numbers and a second array with pointers into the first array, using counting_iterator for both tasks. Finally indirect_iterator is used to print out the numbers into the first array via indirection through the second array.

int N = 7;
std::vector<int> numbers;
typedef std::vector<int>::iterator n_iter;
std::copy(boost::counting_iterator<int>(0),
         boost::counting_iterator<int>(N),
         std::back_inserter(numbers));

std::vector<std::vector<int>::iterator> pointers;
std::copy(boost::make_counting_iterator(numbers.begin()),
          boost::make_counting_iterator(numbers.end()),
          std::back_inserter(pointers));

std::cout << "indirectly printing out the numbers from 0 to " 
          << N << std::endl;
std::copy(boost::make_indirect_iterator(pointers.begin()),
          boost::make_indirect_iterator(pointers.end()),
          std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;

The output is:

indirectly printing out the numbers from 0 to 7
0 1 2 3 4 5 6