I've been surfing the internet in search of some well-documented reference for stuff like boost::any_range, but all I've managed to find is an official source which only gives a brief explanation of what any_range is about and presents some basic signatures. I'm looking for something which would explain it in detail.
A basic template for any_range looks like this:
template<
class Value
, class Traversal
, class Reference
, class Difference
, class Buffer = any_iterator_default_buffer
>
class any_range;
What is the meaning of each template parameter, and what values can it hold?
any_rangeis a type-erased container which allows you to store ranges which have at least the capabilities required by the template parameters you supply.It is based on
any_iterator, for which you can find detailed information in this article.Note that the template parameters in the documentation are missing some default arguments which are in the code itself. The real definition has:
The
Valueparameter specifies the type of the elements exposed by the range. So anany_range<int,...>may store astd::vector<int>, or astd::list<int>, etc.The
Traversalparameter specifies the category of range which is allowed, e.g. random access, forward, input. It can be one of the options from iterator_categories. Anany_range<int, random_access_tag, ...>would be able to store astd::vector<int>, but not astd::list<int>, becausestd::listis only bidirectional, not random-access.The
Referenceparameter indicates which type should be returned when you dereference iterators for the range. It defaults toValue&, and that's fine for most cases. (One case where it would not be okay is if your ranges return proxy references, likestd::vector<bool>does)The
Differenceindicates which type should be returned when you subtract one iterator for the range from another, getting the difference between them. This defaults tostd::ptrdiff_twhich is also fine for most cases.Finally, the
Bufferparameter indicates how to store the underlying type-erased range. This defaults toany_iterator_default_buffer, which stores the underlying range inside theany_rangeobject so long as it's 64 bytes or less. Otherwise it heap allocates it. Other options for this areany_iterator_buffer<MaxStackSize>,any_iterator_heap_only_buffer, andany_iterator_stack_only_buffer<StackSize>.(Sources: I got all of this by reading the source code)