#include "tbb/iterators.h"
template<typename IntType>
class counting_iterator {
public:
typedef decltype(IntType()-IntType()) difference_type;
typedef IntType value_type;
typedef const IntType* pointer;
typedef const IntType& reference;
typedef std::random_access_iterator_tag iterator_category;
explicit counting_iterator(IntType init);
reference operator*() const;
value_type operator[](difference_type i) const;
difference_type operator-(const counting_iterator& it) const;
counting_iterator& operator+=(difference_type forward);
counting_iterator& operator-=(difference_type backward);
counting_iterator& operator++();
counting_iterator& operator--();
counting_iterator operator++(int);
counting_iterator operator--(int);
counting_iterator operator-(difference_type backward) const;
counting_iterator operator+(difference_type forward) const;
friend counting_iterator operator+(difference_type forward, const counting_iterator it);
bool operator==(const counting_iterator& it) const;
bool operator!=(const counting_iterator& it) const;
bool operator<(const counting_iterator& it) const;
bool operator>(const counting_iterator& it) const;
bool operator<=(const counting_iterator& it) const;
bool operator>=(const counting_iterator& it) const;
};
counting_iterator is a random access iterator for STL algorithms. The counter changes according to arithmetic operations of the random access iterator type. The operator*() function returns the current value of the integer counter. Use the iterator for combination of a TBB parallel algorithm with a blocked_range of counting value concept and a STL algorithm which uses the iterators concept or for getting an index of a container element to make some calculation or logic in your functor/lambda passed into an algorithm.
The following example shows usage of an STL algorithm with counting_iterator. You need to initialize array a in a way each even element is a square of the current index value and each odd element is the current index value.
#include <algorithm>
#include <tbb/iterators.h>
int main() {
const int N = 100000;
float a[N];
std::for_each(tbb::counting_iterator<int>(0), tbb::counting_iterator<int>(N),
[&a](int i){
if(i%2 == 0)
a[i] = i*i;
else
a[i] = i;
});
return 0;
}
The following example shows combination of a TBB parallel algorithm and a STL algorithm in case of a blocked_range is parameterized by a counting value.
#include <vector>
#include <algorithm>
#include <tbb/parallel_for.h>
#include <tbb/iterators.h>
int main() {
std::vector<int> vec(1000000);
tbb::parallel_for( tbb::blocked_range<int>(0, vec.size(), /*grainsize=*/ 100),
[&vec](tbb::blocked_range<int>& r) {
using c_it = tbb::counting_iterator<int>;
std::copy(c_it(r.begin()), c_it(r.end()), vec.begin());
});
return 0;
}