Skip to content
Hannes Hauswedell edited this page Feb 27, 2018 · 4 revisions

Introduction

Ranges are an abstraction of "a collection of items", or "something iterable". The most basic definition requires only the existence of begin() and end() on the range and the begin being incrementable, but more refined range concepts add more requirements.

The ranges most commonly known are containers, e.g. std::vector. Containers are types of ranges that own the elements in the collection, but there other types, as well, as we will see below.

The "Ranges Technical Specification" is a modification to the C++ Standard that standardises this "Ranges" abstraction and corresponding Concepts. It also adapts most algorithms in the standard library to take a single range argument, instead of a pair of [begin, end) iterators. It has recently been included in the standard and will be part of C++20. Since we rely only on C++17 plus the Concepts TS in SeqAn3, we cannot assume that Ranges support is available in the compiler and standard library and instead use the Range-V3 library which implements a super set of the technical specifications.

We recommend the following resources to learn more about ranges:

Views

Views are a certain type of ranges, that usually (but not always!) perform an operation on another range. They are lazy-evaluated stateful algorithms that present their result as a range. And they can be chained to combine different algorithms, which can be done via the | operator like on the UNIX command line. What does this mean in practice?

Well, you can, e.g. take a vector of ints, apply a view would compute the square of every element, and then apply a view that drops the first two elements:

std::vector<int> vec{1, 5, 6, 8, 5};
auto v = vec | view::transform([] (int const i) { return i*i; }) | view::drop(2);
std::cout << *v.begin() << '\n'; // prints '36'

And the point here is that only one "squaring-operation" actually happens and that it happens when we dereference the iterator, not before(because of lazy evaluation!).

What type is v? It is some implementation defined type that is guaranteed to satisfy certain range concepts: the input-range concept (it is iterable and readable) and the view concept. The view concept has some important requirements, among them that the type is "light-weight", i.e. copy'able in constant time. So while views appear like containers, they behave more like iterators.

See Howto: Write a View for some tutorials.

Clone this wiki locally