1User Manual       {#mainpage}
2===========
3
4\tableofcontents
5
6\section tutorial-preface Preface
7
8--------------------------------------------
9Range library for C++14/17/20. This code is the basis of [the range support in C++20](http://eel.is/c++draft/#ranges).
10
11**Development Status:**
12
13This code is fairly stable, well-tested, and suitable for casual use, although
14currently lacking documentation. No promise is made about support or long-term
15stability. This code *will* evolve without regard to backwards compatibility.
16
17A notable exception is anything found within the `ranges::cpp20` namespace.
18Those components will change rarely or (preferably) never at all.
19
20\subsection tutorial-installation Installation
21
22--------------------------------------------
23This library is header-only. You can get the source code from the
24[range-v3 repository](https://github.com/ericniebler/range-v3) on github. To
25compile with Range-v3, just `#include` the individual headers you want.
26
27This distribution actually contains three separate header-only libraries:
28
29* <strong><tt>include/concepts/...</tt></strong> contains the Concepts Portability Preprocessor, or
30  CPP, which is a set of macros for defining and using concept checks,
31  regardless of whether your compiler happens to support the C++20 concepts
32  language feature or not.
33* <strong><tt>include/meta/...</tt></strong> contains the Meta Library, which is a set of
34  meta-programming utilities for processing types and lists of types at compile
35  time.
36* <strong><tt>include/range/...</tt></strong> contains the Range-v3 library, as described below.
37
38The Range-v3 library is physically structured in directories by feature group:
39
40* <strong><tt>include/range/v3/actions/...</tt></strong> contains _actions_, or composable
41  components that operate eagerly on containers and return the mutated container
42  for further actions.
43* <strong><tt>include/range/v3/algorithms/...</tt></strong> contains all the STL _algorithms_ with
44  overloads that accept ranges, in addition to the familiar overloads that take iterators.
45* <strong><tt>include/range/v3/functional/...</tt></strong> contains many generally useful
46  components that would be familiar to functional programmers.
47* <strong><tt>include/range/v3/iterator/...</tt></strong> contains the definitions of many useful
48  iterators and iterator-related concepts and utilities.
49* <strong><tt>include/range/v3/numeric/...</tt></strong> contains numeric algorithms corresponding
50  to those found in the standard `<numeric>` header.
51* <strong><tt>include/range/v3/range/...</tt></strong> contains range-related utilities, such as
52  `begin`, `end`, and `size`, range traits and concepts, and conversions to
53  containers.
54* <strong><tt>include/range/v3/utility/...</tt></strong> contains a miscellaneous assortment of
55  reusable code.
56* <strong><tt>include/range/v3/view/...</tt></strong> contains _views_, or composable
57  components that operate lazily on ranges and that themselves return ranges
58  that can be operated upon with additional view adaptors.
59
60\subsection tutorial-license License
61
62--------------------------------------------
63Most of the source code in this project are mine, and those are under the Boost
64Software License. Parts are taken from Alex Stepanov's Elements of Programming,
65Howard Hinnant's libc++, and from the SGI STL. Please see the attached LICENSE
66file and the CREDITS file for the licensing and acknowledgements.
67
68\subsection tutorial-compilers Supported Compilers
69
70--------------------------------------------------------------------------------
71The code is known to work on the following compilers:
72
73- clang 5.0
74- GCC 6.5
75- Clang/LLVM 6 (or later) on Windows
76- MSVC VS2019, with `/permissive-` and either `/std:c++latest` or `/std:c++17`
77
78\section tutorial-quick-start Quick Start
79
80--------------------------------------------------------------------------------
81Range-v3 is a generic library that augments the existing standard library with
82facilities for working with *ranges*. A range can be loosely thought of a pair
83of iterators, although they need not be implemented that way. Bundling begin/end
84iterators into a single object brings several benefits: convenience,
85composability, and correctness.
86
87**Convenience**
88
89It's more convenient to pass a single range object to an algorithm than separate
90begin/end iterators. Compare:
91
92~~~~~~~{.cpp}
93    std::vector<int> v{/*...*/};
94    std::sort( v.begin(), v.end() );
95~~~~~~~
96
97with
98
99~~~~~~~{.cpp}
100    std::vector<int> v{/*...*/};
101    ranges::sort( v );
102~~~~~~~
103
104Range-v3 contains full implementations of all the standard algorithms with
105range-based overloads for convenience.
106
107**Composability**
108
109Having a single range object permits *pipelines* of operations. In a pipeline, a
110range is lazily adapted or eagerly mutated in some way, with the result
111immediately available for further adaptation or mutation. Lazy adaption is
112handled by *views*, and eager mutation is handled by *actions*.
113
114For instance, the below uses _views_ to filter a container using a predicate
115and transform the resulting range with a function. Note that the underlying
116data is `const` and is not mutated by the views.
117
118~~~~~~~{.cpp}
119    std::vector<int> const vi{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
120    using namespace ranges;
121    auto rng = vi | views::remove_if([](int i){ return i % 2 == 1; })
122                  | views::transform([](int i){ return std::to_string(i); });
123    // rng == {"2","4","6","8","10"};
124~~~~~~~
125
126In the code above, `rng` simply stores a reference to the underlying data and
127the filter and transformation functions. No work is done until `rng` is
128iterated.
129
130In contrast, _actions_ do their work eagerly, but they also compose. Consider
131the code below, which reads some data into a vector, sorts it, and makes it
132unique.
133
134~~~~~~~{.cpp}
135    extern std::vector<int> read_data();
136    using namespace ranges;
137    std::vector<int> vi = read_data() | actions::sort | actions::unique;
138~~~~~~~
139
140Unlike views, with actions each step in the pipeline (`actions::sort` and
141`actions::unique`) accepts a container _by value_, mutates it in place, and
142returns it.
143
144**Correctness**
145
146Whether you are using views or actions, you are operating on data in a pure
147functional, declarative style. You rarely need to trouble yourself with
148iterators, although they are there under the covers should you need them.
149
150By operating declaratively and functionally instead of imperatively, we reduce
151the need for overt state manipulation and branches and loops. This brings down
152the number of states your program can be in, which brings down your bug counts.
153
154In short, if you can find a way to express your solution as a composition of
155functional transformations on your data, you can make your code _correct by
156construction_.
157
158\subsection tutorial-views Views
159
160--------------------------------------------------------------------------------
161As described above, the big advantage of ranges over iterators is their
162composability. They permit a functional style of programming where data is
163manipulated by passing it through a series of combinators. In addition, the
164combinators can be *lazy*, only doing work when the answer is requested, and
165*purely functional*, without mutating the original data. This makes it easier to
166reason about your code.
167
168A _view_ is a lightweight wrapper that presents a view of an underlying sequence
169of elements in some custom way without mutating or copying it. Views are cheap
170to create and copy and have non-owning reference semantics. Below are some
171examples that use views:
172
173Filter a container using a predicate and transform it.
174
175~~~~~~~{.cpp}
176    std::vector<int> const vi{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
177    using namespace ranges;
178    auto rng = vi | views::remove_if([](int i){return i % 2 == 1;})
179                  | views::transform([](int i){return std::to_string(i);});
180    // rng == {"2","4","6","8","10"};
181~~~~~~~
182
183Generate an infinite list of integers starting at 1, square them, take the first
18410, and sum them:
185
186~~~~~~~{.cpp}
187    using namespace ranges;
188    int sum = accumulate(views::ints(1)
189                       | views::transform([](int i){return i*i;})
190                       | views::take(10), 0);
191~~~~~~~
192
193Generate a sequence on the fly with a range comprehension and initialize a
194vector with it:
195
196~~~~~~~{.cpp}
197    using namespace ranges;
198    auto vi =
199        views::for_each(views::ints(1, 10), [](int i) {
200            return yield_from(views::repeat_n(i, i));
201        })
202      | to<std::vector>();
203    // vi == {1,2,2,3,3,3,4,4,4,4,5,5,5,5,5,...}
204~~~~~~~
205
206### View const-ness
207
208Logically, a view is a factory for iterators, but in practice a view is often
209implemented as a state machine, with the state stored within the view object
210itself (to keep iterators small) and mutated as the view is iterated. Because
211the view contains mutable state, many views lack a `const`-qualified
212`begin()`/`end()`. When `const` versions of `begin()`/`end()` are provided, they
213are truly `const`; that is, thread-safe.
214
215Since views present the same interface as containers, the temptation is to think
216they behave like containers with regard to `const`-ness. This is not the case.
217Their behavior with regards to `const`-ness is similar to iterators and
218pointers.
219
220The `const`-ness of a view is not related to the `const`-ness of the underlying
221data. A non-`const` view may refer to elements that are themselves `const`, and
222_vice versa_. This is analogous to pointers; an `int* const` is a `const`
223pointer to a mutable `int`, and a `int const*` is a non-`const` pointer to a
224`const` `int`.
225
226Use non-`const` views whenever possible. If you need thread-safety, work with
227view copies in threads; don't share.
228
229### View validity
230
231Any operation on the underlying range that invalidates its iterators or
232sentinels will also invalidate any view that refers to any part of that range.
233Additionally, some views (_e.g._, `views::filter`), are invalidated when the
234underlying elements of the range are mutated. It is best to recreate a view
235after any operation that may have mutated the underlying range.
236
237### List of range views
238
239Below is a list of the lazy range combinators, or views, that Range-v3
240provides, and a blurb about how each is intended to be used.
241
242<DL>
243<DT>\link ranges::views::addressof_fn `views::addressof`\endlink</DT>
244  <DD>Given a source range of lvalue references, return a new view that is the result of taking `std::addressof` of each.</DD>
245<DT>\link ranges::views::adjacent_filter_fn `views::adjacent_filter`\endlink</DT>
246  <DD>For each pair of adjacent elements in a source range, evaluate the specified binary predicate. If the predicate evaluates to false, the second element of the pair is removed from the result range; otherwise, it is included. The first element in the source range is always included. (For instance, `adjacent_filter` with `std::not_equal_to` filters out all the non-unique elements.)</DD>
247<DT>\link ranges::views::adjacent_remove_if_fn `views::adjacent_remove_if`\endlink</DT>
248  <DD>For each pair of adjacent elements in a source range, evaluate the specified binary predicate. If the predicate evaluates to true, the first element of the pair is removed from the result range; otherwise, it is included. The last element in the source range is always included.</DD>
249<DT>\link ranges::views::all_fn `views::all`\endlink</DT>
250  <DD>Return a range containing all the elements in the source. Useful for converting containers to ranges.</DD>
251<DT>\link ranges::any_view `any_view<T>(rng)`\endlink</DT>
252  <DD>Type-erased range of elements with value type `T`; can store _any_ range with this value type.</DD>
253<DT>\link ranges::views::c_str_fn `views::c_str`\endlink</DT>
254  <DD>View a `\0`-terminated C string (e.g. from a `const char*`) as a range.</DD>
255<DT>\link ranges::views::cache1_fn `views::cache1`\endlink</DT>
256  <DD>Caches the most recent element within the view so that dereferencing the view's iterator multiple times doesn't incur any recomputation. This can be useful in adaptor pipelines that include combinations of `view::filter` and `view::transform`, for instance. `views::cache1` is always single-pass.</DD>
257<DT>\link ranges::views::cartesian_product_fn `views::cartesian_product`\endlink</DT>
258  <DD>Enumerates the n-ary cartesian product of `n` ranges, i.e., generates all `n`-tuples `(e1, e2, ... , en)` where `e1` is an element of the first range, `e2` is an element of the second range, etc.</DD>
259<DT>\link ranges::views::chunk_fn `views::chunk`\endlink</DT>
260  <DD>Given a source range and an integer *N*, produce a range of contiguous ranges where each inner range has *N* contiguous elements. The final range may have fewer than *N* elements.</DD>
261<DT>\link ranges::views::common_fn `views::common`\endlink</DT>
262  <DD>Convert the source range to a *common* range, where the type of the `end` is the same as the `begin`. Useful for calling algorithms in the `std::` namespace.</DD>
263<DT>\link ranges::views::concat_fn `views::concat`\endlink</DT>
264  <DD>Given *N* source ranges, produce a result range that is the concatenation of all of them.</DD>
265<DT>\link ranges::views::const_fn `views::const_`\endlink</DT>
266  <DD>Present a `const` view of a source range.</DD>
267<DT>\link ranges::views::counted_fn `views::counted`\endlink</DT>
268  <DD>Given an iterator `it` and a count `n`, create a range that starts at `it` and includes the next `n` elements.</DD>
269<DT>\link ranges::views::cycle_fn `views::cycle`\endlink</DT>
270  <DD>Returns an infinite range that endlessly repeats the source range.</DD>
271<DT>\link ranges::views::delimit_fn `views::delimit`\endlink</DT>
272  <DD>Given a source range and a value, return a new range that ends either at the end of the source or at the first occurrence of the value, whichever comes first. Alternatively, `views::delimit` can be called with an iterator and a value, in which case it returns a range that starts at the specified position and ends at the first occurrence of the value.</DD>
273<DT>\link ranges::views::drop_fn `views::drop`\endlink</DT>
274  <DD>Given a source range and an integral count, return a range consisting of all but the first *count* elements from the source range, or an empty range if it has fewer elements.</DD>
275<DT>\link ranges::views::drop_last_fn `views::drop_last`\endlink</DT>
276  <DD>Given a source range and an integral count, return a range consisting of all but the last *count* elements from the source range, or an empty range if it has fewer elements.</DD>
277<DT>\link ranges::views::drop_exactly_fn `views::drop_exactly`\endlink</DT>
278  <DD>Given a source range and an integral count, return a range consisting of all but the first *count* elements from the source range. The source range must have at least that many elements.</DD>
279<DT>\link ranges::views::drop_while_fn `views::drop_while`\endlink</DT>
280  <DD>Remove elements from the front of a range that satisfy a unary predicate.</DD>
281<DT>\link ranges::views::empty() `views::empty`\endlink</DT>
282  <DD>Create an empty range with a given value type.</DD>
283<DT>\link ranges::views::enumerate() `views::enumerate`\endlink</DT>
284  <DD>Pair each element of a range with its index.</DD>
285<DT>\link ranges::views::filter_fn `views::filter`\endlink</DT>
286  <DD>Given a source range and a unary predicate, filter the elements that satisfy the predicate. (For users of Boost.Range, this is like the `filter` adaptor.)</DD>
287<DT>\link ranges::views::for_each_fn `views::for_each`\endlink</DT>
288  <DD>Lazily applies an unary function to each element in the source range that returns another range (possibly empty), flattening the result.</DD>
289<DT>\link ranges::views::generate_fn `views::generate`\endlink</DT>
290  <DD>Given a nullary function, return an infinite range whose elements are generated with the function.</DD>
291<DT>\link ranges::views::generate_n_fn `views::generate_n`\endlink</DT>
292  <DD>Given a nullary function and a count, return a range that generates the requested number of elements by calling the function.</DD>
293<DT>\link ranges::views::group_by_fn `views::group_by`\endlink</DT>
294  <DD>Given a source range and a binary predicate, return a range of ranges where each range contains contiguous elements from the source range such that the following condition holds: for each element in the range apart from the first, when that element and the first element are passed to the binary predicate, the result is true. In essence, `views::group_by` *groups* contiguous elements together with a binary predicate.</DD>
295<DT>\link ranges::views::indirect_fn `views::indirect`\endlink</DT>
296  <DD>Given a source range of readable values (e.g. pointers or iterators), return a new view that is the result of dereferencing each.</DD>
297<DT>\link ranges::views::intersperse_fn `views::intersperse`\endlink</DT>
298  <DD>Given a source range and a value, return a new range where the value is inserted between contiguous elements from the source.</DD>
299<DT>\link ranges::views::ints_fn `views::ints`\endlink</DT>
300  <DD>Generate a range of monotonically increasing `int`s. When used without arguments, it generates the quasi-infinite range [0,1,2,3...]. It can also be called with a lower bound, or with a lower and upper bound (exclusive). An inclusive version is provided by `closed_ints`.</DD>
301<DT>\link ranges::views::iota_fn `views::iota`\endlink</DT>
302  <DD>A generalization of `views::ints` that generates a sequence of monotonically increasing values of any incrementable type. When specified with a single argument, the result is an infinite range beginning at the specified value. With two arguments, the values are assumed to denote a half-open range.</DD>
303<DT>\link ranges::views::join_fn `views::join`\endlink</DT>
304  <DD>Given a range of ranges, join them into a flattened sequence of elements. Optionally, you can specify a value or a range to be inserted between each source range.</DD>
305<DT>\link ranges::views::keys_fn `views::keys`\endlink</DT>
306  <DD>Given a range of `pair`s (like a `std::map`), return a new range consisting of just the first element of the `pair`.</DD>
307<DT>\link ranges::views::linear_distribute_fn `views::linear_distribute`\endlink</DT>
308  <DD>Distributes `n` values linearly in the closed interval `[from, to]` (the end points are always included). If `from == to`, returns `n`-times `to`, and if `n == 1` it returns `to`.</DD>
309<DT>\link ranges::views::move_fn `views::move`\endlink</DT>
310  <DD>Given a source range, return a new range where each element has been has been cast to an rvalue reference.</DD>
311<DT>\link ranges::views::partial_sum_fn `views::partial_sum`\endlink</DT>
312  <DD>Given a range and a binary function, return a new range where the *N*<SUP>th</SUP> element is the result of applying the function to the *N*<SUP>th</SUP> element from the source range and the (N-1)th element from the result range.</DD>
313<DT>\link ranges::views::remove_fn `views::remove`\endlink</DT>
314  <DD>Given a source range and a value, filter out those elements that do not equal value.</DD>
315<DT>\link ranges::views::remove_if_fn `views::remove_if`\endlink</DT>
316  <DD>Given a source range and a unary predicate, filter out those elements that do not satisfy the predicate. (For users of Boost.Range, this is like the `filter` adaptor with the predicate negated.)</DD>
317<DT>\link ranges::views::repeat_fn `views::repeat`\endlink</DT>
318  <DD>Given a value, create a range that is that value repeated infinitely.</DD>
319<DT>\link ranges::views::repeat_n_fn `views::repeat_n`\endlink</DT>
320  <DD>Given a value and a count, create a range that is that value repeated *count* number of times.</DD>
321<DT>\link ranges::views::replace_fn `views::replace`\endlink</DT>
322  <DD>Given a source range, a source value and a target value, create a new range where all elements equal to the source value are replaced with the target value.</DD>
323<DT>\link ranges::views::replace_if_fn `views::replace_if`\endlink</DT>
324  <DD>Given a source range, a unary predicate and a target value, create a new range where all elements that satisfy the predicate are replaced with the target value.</DD>
325<DT>\link ranges::views::reverse_fn `views::reverse`\endlink</DT>
326  <DD>Create a new range that traverses the source range in reverse order.</DD>
327<DT>\link ranges::views::sample_fn `views::sample`\endlink</DT>
328  <DD>Returns a random sample of a range of length `size(range)`.</DD>
329<DT>\link ranges::views::single_fn `views::single`\endlink</DT>
330  <DD>Given a value, create a range with exactly one element.</DD>
331<DT>\link ranges::views::slice_fn `views::slice`\endlink</DT>
332  <DD>Give a source range a lower bound (inclusive) and an upper bound (exclusive), create a new range that begins and ends at the specified offsets. Both the begin and the end can be integers relative to the front, or relative to the end with "`end-2`" syntax.</DD>
333<DT>\link ranges::views::sliding_fn `views::sliding`\endlink</DT>
334  <DD>Given a range and a count `n`, place a window over the first `n` elements of the underlying range. Return the contents of that window as the first element of the adapted range, then slide the window forward one element at a time until hitting the end of the underlying range.</DD>
335<DT>\link ranges::views::split_fn `views::split`\endlink</DT>
336  <DD>Given a source range and a delimiter specifier, split the source range into a range of ranges using the delimiter specifier to find the boundaries. The delimiter specifier can be an element or a range of elements. The elements matching the delimiter are excluded from the resulting range of ranges.</DD>
337<DT>\link ranges::views::split_when_fn `views::split_when`\endlink</DT>
338  <DD>Given a source range and a delimiter specifier, split the source range into a range of ranges using the delimiter specifier to find the boundaries. The delimiter specifier can be a predicate or a function. The predicate should take a single argument of the range's reference type and return `true` if and only if the element is part of a delimiter. The function should accept an iterator and sentinel indicating the current position and end of the source range and return `std::make_pair(true, iterator_past_the_delimiter)` if the current position is a boundary; otherwise `std::make_pair(false, ignored_iterator_value)`. The elements matching the delimiter are excluded from the resulting range of ranges.</DD>
339<DT>\link ranges::views::stride_fn `views::stride`\endlink</DT>
340  <DD>Given a source range and an integral stride value, return a range consisting of every *N*<SUP>th</SUP> element, starting with the first.</DD>
341<DT>\link ranges::views::tail_fn `views::tail`\endlink</DT>
342  <DD>Given a source range, return a new range without the first element. The range must have at least one element.</DD>
343<DT>\link ranges::views::take_fn `views::take`\endlink</DT>
344  <DD>Given a source range and an integral count, return a range consisting of the first *count* elements from the source range, or the complete range if it has fewer elements. (The result of `views::take` is not a `sized_range`.)</DD>
345<DT>\link ranges::views::take_exactly_fn `views::take_exactly`\endlink</DT>
346  <DD>Given a source range and an integral count, return a range consisting of the first *count* elements from the source range. The source range must have at least that many elements. (The result of `views::take_exactly` is a `sized_range`.)</DD>
347<DT>\link ranges::views::take_last_fn `views::take_last`\endlink</DT>
348  <DD>Given a source range and an integral count, return a range consisting of the last *count* elements from the source range. The source range must be a `sized_range`. If the source range does not have at least *count* elements, the full range is returned.</DD>
349<DT>\link ranges::views::take_while_fn `views::take_while`\endlink</DT>
350  <DD>Given a source range and a unary predicate, return a new range consisting of the  elements from the front that satisfy the predicate.</DD>
351<DT>\link ranges::views::tokenize_fn `views::tokenize`\endlink</DT>
352  <DD>Given a source range and optionally a submatch specifier and a `std::regex_constants::match_flag_type`, return a `std::regex_token_iterator` to step through the regex submatches of the source range. The submatch specifier may be either a plain `int`, a `std::vector<int>`, or a `std::initializer_list<int>`.</DD>
353<DT>\link ranges::views::transform_fn `views::transform`\endlink</DT>
354  <DD>Given a source range and a unary function, return a new range where each result element is the result of applying the unary function to a source element.</DD>
355<DT>\link ranges::views::trim_fn `views::trim`\endlink</DT>
356  <DD>Given a source bidirectional range and a unary predicate, return a new range without the front and back elements that satisfy the predicate.</DD>
357<DT>\link ranges::views::unbounded_fn `views::unbounded`\endlink</DT>
358  <DD>Given an iterator, return an infinite range that begins at that position.</DD>
359<DT>\link ranges::views::unique_fn `views::unique`\endlink</DT>
360  <DD>Given a range, return a new range where all consecutive elements that compare equal save the first have been filtered out.</DD>
361<DT>\link ranges::views::values_fn `views::values`\endlink</DT>
362  <DD>Given a range of `pair`s (like a `std::map`), return a new range consisting of just the second element of the `pair`.</DD>
363<DT>\link ranges::views::zip_fn `views::zip`\endlink</DT>
364  <DD>Given *N* ranges, return a new range where *M*<SUP>th</SUP> element is the result of calling `make_tuple` on the *M*<SUP>th</SUP> elements of all *N* ranges.</DD>
365<DT>\link ranges::views::zip_with_fn `views::zip_with`\endlink</DT>
366  <DD>Given *N* ranges and a *N*-ary function, return a new range where *M*<SUP>th</SUP> element is the result of calling the function on the *M*<SUP>th</SUP> elements of all *N* ranges.</DD>
367</DL>
368
369\subsection tutorial-actions Actions
370
371--------------------------------------------------------------
372When you want to mutate a container in-place, or forward it through a chain of
373mutating operations, you can use actions. The following examples should make it
374clear.
375
376Read data into a vector, sort it, and make it unique.
377
378~~~~~~~{.cpp}
379    extern std::vector<int> read_data();
380    using namespace ranges;
381    std::vector<int> vi = read_data() | actions::sort | actions::unique;
382~~~~~~~
383
384Do the same to a `vector` that already contains some data:
385
386~~~~~~~{.cpp}
387    vi = std::move(vi) | actions::sort | actions::unique;
388~~~~~~~
389
390Mutate the container in-place:
391
392~~~~~~~{.cpp}
393    vi |= actions::sort | actions::unique;
394~~~~~~~
395
396Same as above, but with function-call syntax instead of pipe syntax:
397
398~~~~~~~{.cpp}
399    actions::unique(actions::sort(vi));
400~~~~~~~
401
402### List of range actions
403
404Below is a list of the eager range combinators, or actions, that Range-v3
405provides, and a blurb about how each is intended to be used.
406
407<DL>
408<DT>\link ranges::actions::drop_fn `actions::drop`\endlink</DT>
409  <DD>Removes the first `N` elements of the source range.</DD>
410<DT>\link ranges::actions::drop_while_fn `actions::drop_while`\endlink</DT>
411  <DD>Removes the first elements of the source range that satisfy the unary predicate.</DD>
412<DT>`actions::erase`</DT>
413  <DD>Removes all elements in the sub-range of the source (range version) or all elements after position.</DD>
414<DT>`actions::insert`</DT>
415  <DD>Inserts all elements of the range into the source at position.</DD>
416<DT>\link ranges::actions::join_fn `actions::join`\endlink</DT>
417  <DD>Flattens a range of ranges.</DD>
418<DT> `actions::push_back`</DT>
419  <DD>Appends elements to the tail of the source.</DD>
420<DT>`actions::push_front`</DT>
421  <DD>Appends elements before the head of the source.</DD>
422<DT>\link ranges::actions::remove_if_fn `actions::remove_if`\endlink</DT>
423  <DD>Removes all elements from the source that satisfy the predicate.</DD>
424<DT>\link ranges::actions::remove_fn `actions::remove`\endlink</DT>
425  <DD>Removes all elements from the source that are equal to value.</DD>
426<DT>\link ranges::actions::reverse_fn `actions::reverse`\endlink</DT>
427  <DD>Reverses all the elements in the container.</DD>
428<DT>\link ranges::actions::shuffle_fn `actions::shuffle`\endlink</DT>
429  <DD>Shuffles the source range.</DD>
430<DT>\link ranges::actions::slice_fn `actions::slice`\endlink</DT>
431  <DD>Removes all elements from the source that are not part of the sub-range.</DD>
432<DT>\link ranges::actions::sort_fn `actions::sort`\endlink</DT>
433  <DD>Sorts the source range (unstable).</DD>
434<DT>\link ranges::actions::split_fn `actions::split`\endlink</DT>
435  <DD>Split a range into a sequence of subranges using a delimiter (a value, a sequence of values, a predicate, or a binary function returning a `pair<bool, N>`).</DD>
436<DT>\link ranges::actions::stable_sort_fn `actions::stable_sort`\endlink</DT>
437  <DD>Sorts the source range (stable).</DD>
438<DT>\link ranges::actions::stride_fn `actions::stride`\endlink</DT>
439  <DD>Removes all elements whose position does not match the stride.</DD>
440<DT>\link ranges::actions::take_fn `actions::take`\endlink</DT>
441  <DD>Keeps the first `N`-th elements of the range, removes the rest.</DD>
442<DT>\link ranges::actions::take_while_fn `actions::take_while`\endlink</DT>
443  <DD>Keeps the first elements that satisfy the predicate, removes the rest.</DD>
444<DT>\link ranges::actions::transform_fn `actions::transform`\endlink</DT>
445  <DD>Replaces elements of the source with the result of the unary function.</DD>
446<DT>\link ranges::actions::unique_fn `actions::unique`\endlink</DT>
447  <DD>Removes adjacent elements of the source that compare equal. If the source is sorted, removes all duplicate elements.</DD>
448<DT>\link ranges::actions::unstable_remove_if_fn `actions::unstable_remove_if`\endlink</DT>
449  <DD>Much faster (each element remove has constant time complexity), unordered version of `remove_if`. Requires bidirectional container.</DD>
450</DL>
451
452
453\subsection tutorial-utilities Utilities
454
455----------------------------------------------
456Below we cover some utilities that range-v3 provides for creating your own
457view adaptors and iterators.
458
459#### Create Custom Views with view_facade
460
461Range-v3 provides a utility for easily creating your own range types, called
462\link ranges::view_facade `ranges::view_facade`\endlink. The code below uses
463`view_facade` to create a range that traverses a null-terminated string:
464
465~~~~~~~{.cpp}
466    #include <range/v3/view/facade.hpp>
467
468    // A range that iterates over all the characters in a
469    // null-terminated string.
470    class c_string_range
471      : public ranges::view_facade<c_string_range>
472    {
473        friend ranges::range_access;
474        char const * sz_ = "";
475        char const & read() const { return *sz_; }
476        bool equal(ranges::default_sentinel_t) const { return *sz_ == '\0'; }
477        void next() { ++sz_; }
478    public:
479        c_string_range() = default;
480        explicit c_string_range(char const *sz) : sz_(sz)
481        {
482            assert(sz != nullptr);
483        }
484    };
485~~~~~~~
486
487The `view_facade` class generates an iterator and begin/end member functions
488from the minimal interface provided by `c_string_range`. This is an example of a
489very simple range for which it is not necessary to separate the range itself
490from the thing that iterates the range. Future examples will show examples of
491more sophisticated ranges.
492
493With `c_string_range`, you can now use algorithms to operate on null-terminated
494strings, as below:
495
496~~~~~~~{.cpp}
497    #include <iostream>
498
499    int main()
500    {
501        c_string_range r("hello world");
502        // Iterate over all the characters and print them out
503        ranges::for_each(r, [](char ch){
504            std::cout << ch << ' ';
505        });
506        // prints: h e l l o   w o r l d
507    }
508~~~~~~~
509
510#### Create Custom Views with view_adaptor
511
512Often, a new range type is most easily expressed by adapting an existing range
513type. That's the case for many of the range views provided by the Range-v3
514library; for example, the `views::remove_if` and `views::transform` views. These
515are rich types with many moving parts, but thanks to a helper class called
516\link ranges::view_adaptor `ranges::view_adaptor`\endlink, they aren't hard
517to write.
518
519Below in roughly 2 dozen lines of code is the `transform` view, which takes one
520range and transforms all the elements with a unary function.
521
522~~~~~~~{.cpp}
523    #include <range/v3/view/adaptor.hpp>
524    #include <range/v3/utility/semiregular_box.hpp>
525
526    // A class that adapts an existing range with a function
527    template<class Rng, class Fun>
528    class transform_view
529      : public ranges::view_adaptor<transform_view<Rng, Fun>, Rng>
530    {
531        friend ranges::range_access;
532        ranges::semiregular_box_t<Fun> fun_; // Make Fun model semiregular if it doesn't
533        class adaptor : public ranges::adaptor_base
534        {
535            ranges::semiregular_box_t<Fun> fun_;
536        public:
537            adaptor() = default;
538            adaptor(ranges::semiregular_box_t<Fun> const &fun) : fun_(fun) {}
539            // Here is where we apply Fun to the elements:
540            auto read(ranges::iterator_t<Rng> it) const -> decltype(fun_(*it))
541            {
542                return fun_(*it);
543            }
544        };
545        adaptor begin_adaptor() const { return {fun_}; }
546        adaptor end_adaptor() const { return {fun_}; }
547    public:
548        transform_view() = default;
549        transform_view(Rng && rng, Fun fun)
550          : transform_view::view_adaptor{std::forward<Rng>(rng)}
551          , fun_(std::move(fun))
552        {}
553    };
554
555    template<class Rng, class Fun>
556    transform_view<Rng, Fun> transform(Rng && rng, Fun fun)
557    {
558        return {std::forward<Rng>(rng), std::move(fun)};
559    }
560~~~~~~~
561
562Range transformation is achieved by defining a nested `adaptor` class that
563handles the transformation, and then defining `begin_adaptor` and `end_adaptor`
564members that return adaptors for the begin iterator and the end sentinel,
565respectively. The `adaptor` class has a `read` member that performs the
566transformation. It is passed an iterator to the current element. Other members
567are available for customization: `equal`, `next`, `prev`, `advance`, and
568`distance_to`; but the transform adaptor accepts the defaults defined in
569\link ranges::adaptor_base `ranges::adaptor_base`\endlink.
570
571With `transform_view`, we can print out the first 20 squares:
572
573~~~~~~~{.cpp}
574    int main()
575    {
576        auto squares = ::transform(views::ints(1), [](int i){return i*i;});
577        for(int i : squares | views::take(20))
578            std::cout << i << ' ';
579        std::cout << '\n';
580        // prints 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 400
581    }
582~~~~~~~
583
584The `transform_view` defined above is an input range when it is wrapping an
585input range, a forward range when it's wrapping a forward range, etc. That happens
586because of smart defaults defined in the `adaptor_base` class that frees you
587from having to deal with a host of niggly detail when implementing iterators.
588
589*(Note: the above `transform_view` always stores a copy of the function in the
590sentinel. That is only necessary if the underlying range's sentinel type models
591bidirectional_iterator. That's a finer point that you shouldn't worry about right
592now.)*
593
594##### view_adaptor in details
595
596Each `view_adaptor` contains `base()` member in view and iterator.
597`base()` - allow to access "adapted" range/iterator:
598
599~~~~~~~{.cpp}
600    std::vector<int> vec;
601    auto list = vec | views::transfom([](int i){ return i+1; });
602
603    assert( vec.begin() == list.begin().base() );
604    assert( vec.begin() == list.base().begin() );
605~~~~~~~
606
607Like `basic_iterator`'s `cursor`, `view_adaptor`'s `adaptor` can contain mixin class too,
608to inject things into the public interface of the iterator:
609
610~~~~~~~{.cpp}
611    class adaptor : public ranges::adaptor_base
612    {
613        template<class BaseMixin>
614        struct mixin : BaseMixin
615        {
616              // everything inside this class will be accessible from iterator
617              using BaseMixin::BaseMixin;
618
619              auto& base_value() const
620              {
621                  return *this->base();
622              }
623
624              int get_i() const
625              {
626                  return this->get().i;
627              }
628        };
629
630        int i = 100;
631    };
632~~~~~~~
633
634From within mixin you can call:
635
636* `get()` - to access adaptor internals
637* `base()` - to access adaptable iterator
638
639Iterator/sentinel adaptor may "override" the following members:
640
641~~~~~~~{.cpp}
642    class adaptor : public ranges::adaptor_base
643    {
644        // !For begin_adaptor only!
645        template<typename Rng>
646        constexpr auto begin(Rng &rng)
647        {
648            return ranges::begin(rng.base());
649        }
650
651        // !For end_adaptor only!
652        template<typename Rng>
653        constexpr auto end(Rng &rng)
654        {
655            return ranges::end(rng.base());
656        }
657
658        template<typename I>
659        bool equal(I const &this_iter, I const &that_iter) const
660        {
661            return this_iter == that_iter;
662        }
663        // or
664        template<typename I>
665        bool equal(I const &this_iter, I const &that_iter, adaptor const &that_adapt) const
666        {
667            return
668              *this.some_value == that_adapt.some_value
669              && this_iter == that_iter;
670        }
671
672        // !For end_adaptor only!
673        // Same as equal, but compare iterator with sentinel.
674        // Not used, if iterator same as sentinel, and both have the same adaptor.
675        template<typename I, typename S>
676        constexpr bool empty(I const &it, S const &end) const
677        {
678            return it == end;
679        }
680        // or
681        template<typename I, typename S, typename SA>
682        constexpr bool empty(I const &it, S const &end, SA const &end_adapt) const
683        {
684            return
685              *this.some_value == end_adapt.some_value
686              && it == end;
687        }
688
689        template<typename I>
690        reference_t<I> read(I const &it)
691        {
692            return *it;
693        }
694
695        template<typename I>
696        void next(I &it)
697        {
698            ++it;
699        }
700
701        // !For bidirectional iterator only!
702        template<typename I>
703        void prev(I &it)
704        {
705            --it;
706        }
707
708        // !For random access iterator only!
709        template<typename I>
710        void advance(I &it, difference_type_t<I> n)
711        {
712            it += n;
713        }
714
715        // !For "sized" iterators only!
716        template<typename I>
717        difference_type_t<I> distance_to(I const &this_iter, I const &that_iter)
718        {
719            return that_iter - this_iter;
720        }
721        // or
722        template<typename I>
723        difference_type_t<I> distance_to
724            (I const &this_iter, I const &that_iter, adaptor const &that_adapt)
725        {
726            return that_iter - this_iter;
727        }
728    }
729~~~~~~~
730
731As you can see, some "overrides" have effect only for `begin_adaptor` or
732`end_adaptor`. In order to use full potential of adaptor, you need to have
733separate adaptors for begin and end:
734
735~~~~~~~{.cpp}
736    struct adaptor : adaptor_base
737    {
738        int n = 0;
739
740        void next(iterator_t<Rng>& it)
741        {
742            ++n;
743            ++it;
744        }
745    };
746
747    struct sentinel_adaptor : adaptor_base
748    {
749        int stop_at;
750        bool empty(const iterator_t<Rng>&, const adaptor& ia, const sentinel_t<Rng>& s) const
751        {
752            return ia.n == stop_at;
753        }
754    };
755
756    adaptor begin_adaptor() const { return {}; }
757    sentinel_adaptor end_adaptor() const { return {100}; }
758~~~~~~~
759
760Sometimes, you can use the same adaptor for both `begin_adaptor` and `end_adaptor`:
761
762~~~~~~~{.cpp}
763    struct adaptor : adaptor_base
764    {
765        int n = 0;
766        void next(iterator_t<Rng>& it)
767        {
768            ++n;
769            ++it;
770        }
771
772        // pay attention, we use equal, not empty. empty() will never trigger.
773        template<typename I>
774        bool equal(I const &this_iter, I const &that_iter, adaptor const &that_adapt) const
775        {
776            return *this.n == that_adapt.n;
777        }
778    };
779
780    adaptor begin_adaptor() const { return {}; }
781    adaptor end_adaptor()   const { return {100}; }
782~~~~~~~
783
784Note that all the data you store in the adaptor will become part of the iterator.
785
786If you will not "override" `begin_adaptor()` or/and `end_adaptor()` in your view_adaptor, default ones will be used.
787
788#### Create Custom Iterators with basic_iterator
789
790Here is an example of Range-v3 compatible random access proxy iterator.
791The iterator returns a key/value pair, like the `zip` view.
792
793~~~~~~~{.cpp}
794    #include <range/v3/iterator/basic_iterator.hpp>
795    #include <range/v3/utility/common_tuple.hpp>
796
797    using KeyIter   = typename std::vector<Key>::iterator;
798    using ValueIter = typename std::vector<Value>::iterator;
799
800    struct cursor
801    {
802        // basic_iterator derives from "mixin", if present, so it can be used
803        // to inject things into the public interface of the iterator
804        struct mixin;
805
806        // This is for dereference operator.
807        using value_type = std::pair<Key, Value>;
808        ranges::common_pair<Key&, Value&> read() const
809        {
810            return { *key_iterator, *value_iterator };
811        }
812
813        bool equal(const cursor& other) const
814        {
815            return key_iterator == other.key_iterator;
816        }
817
818        void next()
819        {
820            ++key_iterator;
821            ++value_iterator;
822        }
823
824        // prev optional. Required for Bidirectional iterator
825        void prev()
826        {
827            --key_iterator;
828            --value_iterator;
829        }
830
831        // advance and distance_to are optional. Required for random access iterator
832        void advance(std::ptrdiff_t n)
833        {
834            key_iterator   += n;
835            value_iterator += n;
836        }
837        std::ptrdiff_t distance_to(const cursor& other) const
838        {
839            return other.key_iterator - this->key_iterator;
840        }
841
842        cursor() = default;
843        cursor(KeyIter key_iterator, ValueIter value_iterator)
844          : key_iterator(key_iterator)
845          , value_iterator(value_iterator)
846        {}
847
848        KeyIter   key_iterator;
849        ValueIter value_iterator;
850    };
851
852    struct cursor::mixin : ranges::basic_mixin<cursor>
853    {
854        using ranges::basic_mixin<cursor>::basic_mixin;
855
856        // It is necessary to expose constructor in this way
857        mixin(KeyIter key_iterator, ValueIter value_iterator)
858          : mixin{ cursor(key_iterator, value_iterator) }
859        {}
860
861        KeyIter key_iterator()
862        {
863            return this->get().key_iterator;
864        }
865        ValueIter value_iterator()
866        {
867            return this->get().value_iterator;
868        }
869    };
870
871    using iterator = ranges::basic_iterator<cursor>;
872
873    void test()
874    {
875        std::vector<Key>   keys   = {1};
876        std::vector<Value> values = {10};
877
878        iterator iter(keys.begin(), values.begin());
879        ranges::common_pair<Key&, Value&> pair = *iter;
880        Key&   key   = pair.first;
881        Value& value = pair.second;
882
883        assert(&key   == &keys[0]);
884        assert(&value == &values[0]);
885
886        auto key_iter = iter.key_iterator();
887        assert(key_iter == keys.begin());
888    }
889~~~~~~~
890
891`read()` returns references. But the default for `value_type`, which is
892`decay_t<decltype(read())>`, is `common_pair<Key&, Value&>`. That is not correct
893in our case. It should be `pair<Key, Value>`, so we explicitly specify
894`value_type`.
895
896`ranges::common_pair` has conversions:
897
898> `ranges::common_pair<Key&, Value&>` &harr; `ranges::common_pair<Key, Value>`.
899
900All `ranges::common_pair`s converts to their `std::pair` equivalents, also.
901
902For more information, see [http://wg21.link/P0186#basic-iterators-iterators.basic](http://wg21.link/P0186#basic-iterators-iterators.basic)
903
904\subsection tutorial-concepts Concept Checking
905
906--------------------------------------------------------------------------------
907The Range-v3 library makes heavy use of concepts to constrain functions, control
908overloading, and check type constraints at compile-time. It achieves this with
909the help of a Concepts emulation layer that works on any standard-conforming
910C++14 compiler. The library provides many useful concepts, both for the core
911language and for iterators and ranges. You can use the concepts framework to
912constrain your own code.
913
914For instance, if you would like to write a function that takes an
915iterator/sentinel pair, you can write it like this:
916
917~~~~~~~{.cpp}
918    CPP_template(class Iter, class Sent, class Comp = /*...some_default..*/)
919        (requires sentinel_for<Sent, Iter>)
920    void my_algorithm(Iter first, Sent last, Comp comp = Comp{})
921    {
922        // ...
923    }
924~~~~~~~
925
926You can then add an overload that take a Range:
927
928~~~~~~~{.cpp}
929    CPP_template(class Rng, class Comp = /*...some_default..*/)
930        (requires range<Rng>)
931    void my_algorithm(Rng && rng, Comp comp = Comp{})
932    {
933        return my_algorithm(ranges::begin(rng), ranges::end(rng));
934    }
935~~~~~~~
936
937With the type constraints expressed with the `CPP_template` macro, these
938two overloads are guaranteed to not be ambiguous. When compiling with C++20
939concepts support, this uses real concept checks. On legacy compilers, it falls
940back to using `std::enable_if`.
941
942\subsection tutorial-future Range-v3 and the Future
943
944--------------------------------------------------------------------------------
945Range-v3 formed the basis for the
946[Technical Specification on Ranges](https://www.iso.org/standard/70910.html),
947which has since been merged into the working draft of C++20.
948
949In addition, a subset of range-v3's views are also a part of the C++20 working
950draft, with more slated for eventual inclusion in future versions of C++.
951
952The actions, as well as various utilities, have not yet been reviewed by the
953Committee, although the basic direction has already passed an initial review.
954
955