Argenet
Argenet

Reputation: 389

boost::counting_iterator analogue in range-v3

I am wondering if range-v3 library has any view/utility providing the functionality similar to boost::counting_iterators?

I was looking for something of that kind, but seems there is nothing readily available. But the documentation is incomplete (at least the README suggests so) so maybe there is something I have overlooked.

UPD: what I am actually looking for is not just a range of integers like view::iota but rather a range view (wrapper) that accepts any Incrementable. One such example is the following code from Boost.CountingIterator documentation:

int N = 7;
std::vector<int> numbers;
...
// the code below does what I am actually looking for
// I would like to use a single range instead of two separate iterators here
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));

Upvotes: 2

Views: 437

Answers (2)

Casey
Casey

Reputation: 42554

You do, in fact, want view::iota. It accepts any WeaklyIncrementable type for the range iterator type (not only integral types), and any type that is WeaklyEqualityComparable to that type as the range sentinel. So view::iota(0, 8) is the range of integers {0,1,2,3,4,5,6,7}, and view::iota(i, s) is the range of iterators {i,i+1,i+2,...,s}. The boost counting_iterator example translates to range-v3 as (DEMO):

int N = 7;
std::vector<int> numbers = ranges::view::iota(0, N);

std::vector<std::vector<int>::iterator> pointers =
    ranges::view::iota(numbers.begin(), numbers.end());

std::cout << "indirectly printing out the numbers from 0 to " << N << '\n';
ranges::copy(ranges::view::indirect(pointers),
    ranges::ostream_iterator<>(std::cout, " "));
std::cout << '\n';

Upvotes: 4

Benjamin Lindley
Benjamin Lindley

Reputation: 103703

I believe view::ints is what you're looking for. You can make an unbounded range, and truncate it with something like view::take:

using namespace ranges;
int x = accumulate(view::ints(0) | view::take(10), 0); // 45

or you can make a bounded range (lower inclusive, upper exclusive)

int x = accumulate(view::ints(0, 10), 0);

For your example, you can use view::iota instead.

copy(view::iota(numbers.begin(), numbers.end()), back_inserter(pointers));

Upvotes: 2

Related Questions