Files
allhaileris afb81b8278
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
init
2026-02-16 15:50:16 +03:00

854 lines
91 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Range-v3: User Manual</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(document).ready(function() { init_search(); });
/* @license-end */
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">Range-v3
</div>
<div id="projectbrief">Range algorithms, views, and actions for the Standard Library</div>
</td>
<td> <div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<img id="MSearchSelect" src="search/mag_sel.svg"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(document).ready(function(){initNavTree('index.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div><div class="header">
<div class="headertitle"><div class="title">User Manual </div></div>
</div><!--header-->
<div class="contents">
<div class="toc"><h3>Table of Contents</h3>
<ul><li class="level1"><a href="#tutorial-preface">Preface</a><ul><li class="level2"><a href="#tutorial-installation">Installation</a></li>
<li class="level2"><a href="#tutorial-license">License</a></li>
<li class="level2"><a href="#tutorial-compilers">Supported Compilers</a></li>
</ul>
</li>
<li class="level1"><a href="#tutorial-quick-start">Quick Start</a><ul><li class="level2"><a href="#tutorial-views">Views</a></li>
<li class="level2"><a href="#autotoc_md21">View const-ness</a></li>
<li class="level2"><a href="#autotoc_md22">View validity</a></li>
<li class="level2"><a href="#autotoc_md23">List of range views</a></li>
<li class="level2"><a href="#tutorial-actions">Actions</a></li>
<li class="level2"><a href="#autotoc_md25">List of range actions</a></li>
<li class="level2"><a href="#tutorial-utilities">Utilities</a><ul><li class="level3"><a href="#autotoc_md27">Create Custom Views with view_facade</a></li>
<li class="level3"><a href="#autotoc_md28">Create Custom Views with view_adaptor</a><ul><li class="level4"><a href="#autotoc_md29">view_adaptor in details</a></li>
</ul>
</li>
<li class="level3"><a href="#autotoc_md30">Create Custom Iterators with basic_iterator</a></li>
</ul>
</li>
<li class="level2"><a href="#tutorial-concepts">Concept Checking</a></li>
<li class="level2"><a href="#tutorial-future">Range-v3 and the Future</a></li>
</ul>
</li>
</ul>
</div>
<div class="textblock"><p ><a class="anchor" id="mainpage"></a></p>
<h1><a class="anchor" id="tutorial-preface"></a>
Preface</h1>
<hr />
<p> Range library for C++14/17/20. This code is the basis of <a href="http://eel.is/c++draft/#ranges">the range support in C++20</a>.</p>
<p ><b>Development Status:</b></p>
<p >This code is fairly stable, well-tested, and suitable for casual use, although currently lacking documentation. No promise is made about support or long-term stability. This code <em>will</em> evolve without regard to backwards compatibility.</p>
<p >A notable exception is anything found within the <code>ranges::cpp20</code> namespace. Those components will change rarely or (preferably) never at all.</p>
<h2><a class="anchor" id="tutorial-installation"></a>
Installation</h2>
<hr />
<p> This library is header-only. You can get the source code from the <a href="https://github.com/ericniebler/range-v3">range-v3 repository</a> on github. To compile with Range-v3, just <code>#include</code> the individual headers you want.</p>
<p >This distribution actually contains three separate header-only libraries:</p>
<ul>
<li><b><code>include/concepts/...</code></b> contains the Concepts Portability Preprocessor, or CPP, which is a set of macros for defining and using concept checks, regardless of whether your compiler happens to support the C++20 concepts language feature or not.</li>
<li><b><code>include/meta/...</code></b> contains the Meta Library, which is a set of meta-programming utilities for processing types and lists of types at compile time.</li>
<li><b><code>include/range/...</code></b> contains the Range-v3 library, as described below.</li>
</ul>
<p >The Range-v3 library is physically structured in directories by feature group:</p>
<ul>
<li><b><code>include/range/v3/actions/...</code></b> contains <em>actions</em>, or composable components that operate eagerly on containers and return the mutated container for further actions.</li>
<li><b><code>include/range/v3/algorithms/...</code></b> contains all the STL <em>algorithms</em> with overloads that accept ranges, in addition to the familiar overloads that take iterators.</li>
<li><b><code>include/range/v3/functional/...</code></b> contains many generally useful components that would be familiar to functional programmers.</li>
<li><b><code>include/range/v3/iterator/...</code></b> contains the definitions of many useful iterators and iterator-related concepts and utilities.</li>
<li><b><code>include/range/v3/numeric/...</code></b> contains numeric algorithms corresponding to those found in the standard <code>&lt;numeric&gt;</code> header.</li>
<li><b><code>include/range/v3/range/...</code></b> contains range-related utilities, such as <code>begin</code>, <code>end</code>, and <code>size</code>, range traits and concepts, and conversions to containers.</li>
<li><b><code>include/range/v3/utility/...</code></b> contains a miscellaneous assortment of reusable code.</li>
<li><b><code>include/range/v3/view/...</code></b> contains <em>views</em>, or composable components that operate lazily on ranges and that themselves return ranges that can be operated upon with additional view adaptors.</li>
</ul>
<h2><a class="anchor" id="tutorial-license"></a>
License</h2>
<hr />
<p> Most of the source code in this project are mine, and those are under the Boost Software License. Parts are taken from Alex Stepanov's Elements of Programming, Howard Hinnant's libc++, and from the SGI STL. Please see the attached LICENSE file and the CREDITS file for the licensing and acknowledgements.</p>
<h2><a class="anchor" id="tutorial-compilers"></a>
Supported Compilers</h2>
<hr />
<p> The code is known to work on the following compilers:</p>
<ul>
<li>clang 5.0</li>
<li>GCC 6.5</li>
<li>Clang/LLVM 6 (or later) on Windows</li>
<li>MSVC VS2019, with <code>/permissive-</code> and either <code>/std:c++latest</code>, <code>/std:c++20</code>, or <code>/std:c++17</code></li>
</ul>
<h1><a class="anchor" id="tutorial-quick-start"></a>
Quick Start</h1>
<hr />
<p> Range-v3 is a generic library that augments the existing standard library with facilities for working with <em>ranges</em>. A range can be loosely thought of a pair of iterators, although they need not be implemented that way. Bundling begin/end iterators into a single object brings several benefits: convenience, composability, and correctness.</p>
<p ><b>Convenience</b></p>
<p >It's more convenient to pass a single range object to an algorithm than separate begin/end iterators. Compare:</p>
<div class="fragment"><div class="line">std::vector&lt;int&gt; v{<span class="comment">/*...*/</span>};</div>
<div class="line"><a class="code hl_typedef" href="group__transformation.html#ga24714e0a1e7b99a57052a63d815955a7">std::sort</a>( v.begin(), v.end() );</div>
<div class="ttc" id="agroup__transformation_html_ga24714e0a1e7b99a57052a63d815955a7"><div class="ttname"><a href="group__transformation.html#ga24714e0a1e7b99a57052a63d815955a7">meta::sort</a></div><div class="ttdeci">_t&lt; detail::sort_&lt; L, Fn &gt; &gt; sort</div><div class="ttdoc">Return a new meta::list that is sorted according to invocable predicate Fn.</div><div class="ttdef"><b>Definition:</b> meta.hpp:3277</div></div>
</div><!-- fragment --><p >with</p>
<div class="fragment"><div class="line">std::vector&lt;int&gt; v{<span class="comment">/*...*/</span>};</div>
<div class="line"><a class="code hl_typedef" href="group__transformation.html#ga24714e0a1e7b99a57052a63d815955a7">ranges::sort</a>( v );</div>
</div><!-- fragment --><p >Range-v3 contains full implementations of all the standard algorithms with range-based overloads for convenience.</p>
<p ><b>Composability</b></p>
<p >Having a single range object permits <em>pipelines</em> of operations. In a pipeline, a range is lazily adapted or eagerly mutated in some way, with the result immediately available for further adaptation or mutation. Lazy adaption is handled by <em>views</em>, and eager mutation is handled by <em>actions</em>.</p>
<p >For instance, the below uses <em>views</em> to filter a container using a predicate and transform the resulting range with a function. Note that the underlying data is <code>const</code> and is not mutated by the views.</p>
<div class="fragment"><div class="line">std::vector&lt;int&gt; <span class="keyword">const</span> vi{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};</div>
<div class="line"><span class="keyword">using namespace </span>ranges;</div>
<div class="line"><span class="keyword">auto</span> rng = vi | <a class="code hl_function" href="group__group-algorithms.html#gaa9efe4e4adbdb10bd147b28164f8beb5">views::remove_if</a>([](<span class="keywordtype">int</span> i){ <span class="keywordflow">return</span> i % 2 == 1; })</div>
<div class="line"> | <a class="code hl_typedef" href="group__transformation.html#ga32b72eeac93fde990739bfe3d1729207">views::transform</a>([](<span class="keywordtype">int</span> i){ <span class="keywordflow">return</span> std::to_string(i); });</div>
<div class="line"><span class="comment">// rng == {&quot;2&quot;,&quot;4&quot;,&quot;6&quot;,&quot;8&quot;,&quot;10&quot;};</span></div>
<div class="ttc" id="agroup__group-algorithms_html_gaa9efe4e4adbdb10bd147b28164f8beb5"><div class="ttname"><a href="group__group-algorithms.html#gaa9efe4e4adbdb10bd147b28164f8beb5">ranges::remove_if</a></div><div class="ttdeci">constexpr I remove_if(I first, S last, C pred, P proj=P{})</div><div class="ttdoc">function template remove_if</div><div class="ttdef"><b>Definition:</b> remove_if.hpp:42</div></div>
<div class="ttc" id="agroup__transformation_html_ga32b72eeac93fde990739bfe3d1729207"><div class="ttname"><a href="group__transformation.html#ga32b72eeac93fde990739bfe3d1729207">meta::transform</a></div><div class="ttdeci">_t&lt; detail::transform_&lt; Args... &gt; &gt; transform</div><div class="ttdoc">Return a new meta::list constructed by transforming all the elements in L with the unary invocable Fn...</div><div class="ttdef"><b>Definition:</b> meta.hpp:1852</div></div>
</div><!-- fragment --><p >In the code above, <code>rng</code> simply stores a reference to the underlying data and the filter and transformation functions. No work is done until <code>rng</code> is iterated.</p>
<p >In contrast, <em>actions</em> do their work eagerly, but they also compose. Consider the code below, which reads some data into a vector, sorts it, and makes it unique.</p>
<div class="fragment"><div class="line"><span class="keyword">extern</span> std::vector&lt;int&gt; read_data();</div>
<div class="line"><span class="keyword">using namespace </span>ranges;</div>
<div class="line">std::vector&lt;int&gt; vi = read_data() | <a class="code hl_typedef" href="group__transformation.html#ga24714e0a1e7b99a57052a63d815955a7">actions::sort</a> | <a class="code hl_variable" href="action_2unique_8hpp.html#a2df52ed5e91e92ea7d2d7b1ed5408fcf">actions::unique</a>;</div>
<div class="ttc" id="aaction_2unique_8hpp_html_a2df52ed5e91e92ea7d2d7b1ed5408fcf"><div class="ttname"><a href="action_2unique_8hpp.html#a2df52ed5e91e92ea7d2d7b1ed5408fcf">unique</a></div><div class="ttdeci">constexpr action_closure&lt; unique_fn &gt; unique</div><div class="ttdef"><b>Definition:</b> unique.hpp:57</div></div>
</div><!-- fragment --><p >Unlike views, with actions each step in the pipeline (<code>actions::sort</code> and <code>actions::unique</code>) accepts a container <em>by value</em>, mutates it in place, and returns it.</p>
<p ><b>Correctness</b></p>
<p >Whether you are using views or actions, you are operating on data in a pure functional, declarative style. You rarely need to trouble yourself with iterators, although they are there under the covers should you need them.</p>
<p >By operating declaratively and functionally instead of imperatively, we reduce the need for overt state manipulation and branches and loops. This brings down the number of states your program can be in, which brings down your bug counts.</p>
<p >In short, if you can find a way to express your solution as a composition of functional transformations on your data, you can make your code <em>correct by construction</em>.</p>
<h2><a class="anchor" id="tutorial-views"></a>
Views</h2>
<hr />
<p> As described above, the big advantage of ranges over iterators is their composability. They permit a functional style of programming where data is manipulated by passing it through a series of combinators. In addition, the combinators can be <em>lazy</em>, only doing work when the answer is requested, and <em>purely functional</em>, without mutating the original data. This makes it easier to reason about your code.</p>
<p >A <em>view</em> is a lightweight wrapper that presents a view of an underlying sequence of elements in some custom way without mutating or copying it. Views are cheap to create and copy and have non-owning reference semantics. Below are some examples that use views:</p>
<p >Filter a container using a predicate and transform it.</p>
<div class="fragment"><div class="line">std::vector&lt;int&gt; <span class="keyword">const</span> vi{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};</div>
<div class="line"><span class="keyword">using namespace </span>ranges;</div>
<div class="line"><span class="keyword">auto</span> rng = vi | <a class="code hl_function" href="group__group-algorithms.html#gaa9efe4e4adbdb10bd147b28164f8beb5">views::remove_if</a>([](<span class="keywordtype">int</span> i){<span class="keywordflow">return</span> i % 2 == 1;})</div>
<div class="line"> | <a class="code hl_typedef" href="group__transformation.html#ga32b72eeac93fde990739bfe3d1729207">views::transform</a>([](<span class="keywordtype">int</span> i){<span class="keywordflow">return</span> std::to_string(i);});</div>
<div class="line"><span class="comment">// rng == {&quot;2&quot;,&quot;4&quot;,&quot;6&quot;,&quot;8&quot;,&quot;10&quot;};</span></div>
</div><!-- fragment --><p >Generate an infinite list of integers starting at 1, square them, take the first 10, and sum them:</p>
<div class="fragment"><div class="line"><span class="keyword">using namespace </span>ranges;</div>
<div class="line"><span class="keywordtype">int</span> sum = <a class="code hl_typedef" href="group__transformation.html#gadec7869718bf0ddf69579775156b351d">accumulate</a>(views::ints(1)</div>
<div class="line"> | <a class="code hl_typedef" href="group__transformation.html#ga32b72eeac93fde990739bfe3d1729207">views::transform</a>([](<span class="keywordtype">int</span> i){<span class="keywordflow">return</span> i*i;})</div>
<div class="line"> | views::take(10), 0);</div>
<div class="ttc" id="agroup__transformation_html_gadec7869718bf0ddf69579775156b351d"><div class="ttname"><a href="group__transformation.html#gadec7869718bf0ddf69579775156b351d">meta::accumulate</a></div><div class="ttdeci">fold&lt; L, State, Fn &gt; accumulate</div><div class="ttdoc">An alias for meta::fold.</div><div class="ttdef"><b>Definition:</b> meta.hpp:1597</div></div>
</div><!-- fragment --><p >Generate a sequence on the fly with a range comprehension and initialize a vector with it:</p>
<div class="fragment"><div class="line"><span class="keyword">using namespace </span>ranges;</div>
<div class="line"><span class="keyword">auto</span> vi =</div>
<div class="line"> <a class="code hl_variable" href="group__runtime.html#ga8beaba5ae537715c97e180b05160cc03">views::for_each</a>(views::ints(1, 10), [](<span class="keywordtype">int</span> i) {</div>
<div class="line"> <span class="keywordflow">return</span> yield_from(<a class="code hl_typedef" href="group__list.html#gab4b5da3947303335fc4139f163ed4748">views::repeat_n</a>(i, i));</div>
<div class="line"> })</div>
<div class="line"> | to&lt;std::vector&gt;();</div>
<div class="line"><span class="comment">// vi == {1,2,2,3,3,3,4,4,4,4,5,5,5,5,5,...}</span></div>
<div class="ttc" id="agroup__list_html_gab4b5da3947303335fc4139f163ed4748"><div class="ttname"><a href="group__list.html#gab4b5da3947303335fc4139f163ed4748">meta::repeat_n</a></div><div class="ttdeci">repeat_n_c&lt; N::type::value, T &gt; repeat_n</div><div class="ttdoc">Generate list&lt;T,T,T...T&gt; of size N arguments.</div><div class="ttdef"><b>Definition:</b> meta.hpp:1899</div></div>
<div class="ttc" id="agroup__runtime_html_ga8beaba5ae537715c97e180b05160cc03"><div class="ttname"><a href="group__runtime.html#ga8beaba5ae537715c97e180b05160cc03">meta::for_each</a></div><div class="ttdeci">constexpr auto &amp;&amp; for_each</div><div class="ttdoc">for_each(List, UnaryFunction) calls the UnaryFunction for each argument in the List.</div><div class="ttdef"><b>Definition:</b> meta.hpp:2876</div></div>
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md21"></a>
View const-ness</h2>
<p >Logically, a view is a factory for iterators, but in practice a view is often implemented as a state machine, with the state stored within the view object itself (to keep iterators small) and mutated as the view is iterated. Because the view contains mutable state, many views lack a <code>const</code>-qualified <code><a class="el" href="group__group-range.html#ga446b20253a26c93ef3004fcbfcbf3ec3">begin()</a></code>/<code><a class="el" href="group__group-range.html#ga80d92c391f5b5c0a50156af5f9c9d8c7">end()</a></code>. When <code>const</code> versions of <code><a class="el" href="group__group-range.html#ga446b20253a26c93ef3004fcbfcbf3ec3">begin()</a></code>/<code><a class="el" href="group__group-range.html#ga80d92c391f5b5c0a50156af5f9c9d8c7">end()</a></code> are provided, they are truly <code>const</code>; that is, thread-safe.</p>
<p >Since views present the same interface as containers, the temptation is to think they behave like containers with regard to <code>const</code>-ness. This is not the case. Their behavior with regards to <code>const</code>-ness is similar to iterators and pointers.</p>
<p >The <code>const</code>-ness of a view is not related to the <code>const</code>-ness of the underlying data. A non-<code>const</code> view may refer to elements that are themselves <code>const</code>, and <em>vice versa</em>. This is analogous to pointers; an <code>int* const</code> is a <code>const</code> pointer to a mutable <code>int</code>, and a <code>int const*</code> is a non-<code>const</code> pointer to a <code>const</code> <code>int</code>.</p>
<p >Use non-<code>const</code> views whenever possible. If you need thread-safety, work with view copies in threads; don't share.</p>
<h2><a class="anchor" id="autotoc_md22"></a>
View validity</h2>
<p >Any operation on the underlying range that invalidates its iterators or sentinels will also invalidate any view that refers to any part of that range. Additionally, some views (<em>e.g.</em>, <code>views::filter</code>), are invalidated when the underlying elements of the range are mutated. It is best to recreate a view after any operation that may have mutated the underlying range.</p>
<h2><a class="anchor" id="autotoc_md23"></a>
List of range views</h2>
<p >Below is a list of the lazy range combinators, or views, that Range-v3 provides, and a blurb about how each is intended to be used.</p>
<dl>
<dt><a class="el" href="structranges_1_1views_1_1addressof__fn.html"><code>views::addressof</code></a> </dt>
<dd>Given a source range of lvalue references, return a new view that is the result of taking <code>std::addressof</code> of each. </dd>
<dt><a class="el" href="structranges_1_1views_1_1adjacent__filter__fn.html"><code>views::adjacent_filter</code></a> </dt>
<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, <code>adjacent_filter</code> with <code>std::not_equal_to</code> filters out all the non-unique elements.) </dd>
<dt><a class="el" href="structranges_1_1views_1_1adjacent__remove__if__fn.html"><code>views::adjacent_remove_if</code></a> </dt>
<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>
<dt><a class="el" href="structranges_1_1views_1_1all__fn.html"><code>views::all</code></a> </dt>
<dd>Return a range containing all the elements in the source. Useful for converting containers to ranges. </dd>
<dt><a class="el" href="structranges_1_1any__view.html"><code>any_view&lt;T&gt;(rng)</code></a> </dt>
<dd>Type-erased range of elements with value type <code>T</code>; can store <em>any</em> range with this value type. </dd>
<dt><a class="el" href="structranges_1_1views_1_1c__str__fn.html"><code>views::c_str</code></a> </dt>
<dd>View a <code>\0</code>-terminated C string (e.g. from a <code>const char*</code>) as a range. </dd>
<dt><a class="el" href="structranges_1_1views_1_1cache1__fn.html"><code>views::cache1</code></a> </dt>
<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 <code>view::filter</code> and <code>view::transform</code>, for instance. <code>views::cache1</code> is always single-pass. </dd>
<dt><a class="el" href="structranges_1_1views_1_1cartesian__product__fn.html"><code>views::cartesian_product</code></a> </dt>
<dd>Enumerates the n-ary cartesian product of <code>n</code> ranges, i.e., generates all <code>n</code>-tuples <code>(e1, e2, ... , en)</code> where <code>e1</code> is an element of the first range, <code>e2</code> is an element of the second range, etc. </dd>
<dt><a class="el" href="structranges_1_1views_1_1chunk__fn.html"><code>views::chunk</code></a> </dt>
<dd>Given a source range and an integer <em>N</em>, produce a range of contiguous ranges where each inner range has <em>N</em> contiguous elements. The final range may have fewer than <em>N</em> elements. </dd>
<dt><a class="el" href="structranges_1_1views_1_1common__fn.html"><code>views::common</code></a> </dt>
<dd>Convert the source range to a <em>common</em> range, where the type of the <code>end</code> is the same as the <code>begin</code>. Useful for calling algorithms in the <code>std::</code> namespace. </dd>
<dt><a class="el" href="structranges_1_1views_1_1concat__fn.html"><code>views::concat</code></a> </dt>
<dd>Given <em>N</em> source ranges, produce a result range that is the concatenation of all of them. </dd>
<dt><a class="el" href="structranges_1_1views_1_1const__fn.html"><code>views::const_</code></a> </dt>
<dd>Present a <code>const</code> view of a source range. </dd>
<dt><a class="el" href="structranges_1_1views_1_1counted__fn.html"><code>views::counted</code></a> </dt>
<dd>Given an iterator <code>it</code> and a count <code>n</code>, create a range that starts at <code>it</code> and includes the next <code>n</code> elements. </dd>
<dt><a class="el" href="structranges_1_1views_1_1cycle__fn.html"><code>views::cycle</code></a> </dt>
<dd>Returns an infinite range that endlessly repeats the source range. </dd>
<dt><a class="el" href="structranges_1_1views_1_1delimit__fn.html"><code>views::delimit</code></a> </dt>
<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, <code>views::delimit</code> 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>
<dt><a class="el" href="structranges_1_1views_1_1drop__fn.html"><code>views::drop</code></a> </dt>
<dd>Given a source range and an integral count, return a range consisting of all but the first <em>count</em> elements from the source range, or an empty range if it has fewer elements. </dd>
<dt><a class="el" href="structranges_1_1views_1_1drop__last__fn.html"><code>views::drop_last</code></a> </dt>
<dd>Given a source range and an integral count, return a range consisting of all but the last <em>count</em> elements from the source range, or an empty range if it has fewer elements. </dd>
<dt><a class="el" href="structranges_1_1views_1_1drop__exactly__fn.html"><code>views::drop_exactly</code></a> </dt>
<dd>Given a source range and an integral count, return a range consisting of all but the first <em>count</em> elements from the source range. The source range must have at least that many elements. </dd>
<dt><a class="el" href="structranges_1_1views_1_1drop__while__fn.html"><code>views::drop_while</code></a> </dt>
<dd>Remove elements from the front of a range that satisfy a unary predicate. </dd>
<dt><a class="el" href="group__list.html#gae64f0978e680ad1a96438c0756b4644d"><code>views::empty</code></a> </dt>
<dd>Create an empty range with a given value type. </dd>
<dt><a class="el" href="group__group-iterator.html#gadbd40e512efd99a7fe289b5753d2be4e"><code>views::enumerate</code></a> </dt>
<dd>Pair each element of a range with its index. </dd>
<dt><a class="el" href="structranges_1_1views_1_1filter__fn.html"><code>views::filter</code></a> </dt>
<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 <code>filter</code> adaptor.) </dd>
<dt><a class="el" href="structranges_1_1views_1_1for__each__fn.html"><code>views::for_each</code></a> </dt>
<dd>Lazily applies an unary function to each element in the source range that returns another range (possibly empty), flattening the result. </dd>
<dt><a class="el" href="structranges_1_1views_1_1generate__fn.html"><code>views::generate</code></a> </dt>
<dd>Given a nullary function, return an infinite range whose elements are generated with the function. </dd>
<dt><a class="el" href="structranges_1_1views_1_1generate__n__fn.html"><code>views::generate_n</code></a> </dt>
<dd>Given a nullary function and a count, return a range that generates the requested number of elements by calling the function. </dd>
<dt><a class="el" href="structranges_1_1views_1_1chunk__by__fn.html"><code>views::chunk_by</code></a> </dt>
<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 previous element are passed to the binary predicate, the result is true. In essence, <code>views::chunk_by</code> groups contiguous elements together with a binary predicate. </dd>
<dt><a class="el" href=""><code>views::indirect</code></a> </dt>
<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>
<dt><a class="el" href="structranges_1_1views_1_1intersperse__fn.html"><code>views::intersperse</code></a> </dt>
<dd>Given a source range and a value, return a new range where the value is inserted between contiguous elements from the source. </dd>
<dt><a class="el" href="structranges_1_1views_1_1ints__fn.html"><code>views::ints</code></a> </dt>
<dd>Generate a range of monotonically increasing <code>int</code>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 <code>closed_ints</code>. </dd>
<dt><a class="el" href="structranges_1_1views_1_1iota__fn.html"><code>views::iota</code></a> </dt>
<dd>A generalization of <code>views::ints</code> 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>
<dt><a class="el" href="structranges_1_1views_1_1join__fn.html"><code>views::join</code></a> </dt>
<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>
<dt><a class="el" href="structranges_1_1views_1_1keys__fn.html"><code>views::keys</code></a> </dt>
<dd>Given a range of <code>pair</code>s (like a <code>std::map</code>), return a new range consisting of just the first element of the <code>pair</code>. </dd>
<dt><a class="el" href="structranges_1_1views_1_1linear__distribute__fn.html"><code>views::linear_distribute</code></a> </dt>
<dd>Distributes <code>n</code> values linearly in the closed interval <code>[from, to]</code> (the end points are always included). If <code>from == to</code>, returns <code>n</code>-times <code>to</code>, and if <code>n == 1</code> it returns <code>to</code>. </dd>
<dt><a class="el" href="structranges_1_1views_1_1move__fn.html"><code>views::move</code></a> </dt>
<dd>Given a source range, return a new range where each element has been cast to an rvalue reference. </dd>
<dt><a class="el" href="structranges_1_1views_1_1partial__sum__fn.html"><code>views::partial_sum</code></a> </dt>
<dd>Given a range and a binary function, return a new range where the <em>N</em><sup>th</sup> element is the result of applying the function to the <em>N</em><sup>th</sup> element from the source range and the (N-1)th element from the result range. </dd>
<dt><a class="el" href="structranges_1_1views_1_1remove__fn.html"><code>views::remove</code></a> </dt>
<dd>Given a source range and a value, filter out those elements that do not equal value. </dd>
<dt><a class="el" href="structranges_1_1views_1_1remove__if__fn.html"><code>views::remove_if</code></a> </dt>
<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 <code>filter</code> adaptor with the predicate negated.) </dd>
<dt><a class="el" href="structranges_1_1views_1_1repeat__fn.html"><code>views::repeat</code></a> </dt>
<dd>Given a value, create a range that is that value repeated infinitely. </dd>
<dt><a class="el" href="structranges_1_1views_1_1repeat__n__fn.html"><code>views::repeat_n</code></a> </dt>
<dd>Given a value and a count, create a range that is that value repeated <em>count</em> number of times. </dd>
<dt><a class="el" href="structranges_1_1views_1_1replace__fn.html"><code>views::replace</code></a> </dt>
<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>
<dt><a class="el" href="structranges_1_1views_1_1replace__if__fn.html"><code>views::replace_if</code></a> </dt>
<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>
<dt><a class="el" href="structranges_1_1views_1_1reverse__fn.html"><code>views::reverse</code></a> </dt>
<dd>Create a new range that traverses the source range in reverse order. </dd>
<dt><a class="el" href="structranges_1_1views_1_1sample__fn.html"><code>views::sample</code></a> </dt>
<dd>Returns a random sample of a range of length <code>size(range)</code>. </dd>
<dt><a class="el" href="structranges_1_1views_1_1single__fn.html"><code>views::single</code></a> </dt>
<dd>Given a value, create a range with exactly one element. </dd>
<dt><a class="el" href="structranges_1_1views_1_1slice__fn.html"><code>views::slice</code></a> </dt>
<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>
<dt><a class="el" href="structranges_1_1views_1_1sliding__fn.html"><code>views::sliding</code></a> </dt>
<dd>Given a range and a count <code>n</code>, place a window over the first <code>n</code> 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>
<dt><a class="el" href="structranges_1_1views_1_1split__fn.html"><code>views::split</code></a> </dt>
<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>
<dt><a class="el" href="structranges_1_1views_1_1split__when__fn.html"><code>views::split_when</code></a> </dt>
<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 <code>true</code> 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 <code>std::make_pair(true, iterator_past_the_delimiter)</code> if the current position is a boundary; otherwise <code>std::make_pair(false, ignored_iterator_value)</code>. The elements matching the delimiter are excluded from the resulting range of ranges. </dd>
<dt><a class="el" href="structranges_1_1views_1_1stride__fn.html"><code>views::stride</code></a> </dt>
<dd>Given a source range and an integral stride value, return a range consisting of every <em>N</em><sup>th</sup> element, starting with the first. </dd>
<dt><a class="el" href="structranges_1_1views_1_1tail__fn.html"><code>views::tail</code></a> </dt>
<dd>Given a source range, return a new range without the first element. The range must have at least one element. </dd>
<dt><a class="el" href="structranges_1_1views_1_1take__fn.html"><code>views::take</code></a> </dt>
<dd>Given a source range and an integral count, return a range consisting of the first <em>count</em> elements from the source range, or the complete range if it has fewer elements. (The result of <code>views::take</code> is not a <code>sized_range</code>.) </dd>
<dt><a class="el" href="structranges_1_1views_1_1take__exactly__fn.html"><code>views::take_exactly</code></a> </dt>
<dd>Given a source range and an integral count, return a range consisting of the first <em>count</em> elements from the source range. The source range must have at least that many elements. (The result of <code>views::take_exactly</code> is a <code>sized_range</code>.) </dd>
<dt><a class="el" href="structranges_1_1views_1_1take__last__fn.html"><code>views::take_last</code></a> </dt>
<dd>Given a source range and an integral count, return a range consisting of the last <em>count</em> elements from the source range. The source range must be a <code>sized_range</code>. If the source range does not have at least <em>count</em> elements, the full range is returned. </dd>
<dt><a class="el" href="structranges_1_1views_1_1take__while__fn.html"><code>views::take_while</code></a> </dt>
<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>
<dt><a class="el" href="structranges_1_1views_1_1tokenize__fn.html"><code>views::tokenize</code></a> </dt>
<dd>Given a source range and optionally a submatch specifier and a <code>std::regex_constants::match_flag_type</code>, return a <code>std::regex_token_iterator</code> to step through the regex submatches of the source range. The submatch specifier may be either a plain <code>int</code>, a <code>std::vector&lt;int&gt;</code>, or a <code>std::initializer_list&lt;int&gt;</code>. </dd>
<dt><a class="el" href="structranges_1_1views_1_1transform__fn.html"><code>views::transform</code></a> </dt>
<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>
<dt><a class="el" href="structranges_1_1views_1_1trim__fn.html"><code>views::trim</code></a> </dt>
<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>
<dt><a class="el" href="structranges_1_1views_1_1unbounded__fn.html"><code>views::unbounded</code></a> </dt>
<dd>Given an iterator, return an infinite range that begins at that position. </dd>
<dt><a class="el" href="structranges_1_1views_1_1unique__fn.html"><code>views::unique</code></a> </dt>
<dd>Given a range, return a new range where all consecutive elements that compare equal save the first have been filtered out. </dd>
<dt><a class="el" href="structranges_1_1views_1_1values__fn.html"><code>views::values</code></a> </dt>
<dd>Given a range of <code>pair</code>s (like a <code>std::map</code>), return a new range consisting of just the second element of the <code>pair</code>. </dd>
<dt><a class="el" href="structranges_1_1views_1_1zip__fn.html"><code>views::zip</code></a> </dt>
<dd>Given <em>N</em> ranges, return a new range where <em>M</em><sup>th</sup> element is the result of calling <code>make_tuple</code> on the <em>M</em><sup>th</sup> elements of all <em>N</em> ranges. </dd>
<dt><a class="el" href="structranges_1_1views_1_1zip__with__fn.html"><code>views::zip_with</code></a> </dt>
<dd>Given <em>N</em> ranges and a <em>N</em>-ary function, return a new range where <em>M</em><sup>th</sup> element is the result of calling the function on the <em>M</em><sup>th</sup> elements of all <em>N</em> ranges. </dd>
</dl>
<h2><a class="anchor" id="tutorial-actions"></a>
Actions</h2>
<hr />
<p> When you want to mutate a container in-place, or forward it through a chain of mutating operations, you can use actions. The following examples should make it clear.</p>
<p >Read data into a vector, sort it, and make it unique.</p>
<div class="fragment"><div class="line"><span class="keyword">extern</span> std::vector&lt;int&gt; read_data();</div>
<div class="line"><span class="keyword">using namespace </span>ranges;</div>
<div class="line">std::vector&lt;int&gt; vi = read_data() | <a class="code hl_typedef" href="group__transformation.html#ga24714e0a1e7b99a57052a63d815955a7">actions::sort</a> | <a class="code hl_variable" href="action_2unique_8hpp.html#a2df52ed5e91e92ea7d2d7b1ed5408fcf">actions::unique</a>;</div>
</div><!-- fragment --><p >Do the same to a <code>vector</code> that already contains some data:</p>
<div class="fragment"><div class="line">vi = <a class="code hl_variable" href="group__group-utility.html#ga20b5b25347e7f8173b2118fdb5ea5f58">std::move</a>(vi) | <a class="code hl_typedef" href="group__transformation.html#ga24714e0a1e7b99a57052a63d815955a7">actions::sort</a> | <a class="code hl_variable" href="action_2unique_8hpp.html#a2df52ed5e91e92ea7d2d7b1ed5408fcf">actions::unique</a>;</div>
<div class="ttc" id="agroup__group-utility_html_ga20b5b25347e7f8173b2118fdb5ea5f58"><div class="ttname"><a href="group__group-utility.html#ga20b5b25347e7f8173b2118fdb5ea5f58">ranges::aux::move</a></div><div class="ttdeci">constexpr move_fn move</div><div class="ttdef"><b>Definition:</b> move.hpp:52</div></div>
</div><!-- fragment --><p >Mutate the container in-place:</p>
<div class="fragment"><div class="line">vi |= <a class="code hl_typedef" href="group__transformation.html#ga24714e0a1e7b99a57052a63d815955a7">actions::sort</a> | <a class="code hl_variable" href="action_2unique_8hpp.html#a2df52ed5e91e92ea7d2d7b1ed5408fcf">actions::unique</a>;</div>
</div><!-- fragment --><p >Same as above, but with function-call syntax instead of pipe syntax:</p>
<div class="fragment"><div class="line"><a class="code hl_variable" href="action_2unique_8hpp.html#a2df52ed5e91e92ea7d2d7b1ed5408fcf">actions::unique</a>(<a class="code hl_typedef" href="group__transformation.html#ga24714e0a1e7b99a57052a63d815955a7">actions::sort</a>(vi));</div>
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md25"></a>
List of range actions</h2>
<p >Below is a list of the eager range combinators, or actions, that Range-v3 provides, and a blurb about how each is intended to be used.</p>
<dl>
<dt><a class="el" href="structranges_1_1actions_1_1drop__fn.html"><code>actions::drop</code></a> </dt>
<dd>Removes the first <code>N</code> elements of the source range. </dd>
<dt><a class="el" href="structranges_1_1actions_1_1drop__while__fn.html"><code>actions::drop_while</code></a> </dt>
<dd>Removes the first elements of the source range that satisfy the unary predicate. </dd>
<dt><code>actions::erase</code> </dt>
<dd>Removes all elements in the sub-range of the source (range version) or all elements after position. </dd>
<dt><code>actions::insert</code> </dt>
<dd>Inserts all elements of the range into the source at position. </dd>
<dt><a class="el" href="structranges_1_1actions_1_1join__fn.html"><code>actions::join</code></a> </dt>
<dd>Flattens a range of ranges. </dd>
<dt><code>actions::push_back</code> </dt>
<dd>Appends elements to the tail of the source. </dd>
<dt><code>actions::push_front</code> </dt>
<dd>Appends elements before the head of the source. </dd>
<dt><a class="el" href="structranges_1_1actions_1_1remove__if__fn.html"><code>actions::remove_if</code></a> </dt>
<dd>Removes all elements from the source that satisfy the predicate. </dd>
<dt><a class="el" href="structranges_1_1actions_1_1remove__fn.html"><code>actions::remove</code></a> </dt>
<dd>Removes all elements from the source that are equal to value. </dd>
<dt><a class="el" href="structranges_1_1actions_1_1reverse__fn.html"><code>actions::reverse</code></a> </dt>
<dd>Reverses all the elements in the container. </dd>
<dt><a class="el" href="structranges_1_1actions_1_1shuffle__fn.html"><code>actions::shuffle</code></a> </dt>
<dd>Shuffles the source range. </dd>
<dt><a class="el" href="structranges_1_1actions_1_1slice__fn.html"><code>actions::slice</code></a> </dt>
<dd>Removes all elements from the source that are not part of the sub-range. </dd>
<dt><a class="el" href="structranges_1_1actions_1_1sort__fn.html"><code>actions::sort</code></a> </dt>
<dd>Sorts the source range (unstable). </dd>
<dt><a class="el" href="structranges_1_1actions_1_1split__fn.html"><code>actions::split</code></a> </dt>
<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 <code>pair&lt;bool, N&gt;</code>). </dd>
<dt><a class="el" href="structranges_1_1actions_1_1stable__sort__fn.html"><code>actions::stable_sort</code></a> </dt>
<dd>Sorts the source range (stable). </dd>
<dt><a class="el" href="structranges_1_1actions_1_1stride__fn.html"><code>actions::stride</code></a> </dt>
<dd>Removes all elements whose position does not match the stride. </dd>
<dt><a class="el" href="structranges_1_1actions_1_1take__fn.html"><code>actions::take</code></a> </dt>
<dd>Keeps the first <code>N</code>-th elements of the range, removes the rest. </dd>
<dt><a class="el" href="structranges_1_1actions_1_1take__while__fn.html"><code>actions::take_while</code></a> </dt>
<dd>Keeps the first elements that satisfy the predicate, removes the rest. </dd>
<dt><a class="el" href="structranges_1_1actions_1_1transform__fn.html"><code>actions::transform</code></a> </dt>
<dd>Replaces elements of the source with the result of the unary function. </dd>
<dt><a class="el" href="structranges_1_1actions_1_1unique__fn.html"><code>actions::unique</code></a> </dt>
<dd>Removes adjacent elements of the source that compare equal. If the source is sorted, removes all duplicate elements. </dd>
<dt><a class="el" href="structranges_1_1actions_1_1unstable__remove__if__fn.html"><code>actions::unstable_remove_if</code></a> </dt>
<dd>Much faster (each element remove has constant time complexity), unordered version of <code>remove_if</code>. Requires bidirectional container. </dd>
</dl>
<h2><a class="anchor" id="tutorial-utilities"></a>
Utilities</h2>
<hr />
<p> Below we cover some utilities that range-v3 provides for creating your own view adaptors and iterators.</p>
<h3><a class="anchor" id="autotoc_md27"></a>
Create Custom Views with view_facade</h3>
<p >Range-v3 provides a utility for easily creating your own range types, called <a class="el" href="structranges_1_1view__facade.html"><code>ranges::view_facade</code></a>. The code below uses <code>view_facade</code> to create a range that traverses a null-terminated string:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="facade_8hpp.html">range/v3/view/facade.hpp</a>&gt;</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// A range that iterates over all the characters in a</span></div>
<div class="line"><span class="comment">// null-terminated string.</span></div>
<div class="line"><span class="keyword">class </span>c_string_range</div>
<div class="line"> : <span class="keyword">public</span> <a class="code hl_struct" href="structranges_1_1view__facade.html">ranges::view_facade</a>&lt;c_string_range&gt;</div>
<div class="line">{</div>
<div class="line"> <span class="keyword">friend</span> ranges::range_access;</div>
<div class="line"> <span class="keywordtype">char</span> <span class="keyword">const</span> * sz_ = <span class="stringliteral">&quot;&quot;</span>;</div>
<div class="line"> <span class="keywordtype">char</span> <span class="keyword">const</span> &amp; read()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> *sz_; }</div>
<div class="line"> <span class="keywordtype">bool</span> <a class="code hl_function" href="group__group-algorithms.html#gad02116ac1a7f39cc324dd959e9c1d1de">equal</a>(<a class="code hl_struct" href="structranges_1_1default__sentinel__t.html">ranges::default_sentinel_t</a>)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> *sz_ == <span class="charliteral">&#39;\0&#39;</span>; }</div>
<div class="line"> <span class="keywordtype">void</span> <a class="code hl_variable" href="group__group-iterator.html#gaf136ff254688f2c24f5c5f58df7ff56d">next</a>() { ++sz_; }</div>
<div class="line"><span class="keyword">public</span>:</div>
<div class="line"> c_string_range() = <span class="keywordflow">default</span>;</div>
<div class="line"> <span class="keyword">explicit</span> c_string_range(<span class="keywordtype">char</span> <span class="keyword">const</span> *sz) : sz_(sz)</div>
<div class="line"> {</div>
<div class="line"> assert(sz != <span class="keyword">nullptr</span>);</div>
<div class="line"> }</div>
<div class="line">};</div>
<div class="ttc" id="afacade_8hpp_html"><div class="ttname"><a href="facade_8hpp.html">facade.hpp</a></div></div>
<div class="ttc" id="agroup__group-algorithms_html_gad02116ac1a7f39cc324dd959e9c1d1de"><div class="ttname"><a href="group__group-algorithms.html#gad02116ac1a7f39cc324dd959e9c1d1de">ranges::equal</a></div><div class="ttdeci">constexpr bool equal(I0 begin0, S0 end0, I1 begin1, C pred=C{}, P0 proj0=P0{}, P1 proj1=P1{})</div><div class="ttdoc">function template equal</div><div class="ttdef"><b>Definition:</b> equal.hpp:66</div></div>
<div class="ttc" id="agroup__group-iterator_html_gaf136ff254688f2c24f5c5f58df7ff56d"><div class="ttname"><a href="group__group-iterator.html#gaf136ff254688f2c24f5c5f58df7ff56d">ranges::next</a></div><div class="ttdeci">constexpr next_fn next</div><div class="ttdef"><b>Definition:</b> operations.hpp:316</div></div>
<div class="ttc" id="astructranges_1_1default__sentinel__t_html"><div class="ttname"><a href="structranges_1_1default__sentinel__t.html">ranges::default_sentinel_t</a></div><div class="ttdef"><b>Definition:</b> default_sentinel.hpp:26</div></div>
<div class="ttc" id="astructranges_1_1view__facade_html"><div class="ttname"><a href="structranges_1_1view__facade.html">ranges::view_facade</a></div><div class="ttdoc">A utility for constructing a view from a (derived) type that implements begin and end cursors.</div><div class="ttdef"><b>Definition:</b> facade.hpp:66</div></div>
</div><!-- fragment --><p >The <code>view_facade</code> class generates an iterator and begin/end member functions from the minimal interface provided by <code>c_string_range</code>. This is an example of a very simple range for which it is not necessary to separate the range itself from the thing that iterates the range. Future examples will show examples of more sophisticated ranges.</p>
<p >With <code>c_string_range</code>, you can now use algorithms to operate on null-terminated strings, as below:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div>
<div class="line"><span class="preprocessor">#include &lt;<a class="code" href="algorithm_2for__each_8hpp.html">range/v3/algorithm/for_each.hpp</a>&gt;</span></div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">int</span> main()</div>
<div class="line">{</div>
<div class="line"> c_string_range r(<span class="stringliteral">&quot;hello world&quot;</span>);</div>
<div class="line"> <span class="comment">// Iterate over all the characters and print them out</span></div>
<div class="line"> <a class="code hl_variable" href="group__runtime.html#ga8beaba5ae537715c97e180b05160cc03">ranges::for_each</a>(r, [](<span class="keywordtype">char</span> ch){</div>
<div class="line"> std::cout &lt;&lt; ch &lt;&lt; <span class="charliteral">&#39; &#39;</span>;</div>
<div class="line"> });</div>
<div class="line"> <span class="comment">// prints: h e l l o w o r l d</span></div>
<div class="line">}</div>
<div class="ttc" id="aalgorithm_2for__each_8hpp_html"><div class="ttname"><a href="algorithm_2for__each_8hpp.html">for_each.hpp</a></div></div>
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md28"></a>
Create Custom Views with view_adaptor</h3>
<p >Often, a new range type is most easily expressed by adapting an existing range type. That's the case for many of the range views provided by the Range-v3 library; for example, the <code>views::remove_if</code> and <code>views::transform</code> views. These are rich types with many moving parts, but thanks to a helper class called <a class="el" href="structranges_1_1view__adaptor.html"><code>ranges::view_adaptor</code></a>, they aren't hard to write.</p>
<p >Below in roughly 2 dozen lines of code is the <code>transform</code> view, which takes one range and transforms all the elements with a unary function.</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="adaptor_8hpp.html">range/v3/view/adaptor.hpp</a>&gt;</span></div>
<div class="line"><span class="preprocessor">#include &lt;<a class="code" href="semiregular__box_8hpp.html">range/v3/utility/semiregular_box.hpp</a>&gt;</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// A class that adapts an existing range with a function</span></div>
<div class="line"><span class="keyword">template</span>&lt;<span class="keyword">class</span> Rng, <span class="keyword">class</span> Fun&gt;</div>
<div class="line"><span class="keyword">class </span><a class="code hl_struct" href="structranges_1_1transform__view.html">transform_view</a></div>
<div class="line"> : <span class="keyword">public</span> <a class="code hl_struct" href="structranges_1_1view__adaptor.html">ranges::view_adaptor</a>&lt;transform_view&lt;Rng, Fun&gt;, Rng&gt;</div>
<div class="line">{</div>
<div class="line"> <span class="keyword">friend</span> ranges::range_access;</div>
<div class="line"> ranges::semiregular_box_t&lt;Fun&gt; fun_; <span class="comment">// Make Fun model semiregular if it doesn&#39;t</span></div>
<div class="line"> <span class="keyword">class </span>adaptor : <span class="keyword">public</span> <a class="code hl_struct" href="structranges_1_1adaptor__base.html">ranges::adaptor_base</a></div>
<div class="line"> {</div>
<div class="line"> ranges::semiregular_box_t&lt;Fun&gt; fun_;</div>
<div class="line"> <span class="keyword">public</span>:</div>
<div class="line"> adaptor() = <span class="keywordflow">default</span>;</div>
<div class="line"> adaptor(ranges::semiregular_box_t&lt;Fun&gt; <span class="keyword">const</span> &amp;fun) : fun_(fun) {}</div>
<div class="line"> <span class="comment">// Here is where we apply Fun to the elements:</span></div>
<div class="line"> <span class="keyword">auto</span> read(ranges::iterator_t&lt;Rng&gt; it) <span class="keyword">const</span> -&gt; <span class="keyword">decltype</span>(fun_(*it))</div>
<div class="line"> {</div>
<div class="line"> <span class="keywordflow">return</span> fun_(*it);</div>
<div class="line"> }</div>
<div class="line"> };</div>
<div class="line"> adaptor begin_adaptor()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> {fun_}; }</div>
<div class="line"> adaptor end_adaptor()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> {fun_}; }</div>
<div class="line"><span class="keyword">public</span>:</div>
<div class="line"> <a class="code hl_struct" href="structranges_1_1transform__view.html">transform_view</a>() = <span class="keywordflow">default</span>;</div>
<div class="line"> <a class="code hl_struct" href="structranges_1_1transform__view.html">transform_view</a>(Rng &amp;&amp; rng, Fun fun)</div>
<div class="line"> : <a class="code hl_struct" href="structranges_1_1transform__view.html">transform_view</a>::<a class="code hl_struct" href="structranges_1_1view__adaptor.html">view_adaptor</a>{<a class="code hl_namespace" href="namespacestd.html">std</a>::<a class="code hl_enumvalue" href="any__view_8hpp.html#a37595c031f4d0249cede2046f4254c93a965dbaac085fc891bfbbd4f9d145bbc8">forward</a>&lt;Rng&gt;(rng)}</div>
<div class="line"> , fun_(<a class="code hl_namespace" href="namespacestd.html">std</a>::<a class="code hl_variable" href="group__group-utility.html#ga20b5b25347e7f8173b2118fdb5ea5f58">move</a>(fun))</div>
<div class="line"> {}</div>
<div class="line">};</div>
<div class="line"> </div>
<div class="line"><span class="keyword">template</span>&lt;<span class="keyword">class</span> Rng, <span class="keyword">class</span> Fun&gt;</div>
<div class="line"><a class="code hl_struct" href="structranges_1_1transform__view.html">transform_view&lt;Rng, Fun&gt;</a> <a class="code hl_typedef" href="group__transformation.html#ga32b72eeac93fde990739bfe3d1729207">transform</a>(Rng &amp;&amp; rng, Fun fun)</div>
<div class="line">{</div>
<div class="line"> <span class="keywordflow">return</span> {std::forward&lt;Rng&gt;(rng), <a class="code hl_variable" href="group__group-utility.html#ga20b5b25347e7f8173b2118fdb5ea5f58">std::move</a>(fun)};</div>
<div class="line">}</div>
<div class="ttc" id="aadaptor_8hpp_html"><div class="ttname"><a href="adaptor_8hpp.html">adaptor.hpp</a></div></div>
<div class="ttc" id="aany__view_8hpp_html_a37595c031f4d0249cede2046f4254c93a965dbaac085fc891bfbbd4f9d145bbc8"><div class="ttname"><a href="any__view_8hpp.html#a37595c031f4d0249cede2046f4254c93a965dbaac085fc891bfbbd4f9d145bbc8">ranges::category::forward</a></div><div class="ttdeci">@ forward</div><div class="ttdoc">satisfies ranges::concepts::forward_range</div></div>
<div class="ttc" id="anamespacestd_html"><div class="ttname"><a href="namespacestd.html">std</a></div><div class="ttdoc">STL namespace.</div></div>
<div class="ttc" id="asemiregular__box_8hpp_html"><div class="ttname"><a href="semiregular__box_8hpp.html">semiregular_box.hpp</a></div></div>
<div class="ttc" id="astructranges_1_1adaptor__base_html"><div class="ttname"><a href="structranges_1_1adaptor__base.html">ranges::adaptor_base</a></div><div class="ttdef"><b>Definition:</b> adaptor.hpp:110</div></div>
<div class="ttc" id="astructranges_1_1transform__view_html"><div class="ttname"><a href="structranges_1_1transform__view.html">ranges::transform_view</a></div><div class="ttdef"><b>Definition:</b> transform.hpp:187</div></div>
<div class="ttc" id="astructranges_1_1view__adaptor_html"><div class="ttname"><a href="structranges_1_1view__adaptor.html">ranges::view_adaptor</a></div><div class="ttdef"><b>Definition:</b> adaptor.hpp:451</div></div>
</div><!-- fragment --><p >Range transformation is achieved by defining a nested <code>adaptor</code> class that handles the transformation, and then defining <code>begin_adaptor</code> and <code>end_adaptor</code> members that return adaptors for the begin iterator and the end sentinel, respectively. The <code>adaptor</code> class has a <code>read</code> member that performs the transformation. It is passed an iterator to the current element. Other members are available for customization: <code>equal</code>, <code>next</code>, <code>prev</code>, <code>advance</code>, and <code>distance_to</code>; but the transform adaptor accepts the defaults defined in <a class="el" href="structranges_1_1adaptor__base.html"><code>ranges::adaptor_base</code></a>.</p>
<p >With <code>transform_view</code>, we can print out the first 20 squares:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> main()</div>
<div class="line">{</div>
<div class="line"> <span class="keyword">auto</span> squares = <a class="code hl_typedef" href="group__transformation.html#ga32b72eeac93fde990739bfe3d1729207">::transform</a>(views::ints(1), [](<span class="keywordtype">int</span> i){<span class="keywordflow">return</span> i*i;});</div>
<div class="line"> <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i : squares | views::take(20))</div>
<div class="line"> std::cout &lt;&lt; i &lt;&lt; <span class="charliteral">&#39; &#39;</span>;</div>
<div class="line"> std::cout &lt;&lt; <span class="charliteral">&#39;\n&#39;</span>;</div>
<div class="line"> <span class="comment">// prints 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 400</span></div>
<div class="line">}</div>
</div><!-- fragment --><p >The <code>transform_view</code> defined above is an input range when it is wrapping an input range, a forward range when it's wrapping a forward range, etc. That happens because of smart defaults defined in the <code>adaptor_base</code> class that frees you from having to deal with a host of niggly detail when implementing iterators.</p>
<p >*(Note: the above <code>transform_view</code> always stores a copy of the function in the sentinel. That is only necessary if the underlying range's sentinel type models bidirectional_iterator. That's a finer point that you shouldn't worry about right now.)*</p>
<h4><a class="anchor" id="autotoc_md29"></a>
view_adaptor in details</h4>
<p >Each <code>view_adaptor</code> contains <code>base()</code> member in view and iterator. <code>base()</code> - allow to access "adapted" range/iterator:</p>
<div class="fragment"><div class="line">std::vector&lt;int&gt; vec;</div>
<div class="line"><span class="keyword">auto</span> list = vec | views::transfom([](<span class="keywordtype">int</span> i){ <span class="keywordflow">return</span> i+1; });</div>
<div class="line"> </div>
<div class="line">assert( vec.begin() == list.begin().base() );</div>
<div class="line">assert( vec.begin() == list.base().begin() );</div>
</div><!-- fragment --><p >Like <code>basic_iterator</code>'s <code>cursor</code>, <code>view_adaptor</code>'s <code>adaptor</code> can contain mixin class too, to inject things into the public interface of the iterator:</p>
<div class="fragment"><div class="line"><span class="keyword">class </span>adaptor : <span class="keyword">public</span> <a class="code hl_struct" href="structranges_1_1adaptor__base.html">ranges::adaptor_base</a></div>
<div class="line">{</div>
<div class="line"> <span class="keyword">template</span>&lt;<span class="keyword">class</span> BaseMixin&gt;</div>
<div class="line"> <span class="keyword">struct </span>mixin : BaseMixin</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// everything inside this class will be accessible from iterator</span></div>
<div class="line"> <span class="keyword">using </span>BaseMixin::BaseMixin;</div>
<div class="line"> </div>
<div class="line"> <span class="keyword">auto</span>&amp; base_value()<span class="keyword"> const</span></div>
<div class="line"><span class="keyword"> </span>{</div>
<div class="line"> <span class="keywordflow">return</span> *this-&gt;base();</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keywordtype">int</span> get_i()<span class="keyword"> const</span></div>
<div class="line"><span class="keyword"> </span>{</div>
<div class="line"> <span class="keywordflow">return</span> this-&gt;get().i;</div>
<div class="line"> }</div>
<div class="line"> };</div>
<div class="line"> </div>
<div class="line"> <span class="keywordtype">int</span> i = 100;</div>
<div class="line">};</div>
</div><!-- fragment --><p >From within mixin you can call:</p>
<ul>
<li><code>get()</code> - to access adaptor internals</li>
<li><code>base()</code> - to access adaptable iterator</li>
</ul>
<p >Iterator/sentinel adaptor may "override" the following members:</p>
<div class="fragment"><div class="line"><span class="keyword">class </span>adaptor : <span class="keyword">public</span> <a class="code hl_struct" href="structranges_1_1adaptor__base.html">ranges::adaptor_base</a></div>
<div class="line">{</div>
<div class="line"> <span class="comment">// !For begin_adaptor only!</span></div>
<div class="line"> <span class="keyword">template</span>&lt;<span class="keyword">typename</span> Rng&gt;</div>
<div class="line"> <span class="keyword">constexpr</span> <span class="keyword">auto</span> <a class="code hl_variable" href="group__group-range.html#ga446b20253a26c93ef3004fcbfcbf3ec3">begin</a>(Rng &amp;rng)</div>
<div class="line"> {</div>
<div class="line"> <span class="keywordflow">return</span> <a class="code hl_variable" href="group__group-range.html#ga446b20253a26c93ef3004fcbfcbf3ec3">ranges::begin</a>(rng.base());</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// !For end_adaptor only!</span></div>
<div class="line"> <span class="keyword">template</span>&lt;<span class="keyword">typename</span> Rng&gt;</div>
<div class="line"> <span class="keyword">constexpr</span> <span class="keyword">auto</span> <a class="code hl_variable" href="group__group-range.html#ga80d92c391f5b5c0a50156af5f9c9d8c7">end</a>(Rng &amp;rng)</div>
<div class="line"> {</div>
<div class="line"> <span class="keywordflow">return</span> <a class="code hl_variable" href="group__group-range.html#ga80d92c391f5b5c0a50156af5f9c9d8c7">ranges::end</a>(rng.base());</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keyword">template</span>&lt;<span class="keyword">typename</span> I&gt;</div>
<div class="line"> <span class="keywordtype">bool</span> <a class="code hl_function" href="group__group-algorithms.html#gad02116ac1a7f39cc324dd959e9c1d1de">equal</a>(I <span class="keyword">const</span> &amp;this_iter, I <span class="keyword">const</span> &amp;that_iter)<span class="keyword"> const</span></div>
<div class="line"><span class="keyword"> </span>{</div>
<div class="line"> <span class="keywordflow">return</span> this_iter == that_iter;</div>
<div class="line"> }</div>
<div class="line"> <span class="comment">// or</span></div>
<div class="line"> <span class="keyword">template</span>&lt;<span class="keyword">typename</span> I&gt;</div>
<div class="line"> <span class="keywordtype">bool</span> <a class="code hl_function" href="group__group-algorithms.html#gad02116ac1a7f39cc324dd959e9c1d1de">equal</a>(I <span class="keyword">const</span> &amp;this_iter, I <span class="keyword">const</span> &amp;that_iter, adaptor <span class="keyword">const</span> &amp;that_adapt)<span class="keyword"> const</span></div>
<div class="line"><span class="keyword"> </span>{</div>
<div class="line"> <span class="keywordflow">return</span></div>
<div class="line"> *this.some_value == that_adapt.some_value</div>
<div class="line"> &amp;&amp; this_iter == that_iter;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// !For end_adaptor only!</span></div>
<div class="line"> <span class="comment">// Same as equal, but compare iterator with sentinel.</span></div>
<div class="line"> <span class="comment">// Not used, if iterator same as sentinel, and both have the same adaptor.</span></div>
<div class="line"> <span class="keyword">template</span>&lt;<span class="keyword">typename</span> I, <span class="keyword">typename</span> S&gt;</div>
<div class="line"> <span class="keyword">constexpr</span> <span class="keywordtype">bool</span> <a class="code hl_typedef" href="group__list.html#gae64f0978e680ad1a96438c0756b4644d">empty</a>(I <span class="keyword">const</span> &amp;it, S <span class="keyword">const</span> &amp;<a class="code hl_variable" href="group__group-range.html#ga80d92c391f5b5c0a50156af5f9c9d8c7">end</a>)<span class="keyword"> const</span></div>
<div class="line"><span class="keyword"> </span>{</div>
<div class="line"> <span class="keywordflow">return</span> it == <a class="code hl_variable" href="group__group-range.html#ga80d92c391f5b5c0a50156af5f9c9d8c7">end</a>;</div>
<div class="line"> }</div>
<div class="line"> <span class="comment">// or</span></div>
<div class="line"> <span class="keyword">template</span>&lt;<span class="keyword">typename</span> I, <span class="keyword">typename</span> S, <span class="keyword">typename</span> SA&gt;</div>
<div class="line"> <span class="keyword">constexpr</span> <span class="keywordtype">bool</span> <a class="code hl_typedef" href="group__list.html#gae64f0978e680ad1a96438c0756b4644d">empty</a>(I <span class="keyword">const</span> &amp;it, S <span class="keyword">const</span> &amp;<a class="code hl_variable" href="group__group-range.html#ga80d92c391f5b5c0a50156af5f9c9d8c7">end</a>, SA <span class="keyword">const</span> &amp;end_adapt)<span class="keyword"> const</span></div>
<div class="line"><span class="keyword"> </span>{</div>
<div class="line"> <span class="keywordflow">return</span></div>
<div class="line"> *this.some_value == end_adapt.some_value</div>
<div class="line"> &amp;&amp; it == <a class="code hl_variable" href="group__group-range.html#ga80d92c391f5b5c0a50156af5f9c9d8c7">end</a>;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keyword">template</span>&lt;<span class="keyword">typename</span> I&gt;</div>
<div class="line"> reference_t&lt;I&gt; read(I <span class="keyword">const</span> &amp;it)</div>
<div class="line"> {</div>
<div class="line"> <span class="keywordflow">return</span> *it;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keyword">template</span>&lt;<span class="keyword">typename</span> I&gt;</div>
<div class="line"> <span class="keywordtype">void</span> <a class="code hl_variable" href="group__group-iterator.html#gaf136ff254688f2c24f5c5f58df7ff56d">next</a>(I &amp;it)</div>
<div class="line"> {</div>
<div class="line"> ++it;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// !For bidirectional iterator only!</span></div>
<div class="line"> <span class="keyword">template</span>&lt;<span class="keyword">typename</span> I&gt;</div>
<div class="line"> <span class="keywordtype">void</span> <a class="code hl_variable" href="group__group-iterator.html#gaa5307b0c95d051483a41d4870d65f680">prev</a>(I &amp;it)</div>
<div class="line"> {</div>
<div class="line"> --it;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// !For random access iterator only!</span></div>
<div class="line"> <span class="keyword">template</span>&lt;<span class="keyword">typename</span> I&gt;</div>
<div class="line"> <span class="keywordtype">void</span> <a class="code hl_variable" href="group__group-iterator.html#gaaa3dec40e11c4913663b033a3e98108f">advance</a>(I &amp;it, difference_type_t&lt;I&gt; n)</div>
<div class="line"> {</div>
<div class="line"> it += n;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// !For &quot;sized&quot; iterators only!</span></div>
<div class="line"> <span class="keyword">template</span>&lt;<span class="keyword">typename</span> I&gt;</div>
<div class="line"> difference_type_t&lt;I&gt; distance_to(I <span class="keyword">const</span> &amp;this_iter, I <span class="keyword">const</span> &amp;that_iter)</div>
<div class="line"> {</div>
<div class="line"> <span class="keywordflow">return</span> that_iter - this_iter;</div>
<div class="line"> }</div>
<div class="line"> <span class="comment">// or</span></div>
<div class="line"> <span class="keyword">template</span>&lt;<span class="keyword">typename</span> I&gt;</div>
<div class="line"> difference_type_t&lt;I&gt; distance_to</div>
<div class="line"> (I <span class="keyword">const</span> &amp;this_iter, I <span class="keyword">const</span> &amp;that_iter, adaptor <span class="keyword">const</span> &amp;that_adapt)</div>
<div class="line"> {</div>
<div class="line"> <span class="keywordflow">return</span> that_iter - this_iter;</div>
<div class="line"> }</div>
<div class="line">}</div>
<div class="ttc" id="agroup__group-iterator_html_gaa5307b0c95d051483a41d4870d65f680"><div class="ttname"><a href="group__group-iterator.html#gaa5307b0c95d051483a41d4870d65f680">ranges::prev</a></div><div class="ttdeci">constexpr prev_fn prev</div><div class="ttdef"><b>Definition:</b> operations.hpp:337</div></div>
<div class="ttc" id="agroup__group-iterator_html_gaaa3dec40e11c4913663b033a3e98108f"><div class="ttname"><a href="group__group-iterator.html#gaaa3dec40e11c4913663b033a3e98108f">ranges::advance</a></div><div class="ttdeci">constexpr advance_fn advance</div><div class="ttdef"><b>Definition:</b> operations.hpp:198</div></div>
<div class="ttc" id="agroup__group-range_html_ga446b20253a26c93ef3004fcbfcbf3ec3"><div class="ttname"><a href="group__group-range.html#ga446b20253a26c93ef3004fcbfcbf3ec3">ranges::begin</a></div><div class="ttdeci">constexpr _begin_::fn begin</div><div class="ttdef"><b>Definition:</b> access.hpp:182</div></div>
<div class="ttc" id="agroup__group-range_html_ga80d92c391f5b5c0a50156af5f9c9d8c7"><div class="ttname"><a href="group__group-range.html#ga80d92c391f5b5c0a50156af5f9c9d8c7">ranges::end</a></div><div class="ttdeci">constexpr _end_::fn end</div><div class="ttdef"><b>Definition:</b> access.hpp:313</div></div>
<div class="ttc" id="agroup__list_html_gae64f0978e680ad1a96438c0756b4644d"><div class="ttname"><a href="group__list.html#gae64f0978e680ad1a96438c0756b4644d">meta::empty</a></div><div class="ttdeci">bool_&lt; 0==size&lt; L &gt;::type::value &gt; empty</div><div class="ttdoc">An Boolean integral constant wrapper around true if L is an empty type list; false,...</div><div class="ttdef"><b>Definition:</b> meta.hpp:2231</div></div>
</div><!-- fragment --><p >As you can see, some "overrides" have effect only for <code>begin_adaptor</code> or <code>end_adaptor</code>. In order to use full potential of adaptor, you need to have separate adaptors for begin and end:</p>
<div class="fragment"><div class="line"><span class="keyword">struct </span>adaptor : <a class="code hl_struct" href="structranges_1_1adaptor__base.html">adaptor_base</a></div>
<div class="line">{</div>
<div class="line"> <span class="keywordtype">int</span> n = 0;</div>
<div class="line"> </div>
<div class="line"> <span class="keywordtype">void</span> <a class="code hl_variable" href="group__group-iterator.html#gaf136ff254688f2c24f5c5f58df7ff56d">next</a>(iterator_t&lt;Rng&gt;&amp; it)</div>
<div class="line"> {</div>
<div class="line"> ++n;</div>
<div class="line"> ++it;</div>
<div class="line"> }</div>
<div class="line">};</div>
<div class="line"> </div>
<div class="line"><span class="keyword">struct </span>sentinel_adaptor : <a class="code hl_struct" href="structranges_1_1adaptor__base.html">adaptor_base</a></div>
<div class="line">{</div>
<div class="line"> <span class="keywordtype">int</span> stop_at;</div>
<div class="line"> <span class="keywordtype">bool</span> <a class="code hl_typedef" href="group__list.html#gae64f0978e680ad1a96438c0756b4644d">empty</a>(<span class="keyword">const</span> iterator_t&lt;Rng&gt;&amp;, <span class="keyword">const</span> adaptor&amp; ia, <span class="keyword">const</span> sentinel_t&lt;Rng&gt;&amp; s)<span class="keyword"> const</span></div>
<div class="line"><span class="keyword"> </span>{</div>
<div class="line"> <span class="keywordflow">return</span> ia.n == stop_at;</div>
<div class="line"> }</div>
<div class="line">};</div>
<div class="line"> </div>
<div class="line">adaptor begin_adaptor()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> {}; }</div>
<div class="line">sentinel_adaptor end_adaptor()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> {100}; }</div>
</div><!-- fragment --><p >Sometimes, you can use the same adaptor for both <code>begin_adaptor</code> and <code>end_adaptor</code>:</p>
<div class="fragment"><div class="line"><span class="keyword">struct </span>adaptor : <a class="code hl_struct" href="structranges_1_1adaptor__base.html">adaptor_base</a></div>
<div class="line">{</div>
<div class="line"> <span class="keywordtype">int</span> n = 0;</div>
<div class="line"> <span class="keywordtype">void</span> <a class="code hl_variable" href="group__group-iterator.html#gaf136ff254688f2c24f5c5f58df7ff56d">next</a>(iterator_t&lt;Rng&gt;&amp; it)</div>
<div class="line"> {</div>
<div class="line"> ++n;</div>
<div class="line"> ++it;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// pay attention, we use equal, not empty. empty() will never trigger.</span></div>
<div class="line"> <span class="keyword">template</span>&lt;<span class="keyword">typename</span> I&gt;</div>
<div class="line"> <span class="keywordtype">bool</span> <a class="code hl_function" href="group__group-algorithms.html#gad02116ac1a7f39cc324dd959e9c1d1de">equal</a>(I <span class="keyword">const</span> &amp;this_iter, I <span class="keyword">const</span> &amp;that_iter, adaptor <span class="keyword">const</span> &amp;that_adapt)<span class="keyword"> const</span></div>
<div class="line"><span class="keyword"> </span>{</div>
<div class="line"> <span class="keywordflow">return</span> *this.n == that_adapt.n;</div>
<div class="line"> }</div>
<div class="line">};</div>
<div class="line"> </div>
<div class="line">adaptor begin_adaptor()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> {}; }</div>
<div class="line">adaptor end_adaptor()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> {100}; }</div>
</div><!-- fragment --><p >Note that all the data you store in the adaptor will become part of the iterator.</p>
<p >If you will not "override" <code>begin_adaptor()</code> or/and <code>end_adaptor()</code> in your view_adaptor, default ones will be used.</p>
<h3><a class="anchor" id="autotoc_md30"></a>
Create Custom Iterators with basic_iterator</h3>
<p >Here is an example of Range-v3 compatible random access proxy iterator. The iterator returns a key/value pair, like the <code>zip</code> view.</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="basic__iterator_8hpp.html">range/v3/iterator/basic_iterator.hpp</a>&gt;</span></div>
<div class="line"><span class="preprocessor">#include &lt;<a class="code" href="common__tuple_8hpp.html">range/v3/utility/common_tuple.hpp</a>&gt;</span></div>
<div class="line"> </div>
<div class="line"><span class="keyword">using </span>KeyIter = <span class="keyword">typename</span> std::vector&lt;Key&gt;::iterator;</div>
<div class="line"><span class="keyword">using </span>ValueIter = <span class="keyword">typename</span> std::vector&lt;Value&gt;::iterator;</div>
<div class="line"> </div>
<div class="line"><span class="keyword">struct </span>cursor</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// basic_iterator derives from &quot;mixin&quot;, if present, so it can be used</span></div>
<div class="line"> <span class="comment">// to inject things into the public interface of the iterator</span></div>
<div class="line"> <span class="keyword">struct </span>mixin;</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// This is for dereference operator.</span></div>
<div class="line"> <span class="keyword">using </span>value_type = std::pair&lt;Key, Value&gt;;</div>
<div class="line"> <a class="code hl_struct" href="structranges_1_1common__pair.html">ranges::common_pair&lt;Key&amp;, Value&amp;&gt;</a> read()<span class="keyword"> const</span></div>
<div class="line"><span class="keyword"> </span>{</div>
<div class="line"> <span class="keywordflow">return</span> { *key_iterator, *value_iterator };</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keywordtype">bool</span> <a class="code hl_function" href="group__group-algorithms.html#gad02116ac1a7f39cc324dd959e9c1d1de">equal</a>(<span class="keyword">const</span> cursor&amp; other)<span class="keyword"> const</span></div>
<div class="line"><span class="keyword"> </span>{</div>
<div class="line"> <span class="keywordflow">return</span> key_iterator == other.key_iterator;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keywordtype">void</span> <a class="code hl_variable" href="group__group-iterator.html#gaf136ff254688f2c24f5c5f58df7ff56d">next</a>()</div>
<div class="line"> {</div>
<div class="line"> ++key_iterator;</div>
<div class="line"> ++value_iterator;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// prev optional. Required for Bidirectional iterator</span></div>
<div class="line"> <span class="keywordtype">void</span> <a class="code hl_variable" href="group__group-iterator.html#gaa5307b0c95d051483a41d4870d65f680">prev</a>()</div>
<div class="line"> {</div>
<div class="line"> --key_iterator;</div>
<div class="line"> --value_iterator;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// advance and distance_to are optional. Required for random access iterator</span></div>
<div class="line"> <span class="keywordtype">void</span> <a class="code hl_variable" href="group__group-iterator.html#gaaa3dec40e11c4913663b033a3e98108f">advance</a>(std::ptrdiff_t n)</div>
<div class="line"> {</div>
<div class="line"> key_iterator += n;</div>
<div class="line"> value_iterator += n;</div>
<div class="line"> }</div>
<div class="line"> std::ptrdiff_t distance_to(<span class="keyword">const</span> cursor&amp; other)<span class="keyword"> const</span></div>
<div class="line"><span class="keyword"> </span>{</div>
<div class="line"> <span class="keywordflow">return</span> other.key_iterator - this-&gt;key_iterator;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> cursor() = <span class="keywordflow">default</span>;</div>
<div class="line"> cursor(KeyIter key_iterator, ValueIter value_iterator)</div>
<div class="line"> : key_iterator(key_iterator)</div>
<div class="line"> , value_iterator(value_iterator)</div>
<div class="line"> {}</div>
<div class="line"> </div>
<div class="line"> KeyIter key_iterator;</div>
<div class="line"> ValueIter value_iterator;</div>
<div class="line">};</div>
<div class="line"> </div>
<div class="line"><span class="keyword">struct </span>cursor::mixin : <a class="code hl_struct" href="structranges_1_1basic__mixin.html">ranges::basic_mixin</a>&lt;cursor&gt;</div>
<div class="line">{</div>
<div class="line"> <span class="keyword">using </span><a class="code hl_struct" href="structranges_1_1basic__mixin.html">ranges::basic_mixin</a>&lt;cursor&gt;::basic_mixin;</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// It is necessary to expose constructor in this way</span></div>
<div class="line"> mixin(KeyIter key_iterator, ValueIter value_iterator)</div>
<div class="line"> : mixin{ cursor(key_iterator, value_iterator) }</div>
<div class="line"> {}</div>
<div class="line"> </div>
<div class="line"> KeyIter key_iterator()</div>
<div class="line"> {</div>
<div class="line"> <span class="keywordflow">return</span> this-&gt;get().key_iterator;</div>
<div class="line"> }</div>
<div class="line"> ValueIter value_iterator()</div>
<div class="line"> {</div>
<div class="line"> <span class="keywordflow">return</span> this-&gt;get().value_iterator;</div>
<div class="line"> }</div>
<div class="line">};</div>
<div class="line"> </div>
<div class="line"><span class="keyword">using </span>iterator = <a class="code hl_struct" href="structranges_1_1basic__iterator.html">ranges::basic_iterator&lt;cursor&gt;</a>;</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">void</span> test()</div>
<div class="line">{</div>
<div class="line"> std::vector&lt;Key&gt; keys = {1};</div>
<div class="line"> std::vector&lt;Value&gt; values = {10};</div>
<div class="line"> </div>
<div class="line"> iterator iter(keys.begin(), values.begin());</div>
<div class="line"> <a class="code hl_struct" href="structranges_1_1common__pair.html">ranges::common_pair&lt;Key&amp;, Value&amp;&gt;</a> <a class="code hl_typedef" href="group__list.html#gafd1e131e4e3ae4b0ae9bd3d2ec3a5f74">pair</a> = *iter;</div>
<div class="line"> Key&amp; key = <a class="code hl_typedef" href="group__list.html#gafd1e131e4e3ae4b0ae9bd3d2ec3a5f74">pair</a>.first;</div>
<div class="line"> Value&amp; value = <a class="code hl_typedef" href="group__list.html#gafd1e131e4e3ae4b0ae9bd3d2ec3a5f74">pair</a>.second;</div>
<div class="line"> </div>
<div class="line"> assert(&amp;key == &amp;keys[0]);</div>
<div class="line"> assert(&amp;value == &amp;values[0]);</div>
<div class="line"> </div>
<div class="line"> <span class="keyword">auto</span> key_iter = iter.key_iterator();</div>
<div class="line"> assert(key_iter == keys.begin());</div>
<div class="line">}</div>
<div class="ttc" id="abasic__iterator_8hpp_html"><div class="ttname"><a href="basic__iterator_8hpp.html">basic_iterator.hpp</a></div></div>
<div class="ttc" id="acommon__tuple_8hpp_html"><div class="ttname"><a href="common__tuple_8hpp.html">common_tuple.hpp</a></div></div>
<div class="ttc" id="agroup__list_html_gafd1e131e4e3ae4b0ae9bd3d2ec3a5f74"><div class="ttname"><a href="group__list.html#gafd1e131e4e3ae4b0ae9bd3d2ec3a5f74">meta::pair</a></div><div class="ttdeci">list&lt; F, S &gt; pair</div><div class="ttdoc">A list with exactly two elements.</div><div class="ttdef"><b>Definition:</b> meta.hpp:2246</div></div>
<div class="ttc" id="astructranges_1_1basic__iterator_html"><div class="ttname"><a href="structranges_1_1basic__iterator.html">ranges::basic_iterator</a></div><div class="ttdef"><b>Definition:</b> basic_iterator.hpp:532</div></div>
<div class="ttc" id="astructranges_1_1basic__mixin_html"><div class="ttname"><a href="structranges_1_1basic__mixin.html">ranges::basic_mixin</a></div><div class="ttdef"><b>Definition:</b> basic_iterator.hpp:47</div></div>
<div class="ttc" id="astructranges_1_1common__pair_html"><div class="ttname"><a href="structranges_1_1common__pair.html">ranges::common_pair</a></div><div class="ttdef"><b>Definition:</b> common_tuple.hpp:278</div></div>
</div><!-- fragment --><p ><code>read()</code> returns references. But the default for <code>value_type</code>, which is <code>decay_t&lt;decltype(read())&gt;</code>, is <code>common_pair&lt;Key&amp;, Value&amp;&gt;</code>. That is not correct in our case. It should be <code>pair&lt;Key, Value&gt;</code>, so we explicitly specify <code>value_type</code>.</p>
<p ><code><a class="el" href="structranges_1_1common__pair.html">ranges::common_pair</a></code> has conversions:</p>
<blockquote class="doxtable">
<p >&zwj;<code><a class="el" href="structranges_1_1common__pair.html">ranges::common_pair</a>&lt;Key&amp;, Value&amp;&gt;</code> &harr; <code><a class="el" href="structranges_1_1common__pair.html">ranges::common_pair</a>&lt;Key, Value&gt;</code>. </p>
</blockquote>
<p>All <code><a class="el" href="structranges_1_1common__pair.html">ranges::common_pair</a></code>s converts to their <code>std::pair</code> equivalents, also.</p>
<p >For more information, see <a href="http://wg21.link/P0186#basic-iterators-iterators.basic">http://wg21.link/P0186#basic-iterators-iterators.basic</a></p>
<h2><a class="anchor" id="tutorial-concepts"></a>
Concept Checking</h2>
<hr />
<p> The Range-v3 library makes heavy use of concepts to constrain functions, control overloading, and check type constraints at compile-time. It achieves this with the help of a Concepts emulation layer that works on any standard-conforming C++14 compiler. The library provides many useful concepts, both for the core language and for iterators and ranges. You can use the concepts framework to constrain your own code.</p>
<p >For instance, if you would like to write a function that takes an iterator/sentinel pair, you can write it like this:</p>
<div class="fragment"><div class="line">CPP_template(<span class="keyword">class</span> Iter, <span class="keyword">class</span> Sent, <span class="keyword">class</span> Comp = <span class="comment">/*...some_default..*/</span>)</div>
<div class="line"> (<span class="keyword">requires</span> sentinel_for&lt;Sent, Iter&gt;)</div>
<div class="line"><span class="keywordtype">void</span> my_algorithm(Iter <a class="code hl_typedef" href="group__list.html#ga68418643d5aacd0ec2afe5a0e933ccf3">first</a>, Sent last, Comp comp = Comp{})</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// ...</span></div>
<div class="line">}</div>
<div class="ttc" id="agroup__list_html_ga68418643d5aacd0ec2afe5a0e933ccf3"><div class="ttname"><a href="group__list.html#ga68418643d5aacd0ec2afe5a0e933ccf3">meta::first</a></div><div class="ttdeci">front&lt; Pair &gt; first</div><div class="ttdoc">Retrieve the first element of the pair Pair.</div><div class="ttdef"><b>Definition:</b> meta.hpp:2251</div></div>
</div><!-- fragment --><p >You can then add an overload that take a Range:</p>
<div class="fragment"><div class="line">CPP_template(<span class="keyword">class</span> Rng, <span class="keyword">class</span> Comp = <span class="comment">/*...some_default..*/</span>)</div>
<div class="line"> (<span class="keyword">requires</span> range&lt;Rng&gt;)</div>
<div class="line"><span class="keywordtype">void</span> my_algorithm(Rng &amp;&amp; rng, Comp comp = Comp{})</div>
<div class="line">{</div>
<div class="line"> <span class="keywordflow">return</span> my_algorithm(<a class="code hl_variable" href="group__group-range.html#ga446b20253a26c93ef3004fcbfcbf3ec3">ranges::begin</a>(rng), <a class="code hl_variable" href="group__group-range.html#ga80d92c391f5b5c0a50156af5f9c9d8c7">ranges::end</a>(rng));</div>
<div class="line">}</div>
</div><!-- fragment --><p >With the type constraints expressed with the <code>CPP_template</code> macro, these two overloads are guaranteed to not be ambiguous. When compiling with C++20 concepts support, this uses real concept checks. On legacy compilers, it falls back to using <code>std::enable_if</code>.</p>
<h2><a class="anchor" id="tutorial-future"></a>
Range-v3 and the Future</h2>
<hr />
<p> Range-v3 formed the basis for the <a href="https://www.iso.org/standard/70910.html">Technical Specification on Ranges</a>, which has since been merged into the working draft and shipped with C++20 in the <code>std::ranges</code> namespace.</p>
<p >More range adaptors are slated for inclusion in C++23 and beyond.</p>
<p >The actions, as well as various utilities, have not yet been reviewed by the Committee, although the basic direction has already passed an initial review. </p>
</div></div><!-- PageDoc -->
</div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
</ul>
</div>
</body>
</html>