What's the difference between irange
and counting_range
?
I needed irange
to quickly generate a range of integers like this:
auto example = boost::irange(0, 5); /// result is {0, 1, 2, 3, 4}
But noticed an example somewhere (lost the link) that talks instead about counting_range
to accomplish the same task. Is there a simple explanation of the difference between these two?
The main difference is that irange
is a random-access range while counting_range
isn't. counting_range
is based on Boost.Iterator's counting_iterator
which uses all the underlying integers operations directly. Integers in C++ almost fit the iterator concept: the only thing missing is an operator*
. counting_iterator
provides an operator*
as an identity operation and forwards everything else to the underlying type.
Another difference is that irange
also supports increments different than 1.
None of them ever materialises the entire range of integers that they iterate over, so they both use O(1) memory.
Both irange
and counting_range
model a random access range for integer types. As counting_range
s documentation points out, its iterator category is determined according to the following algorithm:
if (CategoryOrTraversal is not use_default)
return CategoryOrTraversal
else if (numeric_limits<Incrementable>::is_specialized)
return iterator-category(random_access_traversal_tag, Incrementable, const Incrementable&)
else
return iterator-category(iterator_traversal<Incrementable>::type, Incrementable, const Incrementable&)
Therefore, for simple ranges such as boost::irange(0, 10)
and boost::counting_range(0, 10)
there is effectively no difference (aside from the types of each range, of course!).
However, irange
also supports iteration with a different step size, e.g., boost::irange(0, 10, 2)
, and counting_range
also supports types that are only incrementable and do not fully model an integer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With