[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

details CountingIterator< T > Class Template Reference VIGRA

Iterator that counts upwards or downwards with a given step size. More...

#include <vigra/counting_iterator.hxx>

Inherits iterator< std::random_access_iterator_tag, T, std::ptrdiff_t, T const *, T >.

Detailed Description

template<class T = std::ptrdiff_t>
class vigra::CountingIterator< T >

Iterator that counts upwards or downwards with a given step size.

This iterator replicates the functionality of Python's well-known range-function. It is especially convenient in range-based for-loops. CountingIterator also works for floating-point counting.

Usage:

#include <vigra/counting_iterator.hxx>
Namespace: vigra

You will normally construct instances of this iterator with one of the range() factory functions. There are three versions of this function range(end), range(begin, end), and range(begin, end, step).

// count upwards from 0 to 4
for(int i: range(5))
std::cout << i << " "; // prints '0 1 2 3 4'
// count upwards from 4 to 7
for(int i: range(4, 8))
std::cout << i << " "; // prints '4 5 6 7'
// count upwards from 0 to 9 with step 3
for(int i: range(0, 9, 3))
std::cout << i << " "; // prints '0 3 6'
// likewise (note upper bound)
for(int i: range(0, 7, 3))
std::cout << i << " "; // prints '0 3 6'
// count downwards from 4 to 1 with step -1
for(int i: range(4, 0))
std::cout << i << " "; // prints '4 3 2 1'
// count downwards from 8 to 2 with step -2
for(int i: range(8, 0, -2))
std::cout << i << " "; // prints '8 6 4 2'

Alternatively, you can create a traditional random-access iterator pair. The end iterator can be conveniently constructed by the begin iterator's end() function:

auto iter = range(5),
end = iter.end();
std::cout << std::accumulate(iter, end, 0) << std::endl; // prints '10'

range() and CountingIterator also work for floating-point arguments. As in the integer case, the upper bound is excluded from the range if it can be reached by an integer multiple of the step (within machine epsilon):

for(auto i: range(1.0, 1.6, 0.1)) // 1.6 is excluded
std::cout << i << " "; // prints '1 1.1 1.2 1.3 1.4 1.5'
for(auto i: range(1.0, 1.61, 0.1)) // 1.6 is included
std::cout << i << " "; // prints '1 1.1 1.2 1.3 1.4 1.5 1.6'

If you use an iterator pair, you can make clear which behavior you want by using either iter < end or iter <= end to terminate the loop:

auto iter = range(1.0, 1.6, 0.1),
end = iter.end();
for(; iter < end; ++iter) // exclude upper bound
std::cout << *iter << " "; // prints '1 1.1 1.2 1.3 1.4 1.5'
iter = range(1.0, 1.6, 0.1);
for(; iter <= end; ++iter) // include upper bound
std::cout << *iter << " "; // prints '1 1.1 1.2 1.3 1.4 1.5 1.6'

Note that the termination condition is still iter <= end, even when the iterator counts downwards:

auto iter = range(1.6, 1.0, -0.1),
end = iter.end();
for(; iter <= end; ++iter)
std::cout << *iter << " "; // prints '1.6 1.5 1.4 1.3 1.2 1.1 1'

The documentation for this class was generated from the following file:

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.11.1 (Fri May 19 2017)