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&>` ↔ `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