Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between irange and counting_range in Boost

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?

like image 464
Alan Turing Avatar asked Jan 01 '13 06:01

Alan Turing


2 Answers

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.

like image 106
R. Martinho Fernandes Avatar answered Sep 21 '22 06:09

R. Martinho Fernandes


Both irange and counting_range model a random access range for integer types. As counting_ranges 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.

like image 32
Joe Avatar answered Sep 20 '22 06:09

Joe