Imported Upstream version 1.64.0
[platform/upstream/boost.git] / libs / hana / doc / html / index.html
1 <!--
2 Copyright Louis Dionne 2013-2017
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
5 -->
6 <!-- boost-no-inspect -->
7 <!-- HTML header for doxygen 1.8.9.1-->
8 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
9 <html xmlns="http://www.w3.org/1999/xhtml">
10 <head>
11 <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
12 <meta http-equiv="X-UA-Compatible" content="IE=9"/>
13 <meta name="generator" content="Doxygen 1.8.11"/>
14 <title>Boost.Hana: User Manual</title>
15 <link href="tabs.css" rel="stylesheet" type="text/css"/>
16 <script type="text/javascript" src="jquery.js"></script>
17 <script type="text/javascript" src="dynsections.js"></script>
18 <link href="navtree.css" rel="stylesheet" type="text/css"/>
19 <script type="text/javascript" src="resize.js"></script>
20 <script type="text/javascript" src="navtreedata.js"></script>
21 <script type="text/javascript" src="navtree.js"></script>
22 <script type="text/javascript">
23   $(document).ready(initResizable);
24   $(window).load(resizeHeight);
25 </script>
26 <link href="search/search.css" rel="stylesheet" type="text/css"/>
27 <script type="text/javascript" src="search/searchdata.js"></script>
28 <script type="text/javascript" src="search/search.js"></script>
29 <script type="text/javascript">
30   $(document).ready(function() { init_search(); });
31 </script>
32 <script type="text/x-mathjax-config">
33   MathJax.Hub.Config({
34     extensions: ["tex2jax.js"],
35     jax: ["input/TeX","output/HTML-CSS"],
36 });
37 // Copyright Louis Dionne 2013-2017
38 // Distributed under the Boost Software License, Version 1.0.
39 // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
40 MathJax.Hub.Config({
41     "HTML-CSS": {
42         linebreaks: {
43             automatic: true,
44             width: "75% container"
45         }
46     }
47 });
48 </script><script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js"></script>
49 <link href="doxygen.css" rel="stylesheet" type="text/css" />
50 <!-- Additional javascript for drawing charts. -->
51 <script type="text/javascript" src="highcharts.js"></script>
52 <script type="text/javascript" src="highcharts-data.js"></script>
53 <script type="text/javascript" src="highcharts-exporting.js"></script>
54 <script type="text/javascript" src="chart.js"></script>
55 <script type="text/javascript" src="hana.js"></script>
56 </head>
57 <body>
58 <div id="top"><!-- do not remove this div, it is closed by doxygen! -->
59 <div id="titlearea">
60 <table cellspacing="0" cellpadding="0">
61  <tbody>
62  <tr style="height: 56px;">
63   <td id="projectlogo"><img alt="Logo" src="Boost.png"/></td>
64   <td style="padding-left: 0.5em;">
65    <div id="projectname">Boost.Hana
66    &#160;<span id="projectnumber">1.1.0</span>
67    </div>
68    <div id="projectbrief">Your standard library for metaprogramming</div>
69   </td>
70    <td>        <div id="MSearchBox" class="MSearchBoxInactive">
71         <span class="left">
72           <img id="MSearchSelect" src="search/mag_sel.png"
73                onmouseover="return searchBox.OnSearchSelectShow()"
74                onmouseout="return searchBox.OnSearchSelectHide()"
75                alt=""/>
76           <input type="text" id="MSearchField" value="Search" accesskey="S"
77                onfocus="searchBox.OnSearchFieldFocus(true)" 
78                onblur="searchBox.OnSearchFieldFocus(false)" 
79                onkeyup="searchBox.OnSearchFieldChange(event)"/>
80           </span><span class="right">
81             <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
82           </span>
83         </div>
84 </td>
85  </tr>
86  </tbody>
87 </table>
88 </div>
89 <!-- end header part -->
90 <!-- Generated by Doxygen 1.8.11 -->
91 <script type="text/javascript">
92 var searchBox = new SearchBox("searchBox", "search",false,'Search');
93 </script>
94 </div><!-- top -->
95 <div id="side-nav" class="ui-resizable side-nav-resizable">
96   <div id="nav-tree">
97     <div id="nav-tree-contents">
98       <div id="nav-sync" class="sync"></div>
99     </div>
100   </div>
101   <div id="splitbar" style="-moz-user-select:none;" 
102        class="ui-resizable-handle">
103   </div>
104 </div>
105 <script type="text/javascript">
106 $(document).ready(function(){initNavTree('index.html','');});
107 </script>
108 <div id="doc-content">
109 <!-- window showing the filter options -->
110 <div id="MSearchSelectWindow"
111      onmouseover="return searchBox.OnSearchSelectShow()"
112      onmouseout="return searchBox.OnSearchSelectHide()"
113      onkeydown="return searchBox.OnSearchSelectKey(event)">
114 </div>
115
116 <!-- iframe showing the search results (closed by default) -->
117 <div id="MSearchResultsWindow">
118 <iframe src="javascript:void(0)" frameborder="0" 
119         name="MSearchResults" id="MSearchResults">
120 </iframe>
121 </div>
122
123 <div class="header">
124   <div class="headertitle">
125 <div class="title">User Manual </div>  </div>
126 </div><!--header-->
127 <div class="contents">
128 <div class="toc"><h3>Table of Contents</h3>
129 <ul><li class="level1"><a href="#tutorial-description">Description</a></li>
130 <li class="level1"><a href="#tutorial-installation">Prerequisites and installation</a><ul><li class="level2"><a href="#tutorial-installation-requirements">Compiler requirements</a></li>
131 </ul>
132 </li>
133 <li class="level1"><a href="#tutorial-support">Support</a></li>
134 <li class="level1"><a href="#tutorial-introduction">Introduction</a><ul><li class="level2"><a href="#tutorial-introduction-quadrants">C++ computational quadrants</a></li>
135 <li class="level2"><a href="#tutorial-quadrants-about">What is this library about?</a></li>
136 </ul>
137 </li>
138 <li class="level1"><a href="#tutorial-quickstart">Quick start</a><ul><li class="level2"><a href="#tutorial-quickstart-any">A real world example</a></li>
139 </ul>
140 </li>
141 <li class="level1"><a href="#tutorial-cheatsheet">Cheatsheet</a></li>
142 <li class="level1"><a href="#tutorial-assert">Assertions</a></li>
143 <li class="level1"><a href="#tutorial-integral">Compile-time numbers</a><ul><li class="level2"><a href="#tutorial-integral-arithmetic">Compile-time arithmetic</a></li>
144 <li class="level2"><a href="#tutorial-integral-distance">Example: Euclidean distance</a></li>
145 <li class="level2"><a href="#tutorial-integral-branching">Compile-time branching</a></li>
146 <li class="level2"><a href="#tutorial-integral-more">Why stop here?</a></li>
147 </ul>
148 </li>
149 <li class="level1"><a href="#tutorial-type">Type computations</a><ul><li class="level2"><a href="#tutorial-type-objects">Types as objects</a></li>
150 <li class="level2"><a href="#tutorial-type-benefits">Benefits of this representation</a></li>
151 <li class="level2"><a href="#tutorial-type-working">Working with this representation</a></li>
152 <li class="level2"><a href="#tutorial-type-lifting">The generic lifting process</a></li>
153 </ul>
154 </li>
155 <li class="level1"><a href="#tutorial-introspection">Introspection</a><ul><li class="level2"><a href="#tutorial-introspection-is_valid">Checking expression validity</a><ul><li class="level3"><a href="#tutorial-introspection-is_valid-non_static">Non-static members</a></li>
156 <li class="level3"><a href="#tutorial-introspection-is_valid-static">Static members</a></li>
157 <li class="level3"><a href="#tutorial-introspection-is_valid-typename">Nested type names</a></li>
158 <li class="level3"><a href="#tutorial-introspection-is_valid-template">Nested templates</a></li>
159 </ul>
160 </li>
161 <li class="level2"><a href="#tutorial-introspection-sfinae">Taking control of SFINAE</a></li>
162 <li class="level2"><a href="#tutorial-introspection-adapting">Introspecting user-defined types</a></li>
163 <li class="level2"><a href="#tutorial-introspection-json">Example: generating JSON</a></li>
164 </ul>
165 </li>
166 <li class="level1"><a href="#tutorial-containers">Generalities on containers</a><ul><li class="level2"><a href="#tutorial-containers-creating">Container creation</a></li>
167 <li class="level2"><a href="#tutorial-containers-types">Container types</a><ul><li class="level3"><a href="#tutorial-containers-types-overloading">Overloading on container types</a></li>
168 </ul>
169 </li>
170 <li class="level2"><a href="#tutorial-containers-elements">Container elements</a></li>
171 </ul>
172 </li>
173 <li class="level1"><a href="#tutorial-algorithms">Generalities on algorithms</a><ul><li class="level2"><a href="#tutorial-algorithms-value">By-value semantics</a></li>
174 <li class="level2"><a href="#tutorial-algorithms-laziness">(Non-)Laziness</a></li>
175 <li class="level2"><a href="#tutorial-algorithms-codegen">What is generated?</a></li>
176 <li class="level2"><a href="#tutorial-algorithms-effects">Side effects and purity</a></li>
177 <li class="level2"><a href="#tutorial-algorithms-cross_phase">Cross-phase algorithms</a></li>
178 </ul>
179 </li>
180 <li class="level1"><a href="#tutorial-performance">Performance considerations</a><ul><li class="level2"><a href="#tutorial-performance-compile">Compile-time performance</a></li>
181 <li class="level2"><a href="#tutorial-performance-runtime">Runtime performance</a></li>
182 </ul>
183 </li>
184 <li class="level1"><a href="#tutorial-ext">Integration with external libraries</a></li>
185 <li class="level1"><a href="#tutorial-core">Hana&#39;s core</a><ul><li class="level2"><a href="#tutorial-core-tags">Tags</a></li>
186 <li class="level2"><a href="#tutorial-core-tag_dispatching">Tag dispatching</a></li>
187 <li class="level2"><a href="#tutorial-core-concepts">Emulation of C++ concepts</a></li>
188 </ul>
189 </li>
190 <li class="level1"><a href="#tutorial-header_organization">Header organization</a></li>
191 <li class="level1"><a href="#tutorial-conclusion">Conclusion</a><ul><li class="level2"><a href="#tutorial-conclusion-warning">Fair warning: functional programming ahead</a></li>
192 <li class="level2"><a href="#tutorial-conclusion-related_material">Related material</a></li>
193 </ul>
194 </li>
195 <li class="level1"><a href="#tutorial-reference">Using the reference</a><ul><li class="level2"><a href="#tutorial-reference-signatures">Function signatures</a></li>
196 </ul>
197 </li>
198 <li class="level1"><a href="#tutorial-acknowledgements">Acknowledgements</a></li>
199 <li class="level1"><a href="#tutorial-glossary">Glossary</a></li>
200 <li class="level1"><a href="#tutorial-rationales">Rationales/FAQ</a><ul><li class="level2"><a href="#tutorial-rationales-dependencies">Why restrict usage of external dependencies?</a></li>
201 <li class="level2"><a href="#tutorial-rationales-iterators">Why no iterators?</a></li>
202 <li class="level2"><a href="#tutorial-rationales-container_representation">Why leave some container&#39;s representation implementation-defined?</a></li>
203 <li class="level2"><a href="#tutorial-rationales-why_Hana">Why Hana?</a></li>
204 <li class="level2"><a href="#tutorial-rationales-tuple">Why define our own tuple?</a></li>
205 <li class="level2"><a href="#tutorial-rationales-naming">How are names chosen?</a></li>
206 <li class="level2"><a href="#tutorial-rationales-parameters">How is the parameter order decided?</a></li>
207 <li class="level2"><a href="#tutorial-rationales-tag_dispatching">Why tag dispatching?</a></li>
208 <li class="level2"><a href="#tutorial-rationales-zip_longest">Why not provide zip_longest?</a></li>
209 <li class="level2"><a href="#tutorial-rationales-concepts">Why aren&#39;t concepts constexpr functions?</a></li>
210 </ul>
211 </li>
212 <li class="level1"><a href="#tutorial-appendix-constexpr">Appendix I: Advanced constexpr</a><ul><li class="level2"><a href="#tutorial-appendix-constexpr-stripping">Constexpr stripping</a></li>
213 <li class="level2"><a href="#tutorial-tutorial-appendix-constexpr-preservation">Constexpr preservation</a></li>
214 <li class="level2"><a href="#tutorial-appendix-constexpr-effects">Side effects</a></li>
215 </ul>
216 </li>
217 <li class="level1"><a href="#tutorial-appendix-MPL">Appendix II: A minimal MPL</a></li>
218 </ul>
219 </div>
220 <div class="textblock"><h1><a class="anchor" id="tutorial-description"></a>
221 Description</h1>
222 <hr/>
223 <p> Hana is a header-only library for C++ metaprogramming suited for computations on both types and values. The functionality it provides is a superset of what is provided by the well established <a href="http://www.boost.org/doc/libs/release/libs/mpl/doc/index.html">Boost.MPL</a> and <a href="http://www.boost.org/doc/libs/release/libs/fusion/doc/html/index.html">Boost.Fusion</a> libraries. By leveraging C++11/14 implementation techniques and idioms, Hana boasts faster compilation times and runtime performance on par or better than previous metaprogramming libraries, while noticeably increasing the level of expressiveness in the process. Hana is easy to extend in a ad-hoc manner and it provides out-of-the-box inter-operation with Boost.Fusion, Boost.MPL and the standard library.</p>
224 <h1><a class="anchor" id="tutorial-installation"></a>
225 Prerequisites and installation</h1>
226 <hr/>
227 <p> Hana is a header-only library without external dependencies (not even the rest of Boost). Hence, using Hana in your own project is very easy. Basically, just download the project and add the <code>include/</code> directory to your compiler's header search path and you are done. However, if you want to cleanly install Hana, you have a couple of options:</p>
228 <ol type="1">
229 <li><b>Install Boost</b><br />
230 Hana is included in the <a href="http://www.boost.org">Boost</a> distribution starting from Boost 1.61.0, so installing that will give you access to Hana.</li>
231 <li><b>Install locally for CMake projects</b><br />
232 If you use CMake in a project, you can use the provided <a href="https://github.com/boostorg/hana/blob/master/cmake/FindHana.cmake">FindHana.cmake</a> module to setup Hana as an external CMake project. The module allows using an already-installed version of Hana, or installing Hana locally to your CMake project, without needing a system-wide installation.</li>
233 <li><b>Use Homebrew</b><br />
234 On Mac OS, Hana can be installed with <a href="http://brew.sh">Homebrew</a>: <div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;brew install hana</div></div><!-- fragment --></li>
235 <li><b>Install manually</b><br />
236 You can download the code from the official GitHub <a href="https://github.com/boostorg/hana">repository</a> and install the library manually by issuing the following commands from the root of the project (requires <a href="http://www.cmake.org">CMake</a>): <div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;mkdir build &amp;&amp; cd build</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;cmake ..</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;cmake --build . --target install</div></div><!-- fragment --> This will install Hana to the default install-directory for your platform (<code>/usr/local</code> for Unix, <code>C:/Program Files</code> for Windows). If you want to install Hana in a custom location, you can use <div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;cmake .. -DCMAKE_INSTALL_PREFIX=/custom/install/prefix</div></div><!-- fragment --></li>
237 </ol>
238 <dl class="section note"><dt>Note</dt><dd><ul>
239 <li>Both the manual installation and the Homebrew installation will also install a <code>hana.pc</code> file for use with <a href="http://www.freedesktop.org/wiki/Software/pkg-config/">pkg-config</a>.</li>
240 <li>Do not mix a system-wide installation of Hana with a system-wide installation of Boost, because both installations will clash. You won't know which version of Hana is being used, and that could break libraries that depend on the version of Hana provided with Boost (or vice-versa). Generally speaking, you should favor local installations whenever possible.</li>
241 </ul>
242 </dd></dl>
243 <p>Finally, if you want to contribute to Hana, you can see how to best setup your environment for development in the <a href="https://github.com/boostorg/hana/blob/master/README.md#hacking-on-hana">README</a>.</p>
244 <h2><a class="anchor" id="tutorial-installation-requirements"></a>
245 Compiler requirements</h2>
246 <p>The library relies on a C++14 compiler and standard library, but nothing else is required. Here is a table of the current C++14 compilers/toolchains with comments regarding support for Hana:</p>
247 <table class="doxtable">
248 <tr>
249 <th>Compiler/Toolchain </th><th>Status  </th></tr>
250 <tr>
251 <td>Clang &gt;= 3.5.0 </td><td>Fully working; tested on each push to GitHub </td></tr>
252 <tr>
253 <td>Xcode &gt;= 6.3 </td><td>Fully working; tested on each push to GitHub </td></tr>
254 <tr>
255 <td>GCC &gt;= 6.0.0 </td><td>Fully working; tested on each push to GitHub </td></tr>
256 </table>
257 <p>More specifically, Hana requires a compiler/standard library supporting the following C++14 features (non-exhaustively):</p><ul>
258 <li>Generic lambdas</li>
259 <li>Generalized <code>constexpr</code></li>
260 <li>Variable templates</li>
261 <li>Automatically deduced return type</li>
262 <li>All the C++14 type traits from the <code>&lt;type_traits&gt;</code> header</li>
263 </ul>
264 <p>More information for specific platforms is available on <a href="https://github.com/boostorg/hana/wiki">the wiki</a>.</p>
265 <h1><a class="anchor" id="tutorial-support"></a>
266 Support</h1>
267 <hr/>
268 <p>If you have a problem, please review the <a class="el" href="index.html#tutorial-rationales">FAQ</a> and <a href="https://github.com/boostorg/hana/wiki">the wiki</a>. Searching <a href="https://github.com/boostorg/hana/issues">the issues</a> for your problem is also a good idea. If that doesn't help, feel free to chat with us in <a href="https://gitter.im/boostorg/hana">Gitter</a>, or open a new issue. <a href="http://stackoverflow.com">StackOverflow</a> with the <a href="http://stackoverflow.com/questions/tagged/boost-hana">boost-hana</a> tag is the preferred place to ask questions on usage. If you are encountering what you think is a bug, please open an issue.</p>
269 <h1><a class="anchor" id="tutorial-introduction"></a>
270 Introduction</h1>
271 <hr/>
272 <p> When Boost.MPL first appeared, it provided C++ programmers with a huge relief by abstracting tons of template hackery behind a workable interface. This breakthrough greatly contributed to making C++ template metaprogramming more mainstream, and today the discipline is deeply rooted in many serious projects. Recently, C++11 and C++14 brought many major changes to the language, some of which make metaprogramming much easier, while others drastically widen the design space for libraries. A natural question then arises: is it still desirable to have abstractions for metaprogramming, and if so, which ones? After investigating different options like the <a href="http://github.com/ldionne/mpl11">MPL11</a>, the answer eventually came by itself in the form of a library; Hana. The key insight to Hana is that the manipulation of types and values are nothing but two sides of the same coin. By unifying both concepts, metaprogramming becomes easier and new exciting possibilities open before us.</p>
273 <h2><a class="anchor" id="tutorial-introduction-quadrants"></a>
274 C++ computational quadrants</h2>
275 <p>But to really understand what is Hana all about, it is essential to understand the different types of computations in C++. We will focus our attention on four different kinds of computations, even though a finer grained separation would be possible. First, we have runtime computations, which are the usual computations we use in C++. In that world, we have runtime containers, runtime functions and runtime algorithms:</p>
276 <div class="fragment"><div class="line"><span class="keyword">auto</span> f = [](<span class="keywordtype">int</span> i) -&gt; std::string {</div><div class="line">  <span class="keywordflow">return</span> std::to_string(i * i);</div><div class="line">};</div><div class="line"></div><div class="line">std::vector&lt;int&gt; ints{1, 2, 3, 4};</div><div class="line">std::vector&lt;std::string&gt; strings;</div><div class="line"><a class="code" href="group__group-Functor.html#ga5a8975f6e55375d5b6038a9c36ee63e7">std::transform</a>(ints.begin(), ints.end(), std::back_inserter(strings), f);</div><div class="line"></div><div class="line">assert((strings == std::vector&lt;std::string&gt;{<span class="stringliteral">&quot;1&quot;</span>, <span class="stringliteral">&quot;4&quot;</span>, <span class="stringliteral">&quot;9&quot;</span>, <span class="stringliteral">&quot;16&quot;</span>}));</div></div><!-- fragment --><p> The usual toolbox for programming within this quadrant is the C++ standard library, which provides reusable algorithms and containers operating at runtime. Since C++11, a second kind of computation is possible: <code>constexpr</code> computations. There, we have <code>constexpr</code> containers, <code>constexpr</code> functions and <code>constexpr</code> algorithms:</p>
277 <div class="fragment"><div class="line">constexpr <span class="keywordtype">int</span> factorial(<span class="keywordtype">int</span> n) {</div><div class="line">  <span class="keywordflow">return</span> n == 0 ? 1 : n * factorial(n - 1);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T, std::<span class="keywordtype">size_t</span> N, <span class="keyword">typename</span> F&gt;</div><div class="line">  constexpr <a class="code" href="structstd_1_1array.html">std::array&lt;std::result_of_t&lt;F(T)&gt;</a>, N&gt;</div><div class="line"><a class="code" href="group__group-Functor.html#ga5a8975f6e55375d5b6038a9c36ee63e7">transform</a>(<a class="code" href="structstd_1_1array.html">std::array&lt;T, N&gt;</a> array, F f) {</div><div class="line">  <span class="comment">// ...</span></div><div class="line">}</div><div class="line"></div><div class="line">constexpr <a class="code" href="structstd_1_1array.html">std::array&lt;int, 4&gt;</a> ints{{1, 2, 3, 4}};</div><div class="line">constexpr <a class="code" href="structstd_1_1array.html">std::array&lt;int, 4&gt;</a> facts = <a class="code" href="group__group-Functor.html#ga5a8975f6e55375d5b6038a9c36ee63e7">transform</a>(ints, factorial);</div><div class="line">static_assert(facts == <a class="code" href="structstd_1_1array.html">std::array&lt;int, 4&gt;</a>{{1, 2, 6, 24}}, <span class="stringliteral">&quot;&quot;</span>);</div></div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>For the above code to actually work, <code><a class="el" href="structstd_1_1array.html" title="Adaptation of std::array for Hana. ">std::array</a></code>'s <code>operator==</code> would have to be marked <code>constexpr</code>, which is not the case (even in C++14).</dd></dl>
278 <p>Basically, a <code>constexpr</code> computation is different from a runtime computation in that it is simple enough to be evaluated (interpreted, really) by the compiler. In general, any function that does not perform anything too <em>unfriendly</em> to the compiler's evaluator (like throwing or allocating memory) can be marked <code>constexpr</code> without any further change. This makes <code>constexpr</code> computations very similar to runtime computations, except <code>constexpr</code> computations are more restricted and they gain the ability to be evaluated at compile-time. Unfortunately, there is no commonly used toolbox for <code>constexpr</code>-programming, i.e. there is no widely adopted "standard library" for <code>constexpr</code> programming. However, the <a href="https://github.com/bolero-MURAKAMI/Sprout">Sprout</a> library may be worth checking out for those with some interest in <code>constexpr</code> computations.</p>
279 <p>The third kind of computations are heterogeneous computations. Heterogeneous computations differ from normal computations in that instead of having containers holding homogeneous objects (all objects having the same type), the containers may hold objects with different types. Furthermore, functions in this quadrant of computation are <em>heterogeneous</em> functions, which is a complicated way of talking about template functions. Similarly, we have heterogeneous algorithms that manipulate heterogeneous containers and functions:</p>
280 <div class="fragment"><div class="line"><span class="keyword">auto</span> to_string = [](<span class="keyword">auto</span> t) {</div><div class="line">  std::stringstream ss;</div><div class="line">  ss &lt;&lt; t;</div><div class="line">  <span class="keywordflow">return</span> ss.str();</div><div class="line">};</div><div class="line"></div><div class="line">fusion::vector&lt;int, std::string, float&gt; seq{1, <span class="stringliteral">&quot;abc&quot;</span>, 3.4f};</div><div class="line">fusion::vector&lt;std::string, std::string, std::string&gt;</div><div class="line">  strings = <a class="code" href="group__group-Functor.html#ga5a8975f6e55375d5b6038a9c36ee63e7">fusion::transform</a>(seq, to_string);</div><div class="line"></div><div class="line">assert(strings == fusion::make_vector(<span class="stringliteral">&quot;1&quot;</span>s, <span class="stringliteral">&quot;abc&quot;</span>s, <span class="stringliteral">&quot;3.4&quot;</span>s));</div></div><!-- fragment --><p> If manipulating heterogeneous containers seems overly weird to you, just think of it as glorified <code><a class="el" href="structstd_1_1tuple.html" title="Adapter for std::tuples. ">std::tuple</a></code> manipulation. In a C++03 world, the go-to library for doing this kind of computation is <a href="http://www.boost.org/doc/libs/release/libs/fusion/doc/html/index.html">Boost.Fusion</a>, which provides several data structures and algorithms to manipulate heterogeneous collections of data. The fourth and last quadrant of computation that we'll be considering here is the quadrant of type-level computations. In this quadrant, we have type-level containers, type-level functions (usually called metafunctions) and type-level algorithms. Here, everything operates on types: containers hold types and metafunctions take types as arguments and return types as results.</p>
281 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">struct </span>add_const_pointer {</div><div class="line">  <span class="keyword">using</span> type = T <span class="keyword">const</span>*;</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">using</span> types = mpl::vector&lt;int, char, float, void&gt;;</div><div class="line"><span class="keyword">using</span> pointers = mpl::transform&lt;types, add_const_pointer&lt;mpl::_1&gt;&gt;::type;</div><div class="line"></div><div class="line">static_assert(<a class="code" href="group__group-Comparable.html#gacaf1ebea6b3ab96ac9dcb82f0e64e547">mpl::equal</a>&lt;</div><div class="line">  pointers,</div><div class="line">  mpl::vector&lt;int const*, char const*, float const*, void const*&gt;</div><div class="line">&gt;::<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">value</a>, <span class="stringliteral">&quot;&quot;</span>);</div></div><!-- fragment --><p> The realm of type-level computations has been explored quite extensively, and the de-facto solution for type-level computations in C++03 is a library named <a href="http://www.boost.org/doc/libs/release/libs/mpl/doc/index.html">Boost.MPL</a>, which provides type-level containers and algorithms. For low-level type transformations, the metafunctions provided by the <code>&lt;type_traits&gt;</code> standard header can also be used since C++11.</p>
282 <h2><a class="anchor" id="tutorial-quadrants-about"></a>
283 What is this library about?</h2>
284 <p>So all is good, but what is this library actually about? Now that we have set the table by clarifying the kinds of computations available to us in C++, the answer might strike you as very simple. <b>The purpose of Hana is to merge the 3rd and the 4th quadrants of computation</b>. More specifically, Hana is a (long-winded) constructive proof that heterogeneous computations are strictly more powerful than type-level computations, and that we can therefore express any type-level computation by an equivalent heterogeneous computation. This construction is done in two steps. First, Hana is a fully featured library of heterogeneous algorithms and containers, a bit like a modernized Boost.Fusion. Secondly, Hana provides a way of translating any type-level computation into its equivalent heterogeneous computation and back, which allows the full machinery of heterogeneous computations to be reused for type-level computations without any code duplication. Of course, the biggest advantage of this unification is seen by the user, as you will witness by yourself.</p>
285 <h1><a class="anchor" id="tutorial-quickstart"></a>
286 Quick start</h1>
287 <hr/>
288 <p> The goal of this section is to introduce the main concepts of the library from a very high level and at a fairly rapid pace; don't worry if you don't understand everything that's about to be thrown at you. However, this tutorial assumes the reader is already at least <em>familiar</em> with basic metaprogramming and the <a href="http://en.wikipedia.org/wiki/C%2B%2B14">C++14 standard</a>. First, let's include the library:</p>
289 <div class="fragment"><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="hana_8hpp.html">boost/hana.hpp</a>&gt;</span></div><div class="line"><span class="keyword">namespace </span>hana = <a class="code" href="namespaceboost_1_1hana.html">boost::hana</a>;</div></div><!-- fragment --><p> Unless specified otherwise, the documentation assumes the above lines to be present before examples and code snippets. Also note that finer grained headers are provided and will be explained in the <a class="el" href="index.html#tutorial-header_organization">Header organization</a> section. For the purpose of the quickstart, let's now include some additional headers and define some lovely animal types that we'll need below:</p>
290 <div class="fragment"><div class="line"><span class="preprocessor">#include &lt;cassert&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;string&gt;</span></div><div class="line"></div><div class="line"><span class="keyword">struct </span>Fish { std::string name; };</div><div class="line"><span class="keyword">struct </span>Cat  { std::string name; };</div><div class="line"><span class="keyword">struct </span>Dog  { std::string name; };</div></div><!-- fragment --><p> If you are reading this documentation, chances are you already know <code><a class="el" href="structstd_1_1tuple.html" title="Adapter for std::tuples. ">std::tuple</a></code> and <code>std::make_tuple</code>. Hana provides its own tuple and <code>make_tuple</code>:</p>
291 <div class="fragment"><div class="line"><span class="keyword">auto</span> animals = hana::make_tuple(Fish{<span class="stringliteral">&quot;Nemo&quot;</span>}, Cat{<span class="stringliteral">&quot;Garfield&quot;</span>}, Dog{<span class="stringliteral">&quot;Snoopy&quot;</span>});</div></div><!-- fragment --><p> This creates a tuple, which is like an array, except that it can hold elements with different types. Containers that can hold elements with different types such as this are called heterogeneous containers. While the standard library provides very few operations to manipulate <code><a class="el" href="structstd_1_1tuple.html" title="Adapter for std::tuples. ">std::tuple</a></code>s, Hana provides several operations and algorithms to manipulate its own tuples:</p>
292 <div class="fragment"><div class="line"><span class="keyword">using namespace </span>hana::literals;</div><div class="line"></div><div class="line"><span class="comment">// Access tuple elements with operator[] instead of std::get.</span></div><div class="line">Cat garfield = animals[1_c];</div><div class="line"></div><div class="line"><span class="comment">// Perform high level algorithms on tuples (this is like std::transform)</span></div><div class="line"><span class="keyword">auto</span> names = <a class="code" href="group__group-Functor.html#ga5a8975f6e55375d5b6038a9c36ee63e7">hana::transform</a>(animals, [](<span class="keyword">auto</span> a) {</div><div class="line">  <span class="keywordflow">return</span> a.name;</div><div class="line">});</div><div class="line"></div><div class="line">assert(<a class="code" href="group__group-Sequence.html#ga28037560e8f224c53cf6ac168d03a067">hana::reverse</a>(names) == hana::make_tuple(<span class="stringliteral">&quot;Snoopy&quot;</span>, <span class="stringliteral">&quot;Garfield&quot;</span>, <span class="stringliteral">&quot;Nemo&quot;</span>));</div></div><!-- fragment --> <dl class="section note"><dt>Note</dt><dd><code>1_c</code> is a <a href="http://en.wikipedia.org/wiki/C%2B%2B11#User-defined_literals">C++14 user-defined literal</a> creating a <a class="el" href="index.html#tutorial-integral">compile-time number</a>. These user-defined literals are contained in the <code><a class="el" href="namespaceboost_1_1hana_1_1literals.html" title="Namespace containing C++14 user-defined literals provided by Hana. ">boost::hana::literals</a></code> namespace, hence the <code>using</code> directive.</dd></dl>
293 <p>Notice how we pass a <a href="http://en.wikipedia.org/wiki/C%2B%2B14#Generic_lambdas">C++14 generic lambda</a> to <code>transform</code>; this is required because the lambda will first be called with a <code>Fish</code>, then a <code>Cat</code>, and finally a <code>Dog</code>, which all have different types. Hana provides most of the algorithms provided by the C++ standard library, except they work on tuples and related heterogeneous containers instead of <code>std::vector</code> &amp; friends. In addition to working with heterogeneous values, Hana makes it possible to perform type-level computations with a natural syntax, all at compile-time and with no overhead whatsoever. This compiles and does just what you would expect:</p>
294 <div class="fragment"><div class="line"><span class="keyword">auto</span> animal_types = hana::make_tuple(hana::type_c&lt;Fish*&gt;, hana::type_c&lt;Cat&amp;&gt;, hana::type_c&lt;Dog&gt;);</div><div class="line"></div><div class="line"><span class="keyword">auto</span> no_pointers = <a class="code" href="group__group-MonadPlus.html#ga9700169a45664d50377c1be9d58accd3">hana::remove_if</a>(animal_types, [](<span class="keyword">auto</span> a) {</div><div class="line">  <span class="keywordflow">return</span> hana::traits::is_pointer(a);</div><div class="line">});</div><div class="line"></div><div class="line">static_assert(no_pointers == hana::make_tuple(hana::type_c&lt;Cat&amp;&gt;, hana::type_c&lt;Dog&gt;), <span class="stringliteral">&quot;&quot;</span>);</div></div><!-- fragment --> <dl class="section note"><dt>Note</dt><dd><code>type_c&lt;...&gt;</code> is not a type! It is a <a href="http://en.wikipedia.org/wiki/C%2B%2B14#Variable_templates">C++14 variable template</a> yielding an object representing a type for Hana. This is explained in the section on <a class="el" href="index.html#tutorial-type">type computations</a>.</dd></dl>
295 <p>In addition to heterogeneous and compile-time sequences, Hana provides several features to make your metaprogramming nightmares a thing of the past. For example, one can check for the existence of a struct member with one easy line instead of relying on <a href="http://stackoverflow.com/a/257382/627587">clunky SFINAE hacks</a>:</p>
296 <div class="fragment"><div class="line"><span class="keyword">auto</span> has_name = hana::is_valid([](<span class="keyword">auto</span>&amp;&amp; x) -&gt; decltype((<span class="keywordtype">void</span>)x.name) { });</div><div class="line"></div><div class="line">static_assert(has_name(garfield), <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">static_assert(!has_name(1), <span class="stringliteral">&quot;&quot;</span>);</div></div><!-- fragment --><p> Writing a serialization library? Stop crying, we've got you covered. Reflection can be added to user-defined types very easily. This allows iterating over the members of a user-defined type, querying members with a programmatic interface and much more, without any runtime overhead:</p>
297 <div class="fragment"><div class="line"><span class="comment">// 1. Give introspection capabilities to &#39;Person&#39;</span></div><div class="line"><span class="keyword">struct </span>Person {</div><div class="line">  BOOST_HANA_DEFINE_STRUCT(Person,</div><div class="line">    (std::string, name),</div><div class="line">    (<span class="keywordtype">int</span>, age)</div><div class="line">  );</div><div class="line">};</div><div class="line"></div><div class="line"><span class="comment">// 2. Write a generic serializer (bear with std::ostream for the example)</span></div><div class="line"><span class="keyword">auto</span> serialize = [](std::ostream&amp; os, <span class="keyword">auto</span> <span class="keyword">const</span>&amp; object) {</div><div class="line">  <a class="code" href="group__group-Foldable.html#ga2af382f7e644ce3707710bbad313e9c2">hana::for_each</a>(<a class="code" href="group__group-Struct.html#gad301dd8e9fb4639d7874619c97d6d427">hana::members</a>(<span class="keywordtype">object</span>), [&amp;](<span class="keyword">auto</span> member) {</div><div class="line">    os &lt;&lt; member &lt;&lt; std::endl;</div><div class="line">  });</div><div class="line">};</div><div class="line"></div><div class="line"><span class="comment">// 3. Use it</span></div><div class="line">Person john{<span class="stringliteral">&quot;John&quot;</span>, 30};</div><div class="line">serialize(std::cout, john);</div><div class="line"></div><div class="line"><span class="comment">// output:</span></div><div class="line"><span class="comment">// John</span></div><div class="line"><span class="comment">// 30</span></div></div><!-- fragment --><p> That's cool, but I can already hear you complaining about incomprehensible error messages. However, it turns out Hana was built for humans, not professional template metaprogrammers, and this shows. Let's intentionally screw up and see what kind of mess is thrown at us. First, the mistake:</p>
298 <div class="fragment"><div class="line"><span class="keyword">auto</span> serialize = [](std::ostream&amp; os, <span class="keyword">auto</span> <span class="keyword">const</span>&amp; object) {</div><div class="line">  <a class="code" href="group__group-Foldable.html#ga2af382f7e644ce3707710bbad313e9c2">hana::for_each</a>(os, [&amp;](<span class="keyword">auto</span> member) {</div><div class="line">    <span class="comment">//           ^^ oopsie daisy!</span></div><div class="line">    os &lt;&lt; member &lt;&lt; std::endl;</div><div class="line">  });</div><div class="line">};</div></div><!-- fragment --><p> Now, the punishment:</p>
299 <div class="fragment"><div class="line">error: static_assert failed <span class="stringliteral">&quot;hana::for_each(xs, f) requires &#39;xs&#39; to be Foldable&quot;</span></div><div class="line">        static_assert(<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">Foldable&lt;S&gt;::value</a>,</div><div class="line">        ^             ~~~~~~~~~~~~~~~~~~</div><div class="line">note: <a class="code" href="group__group-Searchable.html#ga0d9456ceda38b6ca664998e79d7c45b7">in</a> instantiation of <span class="keyword">function</span> <span class="keyword">template</span> specialization</div><div class="line">      <span class="stringliteral">&#39;boost::hana::for_each_t::operator()&lt;</span></div><div class="line"><span class="stringliteral">        std::__1::basic_ostream&lt;char&gt; &amp;, (lambda at [snip])&gt;&#39;</span> requested here</div><div class="line">  <a class="code" href="group__group-Foldable.html#ga2af382f7e644ce3707710bbad313e9c2">hana::for_each</a>(os, [&amp;](<span class="keyword">auto</span> member) {</div><div class="line">  ^</div><div class="line">note: <a class="code" href="group__group-Searchable.html#ga0d9456ceda38b6ca664998e79d7c45b7">in</a> instantiation of <span class="keyword">function</span> <span class="keyword">template</span> specialization</div><div class="line">    <span class="stringliteral">&#39;main()::(anonymous class)::operator()&lt;Person&gt;&#39;</span> requested here</div><div class="line">serialize(std::cout, john);</div><div class="line">         ^</div></div><!-- fragment --><p>Not that bad, right? However, since small examples are very good to show off without actually doing something useful, let's examine a real world example.</p>
300 <h2><a class="anchor" id="tutorial-quickstart-any"></a>
301 A real world example</h2>
302 <p>In this section our goal will be to implement a kind of <code>switch</code> statement able to process <code>boost::any</code>s. Given a <code>boost::any</code>, the goal is to dispatch to the function associated to the dynamic type of the <code>any</code>:</p>
303 <div class="fragment"><div class="line"><a class="code" href="group__group-Searchable.html#gab7d632b9319b10b1eb7e98f9e1cf8a28">boost::any</a> a = <span class="charliteral">&#39;x&#39;</span>;</div><div class="line">std::string r = switch_(a)(</div><div class="line">  case_&lt;int&gt;([](<span class="keyword">auto</span> i) { <span class="keywordflow">return</span> <span class="stringliteral">&quot;int: &quot;</span>s + std::to_string(i); }),</div><div class="line">  case_&lt;char&gt;([](<span class="keyword">auto</span> c) { <span class="keywordflow">return</span> <span class="stringliteral">&quot;char: &quot;</span>s + std::string{c}; }),</div><div class="line">  default_([] { <span class="keywordflow">return</span> <span class="stringliteral">&quot;unknown&quot;</span>s; })</div><div class="line">);</div><div class="line"></div><div class="line">assert(r == <span class="stringliteral">&quot;char: x&quot;</span>s);</div></div><!-- fragment --> <dl class="section note"><dt>Note</dt><dd>In the documentation, we will often use the <code>s</code> suffix on string literals to create <code>std::string</code>s without syntactic overhead. This is a standard-defined <a href="http://en.wikipedia.org/wiki/C%2B%2B11#User-defined_literals">C++14 user-defined literal</a>.</dd></dl>
304 <p>Since the any holds a <code>char</code>, the second function is called with the <code>char</code> inside it. If the <code>any</code> had held an <code>int</code> instead, the first function would have been called with the <code>int</code> inside it. When the dynamic type of the <code>any</code> does not match any of the covered cases, the <code>default_</code> function is called instead. Finally, the result of the <code>switch</code> is the result of calling the function associated to the <code>any</code>'s dynamic type. The type of that result is inferred to be the common type of the result of all the provided functions:</p>
305 <div class="fragment"><div class="line"><a class="code" href="group__group-Searchable.html#gab7d632b9319b10b1eb7e98f9e1cf8a28">boost::any</a> a = <span class="charliteral">&#39;x&#39;</span>;</div><div class="line"><span class="keyword">auto</span> r = switch_(a)(</div><div class="line">  case_&lt;int&gt;([](<span class="keyword">auto</span>) -&gt; <span class="keywordtype">int</span> { <span class="keywordflow">return</span> 1; }),</div><div class="line">  case_&lt;char&gt;([](<span class="keyword">auto</span>) -&gt; <span class="keywordtype">long</span> { <span class="keywordflow">return</span> 2l; }),</div><div class="line">  default_([]() -&gt; <span class="keywordtype">long</span> <span class="keywordtype">long</span> { <span class="keywordflow">return</span> 3ll; })</div><div class="line">);</div><div class="line"></div><div class="line"><span class="comment">// r is inferred to be a long long</span></div><div class="line">static_assert(std::is_same&lt;decltype(r), <span class="keywordtype">long</span> <span class="keywordtype">long</span>&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">assert(r == 2ll);</div></div><!-- fragment --><p> We'll now look at how this utility can be implemented using Hana. The first step is to associate each type to a function. To do so, we represent each <code>case_</code> as a <code>hana::pair</code> whose first element is a type and whose second element is a function. Furthermore, we (arbitrarily) decide to represent the <code>default_</code> case as a <code>hana::pair</code> mapping a dummy type to a function:</p>
306 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">auto</span> case_ = [](<span class="keyword">auto</span> f) {</div><div class="line">  <span class="keywordflow">return</span> hana::make_pair(hana::type_c&lt;T&gt;, f);</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">struct </span>default_t;</div><div class="line"><span class="keyword">auto</span> default_ = case_&lt;default_t&gt;;</div></div><!-- fragment --><p> To provide the interface we showed above, <code>switch_</code> will have to return a function taking the cases. In other words, <code>switch_(a)</code> must be a function taking any number of cases (which are <code>hana::pair</code>s), and performing the logic to dispatch <code>a</code> to the right function. This can easily be achieved by having <code>switch_</code> return a C++14 generic lambda:</p>
307 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Any&gt;</div><div class="line"><span class="keyword">auto</span> switch_(Any&amp; a) {</div><div class="line">  <span class="keywordflow">return</span> [&amp;a](<span class="keyword">auto</span> ...cases_) {</div><div class="line">    <span class="comment">// ...</span></div><div class="line">  };</div><div class="line">}</div></div><!-- fragment --><p>However, since parameter packs are not very flexible, we'll put the cases into a tuple so we can manipulate them:</p>
308 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Any&gt;</div><div class="line"><span class="keyword">auto</span> switch_(Any&amp; a) {</div><div class="line">  <span class="keywordflow">return</span> [&amp;a](<span class="keyword">auto</span> ...cases_) {</div><div class="line">    <span class="keyword">auto</span> cases = hana::make_tuple(cases_...);</div><div class="line">    <span class="comment">// ...</span></div><div class="line">  };</div><div class="line">}</div></div><!-- fragment --><p>Notice how the <code>auto</code> keyword is used when defining <code>cases</code>; it is often easier to let the compiler deduce the type of the tuple and use <code>make_tuple</code> instead of working out the types manually. The next step is to separate the default case from the rest of the cases. This is where things start to get interesting. To do so, we use Hana's <code>find_if</code> algorithm, which works a bit like <code>std::find_if</code>:</p>
309 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Any&gt;</div><div class="line"><span class="keyword">auto</span> switch_(Any&amp; a) {</div><div class="line">  <span class="keywordflow">return</span> [&amp;a](<span class="keyword">auto</span> ...cases_) {</div><div class="line">    <span class="keyword">auto</span> cases = hana::make_tuple(cases_...);</div><div class="line"></div><div class="line">    <span class="keyword">auto</span> default_ = <a class="code" href="group__group-Searchable.html#ga7f99b80672aa80a7eb8b223955ce546f">hana::find_if</a>(cases, [](<span class="keyword">auto</span> <span class="keyword">const</span>&amp; c) {</div><div class="line">      <span class="keywordflow">return</span> <a class="code" href="group__group-Product.html#ga34bbf4281de06dc3540441e8b2bd24f4">hana::first</a>(c) == hana::type_c&lt;default_t&gt;;</div><div class="line">    });</div><div class="line"></div><div class="line">    <span class="comment">// ...</span></div><div class="line">  };</div><div class="line">}</div></div><!-- fragment --><p><code>find_if</code> takes a <code>tuple</code> and a predicate, and returns the first element of the tuple which satisfies the predicate. The result is returned as a <code>hana::optional</code>, which is very similar to a <code>std::optional</code>, except whether that optional value is empty or not is known at compile-time. If the predicate is not satisfied for any element of the <code>tuple</code>, <code>find_if</code> returns <code>nothing</code> (an empty value). Otherwise, it returns <code>just(x)</code> (a non-empty value), where <code>x</code> is the first element satisfying the predicate. Unlike predicates used in STL algorithms, the predicate used here must be generic because the tuple's elements are heterogeneous. Furthermore, that predicate must return what Hana calls an <code>IntegralConstant</code>, which means that the predicate's result must be known at compile-time. These details are explained in the section on <a class="el" href="index.html#tutorial-algorithms-cross_phase">cross-phase algorithms</a>. Inside the predicate, we simply compare the type of the case's first element to <code>type_c&lt;default_t&gt;</code>. If you recall that we were using <code>hana::pair</code>s to encode cases, this simply means that we're finding the default case among all of the provided cases. But what if no default case was provided? We should fail at compile-time, of course!</p>
310 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Any&gt;</div><div class="line"><span class="keyword">auto</span> switch_(Any&amp; a) {</div><div class="line">  <span class="keywordflow">return</span> [&amp;a](<span class="keyword">auto</span> ...cases_) {</div><div class="line">    <span class="keyword">auto</span> cases = hana::make_tuple(cases_...);</div><div class="line"></div><div class="line">    <span class="keyword">auto</span> default_ = <a class="code" href="group__group-Searchable.html#ga7f99b80672aa80a7eb8b223955ce546f">hana::find_if</a>(cases, [](<span class="keyword">auto</span> <span class="keyword">const</span>&amp; c) {</div><div class="line">      <span class="keywordflow">return</span> <a class="code" href="group__group-Product.html#ga34bbf4281de06dc3540441e8b2bd24f4">hana::first</a>(c) == hana::type_c&lt;default_t&gt;;</div><div class="line">    });</div><div class="line">    static_assert(default_ != hana::nothing,</div><div class="line">      <span class="stringliteral">&quot;switch is missing a default_ case&quot;</span>);</div><div class="line"></div><div class="line">    <span class="comment">// ...</span></div><div class="line">  };</div><div class="line">}</div></div><!-- fragment --><p>Notice how we can use <code>static_assert</code> on the result of the comparison with <code>nothing</code>, even though <code>default_</code> is a non-<code>constexpr</code> object? Boldly, Hana makes sure that no information that's known at compile-time is lost to the runtime, which is clearly the case of the presence of a <code>default_</code> case. The next step is to gather the set of non-default cases. To achieve this, we use the <code>filter</code> algorithm, which keeps only the elements of the sequence satisfying the predicate:</p>
311 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Any&gt;</div><div class="line"><span class="keyword">auto</span> switch_(Any&amp; a) {</div><div class="line">  <span class="keywordflow">return</span> [&amp;a](<span class="keyword">auto</span> ...cases_) {</div><div class="line">    <span class="keyword">auto</span> cases = hana::make_tuple(cases_...);</div><div class="line"></div><div class="line">    <span class="keyword">auto</span> default_ = <a class="code" href="group__group-Searchable.html#ga7f99b80672aa80a7eb8b223955ce546f">hana::find_if</a>(cases, [](<span class="keyword">auto</span> <span class="keyword">const</span>&amp; c) {</div><div class="line">      <span class="keywordflow">return</span> <a class="code" href="group__group-Product.html#ga34bbf4281de06dc3540441e8b2bd24f4">hana::first</a>(c) == hana::type_c&lt;default_t&gt;;</div><div class="line">    });</div><div class="line">    static_assert(default_ != hana::nothing,</div><div class="line">      <span class="stringliteral">&quot;switch is missing a default_ case&quot;</span>);</div><div class="line"></div><div class="line">    <span class="keyword">auto</span> rest = <a class="code" href="group__group-MonadPlus.html#ga65cc6d9f522fb9e8e3b28d80ee5c822a">hana::filter</a>(cases, [](<span class="keyword">auto</span> <span class="keyword">const</span>&amp; c) {</div><div class="line">      <span class="keywordflow">return</span> <a class="code" href="group__group-Product.html#ga34bbf4281de06dc3540441e8b2bd24f4">hana::first</a>(c) != hana::type_c&lt;default_t&gt;;</div><div class="line">    });</div><div class="line"></div><div class="line">    <span class="comment">// ...</span></div><div class="line">  };</div><div class="line">}</div></div><!-- fragment --><p>The next step is to find the first case matching the dynamic type of the <code>any</code>, and then call the function associated to that case. The simplest way to do this is to use classic recursion with variadic parameter packs. Of course, we could probably intertwine Hana algorithms in a convoluted way to achieve this, but sometimes the best way to do something is to write it from scratch using basic techniques. To do so, we'll call an implementation function with the contents of the <code>rest</code> tuple by using the <code>unpack</code> function:</p>
312 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Any&gt;</div><div class="line"><span class="keyword">auto</span> switch_(Any&amp; a) {</div><div class="line">  <span class="keywordflow">return</span> [&amp;a](<span class="keyword">auto</span> ...cases_) {</div><div class="line">    <span class="keyword">auto</span> cases = hana::make_tuple(cases_...);</div><div class="line"></div><div class="line">    <span class="keyword">auto</span> default_ = <a class="code" href="group__group-Searchable.html#ga7f99b80672aa80a7eb8b223955ce546f">hana::find_if</a>(cases, [](<span class="keyword">auto</span> <span class="keyword">const</span>&amp; c) {</div><div class="line">      <span class="keywordflow">return</span> <a class="code" href="group__group-Product.html#ga34bbf4281de06dc3540441e8b2bd24f4">hana::first</a>(c) == hana::type_c&lt;default_t&gt;;</div><div class="line">    });</div><div class="line">    static_assert(default_ != hana::nothing,</div><div class="line">      <span class="stringliteral">&quot;switch is missing a default_ case&quot;</span>);</div><div class="line"></div><div class="line">    <span class="keyword">auto</span> rest = <a class="code" href="group__group-MonadPlus.html#ga65cc6d9f522fb9e8e3b28d80ee5c822a">hana::filter</a>(cases, [](<span class="keyword">auto</span> <span class="keyword">const</span>&amp; c) {</div><div class="line">      <span class="keywordflow">return</span> <a class="code" href="group__group-Product.html#ga34bbf4281de06dc3540441e8b2bd24f4">hana::first</a>(c) != hana::type_c&lt;default_t&gt;;</div><div class="line">    });</div><div class="line"></div><div class="line">    <span class="keywordflow">return</span> <a class="code" href="group__group-Foldable.html#ga7b0c23944364ce61136e10b978ae2170">hana::unpack</a>(rest, [&amp;](<span class="keyword">auto</span>&amp; ...rest) {</div><div class="line">      <span class="keywordflow">return</span> process(a, a.type(), <a class="code" href="group__group-Product.html#ga7bb979d59ffc3ab862cb7d9dc7730077">hana::second</a>(*default_), rest...);</div><div class="line">    });</div><div class="line">  };</div><div class="line">}</div></div><!-- fragment --><p> <code>unpack</code> takes a <code>tuple</code> and a function, and calls the function with the content of the <code>tuple</code> as arguments. The result of <code>unpack</code> is the result of calling that function. In our case, the function is a generic lambda which in turn calls the <code>process</code> function. Our reason for using <code>unpack</code> here was to turn the <code>rest</code> tuple into a parameter pack of arguments, which are easier to process recursively than tuples. Before we move on to the <code>process</code> function, it is worthwhile to explain what <code>second(*default_)</code> is all about. As we explained earlier, <code>default_</code> is an optional value. Like <code>std::optional</code>, this optional value overloads the dereference operator (and the arrow operator) to allow accessing the value inside the <code>optional</code>. If the optional is empty (<code>nothing</code>), a compile-time error is triggered. Since we know <code>default_</code> is not empty (we checked that just above), what we're doing is simply pass the function associated to the default case to the <code>process</code> function. We're now ready for the final step, which is the implementation of the <code>process</code> function:</p>
313 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Any, <span class="keyword">typename</span> Default&gt;</div><div class="line"><span class="keyword">auto</span> process(Any&amp;, std::type_index <span class="keyword">const</span>&amp;, Default&amp; default_) {</div><div class="line">  <span class="keywordflow">return</span> default_();</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Any, <span class="keyword">typename</span> Default, <span class="keyword">typename</span> Case, <span class="keyword">typename</span> ...Rest&gt;</div><div class="line"><span class="keyword">auto</span> process(Any&amp; a, std::type_index <span class="keyword">const</span>&amp; t, Default&amp; default_,</div><div class="line">             Case&amp; case_, Rest&amp; ...rest)</div><div class="line">{</div><div class="line">  <span class="keyword">using</span> T = <span class="keyword">typename</span> decltype(+<a class="code" href="group__group-Product.html#ga34bbf4281de06dc3540441e8b2bd24f4">hana::first</a>(case_))::type;</div><div class="line">  <span class="keywordflow">return</span> t == <span class="keyword">typeid</span>(T) ? <a class="code" href="group__group-Product.html#ga7bb979d59ffc3ab862cb7d9dc7730077">hana::second</a>(case_)(*boost::unsafe_any_cast&lt;T&gt;(&amp;a))</div><div class="line">                        : process(a, t, default_, rest...);</div><div class="line">}</div></div><!-- fragment --><p> There are two overloads of this function: an overload for when there is at least one case to process, and the base case overload for when there's only the default case. As we would expect, the base case simply calls the default function and returns that result. The other overload is slightly more interesting. First, we retrieve the type associated to that case and store it in <code>T</code>. This <code>decltype(...)::type</code> dance might seem convoluted, but it is actually quite simple. Roughly speaking, this takes a type represented as an object (a <code>type&lt;T&gt;</code>) and pulls it back down to the type level (a <code>T</code>). The details are explained in the section on <a class="el" href="index.html#tutorial-type">type-level computations</a>. Then, we compare whether the dynamic type of the <code>any</code> matches this case, and if so we call the function associated to this case with the <code>any</code> casted to the proper type. Otherwise, we simply call <code>process</code> recursively with the rest of the cases. Pretty simple, wasn't it? Here's the final solution:</p>
314 <div class="fragment"><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="hana_8hpp.html">boost/hana.hpp</a>&gt;</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;boost/any.hpp&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;cassert&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;string&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;typeindex&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;typeinfo&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;utility&gt;</span></div><div class="line"><span class="keyword">namespace </span>hana = <a class="code" href="namespaceboost_1_1hana.html">boost::hana</a>;</div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">//! [cases]</span></div><div class="line"><span class="comment"></span><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">auto</span> case_ = [](<span class="keyword">auto</span> f) {</div><div class="line">  <span class="keywordflow">return</span> hana::make_pair(hana::type_c&lt;T&gt;, f);</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">struct </span>default_t;</div><div class="line"><span class="keyword">auto</span> default_ = case_&lt;default_t&gt;;<span class="comment"></span></div><div class="line"><span class="comment">//! [cases]</span></div><div class="line"><span class="comment"></span><span class="comment"></span></div><div class="line"><span class="comment">//! [process]</span></div><div class="line"><span class="comment"></span><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Any, <span class="keyword">typename</span> Default&gt;</div><div class="line"><span class="keyword">auto</span> process(Any&amp;, std::type_index <span class="keyword">const</span>&amp;, Default&amp; default_) {</div><div class="line">  <span class="keywordflow">return</span> default_();</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Any, <span class="keyword">typename</span> Default, <span class="keyword">typename</span> Case, <span class="keyword">typename</span> ...Rest&gt;</div><div class="line"><span class="keyword">auto</span> process(Any&amp; a, std::type_index <span class="keyword">const</span>&amp; t, Default&amp; default_,</div><div class="line">             Case&amp; case_, Rest&amp; ...rest)</div><div class="line">{</div><div class="line">  <span class="keyword">using</span> T = <span class="keyword">typename</span> decltype(+<a class="code" href="group__group-Product.html#ga34bbf4281de06dc3540441e8b2bd24f4">hana::first</a>(case_))::type;</div><div class="line">  <span class="keywordflow">return</span> t == <span class="keyword">typeid</span>(T) ? <a class="code" href="group__group-Product.html#ga7bb979d59ffc3ab862cb7d9dc7730077">hana::second</a>(case_)(*boost::unsafe_any_cast&lt;T&gt;(&amp;a))</div><div class="line">                        : process(a, t, default_, rest...);</div><div class="line">}<span class="comment"></span></div><div class="line"><span class="comment">//! [process]</span></div><div class="line"><span class="comment"></span><span class="comment"></span></div><div class="line"><span class="comment">//! [switch_]</span></div><div class="line"><span class="comment"></span><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Any&gt;</div><div class="line"><span class="keyword">auto</span> switch_(Any&amp; a) {</div><div class="line">  <span class="keywordflow">return</span> [&amp;a](<span class="keyword">auto</span> ...cases_) {</div><div class="line">    <span class="keyword">auto</span> cases = hana::make_tuple(cases_...);</div><div class="line"></div><div class="line">    <span class="keyword">auto</span> default_ = <a class="code" href="group__group-Searchable.html#ga7f99b80672aa80a7eb8b223955ce546f">hana::find_if</a>(cases, [](<span class="keyword">auto</span> <span class="keyword">const</span>&amp; c) {</div><div class="line">      <span class="keywordflow">return</span> <a class="code" href="group__group-Product.html#ga34bbf4281de06dc3540441e8b2bd24f4">hana::first</a>(c) == hana::type_c&lt;default_t&gt;;</div><div class="line">    });</div><div class="line">    static_assert(default_ != hana::nothing,</div><div class="line">      <span class="stringliteral">&quot;switch is missing a default_ case&quot;</span>);</div><div class="line"></div><div class="line">    <span class="keyword">auto</span> rest = <a class="code" href="group__group-MonadPlus.html#ga65cc6d9f522fb9e8e3b28d80ee5c822a">hana::filter</a>(cases, [](<span class="keyword">auto</span> <span class="keyword">const</span>&amp; c) {</div><div class="line">      <span class="keywordflow">return</span> <a class="code" href="group__group-Product.html#ga34bbf4281de06dc3540441e8b2bd24f4">hana::first</a>(c) != hana::type_c&lt;default_t&gt;;</div><div class="line">    });</div><div class="line"></div><div class="line">    <span class="keywordflow">return</span> <a class="code" href="group__group-Foldable.html#ga7b0c23944364ce61136e10b978ae2170">hana::unpack</a>(rest, [&amp;](<span class="keyword">auto</span>&amp; ...rest) {</div><div class="line">      <span class="keywordflow">return</span> process(a, a.type(), <a class="code" href="group__group-Product.html#ga7bb979d59ffc3ab862cb7d9dc7730077">hana::second</a>(*default_), rest...);</div><div class="line">    });</div><div class="line">  };</div><div class="line">}<span class="comment"></span></div><div class="line"><span class="comment">//! [switch_]</span></div></div><!-- fragment --><p> That's it for the quick start! This example only introduced a couple of useful algorithms (<code>find_if</code>, <code>filter</code>, <code>unpack</code>) and heterogeneous containers (<code>tuple</code>, <code>optional</code>), but rest assured that there is much more. The next sections of the tutorial gradually introduce general concepts pertaining to Hana in a friendly way, but you may use the following cheatsheet for quick reference if you want to start coding right away. This cheatsheet contains the most frequently used algorithms and containers, along with a short description of what each of them does.</p>
315 <h1><a class="anchor" id="tutorial-cheatsheet"></a>
316 Cheatsheet</h1>
317 <h3>Remarks</h3>
318 <ul>
319 <li>Most algorithms work on both types and values (see the section on <a class="el" href="index.html#tutorial-type">type computations</a>)</li>
320 <li>Algorithms always return their result as a new container; no in-place mutation is ever performed (see the section on <a class="el" href="index.html#tutorial-algorithms">algorithms</a>)</li>
321 <li>All algorithms are <code>constexpr</code> function objects</li>
322 </ul>
323 <table class="doxtable">
324 <tr>
325 <th align="left">container </th><th align="left">description  </th></tr>
326 <tr>
327 <td align="left"><code><a class="el" href="structboost_1_1hana_1_1tuple.html">tuple</a></code> </td><td align="left">General purpose index-based heterogeneous sequence with a fixed length. Use this as a <code>std::vector</code> for heterogeneous objects. </td></tr>
328 <tr>
329 <td align="left"><code><a class="el" href="structboost_1_1hana_1_1optional.html">optional</a></code> </td><td align="left">Represents an optional value, i.e. a value that can be empty. This is a bit like <code>std::optional</code>, except that the emptiness is known at compile-time. </td></tr>
330 <tr>
331 <td align="left"><code><a class="el" href="structboost_1_1hana_1_1map.html">map</a></code> </td><td align="left">Unordered associative array mapping (unique) compile-time entities to arbitrary objects. This is like <code>std::unordered_map</code> for heterogeneous objects. </td></tr>
332 <tr>
333 <td align="left"><code><a class="el" href="structboost_1_1hana_1_1set.html">set</a></code> </td><td align="left">Unordered container holding unique keys that must be compile-time entities. This is like <code>std::unordered_set</code> for heterogeneous objects. </td></tr>
334 <tr>
335 <td align="left"><code><a class="el" href="structboost_1_1hana_1_1range.html">range</a></code> </td><td align="left">Represents an interval of compile-time numbers. This is like <code><a class="el" href="structstd_1_1integer__sequence.html" title="Adaptation of std::integer_sequence for Hana. ">std::integer_sequence</a></code>, but better. </td></tr>
336 <tr>
337 <td align="left"><code><a class="el" href="structboost_1_1hana_1_1pair.html">pair</a></code> </td><td align="left">Container holding two heterogeneous objects. Like <code><a class="el" href="structstd_1_1pair.html" title="Adaptation of std::pair for Hana. ">std::pair</a></code>, but compresses the storage of empty types. </td></tr>
338 <tr>
339 <td align="left"><code><a class="el" href="structboost_1_1hana_1_1string.html">string</a></code> </td><td align="left">Compile-time string. </td></tr>
340 <tr>
341 <td align="left"><code><a class="el" href="structboost_1_1hana_1_1type.html">type</a></code> </td><td align="left">Container representing a C++ type. This is the root of the unification between types and values, and is of interest for MPL-style computations (type-level computations). </td></tr>
342 <tr>
343 <td align="left"><code><a class="el" href="structboost_1_1hana_1_1integral__constant.html">integral_constant</a></code> </td><td align="left">Represents a compile-time number. This is very similar to <code><a class="el" href="structstd_1_1integral__constant.html" title="Adapter for std::integral_constants. ">std::integral_constant</a></code>, except that <code>hana::integral_constant</code> also defines operators and more syntactic sugar. </td></tr>
344 <tr>
345 <td align="left"><code><a class="el" href="structboost_1_1hana_1_1lazy.html">lazy</a></code> </td><td align="left">Encapsulates a lazy value or computation. </td></tr>
346 <tr>
347 <td align="left"><code><a class="el" href="structboost_1_1hana_1_1basic__tuple.html">basic_tuple</a></code> </td><td align="left">Stripped-down version of <code>hana::tuple</code>. Not standards conforming, but more compile-time efficient. </td></tr>
348 </table>
349 <table class="doxtable">
350 <tr>
351 <th align="left">function </th><th align="left">description  </th></tr>
352 <tr>
353 <td align="left"><code><a class="el" href="group__group-Functor.html#ga7cc731e67ebc1f5303be1a97b2d5e0cd">adjust</a>(sequence, value, f)</code> </td><td align="left">Apply a function to each element of a sequence that compares equal to some value and return the result. </td></tr>
354 <tr>
355 <td align="left"><code><a class="el" href="group__group-Functor.html#gaa0490f57047c1b0d75fbe233688358f4">adjust_if</a>(sequence, predicate, f)</code> </td><td align="left">Apply a function to each element of a sequence satisfying some predicate and return the result. </td></tr>
356 <tr>
357 <td align="left"><code>{<a class="el" href="group__group-Searchable.html#ga81ae9764dd7818ad36270c6419fb1082">all</a>,<a class="el" href="group__group-Searchable.html#gab7d632b9319b10b1eb7e98f9e1cf8a28">any</a>,<a class="el" href="group__group-Searchable.html#ga614ff1e575806f59246b17006e19d479">none</a>}(sequence)</code> </td><td align="left">Returns whether all/any/none of the elements of a sequence are true-valued. </td></tr>
358 <tr>
359 <td align="left"><code>{<a class="el" href="group__group-Searchable.html#ga3a168950082f38afd9edf256f336c8ba">all</a>,<a class="el" href="group__group-Searchable.html#ga5f7ff0125c448983e1b96c3ffb84f646">any</a>,<a class="el" href="group__group-Searchable.html#ga43954c791b5b1351fb009e2a643d00f5">none</a>}_of(sequence, predicate)</code> </td><td align="left">Returns whether all/any/none of the elements of the sequence satisfy some predicate. </td></tr>
360 <tr>
361 <td align="left"><code><a class="el" href="group__group-MonadPlus.html#ga08624924fe05f0cfbfbd6e439db01873">append</a>(sequence, value)</code> </td><td align="left">Append an element to a sequence. </td></tr>
362 <tr>
363 <td align="left"><code><a class="el" href="group__group-Iterable.html#ga8a484304380eae38f3d9663d98860129">at</a>(sequence, index)</code> </td><td align="left">Returns the n-th element of a sequence. The index must be an <code>IntegralConstant</code>. </td></tr>
364 <tr>
365 <td align="left"><code><a class="el" href="group__group-Iterable.html#gab3f4d0035345a453284e46303862d463">back</a>(sequence)</code> </td><td align="left">Returns the last element of a non-empty sequence. </td></tr>
366 <tr>
367 <td align="left"><code><a class="el" href="group__group-MonadPlus.html#ga1946e96c3b4c178c7ae8703724c29c37">concat</a>(sequence1, sequence2)</code> </td><td align="left">Concatenate two sequences. </td></tr>
368 <tr>
369 <td align="left"><code><a class="el" href="group__group-Searchable.html#ga38e7748956cbc9f3d9bb035ac8577906">contains</a>(sequence, value)</code> </td><td align="left">Returns whether a sequence contains the given object. </td></tr>
370 <tr>
371 <td align="left"><code><a class="el" href="group__group-Foldable.html#ga3159cfa41be18a396926741b0a3fdefd">count</a>(sequence, value)</code> </td><td align="left">Returns the number of elements that compare equal to the given value. </td></tr>
372 <tr>
373 <td align="left"><code><a class="el" href="group__group-Foldable.html#ga39d71be65d5b98e7d035a3e5c607e1b4">count_if</a>(sequence, predicate)</code> </td><td align="left">Returns the number of elements that satisfy the predicate. </td></tr>
374 <tr>
375 <td align="left"><code><a class="el" href="group__group-Iterable.html#gad23ce0a4906e2bb0a52f38837b134757">drop_front</a>(sequence[, n])</code> </td><td align="left">Drop the first <code>n</code> elements from a sequence, or the whole sequence if <code>length(sequence) &lt;= n</code>. <code>n</code> must be an <code>IntegralConstant</code>. When not provided, <code>n</code> defaults to 1. </td></tr>
376 <tr>
377 <td align="left"><code><a class="el" href="group__group-Iterable.html#ga4dbc6a82f03ca35b7ac418ca30889cc4">drop_front_exactly</a>(sequence[, n])</code> </td><td align="left">Drop the first <code>n</code> elements from a sequence. <code>n</code> must be an <code>IntegralConstant</code> and the sequence must have at least <code>n</code> elements. When not provided, <code>n</code> defaults to 1. </td></tr>
378 <tr>
379 <td align="left"><code><a class="el" href="group__group-Sequence.html#gac10231310abc86b056585ea0d0e96ef7">drop_back</a>(sequence[, n])</code> </td><td align="left">Drop the last <code>n</code> elements from a sequence, or the whole sequence if <code>length(sequence) &lt;= n</code>. <code>n</code> must be an <code>IntegralConstant</code>. When not provided, <code>n</code> defaults to 1. </td></tr>
380 <tr>
381 <td align="left"><code><a class="el" href="group__group-Iterable.html#ga9f1d02c74a6bdc1db260e0d6a8f1ee56">drop_while</a>(sequence, predicate)</code> </td><td align="left">Drops elements from a sequence while a predicate is satisfied. The predicate must return an <code>IntegralConstant</code>. </td></tr>
382 <tr>
383 <td align="left"><code><a class="el" href="group__group-Functor.html#ga2ce68d315f981ef35751c4dc25ad5642">fill</a>(sequence, value)</code> </td><td align="left">Replace all the elements of a sequence with some value. </td></tr>
384 <tr>
385 <td align="left"><code><a class="el" href="group__group-MonadPlus.html#ga65cc6d9f522fb9e8e3b28d80ee5c822a">filter</a>(sequence, predicate)</code> </td><td align="left">Remove all the elements that do not satisfy a predicate. The predicate must return an <code>IntegralConstant</code>. </td></tr>
386 <tr>
387 <td align="left"><code><a class="el" href="group__group-Searchable.html#ga6b6cdd69942b0fe3bf5254247f9c861e">find</a>(sequence, value)</code> </td><td align="left">Find the first element of a sequence which compares equal to some value and return <code>just</code> it, or return <code>nothing</code>. See <code>hana::optional</code>. </td></tr>
388 <tr>
389 <td align="left"><code><a class="el" href="group__group-Searchable.html#ga7f99b80672aa80a7eb8b223955ce546f">find_if</a>(sequence, predicate)</code> </td><td align="left">Find the first element of a sequence satisfying the predicate and return <code>just</code> it, or return <code>nothing</code>. See <code>hana::optional</code>. </td></tr>
390 <tr>
391 <td align="left"><code><a class="el" href="group__group-Monad.html#gaa5fec6fb418de5da3ecb500fd6cc54dd">flatten</a>(sequence)</code> </td><td align="left">Flatten a sequence of sequences, a bit like <code>std::tuple_cat</code>. </td></tr>
392 <tr>
393 <td align="left"><code><a class="el" href="group__group-Foldable.html#ga38c6b3f6b1cbadb9b8432a05ff16b7d2">fold_left</a>(sequence[, state], f)</code> </td><td align="left">Accumulates the elements of a sequence from the left, optionally with a provided initial state. </td></tr>
394 <tr>
395 <td align="left"><code><a class="el" href="group__group-Foldable.html#ga77d43badebd59b046cf93598733649b4">fold_right</a>(sequence[, state], f)</code> </td><td align="left">Accumulates the elements of a sequence from the right, optionally with a provided initial state. </td></tr>
396 <tr>
397 <td align="left"><code><a class="el" href="group__group-Foldable.html#gaa0fde17f3b947a0678a1c0c01232f2cc">fold</a>(sequence[, state], f)</code> </td><td align="left">Equivalent to <code>fold_left</code>; provided for consistency with Boost.MPL and Boost.Fusion. </td></tr>
398 <tr>
399 <td align="left"><code><a class="el" href="group__group-Foldable.html#ga2af382f7e644ce3707710bbad313e9c2">for_each</a>(sequence, f)</code> </td><td align="left">Call a function on each element of a sequence. Returns <code>void</code>. </td></tr>
400 <tr>
401 <td align="left"><code><a class="el" href="group__group-Iterable.html#ga8a67ea10e8082dbe6705e573fa978444">front</a>(sequence)</code> </td><td align="left">Returns the first element of a non-empty sequence. </td></tr>
402 <tr>
403 <td align="left"><code><a class="el" href="group__group-Sequence.html#gacefca884b3580664b63238cf8ba33fd3">group</a>(sequence[, predicate])</code> </td><td align="left">Group adjacent elements of a sequence which all satisfy (or all do not satisfy) some predicate. The predicate defaults to equality, in which case the elements must be <code>Comparable</code>. </td></tr>
404 <tr>
405 <td align="left"><code><a class="el" href="group__group-Sequence.html#gae22a1a184b1b2dd550fa4fa619bed2e9">insert</a>(sequence, index, element)</code> </td><td align="left">Insert an element at a given index. The index must be an <code>IntegralConstant</code>. </td></tr>
406 <tr>
407 <td align="left"><code><a class="el" href="group__group-Sequence.html#ga3410ba833cf1ff1d929fcfda4df2eae1">insert_range</a>(sequence, index, elements)</code> </td><td align="left">Insert a sequence of elements at a given index. The index must be an <code>IntegralConstant</code>. </td></tr>
408 <tr>
409 <td align="left"><code><a class="el" href="group__group-Iterable.html#ga2a05f564f8a7e4afa04fcbc07ad8f394">is_empty</a>(sequence)</code> </td><td align="left">Returns whether a sequence is empty as an <code>IntegralConstant</code>. </td></tr>
410 <tr>
411 <td align="left"><code><a class="el" href="group__group-Foldable.html#gaf0f8f717245620dc28cd7d7fa44d7475">length</a>(sequence)</code> </td><td align="left">Returns the length of a sequence as an <code>IntegralConstant</code>. </td></tr>
412 <tr>
413 <td align="left"><code><a class="el" href="group__group-Iterable.html#ga660b2649d63ac71dacc64c3852c981e5">lexicographical_compare</a>(sequence1, sequence2[, predicate])</code> </td><td align="left">Performs a lexicographical comparison of two sequences, optionally with a custom predicate, by default with <code>hana::less</code>. </td></tr>
414 <tr>
415 <td align="left"><code><a class="el" href="group__group-Foldable.html#gaf3861a91607203b63a12708e18a4eac5">maximum</a>(sequence[, predicate])</code> </td><td align="left">Returns the greatest element of a sequence, optionally according to a predicate. The elements must be <code>Orderable</code> if no predicate is provided. </td></tr>
416 <tr>
417 <td align="left"><code><a class="el" href="group__group-Foldable.html#ga347429451fdb15f9f7a7fc0de293be1a">minimum</a>(sequence[, predicate])</code> </td><td align="left">Returns the smallest element of a sequence, optionally according to a predicate. The elements must be <code>Orderable</code> if no predicate is provided. </td></tr>
418 <tr>
419 <td align="left"><code><a class="el" href="group__group-Sequence.html#ga5e84ac3f1eb09c637b6b38ef42dccd8d">partition</a>(sequence, predicate)</code> </td><td align="left">Partition a sequence into a pair of elements that satisfy some predicate, and elements that do not satisfy it. </td></tr>
420 <tr>
421 <td align="left"><code><a class="el" href="group__group-MonadPlus.html#ga69afbfd4e91125e3e52fcb409135ca7c">prepend</a>(sequence, value)</code> </td><td align="left">Prepend an element to a sequence. </td></tr>
422 <tr>
423 <td align="left"><code><a class="el" href="group__group-MonadPlus.html#gae3cc0d6e0d8feb3d677bd1da64da6f43">remove</a>(sequence, value)</code> </td><td align="left">Remove all the elements that are equal to a given value. </td></tr>
424 <tr>
425 <td align="left"><code><a class="el" href="group__group-Sequence.html#ga80724ec8ecf319a1e695988a69e22f87">remove_at</a>(sequence, index)</code> </td><td align="left">Remove the element at the given index. The index must be an <code>IntegralConstant</code>. </td></tr>
426 <tr>
427 <td align="left"><code><a class="el" href="group__group-MonadPlus.html#ga9700169a45664d50377c1be9d58accd3">remove_if</a>(sequence, predicate)</code> </td><td align="left">Remove all the elements that satisfy a predicate. The predicate must return an <code>IntegralConstant</code>. </td></tr>
428 <tr>
429 <td align="left"><code><a class="el" href="group__group-Sequence.html#ga6f6d5c1f335780c91d29626fde615c78">remove_range</a>(sequence, from, to)</code> </td><td align="left">Remove the elements at indices in the given <code>[from, to)</code> half-open interval. The indices must be <code>IntegralConstant</code>s. </td></tr>
430 <tr>
431 <td align="left"><code><a class="el" href="group__group-Functor.html#ga94cd3a75d59d70d77cfce144c4acf8ab">replace</a>(sequence, oldval, newval)</code> </td><td align="left">Replace the elements of a sequence that compare equal to some value by some other value. </td></tr>
432 <tr>
433 <td align="left"><code><a class="el" href="group__group-Functor.html#ga1d21b4bccd16367d164fbe0d9ef52150">replace_if</a>(sequence, predicate, newval)</code> </td><td align="left">Replace the elements of a sequence that satisfy some predicate by some value. </td></tr>
434 <tr>
435 <td align="left"><code><a class="el" href="group__group-Sequence.html#ga28037560e8f224c53cf6ac168d03a067">reverse</a>(sequence)</code> </td><td align="left">Reverse the order of the elements in a sequence. </td></tr>
436 <tr>
437 <td align="left"><code><a class="el" href="group__group-Foldable.html#ga947602718a53bd7fcd5c20477694cdcd">reverse_fold</a>(sequence[, state], f)</code> </td><td align="left">Equivalent to <code>fold_right</code>; provided for consistency with Boost.MPL and Boost.Fusion. </td></tr>
438 <tr>
439 <td align="left"><code><a class="el" href="group__group-Foldable.html#ga8ec3ac9a6f5014db943f61ebc9e1e36e">size</a>(sequence)</code> </td><td align="left">Equivalent to <code>length</code>; provided for consistency with the C++ standard library. </td></tr>
440 <tr>
441 <td align="left"><code><a class="el" href="group__group-Sequence.html#ga245d8abaf6ba67e64020be51c8366081">slice</a>(sequence, indices)</code> </td><td align="left">Returns a new sequence containing the elements at the given indices of the original sequence. </td></tr>
442 <tr>
443 <td align="left"><code><a class="el" href="group__group-Sequence.html#gae1f6a2a9cb70564d43c6b3c663b25dd7">slice_c</a>&lt;from, to&gt;(sequence)</code> </td><td align="left">Returns a new sequence containing the elements at indices contained in <code>[from, to)</code> of the original sequence. </td></tr>
444 <tr>
445 <td align="left"><code><a class="el" href="group__group-Sequence.html#gac000a79eb7b9d44ecc8982c93daa40e5">sort</a>(sequence[, predicate])</code> </td><td align="left">Sort (stably) the elements of a sequence, optionally according to a predicate. The elements must be <code>Orderable</code> if no predicate is provided. </td></tr>
446 <tr>
447 <td align="left"><code><a class="el" href="group__group-Sequence.html#ga8d302de01b94b4b17f3bd81e09f42920">take_back</a>(sequence, number)</code> </td><td align="left">Take the last n elements of a sequence, or the whole sequence if <code>length(sequence) &lt;= n</code>. n must be an <code>IntegralConstant</code>. </td></tr>
448 <tr>
449 <td align="left"><code><a class="el" href="group__group-Sequence.html#ga5112e6070d29b4f7fde3f44825da3316">take_front</a>(sequence, number)</code> </td><td align="left">Take the first n elements of a sequence, or the whole sequence if <code>length(sequence) &lt;= n</code>. n must be an <code>IntegralConstant</code>. </td></tr>
450 <tr>
451 <td align="left"><code><a class="el" href="group__group-Sequence.html#ga2d4db4ec5ec5bc16fe74f57de12697fd">take_while</a>(sequence, predicate)</code> </td><td align="left">Take elements of a sequence while some predicate is satisfied, and return that. </td></tr>
452 <tr>
453 <td align="left"><code><a class="el" href="group__group-Functor.html#ga5a8975f6e55375d5b6038a9c36ee63e7">transform</a>(sequence, f)</code> </td><td align="left">Apply a function to each element of a sequence and return the result. </td></tr>
454 <tr>
455 <td align="left"><code><a class="el" href="group__group-Sequence.html#ga35349be79e646c4f5bdd74ec96a846ab">unique</a>(sequence[, predicate])</code> </td><td align="left">Removes all consecutive duplicates from a sequence. The predicate defaults to equality, in which case the elements must be <code>Comparable</code>. </td></tr>
456 <tr>
457 <td align="left"><code><a class="el" href="group__group-Foldable.html#ga7b0c23944364ce61136e10b978ae2170">unpack</a>(sequence, f)</code> </td><td align="left">Calls a function with the contents of a sequence. Equivalent to <code>f(x1, ..., xN)</code>. </td></tr>
458 <tr>
459 <td align="left"><code><a class="el" href="group__group-Sequence.html#gaa5a378d4e71a91e0d6cd3959d9818e8a">zip</a>(s1, ..., sN)</code> </td><td align="left">Zip <code>N</code> sequences into a sequence of tuples. All the sequences must have the same length. </td></tr>
460 <tr>
461 <td align="left"><code><a class="el" href="group__group-Sequence.html#gade78593b3ff51fc5479e1da97142fef5">zip_shortest</a>(s1, ..., sN)</code> </td><td align="left">Zip <code>N</code> sequences into a sequence of tuples. The resulting sequence has the length of the shortest input sequence. </td></tr>
462 <tr>
463 <td align="left"><code><a class="el" href="group__group-Sequence.html#ga6a4bf8549ce69b5b5b7377aec225a0e3">zip_with</a>(f, s1, ..., sN)</code> </td><td align="left">Zip <code>N</code> sequences with a <code>N</code>-ary function. All the sequences must have the same length. </td></tr>
464 <tr>
465 <td align="left"><code><a class="el" href="group__group-Sequence.html#gae7a51104a77db79a0407d7d67b034667">zip_shortest_with</a>(f, s1, ..., sN)</code> </td><td align="left">Zip <code>N</code> sequences with a <code>N</code>-ary function. The resulting sequence has the length of the shortest input sequence. </td></tr>
466 </table>
467 <h1><a class="anchor" id="tutorial-assert"></a>
468 Assertions</h1>
469 <hr/>
470 <p> In the rest of this tutorial, you will come across code snippets where different kinds of assertions like <code>BOOST_HANA_RUNTIME_CHECK</code> and <code>BOOST_HANA_CONSTANT_CHECK</code> are used. Like any sensible <code>assert</code> macro, they basically check that the condition they are given is satisfied. However, in the context of heterogeneous programming, some informations are known at compile-time, while others are known only at runtime. The exact type of assertion that's used in a context tells you whether the condition that's asserted upon can be known at compile-time or if it must be computed at runtime, which is a very precious piece of information. Here are the different kinds of assertions used in the tutorial, with a small description of their particularities. For more details, you should check the <a class="el" href="group__group-assertions.html">reference on assertions</a>.</p>
471 <table class="doxtable">
472 <tr>
473 <th align="left">assertion </th><th align="left">description  </th></tr>
474 <tr>
475 <td align="left"><code>BOOST_HANA_RUNTIME_CHECK</code> </td><td align="left">Assertion on a condition that is not known until runtime. This assertion provides the weakest form of guarantee. </td></tr>
476 <tr>
477 <td align="left"><code>BOOST_HANA_CONSTEXPR_CHECK</code> </td><td align="left">Assertion on a condition that would be <code>constexpr</code> if lambdas were allowed inside constant expressions. In other words, the only reason for it not being a <code>static_assert</code> is the language limitation that lambdas can't appear in constant expressions, which <a href="https://isocpp.org/files/papers/N4487.pdf">might be lifted</a> in C++17. </td></tr>
478 <tr>
479 <td align="left"><code>static_assert</code> </td><td align="left">Assertion on a <code>constexpr</code> condition. This is stronger than <code>BOOST_HANA_CONSTEXPR_CHECK</code> in that it requires the condition to be a constant expression, and it hence assures that the algorithms used in the expression are <code>constexpr</code>-friendly. </td></tr>
480 <tr>
481 <td align="left"><code>BOOST_HANA_CONSTANT_CHECK</code> </td><td align="left">Assertion on a boolean <code>IntegralConstant</code>. This assertion provides the strongest form of guarantee, because an <code>IntegralConstant</code> can be converted to a <code>constexpr</code> value even if it is not <code>constexpr</code> itself. </td></tr>
482 </table>
483 <h1><a class="anchor" id="tutorial-integral"></a>
484 Compile-time numbers</h1>
485 <hr/>
486 <p> This section introduces the important notion of <code>IntegralConstant</code> and the philosophy behind Hana's metaprogramming paradigm. Let's start with a rather odd question. What is an <code>integral_constant</code>?</p>
487 <div class="fragment"><div class="line"><span class="keyword">template</span>&lt;<span class="keyword">class</span> T, T v&gt;</div><div class="line"><span class="keyword">struct </span>integral_constant {</div><div class="line">  <span class="keyword">static</span> constexpr T <a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">value</a> = v;</div><div class="line">  <span class="keyword">typedef</span> T value_type;</div><div class="line">  <span class="keyword">typedef</span> integral_constant type;</div><div class="line">  constexpr <span class="keyword">operator</span> value_type() const noexcept { <span class="keywordflow">return</span> <a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">value</a>; }</div><div class="line">  constexpr value_type operator()() const noexcept { <span class="keywordflow">return</span> <a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">value</a>; }</div><div class="line">};</div></div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>If this is totally new to you, you might want to take a look at the <a href="http://en.cppreference.com/w/cpp/types/integral_constant">documentation</a> for <code><a class="el" href="structstd_1_1integral__constant.html" title="Adapter for std::integral_constants. ">std::integral_constant</a></code>.</dd></dl>
488 <p>One valid answer is that <code>integral_constant</code> represents a type-level encoding of a number, or more generally any object of an integral type. For illustration, we could define a successor function on numbers in that representation very easily by using a template alias:</p>
489 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> N&gt;</div><div class="line"><span class="keyword">using</span> succ = integral_constant&lt;int, N::value + 1&gt;;</div><div class="line"></div><div class="line"><span class="keyword">using</span> <a class="code" href="group__group-Ring.html#gadea531feb3b0a1c5c3d777f7ab45e932">one</a> = integral_constant&lt;int, 1&gt;;</div><div class="line"><span class="keyword">using</span> two = succ&lt;one&gt;;</div><div class="line"><span class="keyword">using</span> three = succ&lt;two&gt;;</div><div class="line"><span class="comment">// ...</span></div></div><!-- fragment --><p>This is the way <code>integral_constant</code>s are usually thought of; as <em>type-level</em> entities that can be used for template metaprogramming. Another way to see an <code>integral_constant</code> is as a runtime object representing a <code>constexpr</code> value of an integral type:</p>
490 <div class="fragment"><div class="line"><span class="keyword">auto</span> <a class="code" href="group__group-Ring.html#gadea531feb3b0a1c5c3d777f7ab45e932">one</a> = integral_constant&lt;int, 1&gt;{};</div></div><!-- fragment --><p>Here, while <code>one</code> is not marked as <code>constexpr</code>, the abstract value it holds (a <code>constexpr 1</code>) is still available at compile-time, because that value is encoded in the type of <code>one</code>. Indeed, even if <code>one</code> is not <code>constexpr</code>, we can use <code>decltype</code> to retrieve the compile-time value it represents:</p>
491 <div class="fragment"><div class="line"><span class="keyword">auto</span> <a class="code" href="group__group-Ring.html#gadea531feb3b0a1c5c3d777f7ab45e932">one</a> = integral_constant&lt;int, 1&gt;{};</div><div class="line">constexpr <span class="keywordtype">int</span> one_constexpr = decltype(<a class="code" href="group__group-Ring.html#gadea531feb3b0a1c5c3d777f7ab45e932">one</a>)::<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">value</a>;</div></div><!-- fragment --><p>But why on earth would we want to consider <code>integral_constant</code>s as objects instead of type-level entities? To see why, consider how we could now implement the same successor function as before:</p>
492 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> N&gt;</div><div class="line"><span class="keyword">auto</span> succ(N) {</div><div class="line">  <span class="keywordflow">return</span> integral_constant&lt;int, N::value + 1&gt;{};</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">auto</span> <a class="code" href="group__group-Ring.html#gadea531feb3b0a1c5c3d777f7ab45e932">one</a> = integral_constant&lt;int, 1&gt;{};</div><div class="line"><span class="keyword">auto</span> two = succ(<a class="code" href="group__group-Ring.html#gadea531feb3b0a1c5c3d777f7ab45e932">one</a>);</div><div class="line"><span class="keyword">auto</span> three = succ(two);</div><div class="line"><span class="comment">// ...</span></div></div><!-- fragment --><p>Did you notice anything new? The difference is that instead of implementing <code>succ</code> at the type-level with a template alias, we're now implementing it at the value-level with a template function. Furthermore, we can now perform compile-time arithmetic using the same syntax as that of normal C++. This way of seeing compile-time entities as objects instead of types is the key to Hana's expressive power.</p>
493 <h2><a class="anchor" id="tutorial-integral-arithmetic"></a>
494 Compile-time arithmetic</h2>
495 <p>The MPL defines <a href="http://www.boost.org/doc/libs/release/libs/mpl/doc/refmanual/arithmetic-operations.html">arithmetic operators</a> that can be used to do compile-time computations with <code>integral_constant</code>s. A typical example of such an operation is <code>plus</code>, which is implemented roughly as:</p>
496 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> X, <span class="keyword">typename</span> Y&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Monoid.html#gaeb5d4a1e967e319712f9e4791948896c">plus</a> {</div><div class="line">  <span class="keyword">using</span> type = integral_constant&lt;</div><div class="line">    decltype(<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">X::value</a> + <a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">Y::value</a>),</div><div class="line">    <a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">X::value</a> + <a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">Y::value</a></div><div class="line">  &gt;;</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">using</span> three = plus&lt;integral_constant&lt;int, 1&gt;,</div><div class="line">                   integral_constant&lt;int, 2&gt;&gt;::type;</div></div><!-- fragment --><p>By viewing <code>integral_constant</code>s as objects instead of types, the translation from a metafunction to a function is very straightforward:</p>
497 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> V, V v, <span class="keyword">typename</span> U, U u&gt;</div><div class="line">constexpr <span class="keyword">auto</span></div><div class="line">operator+(integral_constant&lt;V, v&gt;, integral_constant&lt;U, u&gt;)</div><div class="line">{ <span class="keywordflow">return</span> integral_constant&lt;decltype(v + u), v + u&gt;{}; }</div><div class="line"></div><div class="line"><span class="keyword">auto</span> three = integral_constant&lt;int, 1&gt;{} + integral_constant&lt;int, 2&gt;{};</div></div><!-- fragment --><p>It is very important to emphasize the fact that this operator does not return a normal integer. Instead, it returns a value-initialized object whose type contains the result of the addition. The only useful information contained in that object is actually in its type, and we're creating an object because it allows us to use this nice value-level syntax. It turns out that we can make this syntax even better by using a <a href="http://en.wikipedia.org/wiki/C%2B%2B14#Variable_templates">C++14 variable template</a> to simplify the creation of an <code>integral_constant</code>:</p>
498 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keywordtype">int</span> i&gt;</div><div class="line">constexpr integral_constant&lt;int, i&gt; <a class="code" href="structboost_1_1hana_1_1integral__constant.html#a8669179fa3d068951014b3be07a7d673">int_c</a>{};</div><div class="line"></div><div class="line"><span class="keyword">auto</span> three = int_c&lt;1&gt; + int_c&lt;2&gt;;</div></div><!-- fragment --><p>Now we're talking about a visible gain in expressiveness over the initial type-level approach, aren't we? But there's more; we can also use <a href="http://en.wikipedia.org/wiki/C%2B%2B11#User-defined_literals">C++14 user defined literals</a> to make this process even simpler:</p>
499 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keywordtype">char</span> ...digits&gt;</div><div class="line">constexpr <span class="keyword">auto</span> <span class="keyword">operator</span><span class="stringliteral">&quot;&quot;</span> _c() {</div><div class="line">  <span class="comment">// parse the digits and return an integral_constant</span></div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">auto</span> three = 1_c + 3_c;</div></div><!-- fragment --><p>Hana provides its own <code>integral_constant</code>s, which define arithmetic operators just like we showed above. Hana also provides variable templates to easily create different kinds of <code>integral_constant</code>s: <code>int_c</code>, <code>long_c</code>, <code>bool_c</code>, etc... This allows you to omit the trailing <code>{}</code> braces otherwise required to value-initialize these objects. Of course, the <code>_c</code> suffix is also provided; it is part of the <code>hana::literals</code> namespace, and you must import it into your namespace before using it:</p>
500 <div class="fragment"><div class="line"><span class="keyword">using namespace </span>hana::literals;</div><div class="line"></div><div class="line"><span class="keyword">auto</span> three = 1_c + 3_c;</div></div><!-- fragment --><p>This way, you may do compile-time arithmetic without having to struggle with awkward type-level idiosyncrasies, and your coworkers will now be able to understand what's going on.</p>
501 <h2><a class="anchor" id="tutorial-integral-distance"></a>
502 Example: Euclidean distance</h2>
503 <p>To illustrate how good it gets, let's implement a function computing a 2-D euclidean distance at compile-time. As a reminder, the euclidean distance of two points in the 2-D plane is given by</p>
504 <p class="formulaDsp">
505 \[ \mathrm{distance}\left((x_1, y_1), (x_2, y_2)\right) := \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2} \]
506 </p>
507 <p>First, here's how it looks like with a type-level approach (using the MPL):</p>
508 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> P1, <span class="keyword">typename</span> P2&gt;</div><div class="line"><span class="keyword">struct </span>distance {</div><div class="line">  <span class="keyword">using</span> xs = <span class="keyword">typename</span> <a class="code" href="group__group-Group.html#ga2020c526324f361a2b990fe8d1b07c20">mpl::minus</a>&lt;<span class="keyword">typename</span> P1::x,</div><div class="line">                                 <span class="keyword">typename</span> P2::x&gt;::type;</div><div class="line">  <span class="keyword">using</span> ys = <span class="keyword">typename</span> <a class="code" href="group__group-Group.html#ga2020c526324f361a2b990fe8d1b07c20">mpl::minus</a>&lt;<span class="keyword">typename</span> P1::y,</div><div class="line">                                 <span class="keyword">typename</span> P2::y&gt;::type;</div><div class="line">  <span class="keyword">using</span> type = <span class="keyword">typename</span> sqrt&lt;</div><div class="line">    <span class="keyword">typename</span> <a class="code" href="group__group-Monoid.html#gaeb5d4a1e967e319712f9e4791948896c">mpl::plus</a>&lt;</div><div class="line">      <span class="keyword">typename</span> mpl::multiplies&lt;xs, xs&gt;::type,</div><div class="line">      <span class="keyword">typename</span> mpl::multiplies&lt;ys, ys&gt;::type</div><div class="line">    &gt;::type</div><div class="line">  &gt;::type;</div><div class="line">};</div><div class="line"></div><div class="line">static_assert(mpl::equal_to&lt;</div><div class="line">  distance&lt;point&lt;mpl::int_&lt;3&gt;, mpl::int_&lt;5&gt;&gt;,</div><div class="line">           point&lt;mpl::int_&lt;7&gt;, mpl::int_&lt;2&gt;&gt;&gt;::type,</div><div class="line">  mpl::int_&lt;5&gt;</div><div class="line">&gt;::<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">value</a>, <span class="stringliteral">&quot;&quot;</span>);</div></div><!-- fragment --><p> Yeah... Now, let's implement it with the value-level approach presented above:</p>
509 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> P1, <span class="keyword">typename</span> P2&gt;</div><div class="line">constexpr <span class="keyword">auto</span> distance(P1 p1, P2 p2) {</div><div class="line">  <span class="keyword">auto</span> xs = p1.x - p2.x;</div><div class="line">  <span class="keyword">auto</span> ys = p1.y - p2.y;</div><div class="line">  <span class="keywordflow">return</span> sqrt(xs*xs + ys*ys);</div><div class="line">}</div><div class="line"></div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(distance(point(3_c, 5_c), point(7_c, 2_c)) == 5_c);</div></div><!-- fragment --><p> This version looks arguably cleaner. However, this is not all. Notice how the <code>distance</code> function looks exactly as the one you would have written for computing the euclidean distance on dynamic values? Indeed, because we're using the same syntax for dynamic and compile-time arithmetic, generic functions written for one will work for both!</p>
510 <div class="fragment"><div class="line"><span class="keyword">auto</span> p1 = point(3, 5); <span class="comment">// dynamic values now</span></div><div class="line"><span class="keyword">auto</span> p2 = point(7, 2); <span class="comment">//</span></div><div class="line"><a class="code" href="group__group-assertions.html#ga29b2b21ffa5513e5b706c50ffee980af">BOOST_HANA_RUNTIME_CHECK</a>(distance(p1, p2) == 5); <span class="comment">// same function works!</span></div></div><!-- fragment --><p> <b>Without changing any code</b>, we can use our <code>distance</code> function on runtime values and everything just works. Now that's DRY.</p>
511 <h2><a class="anchor" id="tutorial-integral-branching"></a>
512 Compile-time branching</h2>
513 <p>Once we have compile-time arithmetic, the next thing that might come to mind is compile-time branching. When metaprogramming, it is often useful to have one piece of code be compiled if some condition is true, and a different one otherwise. If you have heard of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4461.html">static_if</a>, this should sound very familiar, and indeed it is exactly what we are talking about. Otherwise, if you don't know why we might want to branch at compile-time, consider the following code (adapted from <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4461.html">N4461</a>):</p>
514 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> ...Args&gt;</div><div class="line">  std::enable_if_t&lt;std::is_constructible&lt;T, Args...&gt;<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">::value</a>,</div><div class="line">std::unique_ptr&lt;T&gt;&gt; make_unique(Args&amp;&amp;... args) {</div><div class="line">  <span class="keywordflow">return</span> std::unique_ptr&lt;T&gt;(<span class="keyword">new</span> T(std::forward&lt;Args&gt;(args)...));</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> ...Args&gt;</div><div class="line">  std::enable_if_t&lt;!std::is_constructible&lt;T, Args...&gt;<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">::value</a>,</div><div class="line">std::unique_ptr&lt;T&gt;&gt; make_unique(Args&amp;&amp;... args) {</div><div class="line">  <span class="keywordflow">return</span> std::unique_ptr&lt;T&gt;(<span class="keyword">new</span> T{std::forward&lt;Args&gt;(args)...});</div><div class="line">}</div></div><!-- fragment --><p>This code creates a <code>std::unique_ptr</code> using the correct form of syntax for the constructor. To achieve this, it uses <a href="http://en.cppreference.com/w/cpp/language/sfinae">SFINAE</a> and requires two different overloads. Now, anyone sane seeing this for the first time would ask why it is not possible to simply write:</p>
515 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> ...Args&gt;</div><div class="line">std::unique_ptr&lt;T&gt; make_unique(Args&amp;&amp;... args) {</div><div class="line">  <span class="keywordflow">if</span> (<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">std::is_constructible&lt;T, Args...&gt;::value</a>)</div><div class="line">    <span class="keywordflow">return</span> std::unique_ptr&lt;T&gt;(<span class="keyword">new</span> T(std::forward&lt;Args&gt;(args)...));</div><div class="line">  <span class="keywordflow">else</span></div><div class="line">    <span class="keywordflow">return</span> std::unique_ptr&lt;T&gt;(<span class="keyword">new</span> T{std::forward&lt;Args&gt;(args)...});</div><div class="line">}</div></div><!-- fragment --><p>The reason is that the compiler is required to compile both branches of the <code>if</code> statement, regardless of the condition (even though it is known at compile-time). But when <code>T</code> is <em>not</em> constructible from <code>Args...</code>, the second branch will fail to compile, which will cause a hard compilation error. What we need really is a way to tell the compiler <b>not to compile</b> the second branch when the condition is true, and the first branch when the condition is false.</p>
516 <p>To emulate this, Hana provides an <code>if_</code> function that works a bit like a normal <code>if</code> statement, except except it takes a condition that can be an <code>IntegralConstant</code> and returns the one of two values (which may have different types) chosen by the condition. If the condition is true, the first value is returned, and otherwise the second value is returned. A somewhat vain example is the following:</p>
517 <div class="fragment"><div class="line"><span class="keyword">auto</span> one_two_three = <a class="code" href="group__group-Logical.html#gafd655d2222367131e7a63616e93dd080">hana::if_</a>(hana::true_c, 123, <span class="stringliteral">&quot;hello&quot;</span>);</div><div class="line"><span class="keyword">auto</span> hello = <a class="code" href="group__group-Logical.html#gafd655d2222367131e7a63616e93dd080">hana::if_</a>(hana::false_c, 123, <span class="stringliteral">&quot;hello&quot;</span>);</div></div><!-- fragment --><dl class="section note"><dt>Note</dt><dd><code>hana::true_c</code> and <code>hana::false_c</code> are just boolean <code>IntegralConstant</code>s representing a compile-time true value and a compile-time false value, respectively.</dd></dl>
518 <p>Here, <code>one_two_three</code> is equal to <code>123</code>, and <code>hello</code> is equal to <code>"hello"</code>. In other words, <code>if_</code> is a little bit like the ternary conditional operator <code>? :</code>, except that both sides of the <code>:</code> can have different types:</p>
519 <div class="fragment"><div class="line"><span class="comment">// fails in both cases because both branches have incompatible types</span></div><div class="line"><span class="keyword">auto</span> one_two_three = hana::true_c ? 123 : <span class="stringliteral">&quot;hello&quot;</span>;</div><div class="line"><span class="keyword">auto</span> hello = hana::false_c ? 123 : <span class="stringliteral">&quot;hello&quot;</span>;</div></div><!-- fragment --><p>Ok, so this is neat, but how can it actually help us write complete branches that are lazily instantiated by the compiler? The answer is to represent both branches of the <code>if</code> statement we'd like to write as generic lambdas, and to use <code>hana::if_</code> to return the branch that we'd like to execute. Here's how we could rewrite <code>make_unique</code>:</p>
520 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> ...Args&gt;</div><div class="line">std::unique_ptr&lt;T&gt; make_unique(Args&amp;&amp;... args) {</div><div class="line">  <span class="keywordflow">return</span> <a class="code" href="group__group-Logical.html#gafd655d2222367131e7a63616e93dd080">hana::if_</a>(std::is_constructible&lt;T, Args...&gt;{},</div><div class="line">    [](<span class="keyword">auto</span>&amp;&amp; ...x) { <span class="keywordflow">return</span> std::unique_ptr&lt;T&gt;(<span class="keyword">new</span> T(std::forward&lt;Args&gt;(x)...)); },</div><div class="line">    [](<span class="keyword">auto</span>&amp;&amp; ...x) { <span class="keywordflow">return</span> std::unique_ptr&lt;T&gt;(<span class="keyword">new</span> T{std::forward&lt;Args&gt;(x)...}); }</div><div class="line">  )(std::forward&lt;Args&gt;(args)...);</div><div class="line">}</div></div><!-- fragment --><p> Here, the first value given to <code>hana::if_</code> is a generic lambda representing the branch we want to execute if the condition is true, and the second value is the branch we want to execute otherwise. <code>hana::if_</code> simply returns the branch chosen by the condition, and we call that branch (which is a generic lambda) immediately with <code>std::forward&lt;Args&gt;(args)...</code>. Hence, the proper generic lambda ends up being called, with <code>x...</code> being <code>args...</code>, and we return the result of that call.</p>
521 <p>The reason why this approach works is because the body of each branch can only be instantiated when the types of all <code>x...</code> are known. Indeed, since the branch is a generic lambda, the type of the argument is not known until the lambda is called, and the compiler must wait for the types of <code>x...</code> to be known before type-checking the lambda's body. Since the erroneous lambda is never called when the condition is not satisfied (<code>hana::if_</code> takes care of that), the body of the lambda that would fail is never type-checked and no compilation error happens.</p>
522 <dl class="section note"><dt>Note</dt><dd>The branches inside the <code>if_</code> are lambdas. As such, they really are different functions from the <code>make_unique</code> function. The variables appearing inside those branches have to be either captured by the lambdas or passed to them as arguments, and so they are affected by the way they are captured or passed (by value, by reference, etc..).</dd></dl>
523 <p>Since this pattern of expressing branches as lambdas and then calling them is very common, Hana provides a <code>eval_if</code> function whose purpose is to make compile-time branching easier. <code>eval_if</code> comes from the fact that in a lambda, one can either receive input data as arguments or capture it from the context. However, for the purpose of emulating a language level <code>if</code> statement, implicitly capturing variables from the enclosing scope is usually more natural. Hence, what we would prefer writing is</p>
524 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> ...Args&gt;</div><div class="line">std::unique_ptr&lt;T&gt; make_unique(Args&amp;&amp;... args) {</div><div class="line">  <span class="keywordflow">return</span> <a class="code" href="group__group-Logical.html#gafd655d2222367131e7a63616e93dd080">hana::if_</a>(std::is_constructible&lt;T, Args...&gt;{},</div><div class="line">    [&amp;] { <span class="keywordflow">return</span> std::unique_ptr&lt;T&gt;(<span class="keyword">new</span> T(std::forward&lt;Args&gt;(args)...)); },</div><div class="line">    [&amp;] { <span class="keywordflow">return</span> std::unique_ptr&lt;T&gt;(<span class="keyword">new</span> T{std::forward&lt;Args&gt;(args)...}); }</div><div class="line">  );</div><div class="line">}</div></div><!-- fragment --><p>Here, we're capturing the <code>args...</code> variables from the enclosing scope, which prevents us from having to introduce the new <code>x...</code> variables and passing them as arguments to the branches. However, this has two problems. First, this will not achieve the right result, since <code>hana::if_</code> will end up returning a lambda instead of returning the result of calling that lambda. To fix this, we can use <code>hana::eval_if</code> instead of <code>hana::if_</code>:</p>
525 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> ...Args&gt;</div><div class="line">std::unique_ptr&lt;T&gt; make_unique(Args&amp;&amp;... args) {</div><div class="line">  <span class="keywordflow">return</span> <a class="code" href="group__group-Logical.html#gab64636f84de983575aac0208f5fa840c">hana::eval_if</a>(std::is_constructible&lt;T, Args...&gt;{},</div><div class="line">    [&amp;] { <span class="keywordflow">return</span> std::unique_ptr&lt;T&gt;(<span class="keyword">new</span> T(std::forward&lt;Args&gt;(args)...)); },</div><div class="line">    [&amp;] { <span class="keywordflow">return</span> std::unique_ptr&lt;T&gt;(<span class="keyword">new</span> T{std::forward&lt;Args&gt;(args)...}); }</div><div class="line">  );</div><div class="line">}</div></div><!-- fragment --><p>Here, we capture the enclosing <code>args...</code> by reference using <code>[&amp;]</code>, and we do not need to receive any arguments. Also, <code>hana::eval_if</code> assumes that its arguments are branches that can be called, and it will take care of calling the branch that is selected by the condition. However, this will still cause a compilation failure, because the bodies of the lambdas are not dependent anymore, and semantic analysis will be done for both branches even though only one would end up being used. The solution to this problem is to make the bodies of the lambdas artificially dependent on something, to prevent the compiler from being able to perform semantic analysis before the lambda is actually used. To make this possible, <code>hana::eval_if</code> will call the selected branch with an identity function (a function that returns its argument unchanged), if the branch accepts such an argument:</p>
526 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> ...Args&gt;</div><div class="line">std::unique_ptr&lt;T&gt; make_unique(Args&amp;&amp;... args) {</div><div class="line">  <span class="keywordflow">return</span> <a class="code" href="group__group-Logical.html#gab64636f84de983575aac0208f5fa840c">hana::eval_if</a>(std::is_constructible&lt;T, Args...&gt;{},</div><div class="line">    [&amp;](<span class="keyword">auto</span> <a class="code" href="group__group-functional.html#gaefe9fd152cba94be71c2b5b9de689d23">_</a>) { <span class="keywordflow">return</span> std::unique_ptr&lt;T&gt;(<span class="keyword">new</span> T(std::forward&lt;Args&gt;(<a class="code" href="group__group-functional.html#gaefe9fd152cba94be71c2b5b9de689d23">_</a>(args))...)); },</div><div class="line">    [&amp;](<span class="keyword">auto</span> <a class="code" href="group__group-functional.html#gaefe9fd152cba94be71c2b5b9de689d23">_</a>) { <span class="keywordflow">return</span> std::unique_ptr&lt;T&gt;(<span class="keyword">new</span> T{std::forward&lt;Args&gt;(<a class="code" href="group__group-functional.html#gaefe9fd152cba94be71c2b5b9de689d23">_</a>(args))...}); }</div><div class="line">  );</div><div class="line">}</div></div><!-- fragment --><p> Here, the bodies of the branches take an additional argument called <code>_</code> by convention. This argument will be provided by <code>hana::eval_if</code> to the branch that was selected. Then, we use <code>_</code> as a function on the variables that we want to make dependent within the body of each branch. What happens is that <code>_</code> will always be a function that returns its argument unchanged. However, the compiler can't possibly know it before the lambda has actually been called, so it can't know the type of <code>_(args)</code>. This prevents the compiler from being able to perform semantic analysis, and no compilation error happens. Plus, since <code>_(x)</code> is guaranteed to be equivalent to <code>x</code>, we know that we're not actually changing the semantics of the branches by using this trick.</p>
527 <p>While using this trick may seem cumbersome, it can be very useful when dealing with many variables inside a branch. Furthermore, it is not required to wrap all variables with <code>_</code>; only variables that are involved in an expression whose type-checking has to be delayed must be wrapped, but the other ones are not required. There are still a few things to know about compile-time branching in Hana, but you can dig deeper by looking at the reference for <code>hana::eval_if</code>, <code>hana::if_</code> and <code>hana::lazy</code>.</p>
528 <h2><a class="anchor" id="tutorial-integral-more"></a>
529 Why stop here?</h2>
530 <p>Why should we limit ourselves to arithmetic operations and branching? When you start considering <code>IntegralConstant</code>s as objects, it becomes sensible to augment their interface with more functions that are generally useful. For example, Hana's <code>IntegralConstant</code>s define a <code>times</code> member function that can be used to invoke a function a certain number of times, which is especially useful for loop unrolling:</p>
531 <div class="fragment"><div class="line">__attribute__((noinline)) void f() { }</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main() {</div><div class="line">  hana::int_c&lt;10&gt;.times(f);</div><div class="line">}</div></div><!-- fragment --><p>In the above code, the 10 calls to <code>f</code> are expanded at compile-time. In other words, this is equivalent to writing</p>
532 <div class="fragment"><div class="line">f(); f(); ... f(); <span class="comment">// 10 times</span></div></div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>Always <a href="https://youtu.be/qkzaZumt_uk?t=4478">be careful</a> about manually unrolling loops or doing other such optimizations manually. In most cases, your compiler is probably better than you at optimizing. When in doubt, benchmark.</dd></dl>
533 <p>Another nice use of <code>IntegralConstant</code>s is to define good-looking operators for indexing heterogeneous sequences. Whereas <code><a class="el" href="structstd_1_1tuple.html" title="Adapter for std::tuples. ">std::tuple</a></code> must be accessed with <code>std::get</code>, <code>hana::tuple</code> can be accessed using the familiar <code>operator[]</code> used for standard library containers:</p>
534 <div class="fragment"><div class="line"><span class="keyword">auto</span> <a class="code" href="structboost_1_1hana_1_1map.html#a2e016a68e3ec6eb25868fadb7ce80132">values</a> = hana::make_tuple(1, <span class="charliteral">&#39;x&#39;</span>, 3.4f);</div><div class="line"><span class="keywordtype">char</span> x = <a class="code" href="structboost_1_1hana_1_1map.html#a2e016a68e3ec6eb25868fadb7ce80132">values</a>[1_c];</div></div><!-- fragment --><p>How this works is very simple. Basically, <code>hana::tuple</code> defines an <code>operator[]</code> taking an <code>IntegralConstant</code> instead of a normal integer, in a way similar to</p>
535 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> N&gt;</div><div class="line">constexpr decltype(<span class="keyword">auto</span>) operator[](N const&amp;) {</div><div class="line">  <span class="keywordflow">return</span> std::get&lt;N::value&gt;(*this);</div><div class="line">}</div></div><!-- fragment --><p>This is the end of the section on <code>IntegralConstant</code>s. This section introduced the feel behind Hana's new way of metaprogramming; if you liked what you've seen so far, the rest of this tutorial should feel just like home.</p>
536 <h1><a class="anchor" id="tutorial-type"></a>
537 Type computations</h1>
538 <hr/>
539 <p> At this point, if you are interested in doing type-level computations as with the MPL, you might be wondering how is Hana going to help you. Do not despair. Hana provides a way to perform type-level computations with a great deal of expressiveness by representing types as values, just like we represented compile-time numbers as values. This is a completely new way of approaching metaprogramming, and you should try to set your old MPL habits aside for a bit if you want to become proficient with Hana.</p>
540 <p>However, please be aware that modern C++ features like <a href="http://en.wikipedia.org/wiki/C%2B%2B14#Function_return_type_deduction">auto-deduced return type</a> remove the need for type computations in many cases. Hence, before even considering to do a type computation, you should ask yourself whether there's a simpler way to achieve what you're trying to achieve. In most cases, the answer will be yes. However, when the answer is no, Hana will provide you with nuclear-strength facilities to do what needs to be done.</p>
541 <h2><a class="anchor" id="tutorial-type-objects"></a>
542 Types as objects</h2>
543 <p>The key behind Hana's approach to type-level computations is essentially the same as the approach to compile-time arithmetic. Basically, the idea is to represent compile-time entities as objects by wrapping them into some kind of container. For <code>IntegralConstant</code>s, the compile-time entities were constant expressions of an integral type and the wrapper we used was <code>integral_constant</code>. In this section, the compile-time entities will be types and the wrapper we'll be using is called <code>type</code>. Just like we did for <code>IntegralConstant</code>s, let's start by defining a dummy template that could be used to represent a type:</p>
544 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">struct </span>basic_type {</div><div class="line">  <span class="comment">// empty (for now)</span></div><div class="line">};</div><div class="line"></div><div class="line">basic_type&lt;int&gt; Int{};</div><div class="line">basic_type&lt;char&gt; Char{};</div><div class="line"><span class="comment">// ...</span></div></div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>We're using the name <code>basic_type</code> here because we're only building a naive version of the actual functionality provided by Hana.</dd></dl>
545 <p>While this may seem completely useless, it is actually enough to start writing metafunctions that look like functions. Indeed, consider the following alternate implementations of <code>std::add_pointer</code> and <code>std::is_pointer</code>:</p>
546 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line">constexpr basic_type&lt;T*&gt; add_pointer(basic_type&lt;T&gt; <span class="keyword">const</span>&amp;)</div><div class="line">{ <span class="keywordflow">return</span> {}; }</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line">constexpr <span class="keyword">auto</span> is_pointer(basic_type&lt;T&gt; <span class="keyword">const</span>&amp;)</div><div class="line">{ <span class="keywordflow">return</span> hana::bool_c&lt;false&gt;; }</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line">constexpr <span class="keyword">auto</span> is_pointer(basic_type&lt;T*&gt; <span class="keyword">const</span>&amp;)</div><div class="line">{ <span class="keywordflow">return</span> hana::bool_c&lt;true&gt;; }</div></div><!-- fragment --><p>We've just written metafunctions that look like functions, just like we wrote compile-time arithmetic metafunctions as heterogeneous C++ operators in the previous section. Here's how we can use them:</p>
547 <div class="fragment"><div class="line">basic_type&lt;int&gt; t{};</div><div class="line"><span class="keyword">auto</span> p = add_pointer(t);</div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(is_pointer(p));</div></div><!-- fragment --><p>Notice how we can now use a normal function call syntax to perform type-level computations? This is analogous to how using values for compile-time numbers allowed us to use normal C++ operators to perform compile-time computations. Like we did for <code>integral_constant</code>, we can also go one step further and use C++14 variable templates to provide syntactic sugar for creating types:</p>
548 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line">constexpr basic_type&lt;T&gt; <a class="code" href="structboost_1_1hana_1_1type.html#ae35139e732c4b75e91061513cf445628">type_c</a>{};</div><div class="line"></div><div class="line"><span class="keyword">auto</span> t = type_c&lt;int&gt;;</div><div class="line"><span class="keyword">auto</span> p = add_pointer(t);</div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(is_pointer(p));</div></div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>This is not exactly how the <code>hana::type_c</code> variable template is implemented because of some subtleties; things were dumbed down here for the sake of the explanation. Please check the reference for <code>hana::type</code> to know exactly what you can expect from a <code>hana::type_c&lt;...&gt;</code>.</dd></dl>
549 <h2><a class="anchor" id="tutorial-type-benefits"></a>
550 Benefits of this representation</h2>
551 <p>But what does that buy us? Well, since a <code>type_c&lt;...&gt;</code> is just an object, we can store it in a heterogeneous sequence like a tuple, we can move it around and pass it to (or return it from) functions, and we can do basically anything else that requires an object:</p>
552 <div class="fragment"><div class="line"><span class="keyword">auto</span> types = hana::make_tuple(hana::type_c&lt;int*&gt;, hana::type_c&lt;char&amp;&gt;, hana::type_c&lt;void&gt;);</div><div class="line"><span class="keyword">auto</span> char_ref = types[1_c];</div><div class="line"></div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(char_ref == hana::type_c&lt;char&amp;&gt;);</div></div><!-- fragment --> <dl class="section note"><dt>Note</dt><dd>Writing <code>make_tuple(type_c&lt;T&gt;...)</code> can be annoying when there are several types. For this reason, Hana provides the <code>tuple_t&lt;T...&gt;</code> variable template, which is syntactic sugar for <code>make_tuple(type_c&lt;T&gt;...)</code>.</dd></dl>
553 <p>Also, notice that since the above tuple is really just a normal heterogeneous sequence, we can apply heterogeneous algorithms on that sequence just like we could on a tuple of <code>int</code>s, for example. Furthermore, since we're just manipulating objects, we can now use the full language instead of just the small subset available at the type-level. For example, consider the task of removing all the types that are not a reference or a pointer from a sequence of types. With the MPL, we would have to use a placeholder expression to express the predicate, which is clunky:</p>
554 <div class="fragment"><div class="line"><span class="keyword">using</span> types = mpl::vector&lt;int, char&amp;, void*&gt;;</div><div class="line"><span class="keyword">using</span> ts = mpl::copy_if&lt;types, mpl::or_&lt;std::is_pointer&lt;mpl::_1&gt;,</div><div class="line">                                        std::is_reference&lt;mpl::_1&gt;&gt;&gt;::type;</div><div class="line"><span class="comment">//                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^</span></div><div class="line"><span class="comment">//                             placeholder expression</span></div><div class="line"></div><div class="line">static_assert(<a class="code" href="group__group-Comparable.html#gacaf1ebea6b3ab96ac9dcb82f0e64e547">mpl::equal</a>&lt;ts, mpl::vector&lt;char&amp;, void*&gt;&gt;::<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">value</a>, <span class="stringliteral">&quot;&quot;</span>);</div></div><!-- fragment --><p> Now, since we're manipulating objects, we can use the full language and use a generic lambda instead, which leads to much more readable code:</p>
555 <div class="fragment"><div class="line"><span class="keyword">auto</span> types = hana::tuple_t&lt;int*, char&amp;, void&gt;;</div><div class="line"></div><div class="line"><span class="keyword">auto</span> ts = <a class="code" href="group__group-MonadPlus.html#ga65cc6d9f522fb9e8e3b28d80ee5c822a">hana::filter</a>(types, [](<span class="keyword">auto</span> t) {</div><div class="line">  <span class="keywordflow">return</span> is_pointer(t) || is_reference(t);</div><div class="line">});</div><div class="line"></div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(ts == hana::tuple_t&lt;int*, char&amp;&gt;);</div></div><!-- fragment --><p> Since Hana handles all heterogeneous containers uniformly, this approach of representing types as values also has the benefit that a single library is now needed for both heterogeneous computations and type level computations. Indeed, whereas we would normally need two different libraries to perform almost identical tasks, we now need a single library. Again, consider the task of filtering a sequence with a predicate. With MPL and Fusion, this is what we must do:</p>
556 <div class="fragment"><div class="line"><span class="comment">// types (MPL)</span></div><div class="line"><span class="keyword">using</span> types = mpl::vector&lt;int*, char&amp;, void&gt;;</div><div class="line"><span class="keyword">using</span> ts = mpl::copy_if&lt;types, mpl::or_&lt;std::is_pointer&lt;mpl::_1&gt;,</div><div class="line">                                        std::is_reference&lt;mpl::_1&gt;&gt;&gt;::type;</div><div class="line"></div><div class="line"><span class="comment">// values (Fusion)</span></div><div class="line"><span class="keyword">auto</span> <a class="code" href="structboost_1_1hana_1_1map.html#a2e016a68e3ec6eb25868fadb7ce80132">values</a> = fusion::make_vector(1, <span class="charliteral">&#39;c&#39;</span>, <span class="keyword">nullptr</span>, 3.5);</div><div class="line"><span class="keyword">auto</span> vs = fusion::filter_if&lt;std::is_integral&lt;mpl::_1&gt;&gt;(<a class="code" href="structboost_1_1hana_1_1map.html#a2e016a68e3ec6eb25868fadb7ce80132">values</a>);</div></div><!-- fragment --><p> With Hana, a single library is required. Notice how we use the same <code>filter</code> algorithm and the same container, and only tweak the predicate so it can operate on values:</p>
557 <div class="fragment"><div class="line"><span class="comment">// types</span></div><div class="line"><span class="keyword">auto</span> types = hana::tuple_t&lt;int*, char&amp;, void&gt;;</div><div class="line"><span class="keyword">auto</span> ts = <a class="code" href="group__group-MonadPlus.html#ga65cc6d9f522fb9e8e3b28d80ee5c822a">hana::filter</a>(types, [](<span class="keyword">auto</span> t) {</div><div class="line">  <span class="keywordflow">return</span> is_pointer(t) || is_reference(t);</div><div class="line">});</div><div class="line"></div><div class="line"><span class="comment">// values</span></div><div class="line"><span class="keyword">auto</span> <a class="code" href="structboost_1_1hana_1_1map.html#a2e016a68e3ec6eb25868fadb7ce80132">values</a> = hana::make_tuple(1, <span class="charliteral">&#39;c&#39;</span>, <span class="keyword">nullptr</span>, 3.5);</div><div class="line"><span class="keyword">auto</span> vs = <a class="code" href="group__group-MonadPlus.html#ga65cc6d9f522fb9e8e3b28d80ee5c822a">hana::filter</a>(values, [](<span class="keyword">auto</span> <span class="keyword">const</span>&amp; t) {</div><div class="line">  <span class="keywordflow">return</span> is_integral(hana::typeid_(t));</div><div class="line">});</div></div><!-- fragment --><p> But that is not all. Indeed, having a unified syntax for type-level and value-level computations allows us to achieve greater consistency in the interface of heterogeneous containers. For example, consider the simple task of creating a heterogeneous map associating types to values, and then accessing an element of it. With Fusion, what's happening is far from obvious to the untrained eye:</p>
558 <div class="fragment"><div class="line"><span class="keyword">auto</span> map = fusion::make_map&lt;char, int, long, float, double, void&gt;(</div><div class="line">  <span class="stringliteral">&quot;char&quot;</span>, <span class="stringliteral">&quot;int&quot;</span>, <span class="stringliteral">&quot;long&quot;</span>, <span class="stringliteral">&quot;float&quot;</span>, <span class="stringliteral">&quot;double&quot;</span>, <span class="stringliteral">&quot;void&quot;</span></div><div class="line">);</div><div class="line"></div><div class="line">std::string Int = fusion::at_key&lt;int&gt;(map);</div><div class="line"><a class="code" href="group__group-assertions.html#ga29b2b21ffa5513e5b706c50ffee980af">BOOST_HANA_RUNTIME_CHECK</a>(Int == <span class="stringliteral">&quot;int&quot;</span>);</div></div><!-- fragment --><p> However, with a unified syntax for types and values, the same thing becomes much clearer:</p>
559 <div class="fragment"><div class="line"><span class="keyword">auto</span> map = hana::make_map(</div><div class="line">  hana::make_pair(hana::type_c&lt;char&gt;,   <span class="stringliteral">&quot;char&quot;</span>),</div><div class="line">  hana::make_pair(hana::type_c&lt;int&gt;,    <span class="stringliteral">&quot;int&quot;</span>),</div><div class="line">  hana::make_pair(hana::type_c&lt;long&gt;,   <span class="stringliteral">&quot;long&quot;</span>),</div><div class="line">  hana::make_pair(hana::type_c&lt;float&gt;,  <span class="stringliteral">&quot;float&quot;</span>),</div><div class="line">  hana::make_pair(hana::type_c&lt;double&gt;, <span class="stringliteral">&quot;double&quot;</span>)</div><div class="line">);</div><div class="line"></div><div class="line">std::string Int = map[hana::type_c&lt;int&gt;];</div><div class="line"><a class="code" href="group__group-assertions.html#ga29b2b21ffa5513e5b706c50ffee980af">BOOST_HANA_RUNTIME_CHECK</a>(Int == <span class="stringliteral">&quot;int&quot;</span>);</div></div><!-- fragment --><p> While Hana's way takes more lines of codes, it is also arguably more readable and closer to how someone would expect to initialize a map.</p>
560 <h2><a class="anchor" id="tutorial-type-working"></a>
561 Working with this representation</h2>
562 <p>So far, we can represent types as values and perform type-level computations on those objects using the usual C++ syntax. This is nice, but it is not very useful because we have no way to get back a normal C++ type from an object representation. For example, how could we declare a variable whose type is the result of a type computation?</p>
563 <div class="fragment"><div class="line"><span class="keyword">auto</span> t = add_pointer(hana::type_c&lt;int&gt;); <span class="comment">// could be a complex type computation</span></div><div class="line"><span class="keyword">using</span> T = the-type-represented-by-t;</div><div class="line"></div><div class="line">T var = ...;</div></div><!-- fragment --><p>Right now, there is no easy way to do it. To make this easier to achieve, we enrich the interface of the <code>basic_type</code> container that we defined above. Instead of being an empty <code>struct</code>, we now define it as</p>
564 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">struct </span>basic_type {</div><div class="line">  <span class="keyword">using</span> type = T;</div><div class="line">};</div></div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>This is equivalent to making <code>basic_type</code> a metafunction in the MPL sense.</dd></dl>
565 <p>This way, we can use <code>decltype</code> to easily access the actual C++ type represented by a <code>type_c&lt;...&gt;</code> object:</p>
566 <div class="fragment"><div class="line"><span class="keyword">auto</span> t = add_pointer(hana::type_c&lt;int&gt;);</div><div class="line"><span class="keyword">using</span> T = decltype(t)::type; <span class="comment">// fetches basic_type&lt;T&gt;::type</span></div><div class="line"></div><div class="line">T var = ...;</div></div><!-- fragment --><p>In general, doing type-level metaprogramming with Hana is a three step process:</p>
567 <ol type="1">
568 <li>Represent types as objects by wrapping them with <code>hana::type_c&lt;...&gt;</code></li>
569 <li>Perform type transformations with value syntax</li>
570 <li>Unwrap the result with <code>decltype(...)::type</code></li>
571 </ol>
572 <p>Now, you must be thinking that this is incredibly cumbersome. In reality, it is very manageable for several reasons. First, this wrapping and unwrapping only needs to happen at some very thin boundaries.</p>
573 <div class="fragment"><div class="line"><span class="keyword">auto</span> t = hana::type_c&lt;T&gt;;</div><div class="line"><span class="keyword">auto</span> result = huge_type_computation(t);</div><div class="line"><span class="keyword">using</span> Result = decltype(result)::type;</div></div><!-- fragment --><p>Furthermore, since you get the advantage of working with objects (without having to wrap/unwrap) inside the computation, the cost of wrapping and unwrapping is amortized on the whole computation. Hence, for complex type computations, the syntactic noise of this three step process quickly becomes negligible in light of the expressiveness gain of working with values inside that computation. Also, using values instead of types means that we can avoid typing <code>typename</code> and <code>template</code> all around the place, which accounted for a lot of syntactic noise in classic metaprogramming.</p>
574 <p>Another point is that the three full steps are not always required. Indeed, sometimes one just needs to do a type-level computation and query something about the result, without necessarily fetching the result as a normal C++ type:</p>
575 <div class="fragment"><div class="line"><span class="keyword">auto</span> t = hana::type_c&lt;T&gt;;</div><div class="line"><span class="keyword">auto</span> result = type_computation(t);</div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(is_pointer(result)); <span class="comment">// third step skipped</span></div></div><!-- fragment --><p>In this case, we were able to skip the third step because we did not need to access the actual type represented by <code>result</code>. In other cases, the first step can be avoided, like when using <code>tuple_t</code>, which has no more syntactic noise than any other pure type-level approach:</p>
576 <div class="fragment"><div class="line"><span class="keyword">auto</span> types = hana::tuple_t&lt;int*, char&amp;, void&gt;; <span class="comment">// first step skipped</span></div><div class="line"></div><div class="line"><span class="keyword">auto</span> pointers = <a class="code" href="group__group-Functor.html#ga5a8975f6e55375d5b6038a9c36ee63e7">hana::transform</a>(types, [](<span class="keyword">auto</span> t) {</div><div class="line">  <span class="keywordflow">return</span> add_pointer(t);</div><div class="line">});</div></div><!-- fragment --><p> For skeptical readers, let's consider the task of finding the smallest type in a sequence of types. This is a very good example of a short type-only computation, which is where we would expect the new paradigm to suffer the most. As you will see, things stay manageable even for small computations. First, let's implement it with the MPL:</p>
577 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> ...T&gt;</div><div class="line"><span class="keyword">struct </span>smallest</div><div class="line">  : mpl::deref&lt;</div><div class="line">    typename mpl::min_element&lt;</div><div class="line">      mpl::vector&lt;T...&gt;,</div><div class="line">      mpl::less&lt;mpl::sizeof_&lt;mpl::_1&gt;, mpl::sizeof_&lt;mpl::_2&gt;&gt;</div><div class="line">    &gt;::type</div><div class="line">  &gt;</div><div class="line">{ };</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> ...T&gt;</div><div class="line"><span class="keyword">using</span> smallest_t = <span class="keyword">typename</span> smallest&lt;T...&gt;::type;</div><div class="line"></div><div class="line">static_assert(std::is_same&lt;</div><div class="line">  smallest_t&lt;char, long, long double&gt;,</div><div class="line">  <span class="keywordtype">char</span></div><div class="line">&gt;::<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">value</a>, <span class="stringliteral">&quot;&quot;</span>);</div></div><!-- fragment --><p> The result is quite readable (for anyone familiar with the MPL). Let's now implement the same thing using Hana:</p>
578 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> ...T&gt;</div><div class="line"><span class="keyword">auto</span> smallest = <a class="code" href="group__group-Foldable.html#ga347429451fdb15f9f7a7fc0de293be1a">hana::minimum</a>(hana::make_tuple(hana::type_c&lt;T&gt;...), [](<span class="keyword">auto</span> t, <span class="keyword">auto</span> u) {</div><div class="line">  <span class="keywordflow">return</span> hana::sizeof_(t) &lt; hana::sizeof_(u);</div><div class="line">});</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> ...T&gt;</div><div class="line"><span class="keyword">using</span> smallest_t = <span class="keyword">typename</span> decltype(smallest&lt;T...&gt;)::type;</div><div class="line"></div><div class="line">static_assert(std::is_same&lt;</div><div class="line">  smallest_t&lt;char, long, long double&gt;, <span class="keywordtype">char</span></div><div class="line">&gt;::<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">value</a>, <span class="stringliteral">&quot;&quot;</span>);</div></div><!-- fragment --><p> As you can witness, the syntactic noise of the 3-step process is almost completely hidden by the rest of the computation.</p>
579 <h2><a class="anchor" id="tutorial-type-lifting"></a>
580 The generic lifting process</h2>
581 <p>The first type-level computation that we introduced in the form of a function looked like:</p>
582 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line">constexpr <span class="keyword">auto</span> add_pointer(hana::basic_type&lt;T&gt; <span class="keyword">const</span>&amp;) {</div><div class="line">  <span class="keywordflow">return</span> hana::type&lt;T*&gt;;</div><div class="line">}</div></div><!-- fragment --><p>While it looks more complicated, we could also write it as:</p>
583 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line">constexpr <span class="keyword">auto</span> add_pointer(hana::basic_type&lt;T&gt; <span class="keyword">const</span>&amp;) {</div><div class="line">  <span class="keywordflow">return</span> hana::type_c&lt;typename std::add_pointer&lt;T&gt;::type&gt;;</div><div class="line">}</div></div><!-- fragment --><p>However, this implementation emphasizes the fact that we're really emulating an existing metafunction and simply representing it as a function. In other words, we're <em>lifting</em> a metafunction (<code>std::add_pointer</code>) to the world of values by creating our own <code>add_pointer</code> function. It turns out that this lifting process is a generic one. Indeed, given any metafunction, we could write almost the same thing:</p>
584 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line">constexpr <span class="keyword">auto</span> add_const(hana::basic_type&lt;T&gt; <span class="keyword">const</span>&amp;)</div><div class="line">{ <span class="keywordflow">return</span> hana::type_c&lt;typename std::add_const&lt;T&gt;::type&gt;; }</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line">constexpr <span class="keyword">auto</span> add_volatile(hana::basic_type&lt;T&gt; <span class="keyword">const</span>&amp;)</div><div class="line">{ <span class="keywordflow">return</span> hana::type_c&lt;typename std::add_volatile&lt;T&gt;::type&gt;; }</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line">constexpr <span class="keyword">auto</span> add_lvalue_reference(hana::basic_type&lt;T&gt; <span class="keyword">const</span>&amp;)</div><div class="line">{ <span class="keywordflow">return</span> hana::type_c&lt;typename std::add_lvalue_reference&lt;T&gt;::type&gt;; }</div><div class="line"></div><div class="line"><span class="comment">// etc...</span></div></div><!-- fragment --><p>This mechanical transformation is easy to abstract into a generic lifter that can handle any <a href="http://www.boost.org/doc/libs/release/libs/mpl/doc/refmanual/metafunction.html">MPL Metafunction</a> as follows:</p>
585 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">template</span> &lt;<span class="keyword">typename</span>&gt; <span class="keyword">class </span>F, <span class="keyword">typename</span> T&gt;</div><div class="line">constexpr <span class="keyword">auto</span> <a class="code" href="group__group-Metafunction.html#gaaa4f85cb8cbce21f5c04ef40ca35cc6a">metafunction</a>(hana::basic_type&lt;T&gt; <span class="keyword">const</span>&amp;)</div><div class="line">{ <span class="keywordflow">return</span> hana::type_c&lt;typename F&lt;T&gt;::type&gt;; }</div><div class="line"></div><div class="line"><span class="keyword">auto</span> t = hana::type_c&lt;int&gt;;</div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(metafunction&lt;std::add_pointer&gt;(t) == hana::type_c&lt;int*&gt;);</div></div><!-- fragment --><p> More generally, we'll want to allow metafunctions with any number of arguments, which brings us to the following less naive implementation:</p>
586 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> ...&gt; <span class="keyword">class </span>F, <span class="keyword">typename</span> ...T&gt;</div><div class="line">constexpr <span class="keyword">auto</span> <a class="code" href="group__group-Metafunction.html#gaaa4f85cb8cbce21f5c04ef40ca35cc6a">metafunction</a>(hana::basic_type&lt;T&gt; <span class="keyword">const</span>&amp; ...)</div><div class="line">{ <span class="keywordflow">return</span> hana::type_c&lt;<span class="keyword">typename</span> F&lt;T...&gt;::type&gt;; }</div><div class="line"></div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(</div><div class="line">  metafunction&lt;std::common_type&gt;(hana::type_c&lt;int&gt;, hana::type_c&lt;long&gt;) == hana::type_c&lt;long&gt;</div><div class="line">);</div></div><!-- fragment --><p> Hana provides a similar generic metafunction lifter called <code>hana::metafunction</code>. One small improvement is that <code>hana::metafunction&lt;F&gt;</code> is a function object instead of an overloaded function, so one can pass it to higher-order algorithms. It is also a model of the slightly more powerful concept of <code>Metafunction</code>, but this can safely be ignored for now. The process we explored in this section does not only apply to metafunctions; it also applies to templates. Indeed, we could define:</p>
587 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> ...&gt; <span class="keyword">class </span>F, <span class="keyword">typename</span> ...T&gt;</div><div class="line">constexpr <span class="keyword">auto</span> <a class="code" href="group__group-Metafunction.html#ga246419f6c3263b648412f346106e6543">template_</a>(hana::basic_type&lt;T&gt; <span class="keyword">const</span>&amp; ...)</div><div class="line">{ <span class="keywordflow">return</span> hana::type_c&lt;F&lt;T...&gt;&gt;; }</div><div class="line"></div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(</div><div class="line">  template_&lt;std::vector&gt;(hana::type_c&lt;int&gt;) == hana::type_c&lt;std::vector&lt;int&gt;&gt;</div><div class="line">);</div></div><!-- fragment --><p> Hana provides a generic lifter for templates named <code>hana::template_</code>, and it also provides a generic lifter for <a href="http://www.boost.org/doc/libs/release/libs/mpl/doc/refmanual/metafunction-class.html">MPL MetafunctionClasses</a> named <code>hana::metafunction_class</code>. This gives us a way to uniformly represent "legacy" type-level computations as functions, so that any code written using a classic type-level metaprogramming library can almost trivially be used with Hana. For example, say you have a large chunk of MPL-based code and you'd like to interface with Hana. The process of doing so is no harder than wrapping your metafunctions with the lifter provided by Hana:</p>
588 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">struct </span>legacy {</div><div class="line">  <span class="keyword">using</span> type = ...; <span class="comment">// something you really don&#39;t want to mess with</span></div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">auto</span> types = hana::make_tuple(...);</div><div class="line"><span class="keyword">auto</span> use = <a class="code" href="group__group-Functor.html#ga5a8975f6e55375d5b6038a9c36ee63e7">hana::transform</a>(types, hana::metafunction&lt;legacy&gt;);</div></div><!-- fragment --><p>However, note that not all type-level computations can be lifted as-is with the tools provided by Hana. For example, <code>std::extent</code> can't be lifted because it requires non-type template parameters. Since there is no way to deal with non-type template parameters uniformly in C++, one must resort to using a hand-written function object specific to that type-level computation:</p>
589 <div class="fragment"><div class="line"><span class="keyword">auto</span> extent = [](<span class="keyword">auto</span> t, <span class="keyword">auto</span> n) {</div><div class="line">  <span class="keywordflow">return</span> std::extent&lt;typename decltype(t)::type, hana::value(n)&gt;{};</div><div class="line">};</div><div class="line"></div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(extent(hana::type_c&lt;char&gt;, hana::int_c&lt;1&gt;) == hana::size_c&lt;0&gt;);</div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(extent(hana::type_c&lt;<span class="keywordtype">char</span>[1][2]&gt;, hana::int_c&lt;1&gt;) == hana::size_c&lt;2&gt;);</div></div><!-- fragment --> <dl class="section note"><dt>Note</dt><dd>Do not forget to include the bridge header for <code><a class="el" href="structstd_1_1integral__constant.html" title="Adapter for std::integral_constants. ">std::integral_constant</a></code>s (<code>&lt;<a class="el" href="ext_2std_2integral__constant_8hpp.html" title="Adapts std::integral_constant for use with Hana. ">boost/hana/ext/std/integral_constant.hpp</a>&gt;</code>) when using type traits from <code>&lt;type_traits&gt;</code> directly.</dd></dl>
590 <p>In practice, however, this should not be a problem since the vast majority of type-level computations can be lifted easily. Finally, since metafunctions provided by the <code>&lt;type_traits&gt;</code> header are used so frequently, Hana provides a lifted version for every one of them. Those lifted traits are in the <code>hana::traits</code> namespace, and they live in the <code>&lt;<a class="el" href="traits_8hpp.html" title="Defines function-like equivalents to the standard &lt;type_traits&gt;, and also to some utilities like std:...">boost/hana/traits.hpp</a>&gt;</code> header:</p>
591 <div class="fragment"><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(hana::traits::add_pointer(hana::type_c&lt;int&gt;) == hana::type_c&lt;int*&gt;);</div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(hana::traits::common_type(hana::type_c&lt;int&gt;, hana::type_c&lt;long&gt;) == hana::type_c&lt;long&gt;);</div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(hana::traits::is_integral(hana::type_c&lt;int&gt;));</div><div class="line"></div><div class="line"><span class="keyword">auto</span> types = hana::tuple_t&lt;int, char, long&gt;;</div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(<a class="code" href="group__group-Searchable.html#ga3a168950082f38afd9edf256f336c8ba">hana::all_of</a>(types, hana::traits::is_integral));</div></div><!-- fragment --><p> This is the end of the section on type computations. While this new paradigm for type level programming might be difficult to grok at first, it will make more sense as you use it more and more. You will also come to appreciate how it blurs the line between types and values, opening new exciting possibilities and simplifying many tasks.</p>
592 <dl class="section note"><dt>Note</dt><dd>Curious or skeptical readers should consider checking the minimal reimplementation of the MPL presented in the <a class="el" href="index.html#tutorial-appendix-MPL">appendices</a>.</dd></dl>
593 <h1><a class="anchor" id="tutorial-introspection"></a>
594 Introspection</h1>
595 <hr/>
596 <p> Static introspection, as we will discuss it here, is the ability of a program to examine the type of an object at compile-time. In other words, it is a programmatic interface to interact with types at compile-time. For example, have you ever wanted to check whether some unknown type has a member named <code>foo</code>? Or perhaps at some point you have needed to iterate on the members of a <code>struct</code>?</p>
597 <div class="fragment"><div class="line"><span class="keyword">struct </span>Person {</div><div class="line">  std::string name;</div><div class="line">  <span class="keywordtype">int</span> age;</div><div class="line">};</div><div class="line"></div><div class="line">Person john{<span class="stringliteral">&quot;John&quot;</span>, 30};</div><div class="line"><span class="keywordflow">for</span> (<span class="keyword">auto</span>&amp; member : john)</div><div class="line">  std::cout &lt;&lt; member.name &lt;&lt; <span class="stringliteral">&quot;: &quot;</span> &lt;&lt; member.value &lt;&lt; std::endl;</div><div class="line"></div><div class="line"><span class="comment">// name: John</span></div><div class="line"><span class="comment">// age: 30</span></div></div><!-- fragment --><p>If you have written a bit of templates in your life, chances are very high that you came across the first problem of checking for a member. Also, anyone having tried to implement object serialization or even just pretty printing has come across the second problem. In most dynamic languages like Python, Ruby or JavaScript, these problems are completely solved and introspection is used every day by programmers to make a lot of tasks simpler. However, as a C++ programmer, we do not have language support for those things, which makes several tasks much harder than they should be. While language support would likely be needed to properly tackle this problem, Hana makes some common introspection patterns much more accessible.</p>
598 <h2><a class="anchor" id="tutorial-introspection-is_valid"></a>
599 Checking expression validity</h2>
600 <p>Given an object of an unknown type, it is sometimes desirable to check whether this object has a member (or member function) with some name. This can be used to perform sophisticated flavors of overloading. For example, consider the problem of calling a <code>toString</code> method on objects that support it, but providing another default implementation for objects that do not support it:</p>
601 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line">std::string optionalToString(T <span class="keyword">const</span>&amp; obj) {</div><div class="line">  <span class="keywordflow">if</span> (obj.toString() is a valid expression)</div><div class="line">    <span class="keywordflow">return</span> obj.toString();</div><div class="line">  <span class="keywordflow">else</span></div><div class="line">    <span class="keywordflow">return</span> <span class="stringliteral">&quot;toString not defined&quot;</span>;</div><div class="line">}</div></div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>While most use cases for this technique will be addressed by <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3580.pdf">concepts lite</a> in future revisions of the standard, there will still be cases where a quick and dirty check is more convenient than creating a full blown concept.</dd></dl>
602 <p>How could we implement a check for the validity of <code>obj.toString()</code> as above in a generic fashion (so it can be reused in other functions, for example)? Normally, we would be stuck writing some kind of SFINAE-based detection:</p>
603 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> = <span class="keywordtype">void</span>&gt;</div><div class="line"><span class="keyword">struct </span>has_toString</div><div class="line">  : std::false_type</div><div class="line">{ };</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">struct </span>has_toString&lt;T, decltype((void)<a class="code" href="namespacestd.html">std</a>::declval&lt;T&gt;().toString())&gt;</div><div class="line">  : std::true_type</div><div class="line">{ };</div></div><!-- fragment --><p> This works, but the intent is not very clear and most people without a deep knowledge of template metaprogramming would think this is black magic. Then, we could implement <code>optionalToString</code> as</p>
604 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line">std::string optionalToString(T <span class="keyword">const</span>&amp; obj) {</div><div class="line">  <span class="keywordflow">if</span> (<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">has_toString&lt;T&gt;::value</a>)</div><div class="line">    <span class="keywordflow">return</span> obj.toString();</div><div class="line">  <span class="keywordflow">else</span></div><div class="line">    <span class="keywordflow">return</span> <span class="stringliteral">&quot;toString not defined&quot;</span>;</div><div class="line">}</div></div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>Of course, this implementation won't actually work because both branches of the <code>if</code> statement will be compiled. If <code>obj</code> does not have a <code>toString</code> method, the compilation of the <code>if</code> branch will fail. We will address this issue in a moment.</dd></dl>
605 <p>Instead of the above SFINAE trick, Hana provides a <code>is_valid</code> function that can be combined with <a href="http://en.wikipedia.org/wiki/C%2B%2B14#Generic_lambdas">C++14 generic lambdas</a> to obtain a much cleaner implementation of the same thing:</p>
606 <div class="fragment"><div class="line"><span class="keyword">auto</span> has_toString = hana::is_valid([](<span class="keyword">auto</span>&amp;&amp; obj) -&gt; decltype(obj.toString()) { });</div></div><!-- fragment --><p> This leaves us with a function object <code>has_toString</code> which returns whether the given expression is valid on the argument we pass to it. The result is returned as an <code>IntegralConstant</code>, so <code>constexpr</code>-ness is not an issue here because the result of the function is represented as a type anyway. Now, in addition to being less verbose (that's a one liner!), the intent is much clearer. Other benefits are the fact that <code>has_toString</code> can be passed to higher order algorithms and it can also be defined at function scope, so there is no need to pollute the namespace scope with implementation details. Here is how we would now write <code>optionalToString</code>:</p>
607 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line">std::string optionalToString(T <span class="keyword">const</span>&amp; obj) {</div><div class="line">  <span class="keywordflow">if</span> (has_toString(obj))</div><div class="line">    <span class="keywordflow">return</span> obj.toString();</div><div class="line">  <span class="keywordflow">else</span></div><div class="line">    <span class="keywordflow">return</span> <span class="stringliteral">&quot;toString not defined&quot;</span>;</div><div class="line">}</div></div><!-- fragment --><p>Much cleaner, right? However, as we said earlier, this implementation won't actually work because both branches of the <code>if</code> always have to be compiled, regardless of whether <code>obj</code> has a <code>toString</code> method. There are several possible options, but the most classical one is to use <code>std::enable_if</code>:</p>
608 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">auto</span> optionalToString(T <span class="keyword">const</span>&amp; obj)</div><div class="line">  -&gt; std::enable_if_t&lt;decltype(has_toString(obj))::value, std::string&gt;</div><div class="line">{ <span class="keywordflow">return</span> obj.toString(); }</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">auto</span> optionalToString(T <span class="keyword">const</span>&amp; obj)</div><div class="line">  -&gt; std::enable_if_t&lt;decltype(!has_toString(obj))::value, std::string&gt;</div><div class="line">{ <span class="keywordflow">return</span> <span class="stringliteral">&quot;toString not defined&quot;</span>; }</div></div><!-- fragment --> <dl class="section note"><dt>Note</dt><dd>We're using the fact that <code>has_toString</code> returns an <code>IntegralConstant</code> to write <code>decltype(...)::value</code>, which is a constant expression. For some reason, <code>has_toString(obj)</code> is not considered a constant expression, even though I think it should be one because we never read from <code>obj</code> (see the section on <a class="el" href="index.html#tutorial-appendix-constexpr">advanced constexpr</a>).</dd></dl>
609 <p>While this implementation is perfectly valid, it is still pretty cumbersome because it requires writing two different functions and going through the hoops of SFINAE explicitly by using <code>std::enable_if</code>. However, as you might remember from the section on <a class="el" href="index.html#tutorial-integral-branching">compile-time branching</a>, Hana provides an <code>if_</code> function that can be used to emulate the functionality of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4461.html">static_if</a>. Here is how we could write <code>optionalToString</code> with <code>hana::if_</code>:</p>
610 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line">std::string optionalToString(T <span class="keyword">const</span>&amp; obj) {</div><div class="line">  <span class="keywordflow">return</span> <a class="code" href="group__group-Logical.html#gafd655d2222367131e7a63616e93dd080">hana::if_</a>(has_toString(obj),</div><div class="line">    [](<span class="keyword">auto</span>&amp; x) { <span class="keywordflow">return</span> x.toString(); },</div><div class="line">    [](<span class="keyword">auto</span>&amp; x) { <span class="keywordflow">return</span> <span class="stringliteral">&quot;toString not defined&quot;</span>; }</div><div class="line">  )(obj);</div><div class="line">}</div></div><!-- fragment --><p> Now, the previous example covered only the specific case of checking for the presence of a non-static member function. However, <code>is_valid</code> can be used to detect the validity of almost any kind of expression. For completeness, we now present a list of common use cases for validity checking along with how to use <code>is_valid</code> to implement them.</p>
611 <h3><a class="anchor" id="tutorial-introspection-is_valid-non_static"></a>
612 Non-static members</h3>
613 <p>The first idiom we'll look at is checking for the presence of a non-static member. We can do it in a similar way as we did for the previous example:</p>
614 <div class="fragment"><div class="line"><span class="keyword">auto</span> has_member = hana::is_valid([](<span class="keyword">auto</span>&amp;&amp; x) -&gt; decltype((<span class="keywordtype">void</span>)x.member) { });</div><div class="line"></div><div class="line"><span class="keyword">struct </span>Foo { <span class="keywordtype">int</span> member[4]; };</div><div class="line"><span class="keyword">struct </span>Bar { };</div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(has_member(Foo{}));</div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(!has_member(Bar{}));</div></div><!-- fragment --><p> Notice how we cast the result of <code>x.member</code> to <code>void</code>? This is to make sure that our detection also works for types that can't be returned from functions, like array types. Also, it is important to use a reference as the parameter to our generic lambda, because that would otherwise require <code>x</code> to be <a href="http://en.cppreference.com/w/cpp/concept/CopyConstructible">CopyConstructible</a>, which is not what we're trying to check. This approach is simple and the most convenient when an object is available. However, when the checker is intended to be used with no object around, the following alternate implementation can be better suited:</p>
615 <div class="fragment"><div class="line"><span class="keyword">auto</span> has_member = hana::is_valid([](<span class="keyword">auto</span> t) -&gt; decltype(</div><div class="line">  (<span class="keywordtype">void</span>)hana::traits::declval(t).member</div><div class="line">) { });</div><div class="line"></div><div class="line"><span class="keyword">struct </span>Foo { <span class="keywordtype">int</span> member[4]; };</div><div class="line"><span class="keyword">struct </span>Bar { };</div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(has_member(hana::type_c&lt;Foo&gt;));</div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(!has_member(hana::type_c&lt;Bar&gt;));</div></div><!-- fragment --><p> This validity checker is different from what we saw earlier because the generic lambda is not expecting an usual object anymore; it is now expecting a <code>type</code> (which is an object, but still represents a type). We then use the <code>hana::traits::declval</code> <em>lifted metafunction</em> from the <code>&lt;<a class="el" href="traits_8hpp.html" title="Defines function-like equivalents to the standard &lt;type_traits&gt;, and also to some utilities like std:...">boost/hana/traits.hpp</a>&gt;</code> header to create an rvalue of the type represented by <code>t</code>, which we can then use to check for a non-static member. Finally, instead of passing an actual object to <code>has_member</code> (like <code>Foo{}</code> or <code>Bar{}</code>), we now pass a <code>type_c&lt;...&gt;</code>. This implementation is ideal for when no object is lying around.</p>
616 <h3><a class="anchor" id="tutorial-introspection-is_valid-static"></a>
617 Static members</h3>
618 <p>Checking for a static member is easy, and it is provided for completeness:</p>
619 <div class="fragment"><div class="line"><span class="keyword">auto</span> has_member = hana::is_valid([](<span class="keyword">auto</span> t) -&gt; decltype(</div><div class="line">  (<span class="keywordtype">void</span>)decltype(t)::type::member</div><div class="line">) { });</div><div class="line"></div><div class="line"><span class="keyword">struct </span>Foo { <span class="keyword">static</span> <span class="keywordtype">int</span> member[4]; };</div><div class="line"><span class="keyword">struct </span>Bar { };</div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(has_member(hana::type_c&lt;Foo&gt;));</div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(!has_member(hana::type_c&lt;Bar&gt;));</div></div><!-- fragment --><p> Again, we expect a <code>type</code> to be passed to the checker. Inside the generic lambda, we use <code>decltype(t)::type</code> to fetch the actual C++ type represented by the <code>t</code> object, as explained in the section on <a class="el" href="index.html#tutorial-type-working">type computations</a>. Then, we fetch the static member inside that type and cast it to <code>void</code>, for the same reason as we did for non-static members.</p>
620 <h3><a class="anchor" id="tutorial-introspection-is_valid-typename"></a>
621 Nested type names</h3>
622 <p>Checking for a nested type name is not hard, but it is slightly more convoluted than the previous cases:</p>
623 <div class="fragment"><div class="line"><span class="keyword">auto</span> has_member = hana::is_valid([](<span class="keyword">auto</span> t) -&gt; hana::type&lt;</div><div class="line">  <span class="keyword">typename</span> decltype(t)::type::member</div><div class="line"><span class="comment">//^^^^^^^^ needed because of the dependent context</span></div><div class="line">&gt; { });</div><div class="line"></div><div class="line"><span class="keyword">struct </span>Foo { <span class="keyword">struct </span>member; <span class="comment">/* not defined! */</span> };</div><div class="line"><span class="keyword">struct </span>Bar { };</div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(has_member(hana::type_c&lt;Foo&gt;));</div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(!has_member(hana::type_c&lt;Bar&gt;));</div></div><!-- fragment --><p> One might wonder why we use <code>-&gt; hana::type&lt;typename-expression&gt;</code> instead of simply <code>-&gt; typename-expression</code>. Again, the reason is that we want to support types that can't be returned from functions, like array types or incomplete types.</p>
624 <h3><a class="anchor" id="tutorial-introspection-is_valid-template"></a>
625 Nested templates</h3>
626 <p>Checking for a nested template name is similar to checking for a nested type name, except we use the <code>template_&lt;...&gt;</code> variable template instead of <code>type&lt;...&gt;</code> in the generic lambda:</p>
627 <div class="fragment"><div class="line"><span class="keyword">auto</span> has_member = hana::is_valid([](<span class="keyword">auto</span> t) -&gt; decltype(<a class="code" href="group__group-Metafunction.html#ga246419f6c3263b648412f346106e6543">hana::template_</a>&lt;</div><div class="line">  decltype(t)::type::template member</div><div class="line">  <span class="comment">//                 ^^^^^^^^ needed because of the dependent context</span></div><div class="line">&gt;) { });</div><div class="line"></div><div class="line"><span class="keyword">struct </span>Foo { <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ...&gt; <span class="keyword">struct </span>member; };</div><div class="line"><span class="keyword">struct </span>Bar { };</div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(has_member(hana::type_c&lt;Foo&gt;));</div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(!has_member(hana::type_c&lt;Bar&gt;));</div></div><!-- fragment --><h2><a class="anchor" id="tutorial-introspection-sfinae"></a>
628 Taking control of SFINAE</h2>
629 <p>Doing something only if an expression is well-formed is a very common pattern in C++. Indeed, the <code>optionalToString</code> function is just one instance of the following pattern, which is very general:</p>
630 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">auto</span> f(T x) {</div><div class="line">  <span class="keywordflow">if</span> (some expression involving x is well-formed)</div><div class="line">    <span class="keywordflow">return</span> something involving x;</div><div class="line">  <span class="keywordflow">else</span></div><div class="line">    <span class="keywordflow">return</span> something <span class="keywordflow">else</span>;</div><div class="line">}</div></div><!-- fragment --><p>To encapsulate this pattern, Hana provides the <code>sfinae</code> function, which allows executing an expression, but only if it is well-formed:</p>
631 <div class="fragment"><div class="line"><span class="keyword">auto</span> maybe_add = hana::sfinae([](<span class="keyword">auto</span> x, <span class="keyword">auto</span> y) -&gt; decltype(x + y) {</div><div class="line">  <span class="keywordflow">return</span> x + y;</div><div class="line">});</div><div class="line"></div><div class="line">maybe_add(1, 2); <span class="comment">// hana::just(3)</span></div><div class="line"></div><div class="line">std::vector&lt;int&gt; v;</div><div class="line">maybe_add(v, <span class="stringliteral">&quot;foobar&quot;</span>); <span class="comment">// hana::nothing</span></div></div><!-- fragment --><p> Here, we create a <code>maybe_add</code> function, which is simply a generic lambda wrapped with Hana's <code>sfinae</code> function. <code>maybe_add</code> is a function which takes two inputs and returns <code>just</code> the result of the generic lambda if that call is well-formed, and <code>nothing</code> otherwise. <code>just(...)</code> and <code>nothing</code> both belong to a type of container called <code>hana::optional</code>, which is essentially a compile-time <code>std::optional</code>. All in all, <code>maybe_add</code> is morally equivalent to the following function returning a <code>std::optional</code>, except that the check is done at compile-time:</p>
632 <div class="fragment"><div class="line"><span class="keyword">auto</span> maybe_add = [](<span class="keyword">auto</span> x, <span class="keyword">auto</span> y) {</div><div class="line">  <span class="keywordflow">if</span> (x + y is well formed)</div><div class="line">    <span class="keywordflow">return</span> std::optional&lt;decltype(x + y)&gt;{x + y};</div><div class="line">  <span class="keywordflow">else</span></div><div class="line">    <span class="keywordflow">return</span> std::optional&lt;???&gt;{};</div><div class="line">};</div></div><!-- fragment --><p>It turns out that we can take advantage of <code>sfinae</code> and <code>optional</code> to implement the <code>optionalToString</code> function as follows:</p>
633 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line">std::string optionalToString(T <span class="keyword">const</span>&amp; obj) {</div><div class="line">  <span class="keyword">auto</span> maybe_toString = hana::sfinae([](<span class="keyword">auto</span>&amp;&amp; x) -&gt; decltype(x.toString()) {</div><div class="line">    <span class="keywordflow">return</span> x.toString();</div><div class="line">  });</div><div class="line"></div><div class="line">  <span class="keywordflow">return</span> maybe_toString(obj).value_or(<span class="stringliteral">&quot;toString not defined&quot;</span>);</div><div class="line">}</div></div><!-- fragment --><p> First, we wrap <code>toString</code> with the <code>sfinae</code> function. Hence, <code>maybe_toString</code> is a function which either returns <code>just(x.toString())</code> if that is well-formed, or <code>nothing</code> otherwise. Secondly, we use the <code>.value_or()</code> function to extract the optional value from the container. If the optional value is <code>nothing</code>, <code>.value_or()</code> returns the default value given to it; otherwise, it returns the value inside the <code>just</code> (here <code>x.toString()</code>). This way of seeing SFINAE as a special case of computations that might fail is very clean and powerful, especially since <code>sfinae</code>'d functions can be combined through the <code>hana::optional</code> <code>Monad</code>, which is left to the reference documentation.</p>
634 <h2><a class="anchor" id="tutorial-introspection-adapting"></a>
635 Introspecting user-defined types</h2>
636 <p>Have you ever wanted to iterate over the members of a user-defined type? The goal of this section is to show you how Hana can be used to do it quite easily. To allow working with user-defined types, Hana defines the <code>Struct</code> concept. Once a user-defined type is a model of that concept, one can iterate over the members of an object of that type and query other useful information. To turn a user-defined type into a <code>Struct</code>, a couple of options are available. First, you may define the members of your user-defined type with the <code>BOOST_HANA_DEFINE_STRUCT</code> macro:</p>
637 <div class="fragment"><div class="line"><span class="keyword">struct </span>Person {</div><div class="line">  BOOST_HANA_DEFINE_STRUCT(Person,</div><div class="line">    (std::string, name),</div><div class="line">    (<span class="keywordtype">int</span>, age)</div><div class="line">  );</div><div class="line">};</div></div><!-- fragment --><p> This macro defines two members (<code>name</code> and <code>age</code>) with the given types. Then, it defines some boilerplate inside a <code>Person::hana</code> nested <code>struct</code>, which is required to make <code>Person</code> a model of the <code>Struct</code> concept. No constructors are defined (so <a href="http://en.cppreference.com/w/cpp/concept/PODType">POD-ness</a> is retained), the members are defined in the same order as they appear here and the macro can be used with template <code>struct</code>s just as well, and at any scope. Also note that you are free to add more members to the <code>Person</code> type after or before you use the macro. However, only members defined with the macro will be picked up when introspecting the <code>Person</code> type. Easy enough? Now, a <code>Person</code> can be accessed programmatically:</p>
638 <div class="fragment"><div class="line">Person john{<span class="stringliteral">&quot;John&quot;</span>, 30};</div><div class="line"></div><div class="line"><a class="code" href="group__group-Foldable.html#ga2af382f7e644ce3707710bbad313e9c2">hana::for_each</a>(john, [](<span class="keyword">auto</span> pair) {</div><div class="line">  std::cout &lt;&lt; hana::to&lt;char const*&gt;(<a class="code" href="group__group-Product.html#ga34bbf4281de06dc3540441e8b2bd24f4">hana::first</a>(pair)) &lt;&lt; <span class="stringliteral">&quot;: &quot;</span></div><div class="line">            &lt;&lt; <a class="code" href="group__group-Product.html#ga7bb979d59ffc3ab862cb7d9dc7730077">hana::second</a>(pair) &lt;&lt; std::endl;</div><div class="line">});</div><div class="line"></div><div class="line"><span class="comment">// name: John</span></div><div class="line"><span class="comment">// age: 30</span></div></div><!-- fragment --><p> Iteration over a <code>Struct</code> is done as if the <code>Struct</code> was a sequence of pairs, where the first element of a pair is the key associated to a member, and the second element is the member itself. When a <code>Struct</code> is defined through the <code>BOOST_HANA_DEFINE_STRUCT</code> macro, the key associated to any member is a compile-time <code>hana::string</code> representing the name of that member. This is why the function used with <code>for_each</code> takes a single argument <code>pair</code>, and then uses <code>first</code> and <code>second</code> to access the subparts of the pair. Also, notice how the <code>to&lt;char const*&gt;</code> function is used on the name of the member? This converts the compile-time string to a <code>constexpr char const*</code> so it can <code>cout</code>ed. Since it can be annoying to always use <code>first</code> and <code>second</code> to fetch the subparts of the pair, we can also use the <code>fuse</code> function to wrap our lambda and make it a binary lambda instead:</p>
639 <div class="fragment"><div class="line"><a class="code" href="group__group-Foldable.html#ga2af382f7e644ce3707710bbad313e9c2">hana::for_each</a>(john, <a class="code" href="group__group-Foldable.html#ga19fcf61d8d1179903952c0f564c538aa">hana::fuse</a>([](<span class="keyword">auto</span> name, <span class="keyword">auto</span> member) {</div><div class="line">  std::cout &lt;&lt; hana::to&lt;char const*&gt;(name) &lt;&lt; <span class="stringliteral">&quot;: &quot;</span> &lt;&lt; member &lt;&lt; std::endl;</div><div class="line">}));</div></div><!-- fragment --><p> Now, it looks much cleaner. As we just mentioned, <code>Struct</code>s are seen as a kind of sequence of pairs for the purpose of iteration. In fact, a <code>Struct</code> can even be searched like an associative data structure whose keys are the names of the members, and whose values are the members themselves:</p>
640 <div class="fragment"><div class="line">std::string name = <a class="code" href="group__group-Searchable.html#ga3c1826aee6c6eb577810bb99c5c3e53d">hana::at_key</a>(john, <span class="stringliteral">&quot;name&quot;</span>_s);</div><div class="line"><a class="code" href="group__group-assertions.html#ga29b2b21ffa5513e5b706c50ffee980af">BOOST_HANA_RUNTIME_CHECK</a>(name == <span class="stringliteral">&quot;John&quot;</span>);</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> age = <a class="code" href="group__group-Searchable.html#ga3c1826aee6c6eb577810bb99c5c3e53d">hana::at_key</a>(john, <span class="stringliteral">&quot;age&quot;</span>_s);</div><div class="line"><a class="code" href="group__group-assertions.html#ga29b2b21ffa5513e5b706c50ffee980af">BOOST_HANA_RUNTIME_CHECK</a>(age == 30);</div></div><!-- fragment --> <dl class="section note"><dt>Note</dt><dd>The <code>_s</code> user-defined literal creates a compile-time <code>hana::string</code>. It is located in the <code><a class="el" href="namespaceboost_1_1hana_1_1literals.html" title="Namespace containing C++14 user-defined literals provided by Hana. ">boost::hana::literals</a></code> namespace. Note that it is not part of the standard yet, but it is supported by Clang and GCC. If you want to stay 100% standard, you can use the <code>BOOST_HANA_STRING</code> macro instead.</dd></dl>
641 <p>The main difference between a <code>Struct</code> and a <code>hana::map</code> is that a map can be modified (keys can be added and removed), while a <code>Struct</code> is immutable. However, you can easily convert a <code>Struct</code> into a <code>hana::map</code> with <code>to&lt;map_tag&gt;</code>, and then you can manipulate it in a more flexible way.</p>
642 <div class="fragment"><div class="line"><span class="keyword">auto</span> map = <a class="code" href="group__group-Sequence.html#gae22a1a184b1b2dd550fa4fa619bed2e9">hana::insert</a>(hana::to&lt;hana::map_tag&gt;(john), hana::make_pair(<span class="stringliteral">&quot;last name&quot;</span>_s, <span class="stringliteral">&quot;Doe&quot;</span>s));</div><div class="line"></div><div class="line">std::string name = map[<span class="stringliteral">&quot;name&quot;</span>_s];</div><div class="line"><a class="code" href="group__group-assertions.html#ga29b2b21ffa5513e5b706c50ffee980af">BOOST_HANA_RUNTIME_CHECK</a>(name == <span class="stringliteral">&quot;John&quot;</span>);</div><div class="line"></div><div class="line">std::string last_name = map[<span class="stringliteral">&quot;last name&quot;</span>_s];</div><div class="line"><a class="code" href="group__group-assertions.html#ga29b2b21ffa5513e5b706c50ffee980af">BOOST_HANA_RUNTIME_CHECK</a>(last_name == <span class="stringliteral">&quot;Doe&quot;</span>);</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> age = map[<span class="stringliteral">&quot;age&quot;</span>_s];</div><div class="line"><a class="code" href="group__group-assertions.html#ga29b2b21ffa5513e5b706c50ffee980af">BOOST_HANA_RUNTIME_CHECK</a>(age == 30);</div></div><!-- fragment --><p> Using the <code>BOOST_HANA_DEFINE_STRUCT</code> macro to adapt a <code>struct</code> is convenient, but sometimes one can't modify the type that needs to be adapted. In these cases, the <code>BOOST_HANA_ADAPT_STRUCT</code> macro can be used to adapt a <code>struct</code> in a ad-hoc manner:</p>
643 <div class="fragment"><div class="line"><span class="keyword">namespace </span>not_my_namespace {</div><div class="line">  <span class="keyword">struct </span>Person {</div><div class="line">    std::string name;</div><div class="line">    <span class="keywordtype">int</span> age;</div><div class="line">  };</div><div class="line">}</div><div class="line"></div><div class="line">BOOST_HANA_ADAPT_STRUCT(not_my_namespace::Person, name, age);</div></div><!-- fragment --> <dl class="section note"><dt>Note</dt><dd>The <code>BOOST_HANA_ADAPT_STRUCT</code> macro must be used at global scope.</dd></dl>
644 <p>The effect is exactly the same as with the <code>BOOST_HANA_DEFINE_STRUCT</code> macro, except you do not need to modify the type you want to adapt, which is sometimes useful. Finally, it is also possible to define custom accessors by using the <code>BOOST_HANA_ADAPT_ADT</code> macro:</p>
645 <div class="fragment"><div class="line"><span class="keyword">namespace </span>also_not_my_namespace {</div><div class="line">  <span class="keyword">struct </span>Person {</div><div class="line">    std::string get_name();</div><div class="line">    <span class="keywordtype">int</span> get_age();</div><div class="line">  };</div><div class="line">}</div><div class="line"></div><div class="line">BOOST_HANA_ADAPT_ADT(also_not_my_namespace::Person,</div><div class="line">  (name, [](<span class="keyword">auto</span> <span class="keyword">const</span>&amp; p) { <span class="keywordflow">return</span> p.get_name(); }),</div><div class="line">  (age, [](<span class="keyword">auto</span> <span class="keyword">const</span>&amp; p) { <span class="keywordflow">return</span> p.get_age(); })</div><div class="line">);</div></div><!-- fragment --><p> This way, the names used to access the members of the <code>Struct</code> will be those specified, and the associated function will be called on the <code>Struct</code> when retrieving that member. Before we move on to a concrete example of using these introspection features, it should also be mentioned that <code>struct</code>s can be adapted without using macros. This advanced interface for defining <code>Struct</code>s can be used for example to specify keys that are not compile-time strings. The advanced interface is described in the documentation of the <code>Struct</code> concept.</p>
646 <h2><a class="anchor" id="tutorial-introspection-json"></a>
647 Example: generating JSON</h2>
648 <p>Let's now move on with a concrete example of using the introspection capabilities we just presented for printing custom objects as JSON. Our end goal is to have something like this:</p>
649 <div class="fragment"><div class="line"><span class="keyword">struct </span>Car {</div><div class="line">  BOOST_HANA_DEFINE_STRUCT(Car,</div><div class="line">    (std::string, brand),</div><div class="line">    (std::string, model)</div><div class="line">  );</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">struct </span>Person {</div><div class="line">  BOOST_HANA_DEFINE_STRUCT(Person,</div><div class="line">    (std::string, name),</div><div class="line">    (std::string, last_name),</div><div class="line">    (<span class="keywordtype">int</span>, age)</div><div class="line">  );</div><div class="line">};</div><div class="line"></div><div class="line">Car bmw{<span class="stringliteral">&quot;BMW&quot;</span>, <span class="stringliteral">&quot;Z3&quot;</span>}, audi{<span class="stringliteral">&quot;Audi&quot;</span>, <span class="stringliteral">&quot;A4&quot;</span>};</div><div class="line">Person john{<span class="stringliteral">&quot;John&quot;</span>, <span class="stringliteral">&quot;Doe&quot;</span>, 30};</div><div class="line"></div><div class="line"><span class="keyword">auto</span> tuple = hana::make_tuple(john, audi, bmw);</div><div class="line">std::cout &lt;&lt; to_json(tuple) &lt;&lt; std::endl;</div></div><!-- fragment --><p> And the output, after passing it through a JSON pretty-printer, should look like</p>
650 <div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;[</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;  {</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;    &quot;name&quot;: &quot;John&quot;,</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;    &quot;last_name&quot;: &quot;Doe&quot;,</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;    &quot;age&quot;: 30</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;  },</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;  {</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;    &quot;brand&quot;: &quot;Audi&quot;,</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;    &quot;model&quot;: &quot;A4&quot;</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;  },</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;  {</div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;    &quot;brand&quot;: &quot;BMW&quot;,</div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;    &quot;model&quot;: &quot;Z3&quot;</div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;  }</div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;]</div></div><!-- fragment --><p>First, let's define a couple of utility functions to make string manipulation easier:</p>
651 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Xs&gt;</div><div class="line">std::string join(Xs&amp;&amp; xs, std::string sep) {</div><div class="line">  <span class="keywordflow">return</span> <a class="code" href="group__group-Foldable.html#gaa0fde17f3b947a0678a1c0c01232f2cc">hana::fold</a>(<a class="code" href="group__group-Sequence.html#gaa18061cd0f63cfaae89abf43ff92b79e">hana::intersperse</a>(std::forward&lt;Xs&gt;(xs), sep), <span class="stringliteral">&quot;&quot;</span>, <a class="code" href="group__group-functional.html#gaefe9fd152cba94be71c2b5b9de689d23">hana::_</a> + <a class="code" href="group__group-functional.html#gaefe9fd152cba94be71c2b5b9de689d23">hana::_</a>);</div><div class="line">}</div><div class="line"></div><div class="line">std::string quote(std::string s) { <span class="keywordflow">return</span> <span class="stringliteral">&quot;\&quot;&quot;</span> + s + <span class="stringliteral">&quot;\&quot;&quot;</span>; }</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">auto</span> to_json(T <span class="keyword">const</span>&amp; x) -&gt; decltype(std::to_string(x)) {</div><div class="line">  <span class="keywordflow">return</span> std::to_string(x);</div><div class="line">}</div><div class="line"></div><div class="line">std::string to_json(<span class="keywordtype">char</span> c) { <span class="keywordflow">return</span> quote({c}); }</div><div class="line">std::string to_json(std::string s) { <span class="keywordflow">return</span> quote(s); }</div></div><!-- fragment --><p> The <code>quote</code> and the <code>to_json</code> overloads are pretty self-explanatory. The <code>join</code> function, however, might need a bit of explanation. Basically, the <code>intersperse</code> function takes a sequence and a separator, and returns a new sequence with the separator in between each pair of elements of the original sequence. In other words, we take a sequence of the form <code>[x1, ..., xn]</code> and turn it into a sequence of the form <code>[x1, sep, x2, sep, ..., sep, xn]</code>. Finally, we fold the resulting sequence with the <code>_ + _</code> function object, which is equivalent to <code>std::plus&lt;&gt;{}</code>. Since our sequence contains <code>std::string</code>s (we assume it does), this has the effect of concatenating all the strings of the sequence into one big string. Now, let's define how to print a <code>Sequence</code>:</p>
652 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Xs&gt;</div><div class="line">  <a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">std::enable_if_t&lt;hana::Sequence&lt;Xs&gt;::value</a>,</div><div class="line">std::string&gt; to_json(Xs <span class="keyword">const</span>&amp; xs) {</div><div class="line">  <span class="keyword">auto</span> json = <a class="code" href="group__group-Functor.html#ga5a8975f6e55375d5b6038a9c36ee63e7">hana::transform</a>(xs, [](<span class="keyword">auto</span> <span class="keyword">const</span>&amp; x) {</div><div class="line">    <span class="keywordflow">return</span> to_json(x);</div><div class="line">  });</div><div class="line"></div><div class="line">  <span class="keywordflow">return</span> <span class="stringliteral">&quot;[&quot;</span> + join(std::move(json), <span class="stringliteral">&quot;, &quot;</span>) + <span class="stringliteral">&quot;]&quot;</span>;</div><div class="line">}</div></div><!-- fragment --><p> First, we use the <code>transform</code> algorithm to turn our sequence of objects into a sequence of <code>std::string</code>s in JSON format. Then, we join that sequence with commas and we enclose it with <code>[]</code> to denote a sequence in JSON notation. Simple enough? Let's now take a look at how to print user-defined types:</p>
653 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line">  <a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">std::enable_if_t&lt;hana::Struct&lt;T&gt;::value</a>,</div><div class="line">std::string&gt; to_json(T <span class="keyword">const</span>&amp; x) {</div><div class="line">  <span class="keyword">auto</span> json = <a class="code" href="group__group-Functor.html#ga5a8975f6e55375d5b6038a9c36ee63e7">hana::transform</a>(<a class="code" href="group__group-Struct.html#gaf8c7199742581e6e66c8397def68e2d3">hana::keys</a>(x), [&amp;](<span class="keyword">auto</span> name) {</div><div class="line">    <span class="keyword">auto</span> <span class="keyword">const</span>&amp; member = <a class="code" href="group__group-Searchable.html#ga3c1826aee6c6eb577810bb99c5c3e53d">hana::at_key</a>(x, name);</div><div class="line">    <span class="keywordflow">return</span> quote(hana::to&lt;char const*&gt;(name)) + <span class="stringliteral">&quot; : &quot;</span> + to_json(member);</div><div class="line">  });</div><div class="line"></div><div class="line">  <span class="keywordflow">return</span> <span class="stringliteral">&quot;{&quot;</span> + join(std::move(json), <span class="stringliteral">&quot;, &quot;</span>) + <span class="stringliteral">&quot;}&quot;</span>;</div><div class="line">}</div></div><!-- fragment --><p> Here, we use the <code>keys</code> method to retrieve a <code>tuple</code> containing the names of the members of the user-defined type. Then, we <code>transform</code> that sequence into a sequence of <code>"name" : member</code> strings, which we then <code>join</code> and enclose with <code>{}</code>, which is used to denote objects in JSON notation. And that's it!</p>
654 <h1><a class="anchor" id="tutorial-containers"></a>
655 Generalities on containers</h1>
656 <hr/>
657 <p> This section explains several important notions about Hana's containers: how to create them, the lifetime of their elements and other concerns.</p>
658 <h2><a class="anchor" id="tutorial-containers-creating"></a>
659 Container creation</h2>
660 <p>While the usual way of creating an object in C++ is to use its constructor, heterogeneous programming makes things a bit more complicated. Indeed, in most cases, one is not interested in (or even aware of) the actual type of the heterogeneous container to be created. At other times, one could write out that type explicitly, but it would be redundant or cumbersome to do so. For this reason, Hana uses a different approach borrowed from <code>std::make_tuple</code> to create new containers. Much like one can create a <code><a class="el" href="structstd_1_1tuple.html" title="Adapter for std::tuples. ">std::tuple</a></code> with <code>std::make_tuple</code>, a <code>hana::tuple</code> can be created with <code>hana::make_tuple</code>. However, more generally, containers in Hana may be created with the <code>make</code> function:</p>
661 <div class="fragment"><div class="line"><span class="keyword">auto</span> xs = hana::make&lt;hana::tuple_tag&gt;(1, 2.2, <span class="charliteral">&#39;a&#39;</span>, <span class="stringliteral">&quot;bcde&quot;</span>s);</div></div><!-- fragment --><p> In fact, <code>make_tuple</code> is just a shortcut for <code>make&lt;tuple_tag&gt;</code> so you don't have to type <code><a class="el" href="group__group-core.html#ga1d92480f0af1029878e773dafa3e2f60" title="Create an object of the given tag with the given arguments. ">boost::hana::make</a>&lt;<a class="el" href="structboost_1_1hana_1_1tuple__tag.html" title="Tag representing hana::tuples. ">boost::hana::tuple_tag</a>&gt;</code> when you are out of Hana's namespace. Simply put, <code>make&lt;...&gt;</code> is is used all around the library to create different types of objects, thus generalizing the <code>std::make_xxx</code> family of functions. For example, one can create a <code>hana::range</code> of compile-time integers with <code>make&lt;range_tag&gt;</code>:</p>
662 <div class="fragment"><div class="line">constexpr <span class="keyword">auto</span> r = hana::make&lt;hana::range_tag&gt;(hana::int_c&lt;3&gt;, hana::int_c&lt;10&gt;);</div><div class="line">static_assert(r == hana::make_range(hana::int_c&lt;3&gt;, hana::int_c&lt;10&gt;), <span class="stringliteral">&quot;&quot;</span>);</div></div><!-- fragment --> <blockquote class="doxtable">
663 <p>These types with a trailing <code>_tag</code> are dummy types <b>representing</b> a family of heterogeneous containers (<code>hana::tuple</code>, <code>hana::map</code>, etc..). Tags are documented in the section on <a class="el" href="index.html#tutorial-core-tags">Hana's core</a>. </p>
664 </blockquote>
665 <p>For convenience, whenever a component of Hana provides a <code>make&lt;xxx_tag&gt;</code> function, it also provides the <code>make_xxx</code> shortcut to reduce typing. Also, an interesting point that can be raised in this example is the fact that <code>r</code> is <code>constexpr</code>. In general, whenever a container is initialized with constant expressions only (which is the case for <code>r</code>), that container may be marked as <code>constexpr</code>.</p>
666 <p>So far, we have only created containers with the <code>make_xxx</code> family of functions. However, some containers do provide constructors as part of their interface. For example, one can create a <code>hana::tuple</code> just like one would create a <code><a class="el" href="structstd_1_1tuple.html" title="Adapter for std::tuples. ">std::tuple</a></code>:</p>
667 <div class="fragment"><div class="line">hana::tuple&lt;int, double, char, std::string&gt; xs{1, 2.2, <span class="charliteral">&#39;a&#39;</span>, <span class="stringliteral">&quot;bcde&quot;</span>s};</div></div><!-- fragment --><p> When constructors (or any member function really) are part of the public interface, they will be documented on a per-container basis. However, in the general case, one should not take for granted that a container can be constructed as the tuple was constructed above. For example, trying to create a <code>hana::range</code> that way will <b>not</b> work:</p>
668 <div class="fragment"><div class="line">hana::range&lt;???&gt; xs{hana::int_c&lt;3&gt;, hana::int_c&lt;10&gt;};</div></div><!-- fragment --><p>In fact, we can't even specify the type of the object we'd like to create in that case, because the exact type of a <code>hana::range</code> is implementation-defined, which brings us to the next section.</p>
669 <h2><a class="anchor" id="tutorial-containers-types"></a>
670 Container types</h2>
671 <p>The goal of this section is to clarify what can be expected from the types of Hana's containers. Indeed, so far, we always let the compiler deduce the actual type of containers by using the <code>make_xxx</code> family of functions along with <code>auto</code>. But in general, what can we say about the type of a container?</p>
672 <div class="fragment"><div class="line"><span class="keyword">auto</span> xs = hana::make_tuple(1, <span class="charliteral">&#39;2&#39;</span>, <span class="stringliteral">&quot;345&quot;</span>);</div><div class="line"><span class="keyword">auto</span> ints = hana::make_range(hana::int_c&lt;0&gt;, hana::int_c&lt;100&gt;);</div><div class="line"><span class="comment">// what can we say about the types of `xs` and `ints`?</span></div></div><!-- fragment --><p> The answer is that it depends. Some containers have well defined types, while others do not specify their representation. In this example, the type of the object returned by <code>make_tuple</code> is well-defined, while the type returned by <code>make_range</code> is implementation-defined:</p>
673 <div class="fragment"><div class="line">hana::tuple&lt;int, char, char const*&gt; xs = hana::make_tuple(1, <span class="charliteral">&#39;2&#39;</span>, <span class="stringliteral">&quot;345&quot;</span>);</div><div class="line"><span class="keyword">auto</span> ints = hana::make_range(hana::int_c&lt;0&gt;, hana::int_c&lt;100&gt;);</div><div class="line"><span class="comment">// can&#39;t specify the type of ints, however</span></div></div><!-- fragment --><p> This is documented on a per-container basis; when a container has an implementation-defined representation, a note explaining exactly what can be expected from that representation is included in the container's description. There are several reasons for leaving the representation of a container unspecified; they are explained in the <a class="el" href="index.html#tutorial-rationales-container_representation">rationales</a>. When the representation of a container is implementation-defined, one must be careful not to make any assumptions about it, unless those assumption are explicitly allowed in the documentation of the container.</p>
674 <h3><a class="anchor" id="tutorial-containers-types-overloading"></a>
675 Overloading on container types</h3>
676 <p>While necessary, leaving the type of some containers unspecified makes some things very difficult to achieve, like overloading functions on heterogeneous containers:</p>
677 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keywordtype">void</span> f(std::vector&lt;T&gt; xs) {</div><div class="line">  <span class="comment">// ...</span></div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> ...???&gt;</div><div class="line"><span class="keywordtype">void</span> f(unspecified-range-type&lt;???&gt; r) {</div><div class="line">  <span class="comment">// ...</span></div><div class="line">}</div></div><!-- fragment --><p>The <code>is_a</code> utility is provided for this reason (and others). <code>is_a</code> allows checking whether a type is a precise kind of container using its tag, regardless of the actual type of the container. For example, the above example could be rewritten as</p>
678 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keywordtype">void</span> f(std::vector&lt;T&gt; xs) {</div><div class="line">  <span class="comment">// ...</span></div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> R, <span class="keyword">typename</span> = std::enable_if_t&lt;hana::is_a&lt;hana::range_tag, R&gt;()&gt;&gt;</div><div class="line"><span class="keywordtype">void</span> f(R r) {</div><div class="line">  <span class="comment">// ...</span></div><div class="line">}</div></div><!-- fragment --><p> This way, the second overload of <code>f</code> will only match when <code>R</code> is a type whose tag is <code>range_tag</code>, regardless of the exact representation of that range. Of course, <code>is_a</code> can be used with any kind of container: <code>tuple</code>, <code>map</code>, <code>set</code> and so on.</p>
679 <h2><a class="anchor" id="tutorial-containers-elements"></a>
680 Container elements</h2>
681 <p>In Hana, containers own their elements. When a container is created, it makes a <em>copy</em> of the elements used to initialize it and stores them inside the container. Of course, unnecessary copies are avoided by using move semantics. Because of those owning semantics, the lifetime of the objects inside the container is the same as that of the container.</p>
682 <div class="fragment"><div class="line">std::string hello = <span class="stringliteral">&quot;Hello&quot;</span>;</div><div class="line">std::vector&lt;char&gt; world = {<span class="charliteral">&#39;W&#39;</span>, <span class="charliteral">&#39;o&#39;</span>, <span class="charliteral">&#39;r&#39;</span>, <span class="charliteral">&#39;l&#39;</span>, <span class="charliteral">&#39;d&#39;</span>};</div><div class="line"></div><div class="line"><span class="comment">// hello is copied, world is moved-in</span></div><div class="line"><span class="keyword">auto</span> xs = hana::make_tuple(hello, std::move(world));</div><div class="line"></div><div class="line"><span class="comment">// s is a reference to the copy of hello inside xs.</span></div><div class="line"><span class="comment">// It becomes a dangling reference as soon as xs is destroyed.</span></div><div class="line">std::string&amp; s = xs[0_c];</div></div><!-- fragment --><p> Much like containers in the standard library, containers in Hana expect their elements to be objects. For this reason, references <em>may not</em> be stored in them. When references must be stored inside a container, one should use a <code>std::reference_wrapper</code> instead:</p>
683 <div class="fragment"><div class="line">std::vector&lt;int&gt; ints = { <span class="comment">/* huge vector of ints */</span> };</div><div class="line">std::vector&lt;std::string&gt; strings = { <span class="comment">/* huge vector of strings */</span> };</div><div class="line"></div><div class="line"><span class="keyword">auto</span> map = hana::make_map(</div><div class="line">  hana::make_pair(hana::type_c&lt;int&gt;, std::ref(ints)),</div><div class="line">  hana::make_pair(hana::type_c&lt;std::string&gt;, std::ref(strings))</div><div class="line">);</div><div class="line"></div><div class="line"><span class="keyword">auto</span>&amp; v = map[hana::type_c&lt;int&gt;].get();</div><div class="line"><a class="code" href="group__group-assertions.html#ga29b2b21ffa5513e5b706c50ffee980af">BOOST_HANA_RUNTIME_CHECK</a>(&amp;v == &amp;ints);</div></div><!-- fragment --><h1><a class="anchor" id="tutorial-algorithms"></a>
684 Generalities on algorithms</h1>
685 <hr/>
686 <p> Much like the previous section introduced general but important notions about heterogeneous containers, this section introduces general notions about heterogeneous algorithms.</p>
687 <h2><a class="anchor" id="tutorial-algorithms-value"></a>
688 By-value semantics</h2>
689 <p>Algorithms in Hana always return a new container holding the result. This allows one to easily chain algorithms by simply using the result of the first as the input of the second. For example, to apply a function to every element of a tuple and then reverse the result, one simply has to connect the <code>reverse</code> and <code>transform</code> algorithms:</p>
690 <div class="fragment"><div class="line"><span class="keyword">auto</span> to_str = [](<span class="keyword">auto</span> <span class="keyword">const</span>&amp; x) {</div><div class="line">  std::stringstream ss;</div><div class="line">  ss &lt;&lt; x;</div><div class="line">  <span class="keywordflow">return</span> ss.str();</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">auto</span> xs = hana::make_tuple(1, 2.2, <span class="charliteral">&#39;a&#39;</span>, <span class="stringliteral">&quot;bcde&quot;</span>);</div><div class="line"></div><div class="line"><a class="code" href="group__group-assertions.html#ga29b2b21ffa5513e5b706c50ffee980af">BOOST_HANA_RUNTIME_CHECK</a>(</div><div class="line">  <a class="code" href="group__group-Sequence.html#ga28037560e8f224c53cf6ac168d03a067">hana::reverse</a>(<a class="code" href="group__group-Functor.html#ga5a8975f6e55375d5b6038a9c36ee63e7">hana::transform</a>(xs, to_str)) == hana::make_tuple(<span class="stringliteral">&quot;bcde&quot;</span>, <span class="stringliteral">&quot;a&quot;</span>, <span class="stringliteral">&quot;2.2&quot;</span>, <span class="stringliteral">&quot;1&quot;</span>)</div><div class="line">);</div></div><!-- fragment --><p> This is different from the algorithms of the standard library, where one has to provide iterators to the underlying sequence. For reasons documented in the <a class="el" href="index.html#tutorial-rationales-iterators">rationales</a>, an iterator-based design was considered but was quickly dismissed in favor of composable and efficient abstractions better suited to the very particular context of heterogeneous programming.</p>
691 <p>One might also think that returning full sequences that own their elements from an algorithm would lead to tons of undesirable copies. For example, when using <code>reverse</code> and <code>transform</code>, one could think that an intermediate copy is made after the call to <code>transform</code>:</p>
692 <div class="fragment"><div class="line"><a class="code" href="group__group-Sequence.html#ga28037560e8f224c53cf6ac168d03a067">hana::reverse</a>(</div><div class="line">  <a class="code" href="group__group-Functor.html#ga5a8975f6e55375d5b6038a9c36ee63e7">hana::transform</a>(xs, to_str) <span class="comment">// &lt;-- copy into reverse(...) here?</span></div><div class="line">);</div></div><!-- fragment --><p> To make sure this does not happen, Hana uses perfect forwarding and move semantics heavily so it can provide an almost optimal runtime performance. So instead of doing a copy, a move occurs between <code>reverse</code> and <code>transform</code>:</p>
693 <div class="fragment"><div class="line"><a class="code" href="group__group-Sequence.html#ga28037560e8f224c53cf6ac168d03a067">hana::reverse</a>(</div><div class="line">  <a class="code" href="group__group-Functor.html#ga5a8975f6e55375d5b6038a9c36ee63e7">hana::transform</a>(xs, to_str) <span class="comment">// &lt;-- nope, move from the temporary instead!</span></div><div class="line">);</div></div><!-- fragment --><p> Ultimately, the goal is that code written using Hana should be equivalent to clever hand-written code, except it should be enjoyable to write. Performance considerations are explained in depth in their own <a class="el" href="index.html#tutorial-performance">section</a>.</p>
694 <h2><a class="anchor" id="tutorial-algorithms-laziness"></a>
695 (Non-)Laziness</h2>
696 <p>Algorithms in Hana are not lazy. When an algorithm is called, it does its job and returns a new sequence containing the result, end of the story. For example, calling the <code>permutations</code> algorithm on a large sequence is a stupid idea, because Hana will actually compute all the permutations:</p>
697 <div class="fragment"><div class="line"><span class="keyword">auto</span> perms = <a class="code" href="group__group-Sequence.html#gac1e182ac088f1990edd739424d30ea07">hana::permutations</a>(hana::make_tuple(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));</div><div class="line"><span class="comment">// perms has 3 628 800 elements, and your compiler just crashed</span></div></div><!-- fragment --><p>To contrast, algorithms in Boost.Fusion return views which hold the original sequence by reference and apply the algorithm on demand, as the elements of the sequence are accessed. This leads to subtle lifetime issues, like having a view that refers to a sequence that was destroyed. Hana's design assumes that most of the time, we want to access all or almost all the elements in a sequence anyway, and hence performance is not a big argument in favor of laziness.</p>
698 <h2><a class="anchor" id="tutorial-algorithms-codegen"></a>
699 What is generated?</h2>
700 <p>Algorithms in Hana are a bit special with respect to the runtime code they are expanded into. The goal of this subsection is not to explain exactly what code is generated, which depends on the compiler anyway, but to give a feel for things. Basically, a Hana algorithm is like an unrolled version of an equivalent classical algorithm. Indeed, since the bounds of the processed sequence are known at compile-time, it makes sense that we can unroll the loop over the sequence. For example, let's consider the <code>for_each</code> algorithm:</p>
701 <div class="fragment"><div class="line"><span class="keyword">auto</span> xs = hana::make_tuple(0, 1, 2, 3);</div><div class="line"><a class="code" href="group__group-Foldable.html#ga2af382f7e644ce3707710bbad313e9c2">hana::for_each</a>(xs, f);</div></div><!-- fragment --><p>If <code>xs</code> was a runtime sequence instead of a tuple, its length would only be known at runtime and the above code would have to be implemented as a loop:</p>
702 <div class="fragment"><div class="line"><span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; xs.size(); ++i) {</div><div class="line">  f(xs[i]);</div><div class="line">}</div></div><!-- fragment --><p>However, in our case, the length of the sequence is known at compile-time and so we don't have to check the index at each iteration. Hence, we can just write:</p>
703 <div class="fragment"><div class="line">f(xs[0_c]);</div><div class="line">f(xs[1_c]);</div><div class="line">f(xs[2_c]);</div><div class="line">f(xs[3_c]);</div></div><!-- fragment --><p>The main difference here is that no bound checking and index increment is done at each step, because there is no index anymore; the loop was effectively unrolled. In some cases, this can be desirable for performance reasons. In other cases, this can be detrimental to performance because it causes the code size to grow. As always, performance is a tricky subject and whether you actually want loop unrolling to happen should be tackled on a case-by-case basis. As a rule of thumb, algorithms processing all (or a subset) of the elements of a container are unrolled. In fact, if you think about it, this unrolling is the only way to go for heterogeneous sequences, because different elements of the sequence may have different types. As you might have noticed, we're not using normal indices into the tuple, but compile-time indices, which can't be generated by a normal <code>for</code> loop. In other words, the following does not make sense:</p>
704 <div class="fragment"><div class="line"><span class="keywordflow">for</span> (??? i = 0_c; i &lt; xs.size(); ++i) {</div><div class="line">  f(xs[i]);</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="tutorial-algorithms-effects"></a>
705 Side effects and purity</h2>
706 <p>By default, Hana assumes functions to be pure. A pure function is a function that has no side-effects at all. In other words, it is a function whose effect on the program is solely determined by its return value. In particular, such a function may not access any state that outlives a single invocation of the function. These functions have very nice properties, like the ability to reason mathematically about them, to reorder or even eliminate calls, and so on. Except where specified otherwise, all functions used with Hana (i.e. used in higher order algorithms) should be pure. In particular, functions passed to higher order algorithms are not guaranteed to be called any specific number of times. Furthermore, the order of execution is generally not specified and should therefore not be taken for granted. If this lack of guarantees about function invocations seems crazy, consider the following use of the <code>any_of</code> algorithm:</p>
707 <div class="fragment"><div class="line"><span class="keyword">auto</span> r = <a class="code" href="group__group-Searchable.html#ga5f7ff0125c448983e1b96c3ffb84f646">hana::any_of</a>(hana::make_tuple(<span class="stringliteral">&quot;hello&quot;</span>s, 1.2, 3), [](<span class="keyword">auto</span> x) {</div><div class="line">  <span class="keywordflow">return</span> std::is_integral&lt;decltype(x)&gt;{};</div><div class="line">});</div><div class="line"></div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(r);</div></div><!-- fragment --> <dl class="section note"><dt>Note</dt><dd>For this to work, the external adapters for <code><a class="el" href="structstd_1_1integral__constant.html" title="Adapter for std::integral_constants. ">std::integral_constant</a></code> contained in <code>&lt;<a class="el" href="ext_2std_2integral__constant_8hpp.html" title="Adapts std::integral_constant for use with Hana. ">boost/hana/ext/std/integral_constant.hpp</a>&gt;</code> must be included.</dd></dl>
708 <p>According to the previous section on unrolling, this algorithm should be expanded into something like:</p>
709 <div class="fragment"><div class="line"><span class="keyword">auto</span> xs = hana::make_tuple(<span class="stringliteral">&quot;hello&quot;</span>s, 1.2, 3);</div><div class="line"><span class="keyword">auto</span> pred = [](<span class="keyword">auto</span> x) { <span class="keywordflow">return</span> std::is_integral&lt;decltype(x)&gt;{}; };</div><div class="line"></div><div class="line"><span class="keyword">auto</span> r = hana::bool_c&lt;</div><div class="line">  pred(xs[0_c]) ? <span class="keyword">true</span> :</div><div class="line">  pred(xs[1_c]) ? <span class="keyword">true</span> :</div><div class="line">  pred(xs[2_c]) ? <span class="keyword">true</span> :</div><div class="line">  <span class="keyword">false</span></div><div class="line">&gt;;</div><div class="line"></div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(r);</div></div><!-- fragment --><p>Of course, the above code can't work as-is, because we're calling <code>pred</code> inside something that would have to be a constant expression, but <code>pred</code> is a lambda (and lambdas can't be called in constant expressions). However, whether any of these objects has an integral type is clearly known at compile-time, and hence we would expect that computing the answer only involves compile-time computations. In fact, this is exactly what Hana does, and the above algorithm is expanded into something like:</p>
710 <div class="fragment"><div class="line"><span class="keyword">auto</span> xs = hana::make_tuple(<span class="stringliteral">&quot;hello&quot;</span>s, 1.2, 3);</div><div class="line"><span class="keyword">auto</span> pred = [](<span class="keyword">auto</span> x) { <span class="keywordflow">return</span> std::is_integral&lt;decltype(x)&gt;{}; };</div><div class="line"></div><div class="line"><span class="keyword">auto</span> r = hana::bool_c&lt;</div><div class="line">  decltype(pred(xs[0_c]))::<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">value</a> ? true :</div><div class="line">  decltype(pred(xs[1_c]))::<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">value</a> ? true :</div><div class="line">  decltype(pred(xs[2_c]))::<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">value</a> ? true :</div><div class="line">  false</div><div class="line">&gt;;</div><div class="line"></div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(r);</div></div><!-- fragment --> <dl class="section note"><dt>Note</dt><dd>As you will be able to deduce from the next section on cross-phase computations, the implementation of <code>any_of</code> must actually be more general than this. However, this <a href="http://en.wikipedia.org/wiki/Lie-to-children">lie-to-children</a> is perfect for educational purposes.</dd></dl>
711 <p>As you can see, the predicate is never even executed; only its result type on a particular object is used. Regarding the order of evaluation, consider the <code>transform</code> algorithm, which is specified (for tuples) as:</p>
712 <div class="fragment"><div class="line"><a class="code" href="group__group-Functor.html#ga5a8975f6e55375d5b6038a9c36ee63e7">hana::transform</a>(hana::make_tuple(x1, ..., xn), f) == hana::make_tuple(f(x1), ..., f(xn))</div></div><!-- fragment --><p>Since <code>make_tuple</code> is a function, and since the evaluation order for the arguments of a function is unspecified, the order in which <code>f</code> is called on each element of the tuple is unspecified too. If one sticks to pure functions, everything works fine and the resulting code is often easier to understand. However, some exceptional algorithms like <code>for_each</code> do expect impure functions, and they guarantee an order of evaluation. Indeed, a <code>for_each</code> algorithm that would only take pure functions would be pretty much useless. When an algorithm can accept an impure function or guarantees some order of evaluation, the documentation for that algorithm will mention it explicitly. However, by default, no guarantees may be taken for granted.</p>
713 <h2><a class="anchor" id="tutorial-algorithms-cross_phase"></a>
714 Cross-phase algorithms</h2>
715 <p>This section introduces the notion of cross-phase computations and algorithms. In fact, we have already used cross-phase algorithms in the <a class="el" href="index.html#tutorial-quickstart">quick start</a>, for example with <code>filter</code>, but we did not explain exactly what was happening at that time. But before we introduce cross-phase algorithms, let's define what we mean by <em>cross-phase</em>. The phases we're referring to here are the compilation and the execution of a program. In C++ as in most statically typed languages, there is a clear distinction between compile-time and runtime; this is called phase distinction. When we speak of a cross-phase computation, we mean a computation that is somehow performed across those phases; i.e. that is partly executed at compile-time and partly executed at runtime.</p>
716 <p>Like we saw in earlier examples, some functions are able to return something that can be used at compile-time even when they are called on a runtime value. For example, let's consider the <code>length</code> function applied to a non-<code>constexpr</code> container:</p>
717 <div class="fragment"><div class="line"><span class="keyword">struct </span>Fish { std::string name; };</div><div class="line"><span class="keyword">struct </span>Cat  { std::string name; };</div><div class="line"><span class="keyword">struct </span>Dog  { std::string name; };</div><div class="line"></div><div class="line"><span class="keyword">auto</span> animals = hana::make_tuple(Fish{<span class="stringliteral">&quot;Nemo&quot;</span>}, Cat{<span class="stringliteral">&quot;Garfield&quot;</span>}, Dog{<span class="stringliteral">&quot;Snoopy&quot;</span>});</div><div class="line"><span class="comment">//   ^^^^^^^ not a compile-time value</span></div><div class="line"></div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(<a class="code" href="group__group-Foldable.html#gaf0f8f717245620dc28cd7d7fa44d7475">hana::length</a>(animals) == hana::size_c&lt;3&gt;);</div><div class="line"><span class="comment">//                        ^^^^^^^^^^^^^^^^^^^^^ assertion done at compile-time</span></div></div><!-- fragment --><p> Obviously, the tuple can't be made <code>constexpr</code>, since it contains runtime <code>std::string</code>s. Still, even though it is not called on a constant expression, <code>length</code> returns something that can be used at compile-time. If you think of it, the size of the tuple is known at compile-time regardless of its content, and hence it would only make sense for this information to be available to us at compile-time. If that seems surprising, think about <code><a class="el" href="structstd_1_1tuple.html" title="Adapter for std::tuples. ">std::tuple</a></code> and <code>std::tuple_size</code>:</p>
718 <div class="fragment"><div class="line"><a class="code" href="structstd_1_1tuple.html">std::tuple&lt;int, char, std::string&gt;</a> xs{1, <span class="charliteral">&#39;2&#39;</span>, std::string{<span class="stringliteral">&quot;345&quot;</span>}};</div><div class="line">static_assert(std::tuple_size&lt;decltype(xs)&gt;::<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">value</a> == 3u, <span class="stringliteral">&quot;&quot;</span>);</div></div><!-- fragment --><p> Since the size of the tuple is encoded in its type, it is always available at compile-time regardless of whether the tuple is <code>constexpr</code> or not. In Hana, this is implemented by having <code>length</code> return an <code>IntegralConstant</code>. Since an <code>IntegralConstant</code>'s value is encoded in its type, the result of <code>length</code> is contained in the type of the object it returns, and the length is therefore known at compile-time. Because <code>length</code> goes from a runtime value (the container) to a compile-time value (the <code>IntegralConstant</code>), <code>length</code> is a trivial example of a cross-phase algorithm (trivial because it does not really manipulate the tuple). Another algorithm that is very similar to <code>length</code> is the <code>is_empty</code> algorithm, which returns whether a container is empty:</p>
719 <div class="fragment"><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(!<a class="code" href="group__group-Iterable.html#ga2a05f564f8a7e4afa04fcbc07ad8f394">hana::is_empty</a>(animals));</div><div class="line"><span class="comment">//                         ^^^^^^^^^^^^^^^^^^^^^^^ assertion done at compile-time</span></div></div><!-- fragment --><p> More generally, any algorithm that takes a container whose value is known at runtime but queries something that can be known at compile-time should be able to return an <code>IntegralConstant</code> or another similar compile-time value. Let's make things slightly more complicated by considering the <code>any_of</code> algorithm, which we already encountered in the previous section:</p>
720 <div class="fragment"><div class="line"><span class="keywordtype">bool</span> any_garfield = <a class="code" href="group__group-Searchable.html#ga5f7ff0125c448983e1b96c3ffb84f646">hana::any_of</a>(animals, [](<span class="keyword">auto</span> animal) {</div><div class="line">  <span class="keywordflow">return</span> animal.name == <span class="stringliteral">&quot;Garfield&quot;</span>s;</div><div class="line">});</div><div class="line"></div><div class="line"><a class="code" href="group__group-assertions.html#ga29b2b21ffa5513e5b706c50ffee980af">BOOST_HANA_RUNTIME_CHECK</a>(any_garfield);</div></div><!-- fragment --><p> In this example, the result can't be known at compile-time, because the predicate returns a <code>bool</code> that is the result of comparing two <code>std::string</code>s. Since <code>std::string</code>s can't be compared at compile-time, the predicate must operate at runtime, and the overall result of the algorithm can then only be known at runtime too. However, let's say we used <code>any_of</code> with the following predicate instead:</p>
721 <div class="fragment"><div class="line"><span class="keyword">auto</span> any_cat = <a class="code" href="group__group-Searchable.html#ga5f7ff0125c448983e1b96c3ffb84f646">hana::any_of</a>(animals, [](<span class="keyword">auto</span> x) {</div><div class="line">  <span class="keywordflow">return</span> std::is_same&lt;decltype(x), Cat&gt;{};</div><div class="line">});</div><div class="line"></div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(any_cat);</div></div><!-- fragment --> <dl class="section note"><dt>Note</dt><dd>For this to work, the external adapters for <code><a class="el" href="structstd_1_1integral__constant.html" title="Adapter for std::integral_constants. ">std::integral_constant</a></code> contained in <code>&lt;<a class="el" href="ext_2std_2integral__constant_8hpp.html" title="Adapts std::integral_constant for use with Hana. ">boost/hana/ext/std/integral_constant.hpp</a>&gt;</code> must be included.</dd></dl>
722 <p>First, since the predicate is only querying information about the type of each element of the tuple, it is clear that its result can be known at compile-time. Since the number of elements in the tuple is also known at compile-time, the overall result of the algorithm can, in theory, be known at compile-time. More precisely, what happens is that the predicate returns a value initialized <code>std::is_same&lt;...&gt;</code>, which inherits from <code><a class="el" href="structstd_1_1integral__constant.html" title="Adapter for std::integral_constants. ">std::integral_constant</a></code>. Hana recognizes these objects, and the algorithm is written in such a way that it preserves the <code>compile-time</code>ness of the predicate's result. In the end, <code>any_of</code> hence returns an <code>IntegralConstant</code> holding the result of the algorithm, and we use the compiler's type deduction in a clever way to make it look easy. Hence, it would be equivalent to write (but then you would need to already know the result of the algorithm!):</p>
723 <div class="fragment"><div class="line">hana::integral_constant&lt;bool, true&gt; any_cat = <a class="code" href="group__group-Searchable.html#ga5f7ff0125c448983e1b96c3ffb84f646">hana::any_of</a>(animals, [](<span class="keyword">auto</span> x) {</div><div class="line">  <span class="keywordflow">return</span> std::is_same&lt;decltype(x), Cat&gt;{};</div><div class="line">});</div><div class="line"></div><div class="line"><a class="code" href="group__group-assertions.html#ga4bf9e0c46c44e21fbe5c5fbb3ace8356">BOOST_HANA_CONSTANT_CHECK</a>(any_cat);</div></div><!-- fragment --><p> Ok, so some algorithms are able to return compile-time values when their input satisfies some constraints with respect to <code>compile-time</code>ness. However, other algorithms are more restrictive and they <em>require</em> their inputs to satisfy some constraints regarding <code>compile-time</code>ness, without which they are not able to operate at all. An example of this is <code>filter</code>, which takes a sequence and a predicate, and returns a new sequence containing only those elements for which the predicate is satisfied. <code>filter</code> requires the predicate to return an <code>IntegralConstant</code>. While this requirement may seem stringent, it really makes sense if you think about it. Indeed, since we're removing some elements from the heterogeneous sequence, the type of the resulting sequence depends on the result of the predicate. Hence, the result of the predicate has to be known at compile-time for the compiler to be able to assign a type to the returned sequence. For example, consider what happens when we try to filter a heterogeneous sequence as follows:</p>
724 <div class="fragment"><div class="line"><span class="keyword">auto</span> animals = hana::make_tuple(Fish{<span class="stringliteral">&quot;Nemo&quot;</span>}, Cat{<span class="stringliteral">&quot;Garfield&quot;</span>}, Dog{<span class="stringliteral">&quot;Snoopy&quot;</span>});</div><div class="line"></div><div class="line"><span class="keyword">auto</span> no_garfield = <a class="code" href="group__group-MonadPlus.html#ga65cc6d9f522fb9e8e3b28d80ee5c822a">hana::filter</a>(animals, [](<span class="keyword">auto</span> animal) {</div><div class="line">  <span class="keywordflow">return</span> animal.name != <span class="stringliteral">&quot;Garfield&quot;</span>s;</div><div class="line">});</div></div><!-- fragment --><p>Clearly, we know that the predicate will only return false on the second element, and hence the result <em>should be</em> a <code>[Fish, Dog]</code> tuple. However, the compiler has no way of knowing this since the predicate's result is the result of a runtime computation, which happens way after the compiler has finished its job. Hence, the compiler does not have enough information to determine the return type of the algorithm. However, we could <code>filter</code> the same sequence with any predicate whose result is available at compile-time:</p>
725 <div class="fragment"><div class="line"><span class="keyword">auto</span> mammals = <a class="code" href="group__group-MonadPlus.html#ga65cc6d9f522fb9e8e3b28d80ee5c822a">hana::filter</a>(animals, [](<span class="keyword">auto</span> animal) {</div><div class="line">  <span class="keywordflow">return</span> hana::type_c&lt;decltype(animal)&gt; != hana::type_c&lt;Fish&gt;;</div><div class="line">});</div></div><!-- fragment --><p> Since the predicate returns an <code>IntegralConstant</code>, we know which elements of the heterogeneous sequence we'll be keeping at compile-time. Hence, the compiler is able to figure out the return type of the algorithm. Other algorithms like <code>partition</code> and <code>sort</code> work similarly; special algorithm requirements are always documented, just read the reference documentation of an algorithm before using it to avoid surprises.</p>
726 <p>This is the end of the section on algorithms. While this constitutes a fairly complete explanation of phase interaction inside algorithms, a deeper understanding can be gained by reading the <a class="el" href="index.html#tutorial-appendix-constexpr">advanced section</a> on <code>constexpr</code> and the reference for <code>Constant</code> and <code>IntegralConstant</code>.</p>
727 <dl class="section warning"><dt>Warning</dt><dd>Hana's algorithms are <code>constexpr</code> function objects instead of being template functions. This allows passing them to higher-order algorithms, which is very useful. However, since those function objects are defined at namespace scope in the header files, this causes each translation unit to see a different algorithm object. Hence, the address of an algorithm function object is not guaranteed to be unique across translation units, which can cause an ODR violation if one relies on such an address. So, in short, do not rely on the uniqueness of the address of any global object provided by Hana, which does not make sense in the general case anyway because such objects are <code>constexpr</code>. See <a href="https://github.com/boostorg/hana/issues/76">issue #76</a> for more information.</dd></dl>
728 <h1><a class="anchor" id="tutorial-performance"></a>
729 Performance considerations</h1>
730 <hr/>
731 <p> C++ programmers love performance, so here's a whole section dedicated to it. Since Hana lives on the frontier between runtime and compile-time computations, we are not only interested in runtime performance, but also compile-time performance. Since both topics are pretty much disjoint, we treat them separately below.</p>
732 <dl class="section note"><dt>Note</dt><dd>The benchmarks presented in this section are updated automatically when we push to the repository. If you notice results that do not withstand the claims made here, open a <a href="https://github.com/boostorg/hana/issues">GitHub issue</a>; it could be a performance regression.</dd></dl>
733 <dl class="section warning"><dt>Warning</dt><dd>As of writing this, not all of Hana's containers are optimized. Implementing Hana was a big enough challenge that containers were initially written naively and are now in the process of being rigorously optimized. In particular, the associative containers (<code>hana::map</code> and <code>hana::set</code>) have a pretty bad compile-time behavior because of their naive implementation, and their runtime behavior also seems to be problematic in some cases. Improving this situation is in the TODO list.</dd></dl>
734 <h2><a class="anchor" id="tutorial-performance-compile"></a>
735 Compile-time performance</h2>
736 <p>C++ metaprogramming brings its share of awful things. One of the most annoying and well-known problem associated to it is interminable compilation times. Hana claims to be more compile-time efficient than its predecessors; this is a bold claim and we will now try to back it. Of course, Hana can't do miracles; metaprogramming is a byproduct of the C++ template system and the compiler is not meant to be used as an interpreter for some meta language. However, by using cutting edge and intensely benchmarked techniques, Hana is able to minimize the strain on the compiler.</p>
737 <dl class="section note"><dt>Note</dt><dd>While Hana has better compile-times than pre-C++11 metaprogramming libraries, modern libraries supporting only type-level computations (such as <a href="https://github.com/edouarda/brigand">Brigand</a>) can provide better compile-times, at the cost of generality. Indeed, Hana's ability to manipulate runtime values comes at a compile-time cost, no matter how hard we try to mitigate it. If you want to use Hana for intensive type-level computations, you should benchmark and see whether it suits you.</dd></dl>
738 <p>Before we dive, let me make a quick note on the methodology used to measure compile-time performance in Hana. Previous metaprogramming libraries measured the compile-time complexity of their meta-algorithms and meta-sequences by looking at the number of instantiations the compiler had to perform. While easy to understand, this way of measuring the compile-time complexity actually does not give us a lot of information regarding the compilation time, which is what we're interested in minimizing at the end of the day. Basically, the reason for this is that template metaprogramming is such a twisted model of computation that it's very hard to find a standard way of measuring the performance of algorithms. Hence, instead of presenting meaningless complexity analyses, we prefer to benchmark everything on every supported compiler and to pick the best implementation on that compiler. Also note that the benchmarks we present here are quite precise. Indeed, even though we do not take multiple measurements and take their mean or something similar to reduce incertitude, the benchmarks are very stable when they are regenerated, which suggests a reasonably good precision. Now, let's dive.</p>
739 <p>First, Hana minimizes its dependency on the preprocessor. In addition to yielding cleaner error messages in many cases, this reduces the overall parsing and preprocessing time for header files. Also, because Hana only supports cutting edge compilers, there are very few workarounds in the library, which results in a cleaner and smaller library. Finally, Hana minimizes reliance on any kind of external dependencies. In particular, it only uses other Boost libraries in a few specific cases, and it does not rely on the standard library for the largest part. There are several reasons (other than include times) for doing so; they are documented in the <a class="el" href="index.html#tutorial-rationales-dependencies">rationales</a>.</p>
740 <p>Below is a chart showing the time required to include different libraries. The chart shows the time for including everything in the (non-external) public API of each library. For example, for Hana this means the <code>&lt;<a class="el" href="hana_8hpp.html" title="Includes all the library components except the adapters for external libraries. ">boost/hana.hpp</a>&gt;</code> header, which excludes the external adapters. For other libraries like Boost.Fusion, this means including all the public headers in the <code>boost/fusion/</code> directory, but not the adapters for external libraries like the MPL.</p>
741 <div class="benchmark-chart" style="min-width: 310px; height: 400px; margin: 0 auto" data-dataset="benchmark.including.compile.json"> </div><p>In addition to reduced preprocessing times, Hana uses modern techniques to implement heterogeneous sequences and algorithms in the most compile-time efficient way possible. Before jumping to the compile-time performance of the algorithms, we will have a look at the compile-time cost of creating heterogeneous sequences. Indeed, since we will be presenting algorithms that work on sequences, we must be aware of the cost of creating the sequences themselves, since that will influence the benchmarks for the algorithms. The following chart presents the compile-time cost of creating a sequence of <code>n</code> heterogeneous elements.</p>
742 <div class="benchmark-chart" style="min-width: 310px; height: 400px; margin: 0 auto" data-dataset="benchmark.make.compile.json"> </div><dl class="section note"><dt>Note</dt><dd>You can zoom on the chart by selecting an area to zoom into. Also, you can hide a series of points by clicking on it in the legend on the right.</dd></dl>
743 <p>The benchmark methodology is to always create the sequences in the most efficient way possible. For Hana and <code><a class="el" href="structstd_1_1tuple.html" title="Adapter for std::tuples. ">std::tuple</a></code>, this simply means using the appropriate <code>make_tuple</code> function. However, for the MPL, this means creating a <code>mpl::vectorN</code> of size up to 20, and then using <code>mpl::push_back</code> to create larger vectors. We use a similar technique for Fusion sequences. The reason for doing so is that Fusion and MPL sequences have fixed size limits, and the techniques used here have been found to be the fastest way to create longer sequences.</p>
744 <p>For completeness, we also present the compile-time cost of creating a <code><a class="el" href="structstd_1_1array.html" title="Adaptation of std::array for Hana. ">std::array</a></code> with <code>n</code> elements. However, note that <code><a class="el" href="structstd_1_1array.html" title="Adaptation of std::array for Hana. ">std::array</a></code> can only hold elements with a single type, so we're comparing apples and oranges here. As you can see, the cost of creating a <code><a class="el" href="structstd_1_1array.html" title="Adaptation of std::array for Hana. ">std::array</a></code> is constant and essentially inexistent (the non-zero overhead is that of simply including the <code>&lt;array&gt;</code> header). Hence, while Hana provides improved compile-times over other heterogeneous containers, please stick with normal homogeneous containers if that's all you need for your application; your compile-times will be much faster that way.</p>
745 <p>You can also see that creating sequences has a non-negligible cost. Actually, this is really the most expensive part of doing heterogeneous computations, as you will see in the following charts. Hence, when you look at the charts below, keep in mind the cost of merely creating the sequences. Also note that only the most important algorithms will be presented here, but the <a href="http://metaben.ch">Metabench</a> project provides micro benchmarks for compile-time performance for almost all of Hana's algorithms. Also, the benchmarks we present compare several different libraries. However, since Hana and Fusion can work with values and not only types, comparing their algorithms with type-only libraries like MPL is not really fair. Indeed, Hana and Fusion algorithms are more powerful since they also allow runtime effects to be performed. However, the comparison between Fusion and Hana is fair, because both libraries are just as powerful (strictly speaking). Finally, we can't show benchmarks of the algorithms for <code><a class="el" href="structstd_1_1tuple.html" title="Adapter for std::tuples. ">std::tuple</a></code>, because the standard does not provide equivalent algorithms. Of course, we could use Hana's external adapters, but that would not be a faithful comparison.</p>
746 <p>The first algorithm which is ubiquitous in metaprogramming is <code>transform</code>. It takes a sequence and a function, and returns a new sequence containing the result of applying the function to each element. The following chart presents the compile-time performance of applying <code>transform</code> to a sequence of <code>n</code> elements. The <code>x</code> axis represents the number of elements in the sequence, and the <code>y</code> axis represents the compilation time in seconds. Also note that we're using the <code>transform</code> equivalent in each library; we're not using Hana's <code>transform</code> through the Boost.Fusion adapters, for example, because we really want to benchmark their implementation against ours.</p>
747 <div class="benchmark-chart" style="min-width: 310px; height: 400px; margin: 0 auto" data-dataset="benchmark.transform.compile.json"> </div><p>Here, we can see that Hana's tuple performs better than all the other alternatives. This is mainly due to the fact that we use C++11 variadic parameter pack expansion to implement this algorithm under the hood, which is quite efficient.</p>
748 <p>Before we move on, it is important to mention something regarding the benchmark methodology for Fusion algorithms. Some algorithms in Fusion are lazy, which means that they don't actually perform anything, but simply return a modified view to the original data. This is the case of <code>fusion::transform</code>, which simply returns a transformed view that applies the function to each element of the original sequence as those elements are accessed. If we want to benchmark anything at all, we need to force the evaluation of that view, as would eventually happen when accessing the elements of the sequence in real code. However, for complex computations with multiple layers, a lazy approach may yield a substantially different compile-time profile. Of course, this difference is poorly represented in micro benchmarks, so keep in mind that these benchmarks only give a part of the big picture. For completeness in the rest of the section, we will mention when a Fusion algorithm is lazy, so that you know when we're <em>artificially</em> forcing the evaluation of the algorithm for the purpose of benchmarking.</p>
749 <dl class="section note"><dt>Note</dt><dd>We are currently considering adding lazy views to Hana. If this feature is important to you, please let us know by commenting <a href="https://github.com/boostorg/hana/issues/193">this issue</a>.</dd></dl>
750 <p>The second important class of algorithms are folds. Folds can be used to implement many other algorithms like <code>count_if</code>, <code>minimum</code> and so on. Hence, a good compile-time performance for fold algorithms ensures a good compile-time performance for those derived algorithms, which is why we're only presenting folds here. Also note that all the non-monadic fold variants are somewhat equivalent in terms of compile-time, so we only present the left folds. The following chart presents the compile-time performance of applying <code>fold_left</code> to a sequence of <code>n</code> elements. The <code>x</code> axis represents the number of elements in the sequence, and the <code>y</code> axis represents the compilation time in seconds. The function used for folding is a dummy function that does nothing. In real code, you would likely fold with a nontrivial operation, so the curves would be worse than that. However, these are micro benchmarks and hence they only show the performance of the algorithm itself.</p>
751 <div class="benchmark-chart" style="min-width: 310px; height: 400px; margin: 0 auto" data-dataset="benchmark.fold_left.compile.json"> </div><p>The third and last algorithm that we present here is the <code>find_if</code> algorithm. This algorithm is difficult to implement efficiently, because it requires stopping at the first element which satisfies the given predicate. For the same reason, modern techniques don't really help us here, so this algorithm constitutes a good test of the implementation quality of Hana, without taking into account the free lunch given to use by C++14.</p>
752 <div class="benchmark-chart" style="min-width: 310px; height: 400px; margin: 0 auto" data-dataset="benchmark.find_if.compile.json"> </div><p>As you can see, Hana performs better than Fusion, and as well as MPL, yet Hana's <code>find_if</code> can be used with values too, unlike MPL's. This concludes the section on compile-time performance. In case you want to see the performance of an algorithm that we have not presented here, the <a href="http://metaben.ch">Metabench</a> project provides compile-time benchmarks for most of Hana's algorithms.</p>
753 <h2><a class="anchor" id="tutorial-performance-runtime"></a>
754 Runtime performance</h2>
755 <p>Hana was designed to be very efficient at runtime. But before we dive into the details, let's clarify one thing. Hana being a metaprogramming library which allows manipulating both types and values, it does not always make sense to even talk about runtime performance. Indeed, for type-level computations and computations on <code>IntegralConstant</code>s, runtime performance is simply not a concern, because the result of the computation is contained in a <em>type</em>, which is a purely compile-time entity. In other words, these computations involve only compile-time work, and no code is even generated to perform these computations at runtime. The only case where it makes sense to discuss runtime performance is when manipulating runtime values in heterogeneous containers and algorithms, because this is the only case where the compiler has to generate some runtime code. It is therefore only computations of this sort that we will be studying in the remainder of this section.</p>
756 <p>Like we did for compile-time benchmarks, the methodology used to measure runtime performance in Hana is data driven rather than analytical. In other words, instead of trying to determine the complexity of an algorithm by counting the number of basic operations it does as a function of the input size, we simply take measurements for the most interesting cases and see how it behaves. There are a couple of reasons for doing so. First, we do not expect Hana's algorithms to be called on large inputs since those algorithms work on heterogeneous sequences whose length must be known at compile-time. For example, if you tried to call the <code>find_if</code> algorithm on a sequence of 100k elements, your compiler would simply die while trying to generate the code for this algorithm. Hence, algorithms can't be called on very large inputs and the analytical approach then loses a lot of its attractiveness. Secondly, processors have evolved into pretty complex beasts, and the actual performance you'll be able to squeeze out is actually controlled by much more than the mere number of steps your algorithm is doing. For example, bad cache behavior or branch misprediction could turn a theoretically efficient algorithm into a slowpoke, especially for small inputs. Since Hana causes a lot of unrolling to happen, these factors must be considered even more carefully and any analytical approach would probably only comfort us into thinking we're efficient. Instead, we want hard data, and pretty charts to display it!</p>
757 <dl class="section note"><dt>Note</dt><dd>Like for compile-time performance, we're forcing the evaluation of some Fusion algorithms that are normally lazy. Again, depending on the complexity of the computation, a lazy algorithm may cause substantially different code to be generated or a different design to be used, for better or worse. Keep this in mind when you look at these runtime benchmarks. If performance is absolutely critical to your application, you should profile <em>before</em> and <em>after</em> switching from Fusion to Hana. And let us know if Hana performs worse; we'll fix it!</dd></dl>
758 <p>There are a couple of different aspects we will want to benchmark. First, we will obviously want to benchmark the execution time of the algorithms. Secondly, because of the by-value semantics used throughout the library, we will also want to make sure that the minimum amount of data is copied around. Finally, we will want to make sure that using Hana does not cause too much code bloat because of unrolling, as explained in the <a class="el" href="index.html#tutorial-algorithms-codegen">section</a> on algorithms.</p>
759 <p>Just like we studied only a couple of key algorithms for compile-time performance, we will focus on the runtime performance of a few algorithms. For each benchmarked aspect, we will compare the algorithm as implemented by different libraries. Our goal is to always be at least as efficient as Boost.Fusion, which is near from optimality in terms of runtime performance. For comparison, we also show the same algorithm as executed on a runtime sequence, and on a sequence whose length is known at compile-time but whose <code>transform</code> algorithm does not use explicit loop unrolling. All the benchmarks presented here are done in a <em>Release</em> CMake configuration, which takes care of passing the proper optimization flags (usually <code>-O3</code>). Let's start with the following chart, which shows the execution time required to <code>transform</code> different kinds of sequences:</p>
760 <div class="benchmark-chart" style="min-width: 310px; height: 400px; margin: 0 auto" data-dataset="benchmark.transform.execute.json"> </div><dl class="section note"><dt>Note</dt><dd>Keep in mind that <code>fusion::transform</code> is usually lazy, and we're forcing its evaluation for the purpose of benchmarking.</dd></dl>
761 <p>As you can see, Hana and Fusion are pretty much on the same line. <code><a class="el" href="structstd_1_1array.html" title="Adaptation of std::array for Hana. ">std::array</a></code> is slightly slower for larger collections data sets, and <code>std::vector</code> is noticeably slower for larger collections. Since we also want to look out for code bloat, let's take a look at the size of the executable generated for the exact same scenario:</p>
762 <div class="benchmark-chart" style="min-width: 310px; height: 400px; margin: 0 auto" data-dataset="benchmark.transform.bloat.json"> </div><p>As you can see, code bloat does not seem to be an issue, at least not one that can be detected in micro benchmarks such as this one. Let's now take a look at the <code>fold</code> algorithm, which is used very frequently:</p>
763 <div class="benchmark-chart" style="min-width: 310px; height: 400px; margin: 0 auto" data-dataset="benchmark.fold_left.execute.json"> </div><p>Here, you can see that everybody is performing pretty much the same, which is a good sign that Hana is at least not screwing things up. Again, let's look at the executable size:</p>
764 <div class="benchmark-chart" style="min-width: 310px; height: 400px; margin: 0 auto" data-dataset="benchmark.fold_left.bloat.json"> </div><p>Here again, the code size did not explode. So at least for moderate usages of Hana (and Fusion for that matter, since they have the same problem), code bloat should not be a major concern. The containers in the charts we just presented contain randomly generated <code>int</code>s, which is cheap to copy around and lends itself well to micro benchmarks. However, what happens when we chain multiple algorithms on a container whose elements are expensive to copy? More generally, the question is: when an algorithm is passed a temporary object, does it seize the opportunity to avoid unnecessary copies? Consider:</p>
765 <div class="fragment"><div class="line"><span class="keyword">auto</span> xs = hana::make_tuple(<span class="stringliteral">&quot;some&quot;</span>s, <span class="stringliteral">&quot;huge&quot;</span>s, <span class="stringliteral">&quot;string&quot;</span>s);</div><div class="line"></div><div class="line"><span class="comment">// No copy of xs&#39;s elements should be made: they should only be moved around.</span></div><div class="line"><span class="keyword">auto</span> ys = <a class="code" href="group__group-Sequence.html#ga28037560e8f224c53cf6ac168d03a067">hana::reverse</a>(std::move(xs));</div></div><!-- fragment --><p>To answer this question, we'll look at the chart generated when benchmarking the above code for strings of about 1k characters. However, note that it does not really make sense to benchmark this for standard library algorithms, because they do not return containers.</p>
766 <div class="benchmark-chart" style="min-width: 310px; height: 400px; margin: 0 auto" data-dataset="benchmark.reverse.move.json"> </div><dl class="section note"><dt>Note</dt><dd>Keep in mind that <code>fusion::reverse</code> is usually lazy, and we're forcing its evaluation for the purpose of benchmarking.</dd></dl>
767 <p>As you can see, Hana is faster than Fusion, probably because of a more consistent use of move semantics in the implementation. If we had not provided a temporary container to <code>reverse</code>, no move could have been performed by Hana and both libraries would have performed similarly:</p>
768 <div class="benchmark-chart" style="min-width: 310px; height: 400px; margin: 0 auto" data-dataset="benchmark.reverse.nomove.json"> </div><p>This concludes the section on runtime performance. Hopefully you are now convinced that Hana was built for speed. Performance is important to us: if you ever encounter a scenario where Hana causes bad code to be generated (and the fault is not on the compiler), please open an <a href="https://github.com/boostorg/hana/issues">issue</a> so the problem can be addressed.</p>
769 <h1><a class="anchor" id="tutorial-ext"></a>
770 Integration with external libraries</h1>
771 <hr/>
772 <p>Hana provides out-of-the-box integration with some existing libraries. Specifically, this means that you can use some containers from these libraries in Hana's algorithms by simply including the appropriate header making the bridge between Hana and the external component. This can be very useful for porting existing code from e.g. Fusion/MPL to Hana:</p>
773 <div class="fragment"><div class="line"><span class="comment">// In the old code, this used to receive a Fusion sequence.</span></div><div class="line"><span class="comment">// Now, it can be either a Hana sequence or a Fusion sequence.</span></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence&gt;</div><div class="line"><span class="keywordtype">void</span> f(Sequence <span class="keyword">const</span>&amp; seq) {</div><div class="line">    <a class="code" href="group__group-Foldable.html#ga2af382f7e644ce3707710bbad313e9c2">hana::for_each</a>(seq, [](<span class="keyword">auto</span> <span class="keyword">const</span>&amp; element) {</div><div class="line">        std::cout &lt;&lt; element &lt;&lt; std::endl;</div><div class="line">    });</div><div class="line">}</div></div><!-- fragment --> <dl class="section note"><dt>Note</dt><dd>At this time, only adapters to use data types from other libraries inside Hana are provided; adapters for the other way around (using Hana containers inside other libraries) are not provided.</dd></dl>
774 <p>However, using external adapters has a couple of pitfalls. For example, after a while using Hana, you might become used to comparing Hana tuples using the normal comparison operators, or doing arithmetic with Hana <code>integral_constant</code>s. Of course, nothing guarantees that these operators are defined for external adapters too (and in general they won't be). Hence, you'll have to stick to the functions provided by Hana that implement these operators. For example:</p>
775 <div class="fragment"><div class="line"><span class="keyword">auto</span> r = <a class="code" href="classstd_1_1ratio.html">std::ratio&lt;3, 4&gt;</a>{} + <a class="code" href="classstd_1_1ratio.html">std::ratio&lt;4, 5&gt;</a>{}; <span class="comment">// error, the operator is not defined!</span></div></div><!-- fragment --><p>Instead, you should use the following:</p>
776 <div class="fragment"><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="ratio_8hpp.html">boost/hana/ext/std/ratio.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="plus_8hpp.html">boost/hana/plus.hpp</a>&gt;</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;ratio&gt;</span></div><div class="line"><span class="keyword">namespace </span>hana = <a class="code" href="namespaceboost_1_1hana.html">boost::hana</a>;</div><div class="line"></div><div class="line"><span class="keyword">auto</span> r = <a class="code" href="group__group-Monoid.html#gaeb5d4a1e967e319712f9e4791948896c">hana::plus</a>(<a class="code" href="classstd_1_1ratio.html">std::ratio&lt;3, 4&gt;</a>{}, <a class="code" href="classstd_1_1ratio.html">std::ratio&lt;4, 5&gt;</a>{});</div></div><!-- fragment --><p> But sometimes, it's much worse. Some external components define operators, but they don't necessarily have the same semantics as those from Hana. For example, comparing two <code><a class="el" href="structstd_1_1tuple.html" title="Adapter for std::tuples. ">std::tuple</a></code>s of different lengths will give an error when using <code>operator==</code>:</p>
777 <div class="fragment"><div class="line">std::make_tuple(1, 2, 3) == std::make_tuple(1, 2); <span class="comment">// compiler error</span></div></div><!-- fragment --><p>On the other hand, comparing Hana tuples of different lengths will just return a false <code>IntegralConstant</code>:</p>
778 <div class="fragment"><div class="line">hana::make_tuple(1, 2, 3) == hana::make_tuple(1, 2); <span class="comment">// hana::false_c</span></div></div><!-- fragment --><p>This is because <code><a class="el" href="structstd_1_1tuple.html" title="Adapter for std::tuples. ">std::tuple</a></code> defines its own operators, and their semantics are different from that of Hana's operators. The solution is to stick with Hana's named functions instead of using operators when you know you'll have to work with other libraries:</p>
779 <div class="fragment"><div class="line"><a class="code" href="group__group-Comparable.html#gacaf1ebea6b3ab96ac9dcb82f0e64e547">hana::equal</a>(std::make_tuple(1, 2, 3), std::make_tuple(1, 2)); <span class="comment">// hana::false_c</span></div></div><!-- fragment --><p>When using external adapters, one should also be careful not to forget including the proper bridge headers. For example, suppose I want to use a Boost.MPL vector with Hana. I include the appropriate bridge header:</p>
780 <div class="fragment"><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="boost_2mpl_2vector_8hpp.html">boost/hana/ext/boost/mpl/vector.hpp</a>&gt;</span> <span class="comment">// bridge header</span></div><div class="line"></div><div class="line"><span class="keyword">using</span> Vector = mpl::vector&lt;int, char, float&gt;;</div><div class="line">static_assert(<a class="code" href="group__group-Iterable.html#ga8a67ea10e8082dbe6705e573fa978444">hana::front</a>(Vector{}) == hana::type_c&lt;int&gt;, <span class="stringliteral">&quot;&quot;</span>);</div></div><!-- fragment --> <dl class="section note"><dt>Note</dt><dd>The exact layout of these bridge headers is documented in the section about <a class="el" href="index.html#tutorial-header_organization">Header organization</a>.</dd></dl>
781 <p>Now, however, suppose that I use <code>mpl::size</code> to query the size of the vector and then compare it to some value. I could also use <code>hana::length</code> and everything would be fine, but bear with me for the sake of the example:</p>
782 <div class="fragment"><div class="line"><span class="keyword">using</span> Size = mpl::size&lt;Vector&gt;::type;</div><div class="line">static_assert(<a class="code" href="group__group-Comparable.html#gacaf1ebea6b3ab96ac9dcb82f0e64e547">hana::equal</a>(Size{}, hana::int_c&lt;3&gt;), <span class="stringliteral">&quot;&quot;</span>); <span class="comment">// breaks!</span></div></div><!-- fragment --><p> The reason why this breaks is that <code>mpl::size</code> returns a MPL IntegralConstant, and Hana has no way of knowing about these unless you include the proper bridge header. Hence, you should do the following instead:</p>
783 <div class="fragment"><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="integral__c_8hpp.html">boost/hana/ext/boost/mpl/integral_c.hpp</a>&gt;</span></div><div class="line"></div><div class="line"><span class="keyword">using</span> Size = mpl::size&lt;Vector&gt;::type;</div><div class="line">static_assert(<a class="code" href="group__group-Comparable.html#gacaf1ebea6b3ab96ac9dcb82f0e64e547">hana::equal</a>(Size{}, hana::int_c&lt;3&gt;), <span class="stringliteral">&quot;&quot;</span>);</div></div><!-- fragment --><p> The morale is that when working with external libraries, you have to be a bit careful about what objects you are manipulating. The final pitfall is about implementation limits in external libraries. Many older libraries have limits regarding the maximum size of the heterogeneous containers that can be created with them. For example, one may not create a Fusion list of more than <code>FUSION_MAX_LIST_SIZE</code> elements in it. Obviously, these limits are inherited by Hana and for example, trying to compute the permutations of a <code>fusion::list</code> containing 5 elements (the resulting list would contain 120 elements) will fail in a gruesome way:</p>
784 <div class="fragment"><div class="line"><span class="keyword">auto</span> list = fusion::make_list(1, 2, 3, 4, 5);</div><div class="line"><span class="keyword">auto</span> oh_jeez = <a class="code" href="group__group-Sequence.html#gac1e182ac088f1990edd739424d30ea07">hana::permutations</a>(list); <span class="comment">// probably won&#39;t make it</span></div></div><!-- fragment --><p>Apart from the pitfalls explained in this section, using external adapters should be just as straightforward as using normal Hana containers. Of course, whenever possible, you should try to stick with Hana's containers because they are usually more friendly to work with and are often more optimized.</p>
785 <h1><a class="anchor" id="tutorial-core"></a>
786 Hana's core</h1>
787 <hr/>
788 <p> The goal of this section is to give a high-level overview of Hana's core. This core is based on the notion of <em>tag</em>, which is borrowed from the Boost.Fusion and Boost.MPL libraries but taken much further by Hana. These tags are then used for several purposes, like algorithm customization, documentation grouping, improving error messages and converting containers into other containers. Because of its modular design, Hana can be extended in a ad-hoc manner very easily. In fact, all the functionality of the library is provided through an ad-hoc customization mechanism, which is explained here.</p>
789 <h2><a class="anchor" id="tutorial-core-tags"></a>
790 Tags</h2>
791 <p>Heterogeneous programming is basically programming with objects having different types. However, it is clear that some families of objects, while having different representations (C++ types), are strongly related. For example, the <code><a class="el" href="structstd_1_1integral__constant.html" title="Adapter for std::integral_constants. ">std::integral_constant</a>&lt;int, n&gt;</code> types are different for each different <code>n</code>, but conceptually they all represent the same thing; a compile-time number. The fact that <code><a class="el" href="structstd_1_1integral__constant.html" title="Adapter for std::integral_constants. ">std::integral_constant</a>&lt;int, 1&gt;{}</code> and <code><a class="el" href="structstd_1_1integral__constant.html" title="Adapter for std::integral_constants. ">std::integral_constant</a>&lt;int, 2&gt;{}</code> have different types is just a side effect of the fact that we're using their type to encode the <em>value</em> of these objects. Indeed, when manipulating a sequence of <code><a class="el" href="structstd_1_1integral__constant.html" title="Adapter for std::integral_constants. ">std::integral_constant</a>&lt;int, ...&gt;</code>s, chances are that you actually think of it as a homogeneous sequence of an imaginary <code>integral_constant</code> type, disregarding the actual types of the objects and pretending they are all just <code>integral_constant</code>s with different values.</p>
792 <p>To reflect this reality, Hana provides <em>tags</em> representing its heterogeneous containers and other compile-time entities. For example, all of Hana's <code>integral_constant&lt;int, ...&gt;</code>s have different types, but they all share the same tag, <code>integral_constant_tag&lt;int&gt;</code>. This allows the programmer to think in terms of that single type instead of trying to think in terms of the actual types of the objects. Concretely, tags are implemented as empty <code>struct</code>s. To make them stand out, Hana adopts the convention of naming these tags by adding the <code>_tag</code> suffix.</p>
793 <dl class="section note"><dt>Note</dt><dd>The tag of an object of type <code>T</code> can be obtained by using <code>tag_of&lt;T&gt;::type</code>, or equivalently <code>tag_of_t&lt;T&gt;</code>.</dd></dl>
794 <p>Tags are an extension to normal C++ types. Indeed, by default, the tag of a type <code>T</code> is <code>T</code> itself, and the core of the library is designed to work in those cases. For example, <code>hana::make</code> expects either a tag or an actual type; if you send it a type <code>T</code>, it will do the logical thing and construct an object of type <code>T</code> with the arguments you pass it. If you pass a tag to it, however, you should specialize <code>make</code> for that tag and provide your own implementation, as explained below. Because tags are an extension to usual types, we end up mostly reasoning in terms of tags instead of usual types, and the documentation sometimes uses the words <em>type</em>, <em>data type</em> and <em>tag</em> interchangeably.</p>
795 <h2><a class="anchor" id="tutorial-core-tag_dispatching"></a>
796 Tag dispatching</h2>
797 <p>Tag dispatching is a generic programming technique for picking the right implementation of a function depending on the type of the arguments passed to the function. The usual mechanism for overriding a function's behavior is overloading. Unfortunately, this mechanism is not always convenient when dealing with families of related types having different base templates, or when the kind of template parameters is not known (is it a type or a non-type template parameter?). For example, consider trying to overload a function for all Boost.Fusion vectors:</p>
798 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> ...T&gt;</div><div class="line"><span class="keywordtype">void</span> <span class="keyword">function</span>(<a class="code" href="structboost_1_1fusion_1_1vector.html">boost::fusion::vector</a>&lt;T...&gt; v) {</div><div class="line">    <span class="comment">// whatever</span></div><div class="line">}</div></div><!-- fragment --><p>If you know Boost.Fusion, then you probably know that it won't work. This is because Boost.Fusion vectors are not necessarily specializations of the <code><a class="el" href="structboost_1_1fusion_1_1vector.html" title="Adapter for Boost.Fusion vectors. ">boost::fusion::vector</a></code> template. Fusion vectors also exist in numbered forms, which are all of different types:</p>
799 <div class="fragment"><div class="line">boost::fusion::vector1&lt;T&gt;</div><div class="line">boost::fusion::vector2&lt;T, U&gt;</div><div class="line">boost::fusion::vector3&lt;T, U, V&gt;</div><div class="line">...</div></div><!-- fragment --><p>This is an implementation detail required by the lack of variadic templates in C++03 that leaks into the interface. This is unfortunate, but we need a way to work around it. To do so, we use an infrastructure with three distinct components:</p>
800 <ol type="1">
801 <li>A metafunction associating a single tag to every type in a family of related types. In Hana, this tag can be accessed using the <code>tag_of</code> metafunction. Specifically, for any type <code>T</code>, <code>tag_of&lt;T&gt;::type</code> is the tag used to dispatch it.</li>
802 <li>A function belonging to the public interface of the library, for which we'd like to be able to provide a customized implementation. In Hana, these functions are the algorithms associated to a concept, like <code>transform</code> or <code>unpack</code>.</li>
803 <li>An implementation for the function, parameterized with the tag(s) of the argument(s) passed to the function. In Hana, this is usually done by having a separate template called <code>xxx_impl</code> (for an interface function <code>xxx</code>) with a nested <code>apply</code> static function, as will be shown below.</li>
804 </ol>
805 <p>When the public interface function <code>xxx</code> is called, it will get the tag of the argument(s) it wishes to dispatch the call on, and then forward the call to the <code>xxx_impl</code> implementation associated to those tags. For example, let's implement a basic setup for tag dispatching of a function that prints its argument to a stream. First, we define the public interface function and the implementation that can be specialized:</p>
806 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Tag&gt;</div><div class="line"><span class="keyword">struct </span>print_impl {</div><div class="line">  <span class="keyword">template</span> &lt;<span class="keyword">typename</span> X&gt;</div><div class="line">  <span class="keyword">static</span> <span class="keywordtype">void</span> <a class="code" href="group__group-functional.html#ga30027c383676084be151ef3c6cf2829f">apply</a>(std::ostream&amp;, X <span class="keyword">const</span>&amp;) {</div><div class="line">    <span class="comment">// possibly some default implementation</span></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">typename</span> X&gt;</div><div class="line"><span class="keywordtype">void</span> <a class="code" href="group__group-experimental.html#ga660c0769106006a86948b5b355fad050">print</a>(std::ostream&amp; os, X x) {</div><div class="line">  <span class="keyword">using</span> Tag = <span class="keyword">typename</span> hana::tag_of&lt;X&gt;::type;</div><div class="line">  <a class="code" href="group__group-functional.html#ga30027c383676084be151ef3c6cf2829f">print_impl&lt;Tag&gt;::apply</a>(os, x);</div><div class="line">}</div></div><!-- fragment --><p> Now, let's define a type that needs tag dispatching to customize the behavior of <code>print</code>. While some C++14 examples exist, they are too complicated to show in this tutorial and we will therefore use a C++03 tuple implemented as several different types to illustrate the technique:</p>
807 <div class="fragment"><div class="line"><span class="keyword">struct </span>vector_tag;</div><div class="line"></div><div class="line"><span class="keyword">struct </span>vector0 {</div><div class="line">  <span class="keyword">using</span> hana_tag = vector_tag;</div><div class="line">  <span class="keyword">static</span> constexpr std::size_t <a class="code" href="group__group-Foldable.html#ga8ec3ac9a6f5014db943f61ebc9e1e36e">size</a> = 0;</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T1&gt;</div><div class="line"><span class="keyword">struct </span>vector1 {</div><div class="line">  T1 t1;</div><div class="line">  <span class="keyword">using</span> hana_tag = vector_tag;</div><div class="line">  <span class="keyword">static</span> constexpr std::size_t <a class="code" href="group__group-Foldable.html#ga8ec3ac9a6f5014db943f61ebc9e1e36e">size</a> = 1;</div><div class="line"></div><div class="line">  <span class="keyword">template</span> &lt;<span class="keyword">typename</span> Index&gt;</div><div class="line">  <span class="keyword">auto</span> <span class="keyword">const</span>&amp; operator[](Index i)<span class="keyword"> const </span>{</div><div class="line">    static_assert(i == 0u, <span class="stringliteral">&quot;index out of bounds&quot;</span>);</div><div class="line">    <span class="keywordflow">return</span> t1;</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">typename</span> T1, <span class="keyword">typename</span> T2&gt;</div><div class="line"><span class="keyword">struct </span>vector2 {</div><div class="line">  T1 t1; T2 t2;</div><div class="line">  <span class="keyword">using</span> hana_tag = vector_tag;</div><div class="line">  <span class="keyword">static</span> constexpr std::size_t <a class="code" href="group__group-Foldable.html#ga8ec3ac9a6f5014db943f61ebc9e1e36e">size</a> = 2;</div><div class="line"></div><div class="line">  <span class="comment">// Using Hana as a backend to simplify the example.</span></div><div class="line">  <span class="keyword">template</span> &lt;<span class="keyword">typename</span> Index&gt;</div><div class="line">  <span class="keyword">auto</span> <span class="keyword">const</span>&amp; operator[](Index i)<span class="keyword"> const </span>{</div><div class="line">    <span class="keywordflow">return</span> *hana::make_tuple(&amp;t1, &amp;t2)[i];</div><div class="line">  }</div><div class="line">};</div><div class="line"></div><div class="line"><span class="comment">// and so on...</span></div></div><!-- fragment --><p> The nested <code>using hana_tag = vector_tag;</code> part is a terse way of controling the result of the <code>tag_of</code> metafunction, and hence the tag of the <code>vectorN</code> type. This is explained in the reference for <code>tag_of</code>. Finally, if you wanted to customize the behavior of the <code>print</code> function for all the <code>vectorN</code> types, you would normally have to write something along the lines of</p>
808 <div class="fragment"><div class="line"><span class="keywordtype">void</span> <a class="code" href="group__group-experimental.html#ga660c0769106006a86948b5b355fad050">print</a>(std::ostream&amp; os, vector0)</div><div class="line">{ os &lt;&lt; <span class="stringliteral">&quot;[]&quot;</span>; }</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T1&gt;</div><div class="line"><span class="keywordtype">void</span> <a class="code" href="group__group-experimental.html#ga660c0769106006a86948b5b355fad050">print</a>(std::ostream&amp; os, vector1&lt;T1&gt; v)</div><div class="line">{ os &lt;&lt; <span class="stringliteral">&quot;[&quot;</span> &lt;&lt; v.t1 &lt;&lt; <span class="stringliteral">&quot;]&quot;</span>; }</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T1, <span class="keyword">typename</span> T2&gt;</div><div class="line"><span class="keywordtype">void</span> <a class="code" href="group__group-experimental.html#ga660c0769106006a86948b5b355fad050">print</a>(std::ostream&amp; os, vector2&lt;T1, T2&gt; v)</div><div class="line">{ os &lt;&lt; <span class="stringliteral">&quot;[&quot;</span> &lt;&lt; v.t1 &lt;&lt; <span class="stringliteral">&quot;, &quot;</span> &lt;&lt; v.t2 &lt;&lt; <span class="stringliteral">&quot;]&quot;</span>; }</div><div class="line"></div><div class="line"><span class="comment">// and so on...</span></div></div><!-- fragment --><p> Now, with tag dispatching, you can rely on the <code>vectorN</code>s all sharing the same tag and specialize only the <code>print_impl</code> struct instead:</p>
809 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;&gt;</div><div class="line"><span class="keyword">struct </span>print_impl&lt;vector_tag&gt; {</div><div class="line">  <span class="keyword">template</span> &lt;<span class="keyword">typename</span> vectorN&gt;</div><div class="line">  <span class="keyword">static</span> <span class="keywordtype">void</span> <a class="code" href="group__group-functional.html#ga30027c383676084be151ef3c6cf2829f">apply</a>(std::ostream&amp; os, vectorN xs) {</div><div class="line">    constexpr <span class="keyword">auto</span> N = hana::size_c&lt;vectorN::size&gt;;</div><div class="line"></div><div class="line">    os &lt;&lt; <span class="stringliteral">&quot;[&quot;</span>;</div><div class="line">    N.times.with_index([&amp;](<span class="keyword">auto</span> i) {</div><div class="line">      os &lt;&lt; xs[i];</div><div class="line">      <span class="keywordflow">if</span> (i != N - hana::size_c&lt;1&gt;) os &lt;&lt; <span class="stringliteral">&quot;, &quot;</span>;</div><div class="line">    });</div><div class="line">    os &lt;&lt; <span class="stringliteral">&quot;]&quot;</span>;</div><div class="line">  }</div><div class="line">};</div></div><!-- fragment --><p> One upside is that all <code>vectorN</code>s can now be treated uniformly by the <code>print</code> function, at the cost of some boilerplate when creating the data structure (to specify the tag of each <code>vectorN</code>) and when creating the initial <code>print</code> function (to setup the tag dispatching system with <code>print_impl</code>). There are also other advantages to this technique, like the ability to check for preconditions in the interface function without having to do it in each custom implementation, which would be tedious:</p>
810 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> X&gt;</div><div class="line"><span class="keywordtype">void</span> <a class="code" href="group__group-experimental.html#ga660c0769106006a86948b5b355fad050">print</a>(std::ostream&amp; os, X x) {</div><div class="line">  <span class="comment">// **** check some precondition ****</span></div><div class="line"></div><div class="line">  <span class="comment">// The precondition only has to be checked here; implementations</span></div><div class="line">  <span class="comment">// can assume their arguments to always be sane.</span></div><div class="line"></div><div class="line">  <span class="keyword">using</span> Tag = <span class="keyword">typename</span> hana::tag_of&lt;X&gt;::type;</div><div class="line">  <a class="code" href="group__group-functional.html#ga30027c383676084be151ef3c6cf2829f">print_impl&lt;Tag&gt;::apply</a>(os, x);</div><div class="line">}</div></div><!-- fragment --> <dl class="section note"><dt>Note</dt><dd>Checking preconditions does not make much sense for a <code>print</code> function, but consider for example a function to get the <code>n</code>th element of a sequence; you might want to make sure that the index is not out-of-bounds.</dd></dl>
811 <p>This technique also makes it easier to provide interface functions as function objects instead of normal overloaded functions, because only the interface function itself must go through the trouble of defining a function object. Function objects have several advantages over overloaded functions, like the ability to be used in higher order algorithms or as variables:</p>
812 <div class="fragment"><div class="line"><span class="comment">// Defining a function object is only needed once and implementations do not</span></div><div class="line"><span class="comment">// have to worry about static initialization and other painful tricks.</span></div><div class="line"><span class="keyword">struct </span>print_t {</div><div class="line">  <span class="keyword">template</span> &lt;<span class="keyword">typename</span> X&gt;</div><div class="line">  <span class="keywordtype">void</span> operator()(std::ostream&amp; os, X x)<span class="keyword"> const </span>{</div><div class="line">    <span class="keyword">using</span> Tag = <span class="keyword">typename</span> hana::tag_of&lt;X&gt;::type;</div><div class="line">    <a class="code" href="group__group-functional.html#ga30027c383676084be151ef3c6cf2829f">print_impl&lt;Tag&gt;::apply</a>(os, x);</div><div class="line">  }</div><div class="line">};</div><div class="line">constexpr print_t <a class="code" href="group__group-experimental.html#ga660c0769106006a86948b5b355fad050">print</a>{};</div></div><!-- fragment --><p> As you are probably aware of, being able to implement an algorithm for many types at the same time is tremendously useful (that's precisely the goal of C++ templates!). However, even more useful is the ability to implement an algorithm for many types <em>that satisfy some condition</em>. C++ templates are currently missing this ability to constrain their template parameters, but a language feature called <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3580.pdf">concepts</a> is being rolled out with the goal of addressing this issue.</p>
813 <p>With something similar in mind, Hana's algorithms support an additional layer of tag-dispatching to what was explained above. This layer allows us to "specialize" an algorithm for all types that satisfy some predicate. For example, let's say we wanted to implement the <code>print</code> function above for all types that represent some kind of sequence. Right now, we wouldn't have an easy way to do this. However, the tag dispatching for Hana's algorithms is set up slightly differently than what was shown above, and we could hence write the following:</p>
814 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Tag&gt;</div><div class="line"><span class="keyword">struct </span>print_impl&lt;Tag, hana::when&lt;Tag represents some kind of sequence&gt;&gt; {</div><div class="line">  <span class="keyword">template</span> &lt;<span class="keyword">typename</span> Seq&gt;</div><div class="line">  <span class="keyword">static</span> <span class="keywordtype">void</span> <a class="code" href="group__group-functional.html#ga30027c383676084be151ef3c6cf2829f">apply</a>(std::ostream&amp; os, Seq xs) {</div><div class="line">    <span class="comment">// Some implementation for any sequence</span></div><div class="line">  }</div><div class="line">};</div></div><!-- fragment --><p> where <code>Tag represents some kind of sequence</code> would only need to be a boolean expression representing whether <code>Tag</code> is a sequence. We'll see how such predicates can be created in the next section, but for now let's assume that it <em>just works</em>. Without going into the details of how this tag-dispatching is set up, the above specialization will only be picked up when the predicate is satisfied, and if no better match can be found. Hence, for example, if our <code>vector_tag</code> was to satisfy the predicate, our initial implementation for <code>vector_tag</code> would still be preferred over the <code>hana::when</code>-based specialization, because it represents a better match. In general, any specialization (whether explicit or partial) <em>not</em> using <code>hana::when</code> will be preferred over a specialization using <code>hana::when</code>, which was designed to be as unsurprising as possible from a user point of view. This covers pretty much all there's to say about tag-dispatching in Hana. The next section will explain how we can create C++ concepts for metaprogramming, which could then be used in conjunction with <code>hana::when</code> to achieve a great deal of expressiveness.</p>
815 <h2><a class="anchor" id="tutorial-core-concepts"></a>
816 Emulation of C++ concepts</h2>
817 <p>The implementation of concepts in Hana is very simple. At its heart, a concept is just a template <code>struct</code> that inherits from a boolean <code>integral_constant</code> representing whether the given type is a <em>model</em> of the concept:</p>
818 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">struct </span>Concept</div><div class="line">  : hana::integral_constant&lt;bool, whether T models Concept&gt;</div><div class="line">{ };</div></div><!-- fragment --><p>Then, one can test whether a type <code>T</code> is a model of <code>Concept</code> by looking at <code>Concept&lt;T&gt;::value</code>. Simple enough, right? Now, while the way one might implement the check does not have to be anything specific as far as Hana is concerned, the rest of this section will explain how it is usually done in Hana, and how it interacts with tag dispatching. You should then be able to define your own concepts if you so desire, or at least to understand better how Hana works internally.</p>
819 <p>Usually, a concept defined by Hana will require that any model implements some tag-dispatched functions. For example, the <code>Foldable</code> concept requires that any model defines at least one of <code>hana::unpack</code> and <code>hana::fold_left</code>. Of course, concepts usually also define semantic requirements (called laws) that must be satisfied by their models, but these laws are not (and couldn't be) checked by the concept. But how do we check that some functions are properly implemented? For this, we'll have to slightly modify the way we defined tag-dispatched methods as shown in the previous section. Let's go back to our <code>print</code> example and try to define a <code>Printable</code> concept for those objects that can be <code>print</code>ed. Our end goal is to have a template struct such as</p>
820 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">struct </span>Printable</div><div class="line">  : hana::integral_constant&lt;bool, whether print_impl&lt;tag of T&gt; is defined&gt;</div><div class="line">{ };</div></div><!-- fragment --><p>To know whether <code>print_impl&lt;...&gt;</code> has been defined, we'll modify <code>print_impl</code> so that it inherits from a special base class when it is not overridden, and we'll simply check whether <code>print_impl&lt;T&gt;</code> inherits from that base class:</p>
821 <div class="fragment"><div class="line"><span class="keyword">struct </span>special_base_class { };</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">struct </span>print_impl : special_base_class {</div><div class="line">  <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ...Args&gt;</div><div class="line">  <span class="keyword">static</span> constexpr <span class="keyword">auto</span> <a class="code" href="group__group-functional.html#ga30027c383676084be151ef3c6cf2829f">apply</a>(Args&amp;&amp; ...) = <span class="keyword">delete</span>;</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">struct </span>Printable</div><div class="line">    : hana::integral_constant&lt;bool,</div><div class="line">        !std::is_base_of&lt;special_base_class, print_impl&lt;hana::tag_of_t&lt;T&gt;&gt;&gt;::value</div><div class="line">    &gt;</div><div class="line">{ };</div></div><!-- fragment --><p> Of course, when we specialize <code>print_impl</code> with a custom type, we don't inherit from that <code>special_base_class</code> type:</p>
822 <div class="fragment"><div class="line"><span class="keyword">struct </span>Person { std::string name; };</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;&gt;</div><div class="line"><span class="keyword">struct </span>print_impl&lt;Person&gt; <span class="comment">/* don&#39;t inherit from special_base_class */</span> {</div><div class="line">  <span class="comment">// ... implementation ...</span></div><div class="line">};</div><div class="line"></div><div class="line">static_assert(<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">Printable&lt;Person&gt;::value</a>, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">static_assert(!<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">Printable&lt;void&gt;::value</a>, <span class="stringliteral">&quot;&quot;</span>);</div></div><!-- fragment --><p> As you can see, <code>Printable&lt;T&gt;</code> really only checks whether the <code>print_impl&lt;T&gt;</code> struct was specialized by a custom type. In particular, it does not even check whether the nested <code>::apply</code> function is defined or if it is syntactically valid. It is assumed that if one specializes <code>print_impl</code> for a custom type, the nested <code>::apply</code> function exists and is correct. If it is not, a compilation error will be triggered when one tries to call <code>print</code> on an object of that type. Concepts in Hana make the same assumptions.</p>
823 <p>Since this pattern of inheriting from a special base class is quite abundant in Hana, the library provides a dummy type called <code>hana::default_</code> that can be used in place of <code>special_base_class</code>. Then, instead of using <code>std::is_base_of</code>, one can use <code>hana::is_default</code>, which looks nicer. With this syntactic sugar, the code now becomes:</p>
824 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">struct </span>print_impl : hana::default_ {</div><div class="line">  <span class="keyword">template</span> &lt;<span class="keyword">typename</span> ...Args&gt;</div><div class="line">  <span class="keyword">static</span> constexpr <span class="keyword">auto</span> <a class="code" href="group__group-functional.html#ga30027c383676084be151ef3c6cf2829f">apply</a>(Args&amp;&amp; ...) = <span class="keyword">delete</span>;</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">struct </span>Printable</div><div class="line">    : hana::integral_constant&lt;bool,</div><div class="line">        !hana::is_default&lt;print_impl&lt;hana::tag_of_t&lt;T&gt;&gt;&gt;::value</div><div class="line">    &gt;</div><div class="line">{ };</div></div><!-- fragment --><p> This is all that there's to know about the interaction between tag-dispatched functions and concepts. However, some concepts in Hana do not rely solely on the definition of specific tag-dispatched functions to determine if a type is a model of the concept. This can happen when a concept merely introduces semantic guarantees through laws and refined concepts, but no additional syntactic requirements. Defining such a concept can be useful for several reasons. First, it sometimes happen that an algorithm can be implemented more efficiently if we can assume some semantic guarantees X or Y, so we might create a concept to enforce those guarantees. Secondly, it is sometimes possible to automatically define the models for several concepts when we have additional semantic guarantees, which saves the user the trouble of defining those models manually. For example, this is the case of the <code>Sequence</code> concept, which basically adds semantic guarantees to <code>Iterable</code> and <code>Foldable</code>, and in turn allows us to define the models for a myriad of concepts ranging from <code>Comparable</code> to <code>Monad</code>.</p>
825 <p>For these concepts, it is usually necessary to specialize the corresponding template struct in the <code><a class="el" href="namespaceboost_1_1hana.html" title="Namespace containing everything in the library. ">boost::hana</a></code> namespace to provide a model for a custom type. Doing so is like providing a seal saying that the semantic guarantees required by the concept are respected by the custom type. The concepts that require being explicitly specialized will document that fact. So that's it! This is all that there's to know about concepts in Hana, which ends this section about the core of Hana.</p>
826 <h1><a class="anchor" id="tutorial-header_organization"></a>
827 Header organization</h1>
828 <hr/>
829 <p> The library is designed to be modular while keeping the number of headers that must be included to get basic functionality reasonably low. The structure of the library was also intentionally kept simple, because we all love simplicity. What follows is a general overview of the header organization. A list of all the headers provided by the library is also available in the panel on the left (under the <a href="files.html">Headers</a> label) in case you need more details.</p>
830 <ul>
831 <li><code><a class="el" href="hana_8hpp.html" title="Includes all the library components except the adapters for external libraries. ">boost/hana.hpp</a></code><br />
832  This is the master header of the library, which includes the whole public interface of the library. Note that external adapters, experimental features and implementation details are not included by this header, however, since some of them require additional dependencies.</li>
833 <li><code>boost/hana/</code><br />
834  This is the main directory of the library containing the definitions of everything provided by the library. Each algorithm and container provided by the library has its own header. For a container or an algorithm named <code>XXX</code>, the corresponding header is <code>boost/hana/XXX.hpp</code>.<ul>
835 <li><code>boost/hana/concept/</code><br />
836  This subdirectory contains the definition of Hana's concepts. These headers provide a way to check whether an object is a model of the corresponding concept, and they sometimes also provide default implementations for other related concepts, which are documented on a per-concept basis. They also include all the algorithms associated to that concept.</li>
837 <li><code>boost/hana/core/</code><br />
838  This subdirectory contains the machinery for tag dispatching and other related utilities like <code>make</code> and <code>to</code>.</li>
839 <li><code>boost/hana/fwd/</code><br />
840  This subdirectory contains the forward declaration of everything in the library. It is essentially a mirror of the <code>boost/hana/</code> directory, except all the headers contain only forward declarations and documentation. For example, to include the <code>hana::tuple</code> container, one can use the <code><a class="el" href="tuple_8hpp.html" title="Defines boost::hana::tuple. ">boost/hana/tuple.hpp</a></code> header. However, if one only wants the forward declaration of that container, the <code><a class="el" href="fwd_2tuple_8hpp.html" title="Forward declares boost::hana::tuple. ">boost/hana/fwd/tuple.hpp</a></code> header can be used instead. Note that forward declarations for headers in <code>boost/hana/ext/</code> and <code>boost/hana/functional/</code> are not provided.</li>
841 <li><code>boost/hana/functional/</code><br />
842  This subdirectory contains various function objects that are often useful, but that do not necessarily belong to a concept.</li>
843 <li><p class="startli"><code>boost/hana/ext/</code><br />
844  This directory contains adapters for external libraries. For a component named <code>xxx</code> in a namespace <code>ns</code>, the external adapter lives in the <code>boost/hana/ext/ns/xxx.hpp</code> header. For example, the external adapter for <code><a class="el" href="structstd_1_1tuple.html" title="Adapter for std::tuples. ">std::tuple</a></code> lives in the <code><a class="el" href="ext_2std_2tuple_8hpp.html" title="Adapts std::tuple for use with Hana. ">boost/hana/ext/std/tuple.hpp</a></code> header, while the external adapter for <code><a class="el" href="structboost_1_1mpl_1_1vector.html" title="Adapter for Boost.MPL vectors. ">boost::mpl::vector</a></code> is in <code><a class="el" href="boost_2mpl_2vector_8hpp.html" title="Adapts boost::mpl::vector for use with Hana. ">boost/hana/ext/boost/mpl/vector.hpp</a></code>.</p>
845 <p class="startli">Note that only the strict minimum required to adapt the external components is included in these headers (e.g. a forward declaration). This means that the definition of the external component should still be included when one wants to use it. For example: </p><div class="fragment"><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="ext_2std_2tuple_8hpp.html">boost/hana/ext/std/tuple.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="front_8hpp.html">boost/hana/front.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;tuple&gt;</span> <span class="comment">// still required to create a tuple</span></div><div class="line"><span class="keyword">namespace </span>hana = <a class="code" href="namespaceboost_1_1hana.html">boost::hana</a>;</div><div class="line"></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main() {</div><div class="line">  constexpr <a class="code" href="structstd_1_1tuple.html">std::tuple&lt;int, char, float&gt;</a> xs{1, <span class="charliteral">&#39;2&#39;</span>, 3.0f};</div><div class="line">  static_assert(<a class="code" href="group__group-Iterable.html#ga8a67ea10e8082dbe6705e573fa978444">hana::front</a>(xs) == 1, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div></div><!-- fragment --></li>
846 <li><p class="startli"><code>boost/hana/experimental/</code><br />
847  This directory contains experimental features that may or may not make it into the library at some point, but that were deemed useful enough to be made available to the public. Features in this subdirectory reside in the <code>hana::experimental</code> namespace. Also, do not expect these features to be stable; they may be moved, renamed, changed or removed between releases of the library. These features may also require additional external dependencies; each feature documents the additional dependencies it requires, if any.</p>
848 <p class="startli">Because of the potential additional dependencies, these headers are also not included by the master header of the library.</p>
849 </li>
850 <li><code>boost/hana/detail/</code><br />
851  This directory contains utilities required internally. Nothing in <code>detail/</code> is guaranteed to be stable, so you should not use it.</li>
852 </ul>
853 </li>
854 </ul>
855 <h1><a class="anchor" id="tutorial-conclusion"></a>
856 Conclusion</h1>
857 <hr/>
858 <p> You now have everything you need to start using the library. From this point forward, mastering the library is only a matter of understanding how to use the general purpose concepts and containers provided with it, which is best done by looking at the reference documentation. At some point, you will probably also want to create your own concepts and data types that fit your needs better; go ahead, the library was designed to be used that way.</p>
859 <h2><a class="anchor" id="tutorial-conclusion-warning"></a>
860 Fair warning: functional programming ahead</h2>
861 <p>Programming with heterogeneous objects is inherently functional &ndash; since it is impossible to modify the type of an object, a new object must be introduced instead, which rules out mutation. Unlike previous metaprogramming libraries whose design was modeled on the STL, Hana uses a functional style of programming which is the source for a good portion of its expressiveness. However, as a result, many concepts presented in the reference will be unfamiliar to C++ programmers without a knowledge of functional programming. The reference attempts to make these concepts approachable by using intuition whenever possible, but bear in mind that the highest rewards are usually the fruit of some effort.</p>
862 <h2><a class="anchor" id="tutorial-conclusion-related_material"></a>
863 Related material</h2>
864 <p>Through the years, I have produced some material about Hana and metaprogramming more generally. You may find some of it useful:</p>
865 <ul>
866 <li>Keynote on metaprogramming at <a href="https://meetingcpp.com">Meeting C++</a> 2016 (<a href="http://ldionne.com/meetingcpp-2016">slides</a>/<a href="https://youtu.be/X_p9X5RzBJE">video</a>)</li>
867 <li>Talk on advanced metaprogramming techniques used in Hana at <a href="http://cppnow.org">C++Now</a> 2016 (<a href="http://ldionne.com/cppnow-2016-metaprogramming-for-the-brave">slides</a>/<a href="https://youtu.be/UXwWXHrvTug">video</a>)</li>
868 <li>Introduction to metaprogramming with Hana at <a href="http://cppnow.org">C++Now</a> 2016 (<a href="http://ldionne.com/cppnow-2016-metaprogramming-for-dummies">slides</a>/<a href="https://youtu.be/a1doqFAumCk">video</a>)</li>
869 <li>Talk on metaprogramming and Hana at <a href="http://cppcon.org">CppCon</a> 2015 (<a href="http://ldionne.com/hana-cppcon-2015">slides</a>/<a href="https://youtu.be/cg1wOINjV9U">video</a>)</li>
870 <li>Talk on metaprogramming and Hana at <a href="http://cppnow.org">C++Now</a> 2015 (<a href="http://ldionne.com/hana-cppnow-2015">slides</a>/<a href="https://youtu.be/Z2ABRaQiFHs">video</a>)</li>
871 <li>Talk on Hana at <a href="http://cppcon.org">CppCon</a> 2014 (<a href="http://ldionne.com/hana-cppcon-2014">slides</a>/<a href="https://youtu.be/L2SktfaJPuU">video</a>)</li>
872 <li>The <a href="http://github.com/ldionne/mpl11">MPL11</a> library, which is how Hana started out</li>
873 <li>Talk on the MPL11 at <a href="http://cppnow.org">C++Now</a> 2014 (<a href="http://ldionne.com/mpl11-cppnow-2014">slides</a>/<a href="https://youtu.be/8c0aWLuEO0Y">video</a>)</li>
874 <li>My bachelor's thesis was a formalization of C++ metaprogramming using category theory. The thesis is available <a href="https://github.com/ldionne/hana-thesis/blob/gh-pages/main.pdf">here</a>, and the slides of a related presentation are available <a href="http://ldionne.com/hana-thesis">here</a>. Unfortunately, both are in french only.</li>
875 </ul>
876 <p>This finishes the tutorial part of the documentation. I hope you enjoy using the library, and please consider <a href="https://github.com/boostorg/hana/blob/master/CONTRIBUTING.md#how-to-contribute">contributing</a> to make it even better!</p>
877 <p>&ndash; Louis</p>
878 <h1><a class="anchor" id="tutorial-reference"></a>
879 Using the reference</h1>
880 <hr/>
881 <p> As for most generic libraries, algorithms in Hana are documented by the concept to which they belong (<code>Foldable</code>, <code>Iterable</code>, <code>Searchable</code>, <code>Sequence</code>, etc...). The different containers are then documented on their own page, and the concepts that they model are documented there. The concepts modeled by some container defines what algorithms can be used with such a container.</p>
882 <p>More specifically, the structure of the reference (available in the menu to the left) goes as follow:</p>
883 <ul>
884 <li><a class="el" href="group__group-core.html">Core</a><br />
885  Documentation for the core module, which contains everything needed to create concepts, data types and related utilities. This is relevant if you need to extend the library, but otherwise you can probably ignore this.</li>
886 <li><a class="el" href="group__group-concepts.html">Concepts</a><br />
887  Documentation for all the concepts provided with the library. Each concept:<ul>
888 <li>Documents which functions must be implemented absolutely in order to model that concept. The set of functions that must be provided is called a <em>minimal complete definition</em>.</li>
889 <li>Documents semantic constraints that any model of that concept must satisfy. These constraints are usually called laws and they are expressed in a semi-formal mathematical language. Of course, those laws can't be checked automatically but you should still make sure you satisfy them.</li>
890 <li>Documents the concept(s) it refines, if any. Sometimes, a concept is powerful enough to provide a model of a concept it refines, or at least the implementation for some of its associated functions. When this is the case, the concept will document which functions of the refined concept it provides, and how it does so. Also, it is sometimes possible that the model for a refined concept is unique, in which case it can be provided automatically. When this happens, it will be documented but you don't have to do anything special to get that model.</li>
891 </ul>
892 </li>
893 <li><a class="el" href="group__group-datatypes.html">Data types</a><br />
894  Documentation for all the data structures provided with the library. Each data structure documents the concept(s) it models, and how it does so. It also documents the methods tied to it but not to any concept, for example <code>maybe</code> for <code>optional</code>.</li>
895 <li><a class="el" href="group__group-functional.html">Functional</a><br />
896  General purpose function objects that are generally useful in a purely functional setting. These are currently not tied to any concept or container.</li>
897 <li><a class="el" href="group__group-ext.html">External adapters</a><br />
898  Documentation for all the adapters for external libraries. These adapters are documented as if they were native types provided by Hana, but obviously Hana only provides the compatibility layer between them and the library.</li>
899 <li><a class="el" href="group__group-config.html">Configuration options</a><br />
900  Macros that can be used to tweak the global behavior of the library.</li>
901 <li><a class="el" href="group__group-assertions.html">Assertions</a><br />
902  Macros to perform various types of assertions.</li>
903 <li><a href="functions.html"><b>Alphabetical index</b></a><br />
904  Alphabetical index of everything provided in the library.</li>
905 <li><a href="files.html"><b>Headers</b></a><br />
906  A list of all the headers provided by the library.</li>
907 <li><a class="el" href="group__group-details.html">Details</a><br />
908  Implementation details; don't go there. Anything not documented at all or documented in this group is not guaranteed to be stable.</li>
909 </ul>
910 <p>After you get to know Hana a bit better, it will probably happen that you just want to find the reference for a precise function, concept or container. If you know the name of what you're looking for, you can use the <em>search</em> box located in the upper right corner of any page of the documentation. My personal experience is that this is by far the quickest way of finding what you want when you already know its name.</p>
911 <h2><a class="anchor" id="tutorial-reference-signatures"></a>
912 Function signatures</h2>
913 <p>As you will see in the reference, several functions provide signatures documented in a semi-formal mathematical language. We are in the process of documenting all functions in this way, but this may take a while. The notation used is the usual mathematical notation for defining functions. Specifically, a function <code>Return f(Arg1, ..., ArgN);</code> can be defined equivalently using mathematical notation as</p>
914 <p class="formulaDsp">
915 \[ \mathtt{f} : \mathtt{Arg}_1 \times \dots \times \mathtt{Arg}_n \to \mathtt{Return} \]
916 </p>
917 <p>However, instead of documenting the actual argument and return types of functions, those signatures are written in terms of argument and return tags. This is done because of the heterogeneous setting, where the actual type of an object is usually pretty meaningless and does not help to reason about what's being returned or taken by a function. For example, instead of documenting the <code>equal</code> function for <code>integral_constant</code>s as</p>
918 <p class="formulaDsp">
919 \[ \mathtt{equal} : \mathtt{integral\_constant&lt;T, n&gt;} \times \mathtt{integral\_constant&lt;T, m&gt;} \to \mathtt{integral\_constant&lt;bool, n == m&gt;} \]
920 </p>
921 <p>which is not really helpful (as it really presents nothing but the implementation), it is instead documented using <code>integral_constant_tag</code>, which acts as the "type" of all <code>integral_constant</code>s. Note that since <code>equal</code> is part of the <code>Comparable</code> concept, it is not <em>actually</em> documented for <code>hana::integral_constant</code> specifically, but the idea is there:</p>
922 <p class="formulaDsp">
923 \[ \mathtt{equal} : \mathtt{integral\_constant\_tag&lt;T&gt;} \times \mathtt{integral\_constant\_tag&lt;T&gt;} \to \mathtt{integral\_constant\_tag&lt;bool&gt;} \]
924 </p>
925 <p>This clearly conveys the intention that comparing two <code>integral_constant</code>s gives back another <code>integral_constant</code> holding a <code>bool</code>. In general, this abstraction of the actual representation of objects makes it possible for us to reason in a high level manner about functions, even though their actual return and argument types are heterogeneous and not helpful. Finally, most functions expect container elements to have some properties. For example, this is the case of the <code>sort</code> algorithm, which obviously requires the container elements to be <code>Orderable</code>. Normally, we would write the signature for the non-predicated version of <code>sort</code> as</p>
926 <p class="formulaDsp">
927 \[ \mathtt{sort} : \mathtt{S} \to \mathtt{S} \\ \text{where S is a Sequence} \]
928 </p>
929 <p>However, this fails to express the requirement that the contents of <code>S</code> are <code>Orderable</code>. To express this, we use the following notation:</p>
930 <p class="formulaDsp">
931 \[ \mathtt{sort} : \mathtt{S(T)} \to \mathtt{S(T)} \\ \text{where S is a Sequence and T is Orderable} \]
932 </p>
933 <p>One way to see this is to pretend that <code>S</code>, the sequence tag, is actually parameterized by the tag of the sequence's elements, <code>T</code>. We're also pretending that the elements all have the same tag <code>T</code>, which is not the case in general. Now, by stating that <code>T</code> must be <code>Orderable</code>, we're expressing the fact that the sequence's elements must be <code>Orderable</code>. This notation is used in different flavors to express different kinds of requirements. For example, the <code>cartesian_product</code> algorithm takes a sequence of sequences and returns the cartesian product of those sequences as a sequence of sequences. Using our notation, this can be conveyed very easily:</p>
934 <p class="formulaDsp">
935 \[ \mathtt{cartesian\_product} : \mathtt{S(S(T))} \to \mathtt{S(S(T))} \\ \text{where S is a Sequence} \]
936 </p>
937 <h1><a class="anchor" id="tutorial-acknowledgements"></a>
938 Acknowledgements</h1>
939 <hr/>
940 <p> I'd like to thank the following persons and organizations for contributing to Hana in one way or another:</p>
941 <ul>
942 <li>Zach Laine and Matt Calabrese for the original idea of using function call syntax to do type-level computations, as presented in their BoostCon <a href="https://www.youtube.com/watch?v=x7UmrRzKAXU">presentation</a> (<a href="https://github.com/boostcon/2010_presentations/raw/master/mon/instantiations_must_go.pdf">slides 1</a>) (<a href="https://github.com/boostcon/2010_presentations/raw/master/mon/instantiations_must_go_2.pdf">slides 2</a>).</li>
943 <li>Joel Falcou for mentoring me two consecutive years during my work on Hana as part of the <a href="http://www.google-melange.com/gsoc/homepage/google/gsoc2014">Google Summer of Code</a> program, Niall Douglas for being the GSoC admin for Boost and helping me get in the program, and finally Google for their awesome GSoC program.</li>
944 <li>The <a href="https://sites.google.com/a/boost.org/steering/home">Boost Steering committee</a> for unlocking a grant for me to work on Hana in the winter of 2015, as an extension to the previous year's GSoC.</li>
945 <li>Several <a href="http://cppnow.org">C++Now</a> attendees and members of the <a href="http://lists.boost.org/Archives/boost">Boost mailing list</a> for insightful conversations, comments and questions about the project.</li>
946 </ul>
947 <h1><a class="anchor" id="tutorial-glossary"></a>
948 Glossary</h1>
949 <hr/>
950 <p> The reference documentation uses a couple of terms that are specific to this library. Also, a simplified implementation of functions is sometimes provided in pseudo-code, the actual implementation sometimes being slightly hard to understand. This section defines terms used in the reference and in the pseudo-code used to describe some functions.</p>
951 <p><a class="anchor" id="tutorial-glossary-forwarded"></a></p><h4><code>forwarded(x)</code></h4>
952 <p>Means that the object is forwarded optimally. This means that if <code>x</code> is a parameter, it is <code>std::forward</code>ed, and if it is a captured variable, it is moved from whenever the enclosing lambda is an rvalue.</p>
953 <p>Also note that when <code>x</code> can be moved from, the statement <code>return forwarded(x);</code> in a function with <code>decltype(auto)</code> does not mean that an rvalue reference to <code>x</code> will be returned, which would create a dangling reference. Rather, it means that <code>x</code> is returned by value, the value being constructed with the <code>std::forward</code>ed <code>x</code>.</p>
954 <p><a class="anchor" id="tutorial-glossary-perfect_capture"></a></p><h4><code>perfect-capture</code></h4>
955 <p>This is used in lambdas to signify that the captured variables are initialized using perfect forwarding, as if <code>[x(forwarded(x))...]() { }</code> had been used.</p>
956 <p><a class="anchor" id="tutorial-glossary-tag_dispatched"></a></p><h4><code>tag-dispatched</code></h4>
957 <p>This means that the documented function uses <a class="el" href="index.html#tutorial-core-tag_dispatching">tag dispatching</a>, and hence the exact implementation depends on the model of the concept associated to the function.</p>
958 <p><a class="anchor" id="tutorial-glossary-implementation_defined"></a></p><h4><code>implementation-defined</code></h4>
959 <p>This expresses the fact that the exact implementation of an entity (usually a type) should not be relied upon by users. In particular, this means that one can not assume anything beyond what is written explicitly in the documentation. Usually, the concepts satisfied by an implementation-defined entity will be documented, because one could otherwise do nothing with it. Concretely, assuming too much about an implementation-defined entity will probably not kill you, but it will very probably break your code when you update to a newer version of Hana.</p>
960 <h1><a class="anchor" id="tutorial-rationales"></a>
961 Rationales/FAQ</h1>
962 <hr/>
963 <p> This section documents the rationale for some design choices. It also serves as a FAQ for some (not so) frequently asked questions. If you think something should be added to this list, open a GitHub issue and we'll consider either improving the documentation or adding the question here.</p>
964 <h2><a class="anchor" id="tutorial-rationales-dependencies"></a>
965 Why restrict usage of external dependencies?</h2>
966 <p>There are several reasons for doing so. First, Hana is a very fundamental library; we are basically reimplementing the core language and the standard library with support for heterogeneous types. When going through the code, one quickly realizes that other libraries are rarely needed, and that almost everything has to be implemented from scratch. Also, since Hana is very fundamental, there is even more incentive for keeping the dependencies minimal, because those dependencies will be handed down to the users. Regarding the minimal reliance on Boost in particular, one big argument for using it is portability. However, as a cutting edge library, Hana only targets very recent compilers. Hence, we can afford to depend on modern constructs and the portability given to us by using Boost would mostly represent dead weight.</p>
967 <h2><a class="anchor" id="tutorial-rationales-iterators"></a>
968 Why no iterators?</h2>
969 <p>Iterator based designs have their own merits, but they are also known to reduce the composability of algorithms. Furthermore, the context of heterogeneous programming brings a lot of points that make iterators much less interesting. For example, incrementing an iterator would have to return a new iterator with a different type, because the type of the new object it is pointing to in the sequence might be different. It also turns out that implementing most algorithms in terms of iterators leads to a worse compile-time performance, simply because the execution model of metaprogramming (using the compiler as an interpreter) is so different from the runtime execution model of C++ (a processor accessing contiguous memory).</p>
970 <h2><a class="anchor" id="tutorial-rationales-container_representation"></a>
971 Why leave some container's representation implementation-defined?</h2>
972 <p>First, it gives much more wiggle room for the implementation to perform compile-time and runtime optimizations by using clever representations for specific containers. For example, a tuple containing homogeneous objects of type <code>T</code> could be implemented as an array of type <code>T</code> instead, which is more efficient at compile-time. Secondly, and most importantly, it turns out that knowing the type of a <em>heterogeneous</em> container is not as useful as you would think. Indeed, in the context of heterogeneous programming, the type of the object returned by a computation is usually part of the computation too. In other words, there is no way to know the type of the object returned by an algorithm without actually performing the algorithm. For example, consider the <code>find_if</code> algorithm:</p>
973 <div class="fragment"><div class="line"><span class="keyword">auto</span> tuple = hana::make_tuple(1, <span class="charliteral">&#39;x&#39;</span>, 3.4f);</div><div class="line"></div><div class="line"><span class="keyword">auto</span> result = <a class="code" href="group__group-Searchable.html#ga7f99b80672aa80a7eb8b223955ce546f">hana::find_if</a>(tuple, [](<span class="keyword">auto</span> <span class="keyword">const</span>&amp; x) {</div><div class="line">  <span class="keywordflow">return</span> hana::traits::is_integral(hana::typeid_(x));</div><div class="line">});</div></div><!-- fragment --><p> If the predicate is satisfied for some element of the tuple, result will be equal to <code>just(x)</code>. Otherwise, <code>result</code> will be equal to <code>nothing</code>. However, the <code>nothing</code>ness of the result is known at compile-time, which requires <code>just(x)</code> and <code>nothing</code> to have different types. Now, say you wanted to explicitly write the type of the result:</p>
974 <div class="fragment"><div class="line">some_type result = <a class="code" href="group__group-Searchable.html#ga7f99b80672aa80a7eb8b223955ce546f">hana::find_if</a>(tuple, [](<span class="keyword">auto</span> <span class="keyword">const</span>&amp; x) {</div><div class="line">  <span class="keywordflow">return</span> hana::traits::is_integral(hana::typeid_(x));</div><div class="line">});</div></div><!-- fragment --><p> In order to possess the knowledge of what <code>some_type</code> is, you would need to actually perform the algorithm, because <code>some_type</code> depends on whether the predicate is satisfied or not for some element in the container. In other words, if you were able to write the above, then you would already know what the result of the algorithm is and you would not need to perform the algorithm in the first place. In Boost.Fusion, this problem is addressed by having a separate <code>result_of</code> namespace, which contains a metafunction computing the result type of any algorithm given the types of the arguments passed to it. For example, the above example could be rewritten with Fusion as:</p>
975 <div class="fragment"><div class="line"><span class="keyword">using</span> Container = fusion::result_of::make_vector&lt;int, char, float&gt;::type;</div><div class="line">Container tuple = fusion::make_vector(1, <span class="charliteral">&#39;x&#39;</span>, 3.4f);</div><div class="line"></div><div class="line"><span class="keyword">using</span> Predicate = mpl::quote1&lt;std::is_integral&gt;;</div><div class="line"><span class="keyword">using</span> Result = fusion::result_of::find_if&lt;Container, Predicate&gt;::type;</div><div class="line">Result result = fusion::find_if&lt;Predicate&gt;(tuple);</div></div><!-- fragment --><p> Notice that we're basically doing the computation twice; once in the <code>result_of</code> namespace and once in the normal <code>fusion</code> namespace, which is highly redundant. Before the days of <code>auto</code> and <code>decltype</code>, such techniques were necessary to perform heterogeneous computations. However, since the advent of modern C++, the need for explicit return types in the context of heterogeneous programming is largely obsolete, and knowing the actual type of containers is usually not that useful.</p>
976 <h2><a class="anchor" id="tutorial-rationales-why_Hana"></a>
977 Why Hana?</h2>
978 <p>No, it isn't the name of my girlfriend! I just needed a short and good looking name that people would easily remember, and Hana came up. It also came to my attention that Hana means <em>flower</em> in Japanese, and <em>one</em> in Korean. Since Hana is pretty and it unifies type-level and heterogeneous programming under a single paradigm, the name appears to be quite well chosen in retrospect :-).</p>
979 <h2><a class="anchor" id="tutorial-rationales-tuple"></a>
980 Why define our own tuple?</h2>
981 <p>Since Hana defines a lot of algorithms on tuples, a possible way to go would have been to simply use <code><a class="el" href="structstd_1_1tuple.html" title="Adapter for std::tuples. ">std::tuple</a></code> and provide the algorithms only, instead of also providing our own tuple. The reason for providing our own tuple is principally performance. Indeed, all the <code><a class="el" href="structstd_1_1tuple.html" title="Adapter for std::tuples. ">std::tuple</a></code> implementations tested so far have a very bad compile-time performance. Also, to get truly amazing compile-time performance, we need to take advantage of the tuple's internal representation in some algorithms, which requires defining our own. Finally, some sugar like <code>operator[]</code> could not be provided if we were using a <code><a class="el" href="structstd_1_1tuple.html" title="Adapter for std::tuples. ">std::tuple</a></code>, since that operator must be defined as a member function.</p>
982 <h2><a class="anchor" id="tutorial-rationales-naming"></a>
983 How are names chosen?</h2>
984 <p>When deciding upon a name <code>X</code>, I try to balance the following things (in no specific order):</p>
985 <ul>
986 <li>How idiomatic is <code>X</code> in C++?</li>
987 <li>How idiomatic is <code>X</code> in the rest of the programming world?</li>
988 <li>How good of a name <code>X</code> <em>actually is</em>, regardless of historical reasons</li>
989 <li>How do I, as the library author, feel about <code>X</code></li>
990 <li>How do users of the library feel about <code>X</code></li>
991 <li>Are there technical reasons not to use <code>X</code>, like name clashes or names reserved by the standard</li>
992 </ul>
993 <p>Of course, good naming is and will always be hard. Names are and will always be tainted by the author's own bias. Still, I try to choose names in a reasonable manner.</p>
994 <h2><a class="anchor" id="tutorial-rationales-parameters"></a>
995 How is the parameter order decided?</h2>
996 <p>Unlike naming, which is fairly subjective, the order of the parameters of a function is usually pretty straightforward to determine. Basically, the rule of thumb is "the container goes first". It has always been this way in Fusion and MPL, and this is intuitive for most C++ programmers. Also, in higher-order algorithms, I try to put the function parameter last, so that multi-line lambdas look nice:</p>
997 <div class="fragment"><div class="line">algorithm(container, [](<span class="keyword">auto</span> x) {</div><div class="line">  <span class="keywordflow">return</span> ...;</div><div class="line">});</div><div class="line"></div><div class="line"><span class="comment">// is nicer than</span></div><div class="line"></div><div class="line">algorithm([](<span class="keyword">auto</span> x) {</div><div class="line">  <span class="keywordflow">return</span> ...;</div><div class="line">}, container);</div></div><!-- fragment --><h2><a class="anchor" id="tutorial-rationales-tag_dispatching"></a>
998 Why tag dispatching?</h2>
999 <p>There are several different techniques we could have used to provide customization points in the library, and tag-dispatching was chosen. Why? First, I wanted a two-layer dispatching system because this allows functions from the first layer (the ones that are called by users) to actually be function objects, which allows passing them to higher-order algorithms. Using a dispatching system with two layers also allows adding some compile-time sanity checks to the first layer, which improves error messages.</p>
1000 <p>Now, tag-dispatching was chosen over other techniques with two layers for a couple of reasons. First, having to explicitly state how some tag is a model of a concept gives the responsibility of making sure that the semantic requirements of the concept are respected to the user. Secondly, when checking whether a type is a model of some concept, we basically check that some key functions are implemented. In particular, we check that the functions from the minimal complete definition of that concept are implemented. For example, <code>Iterable&lt;T&gt;</code> checks whether the <code>is_empty</code>, <code>at</code> and <code>drop_front</code> functions implemented for <code>T</code>. However, the only way to detect this without tag-dispatching is to basically check whether the following expressions are valid in a SFINAE-able context:</p>
1001 <div class="fragment"><div class="line">implementation_of_at(std::declval&lt;T&gt;(), std::declval&lt;N&gt;())</div><div class="line">implementation_of_is_empty(<a class="code" href="namespacestd.html">std</a>::declval&lt;T&gt;())</div><div class="line">implementation_of_drop_front(<a class="code" href="namespacestd.html">std</a>::declval&lt;T&gt;())</div></div><!-- fragment --><p>Unfortunately, this requires actually doing the algorithms, which might either trigger a hard compile-time error or hurt compile-time performance. Also, this requires picking an arbitrary index <code>N</code> to call <code>at</code> with: what if the <code>Iterable</code> is empty? With tag dispatching, we can just ask whether <code>at_impl&lt;T&gt;</code>, <code>is_empty_impl&lt;T&gt;</code> and <code>drop_front_impl&lt;T&gt;</code> are defined, and nothing happens until we actually call their nested <code>::apply</code> function.</p>
1002 <h2><a class="anchor" id="tutorial-rationales-zip_longest"></a>
1003 Why not provide zip_longest?</h2>
1004 <p>It would require either (1) padding the shortest sequences with an arbitrary object, or (2) padding the shortest sequences with an object provided by the user when calling <code>zip_longest</code>. Since there is no requirement that all the zipped sequences have elements of similar types, there is no way to provide a single consistent padding object in all cases. A tuple of padding objects should be provided, but I find it perhaps too complicated to be worth it for now. If you need this functionality, open a GitHub issue.</p>
1005 <h2><a class="anchor" id="tutorial-rationales-concepts"></a>
1006 Why aren't concepts constexpr functions?</h2>
1007 <p>Since the C++ concept proposal maps concepts to boolean <code>constexpr</code> functions, it would make sense that Hana defines its concepts as such too, instead of as structs with a nested <code>::value</code>. Indeed, this was the first choice, but it had to be revised because template functions have one limitation that makes them less flexible. Specifically, a template function can't be passed to a higher-order metafunction. In other words, it is not possible to write the following</p>
1008 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;??? Concept&gt;</div><div class="line"><span class="keyword">struct </span>some_metafunction {</div><div class="line">  <span class="comment">// ...</span></div><div class="line">};</div></div><!-- fragment --><p>This sort of code is very useful in some contexts, such as checking whether two types have a common embedding modeling a concept:</p>
1009 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;??? Concept, <span class="keyword">typename</span> T, <span class="keyword">typename</span> U&gt;</div><div class="line"><span class="keyword">struct </span>have_common_embedding {</div><div class="line">  <span class="comment">// whether T and U both model Concept, and share a common type that also models Concept</span></div><div class="line">};</div></div><!-- fragment --><p>With concepts as boolean <code>constexpr</code> functions, this can't be written generically. When concepts are just template structs, however, we can use template template parameters:</p>
1010 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> ...&gt; <span class="keyword">class </span>Concept, <span class="keyword">typename</span> T, <span class="keyword">typename</span> U&gt;</div><div class="line"><span class="keyword">struct </span>have_common_embedding {</div><div class="line">  <span class="comment">// whether T and U both model Concept, and share a common type that also models Concept</span></div><div class="line">};</div></div><!-- fragment --><h1><a class="anchor" id="tutorial-appendix-constexpr"></a>
1011 Appendix I: Advanced constexpr</h1>
1012 <hr/>
1013 <p> In C++, the border between compile-time and runtime is hazy, a fact that is even more true with the introduction of <a href="http://en.wikipedia.org/wiki/C%2B%2B11#constexpr_.E2.80.93_Generalized_constant_expressions">generalized constant expressions</a> in C++14. However, being able to manipulate heterogeneous objects is all about understanding that border and then crossing it at one's will. The goal of this section is to set things straight with <code>constexpr</code>; to understand which problems it can solve and which ones it can't. This section covers advanced concepts about to constant expressions; only readers with a good understanding of <code>constexpr</code> should attempt to read this.</p>
1014 <h2><a class="anchor" id="tutorial-appendix-constexpr-stripping"></a>
1015 Constexpr stripping</h2>
1016 <p>Let's start with a challenging question. Should the following code compile?</p>
1017 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keywordtype">void</span> f(T t) {</div><div class="line">  static_assert(t == 1, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line">constexpr <span class="keywordtype">int</span> <a class="code" href="group__group-Ring.html#gadea531feb3b0a1c5c3d777f7ab45e932">one</a> = 1;</div><div class="line">f(one);</div></div><!-- fragment --><p>The answer is no, and the error given by Clang goes like</p>
1018 <div class="fragment"><div class="line">error: static_assert expression is not an <a class="code" href="group__group-Metafunction.html#gaf7045fe6a627f88f5f646dad22d37aae">integral</a> constant expression</div><div class="line">  static_assert(t == 1, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">                ^~~~~~</div></div><!-- fragment --><p>The explanation is that inside of <code>f</code>'s body, <code>t</code> is not a constant expression, and hence it can't be used as the operand to a <code>static_assert</code>. The reason is that such a function simply can't be generated by the compiler. To understand the issue, consider what should happen when we instantiate the <code>f</code> template with a concrete type:</p>
1019 <div class="fragment"><div class="line"><span class="comment">// Here, the compiler should generate the code for f&lt;int&gt; and store the</span></div><div class="line"><span class="comment">// address of that code into fptr.</span></div><div class="line">void (*fptr)(int) = f&lt;int&gt;;</div></div><!-- fragment --><p>Clearly, the compiler can't generate <code>f&lt;int&gt;</code>'s code, which should trigger a <code>static_assert</code> if <code>t != 1</code>, because we haven't specified <code>t</code> yet. Even worse, the generated function should work on both constant and non-constant expressions:</p>
1020 <div class="fragment"><div class="line">void (*fptr)(int) = f&lt;int&gt;; <span class="comment">// assume this was possible</span></div><div class="line"><span class="keywordtype">int</span> i = ...; <span class="comment">// user input</span></div><div class="line">fptr(i);</div></div><!-- fragment --><p>Clearly, <code>fptr</code>'s code can't be generated, because it would require being able to <code>static_assert</code> on a runtime value, which does not make sense. Furthermore, note that it does not matter whether you make the function <code>constexpr</code> or not; making <code>f</code> <code>constexpr</code> would only state that the <em>result</em> of <code>f</code> is a constant expression whenever its argument is a constant expression, but it still does not give you the ability to know whether you were called with a constant expression from <code>f</code>'s body. In other words, what we would want is something like:</p>
1021 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keywordtype">void</span> f(constexpr T t) {</div><div class="line">  static_assert(t == 1, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line">constexpr <span class="keywordtype">int</span> one = 1;</div><div class="line">f(one);</div></div><!-- fragment --><p>In this hypothetical scenario, the compiler would know that <code>t</code> is a constant expression from the body of <code>f</code>, and the <code>static_assert</code> could be made to work. However, <code>constexpr</code> parameters do not exist in the current language, and adding them would bring up very challenging design and implementation issues. The conclusion of this little experiment is that <b>argument passing strips away <code>constexpr</code>-ness</b>. What might be unclear by now are the consequences of this stripping, which are explained next.</p>
1022 <h2><a class="anchor" id="tutorial-tutorial-appendix-constexpr-preservation"></a>
1023 Constexpr preservation</h2>
1024 <p>The fact that an argument is not a constant expression means that we can't use it as a non-type template parameter, as an array bound, inside a <code>static_assert</code> or anything else that requires a constant expression. In addition, this means that the return type of a function can't depend on the <em>value</em> of an argument which is nothing new if you think about it:</p>
1025 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keywordtype">int</span> i&gt;</div><div class="line"><span class="keyword">struct </span>foo { };</div><div class="line"></div><div class="line"><span class="keyword">auto</span> f(<span class="keywordtype">int</span> i) -&gt; foo&lt;i&gt;; <span class="comment">// obviously won&#39;t work</span></div></div><!-- fragment --><p>In fact, the return type of a function may only depend on the types of its arguments, and <code>constexpr</code> can't change this fact. This is of utmost importance to us, because we're interested in manipulating heterogeneous objects, which eventually means returning objects with different types depending on the argument of the function. For example, a function might want to return an object of type <code>T</code> in one case and an object of type <code>U</code> in the other; from our analysis, we now know that these "cases" will have to depend on information encoded in the <em>types</em> of the arguments, not in their <em>values</em>.</p>
1026 <p>To preserve <code>constexpr</code>-ness through argument passing, we have to encode the <code>constexpr</code> value into a type, and then pass a not-necessarily-<code>constexpr</code> object of that type to the function. The function, which must be a template, may then access the <code>constexpr</code> value encoded inside that type.</p>
1027 <dl class="todo"><dt><b><a class="el" href="todo.html#_todo000014">Todo:</a></b></dt><dd>Improve this explanation and talk about non-integral constant expressions wrapped into types.</dd></dl>
1028 <h2><a class="anchor" id="tutorial-appendix-constexpr-effects"></a>
1029 Side effects</h2>
1030 <p>Let me ask a tricky question. Is the following code valid?</p>
1031 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line">constexpr <span class="keywordtype">int</span> f(T&amp; n) { <span class="keywordflow">return</span> 1; }</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> n = 0;</div><div class="line">constexpr <span class="keywordtype">int</span> i = f(n);</div></div><!-- fragment --><p>The answer is <em>yes</em>, but the reason might not be obvious at first. What happens here is that we have a non-<code>constexpr</code> <code>int n</code>, and a <code>constexpr</code> function <code>f</code> taking a reference to its argument. The reason why most people think it shouldn't work is that <code>n</code> is not <code>constexpr</code>. However, we're not doing anything with <code>n</code> inside of <code>f</code>, so there is no actual reason why this shouldn't work! This is a bit like <code>throw</code>ing inside of a <code>constexpr</code> function:</p>
1032 <div class="fragment"><div class="line">constexpr <span class="keywordtype">int</span> sqrt(<span class="keywordtype">int</span> i) {</div><div class="line">  <span class="keywordflow">if</span> (i &lt; 0) <span class="keywordflow">throw</span> <span class="stringliteral">&quot;i should be non-negative&quot;</span>;</div><div class="line"></div><div class="line">  <span class="keywordflow">return</span> ...;</div><div class="line">}</div><div class="line"></div><div class="line">constexpr <span class="keywordtype">int</span> two = sqrt(4); <span class="comment">// ok: did not attempt to throw</span></div><div class="line">constexpr <span class="keywordtype">int</span> error = sqrt(-4); <span class="comment">// error: can&#39;t throw in a constant expression</span></div></div><!-- fragment --><p>As long as the code path where <code>throw</code> appears is not executed, the result of the invocation can be a constant expression. Similarly, we can do whatever we want inside of <code>f</code>, as long as we don't execute a code path that requires accessing its argument <code>n</code>, which is not a constant expression:</p>
1033 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line">constexpr <span class="keywordtype">int</span> f(T&amp; n, <span class="keywordtype">bool</span> touch_n) {</div><div class="line">  <span class="keywordflow">if</span> (touch_n) n + 1;</div><div class="line">  <span class="keywordflow">return</span> 1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> n = 0;</div><div class="line">constexpr <span class="keywordtype">int</span> i = f(n, <span class="keyword">false</span>); <span class="comment">// ok</span></div><div class="line">constexpr <span class="keywordtype">int</span> j = f(n, <span class="keyword">true</span>); <span class="comment">// error</span></div></div><!-- fragment --><p>The error given by Clang for the second invocation is</p>
1034 <div class="fragment"><div class="line">error: constexpr variable <span class="charliteral">&#39;j&#39;</span> must be initialized by a constant expression</div><div class="line">constexpr <span class="keywordtype">int</span> j = f(n, <span class="keyword">true</span>); <span class="comment">// error</span></div><div class="line">              ^   ~~~~~~~~~~</div><div class="line">note: read of non-<span class="keyword">const</span> variable <span class="charliteral">&#39;n&#39;</span> is not allowed <a class="code" href="group__group-Searchable.html#ga0d9456ceda38b6ca664998e79d7c45b7">in</a> a constant expression</div><div class="line">  <span class="keywordflow">if</span> (touch_n) n + 1;</div><div class="line">               ^</div></div><!-- fragment --><p>Let's now step the game up a bit and consider a more subtle example. Is the following code valid?</p>
1035 <div class="fragment"><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line">constexpr <span class="keywordtype">int</span> f(T n) { <span class="keywordflow">return</span> 1; }</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> n = 0;</div><div class="line">constexpr <span class="keywordtype">int</span> i = f(n);</div></div><!-- fragment --><p>The only difference with our initial scenario is that <code>f</code> now takes its argument by value instead of by reference. However, this makes a world of difference. Indeed, we're now asking the compiler to make a copy of <code>n</code> and to pass this copy to <code>f</code>. However, <code>n</code> is not <code>constexpr</code>, so its value is only known at runtime. How could the compiler make a copy (at compile-time) of a variable whose value is only known at runtime? Of course, it can't. Indeed, the error message given by Clang is pretty explicit about what's happening:</p>
1036 <div class="fragment"><div class="line">error: constexpr variable <span class="charliteral">&#39;i&#39;</span> must be initialized by a constant expression</div><div class="line">constexpr <span class="keywordtype">int</span> i = f(n);</div><div class="line">              ^   ~~~~</div><div class="line">note: read of non-<span class="keyword">const</span> variable <span class="charliteral">&#39;n&#39;</span> is not allowed <a class="code" href="group__group-Searchable.html#ga0d9456ceda38b6ca664998e79d7c45b7">in</a> a constant expression</div><div class="line">constexpr <span class="keywordtype">int</span> i = f(n);</div><div class="line">                    ^</div></div><!-- fragment --><dl class="todo"><dt><b><a class="el" href="todo.html#_todo000015">Todo:</a></b></dt><dd>Explain how side-effects may not appear inside constant expressions, even if the expression they yield are not accessed.</dd></dl>
1037 <h1><a class="anchor" id="tutorial-appendix-MPL"></a>
1038 Appendix II: A minimal MPL</h1>
1039 <hr/>
1040 <p> This section presents a mini reimplementation of the MPL library. The goal is to be as backward compatible as possible with the MPL, while still using Hana under the hood. Only the "Algorithms" part of the MPL is implemented as a case study, but it should be possible to implement many (but not all) metafunctions of the MPL.</p>
1041 <p>Scroll down to the <code>main</code> function to see the tests. The tests are exactly the examples in the MPL documentation that were copy/pasted and then modified as little as possible to work with this reimplementation.</p>
1042 <div class="fragment"><div class="line"><span class="comment">// Copyright Louis Dionne 2013-2017</span></div><div class="line"><span class="comment">// Distributed under the Boost Software License, Version 1.0.</span></div><div class="line"><span class="comment">// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="hana_8hpp.html">boost/hana.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="mpl_8hpp.html">boost/hana/ext/boost/mpl.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="std_8hpp.html">boost/hana/ext/std.hpp</a>&gt;</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;boost/mpl/lambda.hpp&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;boost/mpl/placeholders.hpp&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;boost/mpl/quote.hpp&gt;</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;type_traits&gt;</span></div><div class="line"><span class="keyword">namespace </span>hana = <a class="code" href="namespaceboost_1_1hana.html">boost::hana</a>;</div><div class="line"><span class="keyword">namespace </span>mpl = <a class="code" href="namespaceboost_1_1mpl.html">boost::mpl</a>;</div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">namespace </span>hpl {<span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="comment">// Utilities</span><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="keyword">namespace </span>detail {</div><div class="line">    <span class="keyword">template</span> &lt;<span class="keyword">typename</span> Pred&gt;</div><div class="line">    constexpr <span class="keyword">auto</span> mpl_predicate = <a class="code" href="group__group-Metafunction.html#gaf7045fe6a627f88f5f646dad22d37aae">hana::integral</a>(<a class="code" href="group__group-Metafunction.html#gacec153d7f86aa7cf1efd813b3fd212b4">hana::metafunction_class</a>&lt;</div><div class="line">        <span class="keyword">typename</span> mpl::lambda&lt;Pred&gt;::type</div><div class="line">    &gt;);</div><div class="line"></div><div class="line">    <span class="keyword">template</span> &lt;<span class="keyword">typename</span> F&gt;</div><div class="line">    constexpr <span class="keyword">auto</span> mpl_metafunction = <a class="code" href="group__group-Metafunction.html#gacec153d7f86aa7cf1efd813b3fd212b4">hana::metafunction_class</a>&lt;</div><div class="line">        <span class="keyword">typename</span> mpl::lambda&lt;F&gt;::type</div><div class="line">    &gt;;</div><div class="line">}</div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="comment">// integral_c</span><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T, T v&gt;</div><div class="line"><span class="keyword">using</span> integral_c = <a class="code" href="structstd_1_1integral__constant.html">std::integral_constant&lt;T, v&gt;</a>;</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keywordtype">int</span> i&gt;</div><div class="line"><span class="keyword">using</span> int_ = integral_c&lt;int, i&gt;;</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keywordtype">long</span> i&gt;</div><div class="line"><span class="keyword">using</span> long_ = integral_c&lt;long, i&gt;;</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keywordtype">bool</span> b&gt;</div><div class="line"><span class="keyword">using</span> bool_ = integral_c&lt;bool, b&gt;;</div><div class="line"></div><div class="line"><span class="keyword">using</span> true_ = bool_&lt;true&gt;;</div><div class="line"><span class="keyword">using</span> false_ = bool_&lt;false&gt;;</div><div class="line"></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="comment">// Sequences, compile-time integers &amp; al</span></div><div class="line"><span class="comment">//</span></div><div class="line"><span class="comment">// Differences with the MPL:</span></div><div class="line"><span class="comment">// 1. `pair&lt;...&gt;::first` and `pair&lt;...&gt;::second` won&#39;t work;</span></div><div class="line"><span class="comment">//    use `first&lt;pair&lt;...&gt;&gt;` instead</span><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="keyword">template</span> &lt;<span class="keyword">typename</span> ...T&gt;</div><div class="line"><span class="keyword">using</span> vector = hana::tuple&lt;hana::type&lt;T&gt;...&gt;;</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T, T ...v&gt;</div><div class="line"><span class="keyword">using</span> vector_c = hana::tuple&lt;hana::integral_constant&lt;T, v&gt;...&gt;;</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T, T from, T to&gt;</div><div class="line"><span class="keyword">using</span> range_c = decltype(hana::range_c&lt;T, from, to&gt;);</div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> T, <span class="keyword">typename</span> U&gt;</div><div class="line"><span class="keyword">using</span> pair = hana::pair&lt;hana::type&lt;T&gt;, hana::type&lt;U&gt;&gt;;</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> P&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Product.html#ga34bbf4281de06dc3540441e8b2bd24f4">first</a> : decltype(+hana::first(P{})) { };</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> P&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Product.html#ga7bb979d59ffc3ab862cb7d9dc7730077">second</a> : decltype(+hana::second(P{})) { };</div><div class="line"></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="comment">// Miscellaneous metafunctions</span><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="keyword">template</span> &lt;<span class="keyword">typename</span> C1, <span class="keyword">typename</span> C2&gt;</div><div class="line"><span class="keyword">struct </span>equal_to</div><div class="line">    : bool_&lt;C1::value == C2::value&gt;</div><div class="line">{ };</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> C1, <span class="keyword">typename</span> C2&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Orderable.html#gad510011602bdb14686f1c4ec145301c9">less</a></div><div class="line">    : bool_&lt;(C1::value &lt; C2::value)&gt;</div><div class="line">{ };</div><div class="line"></div><div class="line">template &lt;typename C1, typename C2&gt;</div><div class="line">struct greater</div><div class="line">    : bool_&lt;(C1::value &gt; C2::value)&gt;</div><div class="line">{ };</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> N&gt;</div><div class="line"><span class="keyword">struct </span>next</div><div class="line">    : integral_c&lt;typename N::value_type, N::value + 1&gt;</div><div class="line">{ };</div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="comment">// Intrinsics</span></div><div class="line"><span class="comment">//</span></div><div class="line"><span class="comment">// Differences with the MPL:</span></div><div class="line"><span class="comment">// 1. `at` does not work for associative sequences; use `find` instead.</span></div><div class="line"><span class="comment">// 2. `begin`, `end`, `clear`, `erase`, `erase_key`, `insert`, `insert_range`,</span></div><div class="line"><span class="comment">//    `is_sequence`, `key_type`, `order`, `sequence_tag`, `value_type`: not implemented</span><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence, <span class="keyword">typename</span> N&gt;</div><div class="line"><span class="keyword">struct </span>at</div><div class="line">    : decltype(hana::at(Sequence{}, N{}))</div><div class="line">{ };</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence, <span class="keywordtype">long</span> n&gt;</div><div class="line"><span class="keyword">using</span> <a class="code" href="group__group-Iterable.html#ga4cb99cfbef936cb267e76f66f40f529c">at_c</a> = at&lt;Sequence, long_&lt;n&gt;&gt;;</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Iterable.html#gab3f4d0035345a453284e46303862d463">back</a></div><div class="line">    : decltype(+hana::back(Sequence{}))</div><div class="line">{ };</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-MonadPlus.html#gaa6be1e83ad72b9d69b43b4bada0f3a75">empty</a></div><div class="line">    : decltype(hana::is_empty(Sequence{}))</div><div class="line">{ };</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Iterable.html#ga8a67ea10e8082dbe6705e573fa978444">front</a></div><div class="line">    : decltype(+hana::front(Sequence{}))</div><div class="line">{ };</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence&gt;</div><div class="line"><span class="keyword">struct </span>pop_back {</div><div class="line">    <span class="keyword">using</span> type = decltype(<a class="code" href="group__group-Sequence.html#gac10231310abc86b056585ea0d0e96ef7">hana::drop_back</a>(</div><div class="line">        hana::to_tuple(Sequence{}), hana::size_c&lt;1&gt;</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">typename</span> Sequence&gt;</div><div class="line"><span class="keyword">struct </span>pop_front {</div><div class="line">    <span class="keyword">using</span> type = decltype(<a class="code" href="group__group-Iterable.html#gad23ce0a4906e2bb0a52f38837b134757">hana::drop_front</a>(Sequence{}));</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence, <span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">struct </span>push_back {</div><div class="line">    <span class="keyword">using</span> type = decltype(<a class="code" href="group__group-MonadPlus.html#ga08624924fe05f0cfbfbd6e439db01873">hana::append</a>(Sequence{}, hana::type_c&lt;T&gt;));</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence, <span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">struct </span>push_front {</div><div class="line">    <span class="keyword">using</span> type = decltype(<a class="code" href="group__group-MonadPlus.html#ga69afbfd4e91125e3e52fcb409135ca7c">hana::prepend</a>(Sequence{}, hana::type_c&lt;T&gt;));</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Foldable.html#ga8ec3ac9a6f5014db943f61ebc9e1e36e">size</a></div><div class="line">    : decltype(hana::length(Sequence{}))</div><div class="line">{ };</div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="comment">// Iteration algorithms</span></div><div class="line"><span class="comment">//</span></div><div class="line"><span class="comment">// Differences with the MPL:</span></div><div class="line"><span class="comment">// 1. reverse_fold:</span></div><div class="line"><span class="comment">//    Does not take an optional additional ForwardOp argument.</span></div><div class="line"><span class="comment">//</span></div><div class="line"><span class="comment">// 2. iter_fold, reverse_iter_fold:</span></div><div class="line"><span class="comment">//    Not implemented because we don&#39;t use iterators</span><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence, <span class="keyword">typename</span> State, <span class="keyword">typename</span> F&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Foldable.html#gaa0fde17f3b947a0678a1c0c01232f2cc">fold</a></div><div class="line">    : decltype(hana::fold(</div><div class="line">        Sequence{}, hana::type_c&lt;State&gt;, detail::mpl_metafunction&lt;F&gt;</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">typename</span> Sequence, <span class="keyword">typename</span> State, <span class="keyword">typename</span> F&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Foldable.html#ga947602718a53bd7fcd5c20477694cdcd">reverse_fold</a></div><div class="line">    : decltype(hana::reverse_fold(</div><div class="line">        Sequence{}, hana::type_c&lt;State&gt;, detail::mpl_metafunction&lt;F&gt;</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">typename</span> Sequence, <span class="keyword">typename</span> State, <span class="keyword">typename</span> F&gt;</div><div class="line"><span class="keyword">using</span> accumulate = fold&lt;Sequence, State, F&gt;;</div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="comment">// Query algorithms</span></div><div class="line"><span class="comment">//</span></div><div class="line"><span class="comment">// Differences with the MPL:</span></div><div class="line"><span class="comment">// 1. find_if and find:</span></div><div class="line"><span class="comment">//    Instead of returning an iterator, they either have a nested `::type`</span></div><div class="line"><span class="comment">//    alias to the answer, or they have no nested `::type` at all, which</span></div><div class="line"><span class="comment">//    makes them SFINAE-friendly.</span></div><div class="line"><span class="comment">//</span></div><div class="line"><span class="comment">// 2. lower_bound, upper_bound:</span></div><div class="line"><span class="comment">//    Not implemented.</span></div><div class="line"><span class="comment">//</span></div><div class="line"><span class="comment">// 3. {min,max}_element:</span></div><div class="line"><span class="comment">//    Not returning an iterator, and also won&#39;t work on empty sequences.</span><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence, <span class="keyword">typename</span> Pred&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Searchable.html#ga7f99b80672aa80a7eb8b223955ce546f">find_if</a></div><div class="line">    : decltype(hana::find_if(Sequence{}, detail::mpl_predicate&lt;Pred&gt;))</div><div class="line">{ };</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence, <span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Searchable.html#ga6b6cdd69942b0fe3bf5254247f9c861e">find</a></div><div class="line">    : decltype(hana::find(Sequence{}, hana::type_c&lt;T&gt;))</div><div class="line">{ };</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence, <span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Searchable.html#ga38e7748956cbc9f3d9bb035ac8577906">contains</a></div><div class="line">    : decltype(hana::contains(Sequence{}, hana::type_c&lt;T&gt;))</div><div class="line">{ };</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence, <span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Foldable.html#ga3159cfa41be18a396926741b0a3fdefd">count</a></div><div class="line">    : decltype(hana::count(Sequence{}, hana::type_c&lt;T&gt;))</div><div class="line">{ };</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence, <span class="keyword">typename</span> Pred&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Foldable.html#ga39d71be65d5b98e7d035a3e5c607e1b4">count_if</a></div><div class="line">    : decltype(hana::count_if(Sequence{}, detail::mpl_predicate&lt;Pred&gt;))</div><div class="line">{ };</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence, <span class="keyword">typename</span> Pred = mpl::quote2&lt;less&gt;&gt;</div><div class="line"><span class="keyword">struct </span>min_element</div><div class="line">    : decltype(hana::minimum(Sequence{}, detail::mpl_predicate&lt;Pred&gt;))</div><div class="line">{ };</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence, <span class="keyword">typename</span> Pred = mpl::quote2&lt;less&gt;&gt;</div><div class="line"><span class="keyword">struct </span>max_element</div><div class="line">    : decltype(hana::maximum(Sequence{}, detail::mpl_predicate&lt;Pred&gt;))</div><div class="line">{ };</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> S1, <span class="keyword">typename</span> S2, <span class="keyword">typename</span> Pred = mpl::quote2&lt;std::is_same&gt;&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Comparable.html#gacaf1ebea6b3ab96ac9dcb82f0e64e547">equal</a></div><div class="line">    : decltype( <span class="comment">// inefficient but whatever</span></div><div class="line">        hana::length(S1{}) == hana::length(S2{}) &amp;&amp;</div><div class="line">        hana::all(hana::zip_shortest_with(detail::mpl_predicate&lt;Pred&gt;,</div><div class="line">                hana::to_tuple(S1{}),</div><div class="line">                hana::to_tuple(S2{})))</div><div class="line">    )</div><div class="line">{ };</div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="comment">// Transformation algorithms</span></div><div class="line"><span class="comment">//</span></div><div class="line"><span class="comment">// Differences from the MPL:</span></div><div class="line"><span class="comment">// 1. The algorithms do not accept an optional inserter, and they always</span></div><div class="line"><span class="comment">//    return a `vector`.</span></div><div class="line"><span class="comment">// 2. stable_partition: not implemented</span></div><div class="line"><span class="comment">// 3. All the reverse_* algorithms are not implemented.</span><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence&gt;</div><div class="line"><span class="keyword">struct </span>copy {</div><div class="line">    <span class="keyword">using</span> type = decltype(hana::to_tuple(Sequence{}));</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence, <span class="keyword">typename</span> Pred&gt;</div><div class="line"><span class="keyword">struct </span>copy_if {</div><div class="line">    <span class="keyword">using</span> type = decltype(<a class="code" href="group__group-MonadPlus.html#ga65cc6d9f522fb9e8e3b28d80ee5c822a">hana::filter</a>(</div><div class="line">        hana::to_tuple(Sequence{}),</div><div class="line">        detail::mpl_predicate&lt;Pred&gt;</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">typename</span> Sequence, <span class="keyword">typename</span> Sequence_or_Op, <span class="keyword">typename</span> = <span class="keywordtype">void</span>&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Functor.html#ga5a8975f6e55375d5b6038a9c36ee63e7">transform</a>;</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence, <span class="keyword">typename</span> Op&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Functor.html#ga5a8975f6e55375d5b6038a9c36ee63e7">transform</a>&lt;Sequence, Op&gt; {</div><div class="line">    <span class="keyword">using</span> type = decltype(<a class="code" href="group__group-Functor.html#ga5a8975f6e55375d5b6038a9c36ee63e7">hana::transform</a>(</div><div class="line">        hana::to_tuple(Sequence{}), detail::mpl_metafunction&lt;Op&gt;</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">typename</span> S1, <span class="keyword">typename</span> S2, <span class="keyword">typename</span> Op&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Functor.html#ga5a8975f6e55375d5b6038a9c36ee63e7">transform</a> {</div><div class="line">    <span class="keyword">using</span> type = decltype(<a class="code" href="group__group-Sequence.html#ga6a4bf8549ce69b5b5b7377aec225a0e3">hana::zip_with</a>(</div><div class="line">        detail::mpl_metafunction&lt;Op&gt;,</div><div class="line">        hana::to_tuple(S1{}),</div><div class="line">        hana::to_tuple(S2{})</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">typename</span> Sequence, <span class="keyword">typename</span> OldType, <span class="keyword">typename</span> NewType&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Functor.html#ga94cd3a75d59d70d77cfce144c4acf8ab">replace</a> {</div><div class="line">    <span class="keyword">using</span> type = decltype(<a class="code" href="group__group-Functor.html#ga94cd3a75d59d70d77cfce144c4acf8ab">hana::replace</a>(</div><div class="line">        hana::to_tuple(Sequence{}),</div><div class="line">        hana::type_c&lt;OldType&gt;,</div><div class="line">        hana::type_c&lt;NewType&gt;</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">typename</span> Sequence, <span class="keyword">typename</span> Pred, <span class="keyword">typename</span> NewType&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Functor.html#ga1d21b4bccd16367d164fbe0d9ef52150">replace_if</a> {</div><div class="line">    <span class="keyword">using</span> type = decltype(<a class="code" href="group__group-Functor.html#ga1d21b4bccd16367d164fbe0d9ef52150">hana::replace_if</a>(</div><div class="line">        hana::to_tuple(Sequence{}),</div><div class="line">        detail::mpl_predicate&lt;Pred&gt;,</div><div class="line">        hana::type_c&lt;NewType&gt;</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">typename</span> Sequence, <span class="keyword">typename</span> T&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-MonadPlus.html#gae3cc0d6e0d8feb3d677bd1da64da6f43">remove</a> {</div><div class="line">    <span class="keyword">using</span> type = decltype(<a class="code" href="group__group-MonadPlus.html#ga65cc6d9f522fb9e8e3b28d80ee5c822a">hana::filter</a>(</div><div class="line">        hana::to_tuple(Sequence{}),</div><div class="line">        <a class="code" href="group__group-Comparable.html#gae33be2e0d5e04f19082f4b7740dfc9cd">hana::not_equal</a>.<a class="code" href="group__group-core.html#gadc70755c1d059139297814fb3bfeb91e">to</a>(hana::type_c&lt;T&gt;)</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">typename</span> Sequence, <span class="keyword">typename</span> Pred&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-MonadPlus.html#ga9700169a45664d50377c1be9d58accd3">remove_if</a> {</div><div class="line">    <span class="keyword">using</span> type = decltype(<a class="code" href="group__group-MonadPlus.html#ga65cc6d9f522fb9e8e3b28d80ee5c822a">hana::filter</a>(</div><div class="line">        hana::to_tuple(Sequence{}),</div><div class="line">        <a class="code" href="group__group-functional.html#ga3b16146e53efcdf9ecbb9a7b21f8cd0b">hana::compose</a>(<a class="code" href="group__group-Logical.html#ga4a7c9d7037601d5e553fd20777958980">hana::not_</a>, detail::mpl_predicate&lt;Pred&gt;)</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">typename</span> Sequence, <span class="keyword">typename</span> Pred&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Sequence.html#ga35349be79e646c4f5bdd74ec96a846ab">unique</a> {</div><div class="line">    <span class="keyword">using</span> type = decltype(<a class="code" href="group__group-Sequence.html#ga35349be79e646c4f5bdd74ec96a846ab">hana::unique</a>(</div><div class="line">        hana::to_tuple(Sequence{}),</div><div class="line">        detail::mpl_predicate&lt;Pred&gt;</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">typename</span> Sequence, <span class="keyword">typename</span> Pred&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Sequence.html#ga5e84ac3f1eb09c637b6b38ef42dccd8d">partition</a> {</div><div class="line">    <span class="keyword">using</span> hana_pair = decltype(<a class="code" href="group__group-Sequence.html#ga5e84ac3f1eb09c637b6b38ef42dccd8d">hana::partition</a>(</div><div class="line">        hana::to_tuple(Sequence{}),</div><div class="line">        detail::mpl_predicate&lt;Pred&gt;</div><div class="line">    ));</div><div class="line">    <span class="keyword">using</span> type = pair&lt;</div><div class="line">        decltype(<a class="code" href="group__group-Product.html#ga34bbf4281de06dc3540441e8b2bd24f4">hana::first</a>(hana_pair{})),</div><div class="line">        decltype(<a class="code" href="group__group-Product.html#ga7bb979d59ffc3ab862cb7d9dc7730077">hana::second</a>(hana_pair{}))</div><div class="line">    &gt;;</div><div class="line">};</div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence, <span class="keyword">typename</span> Pred = mpl::quote2&lt;less&gt;&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Sequence.html#gac000a79eb7b9d44ecc8982c93daa40e5">sort</a> {</div><div class="line">    <span class="keyword">using</span> type = decltype(<a class="code" href="group__group-Sequence.html#gac000a79eb7b9d44ecc8982c93daa40e5">hana::sort</a>(</div><div class="line">        hana::to_tuple(Sequence{}), detail::mpl_predicate&lt;Pred&gt;</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">typename</span> Sequence&gt;</div><div class="line"><span class="keyword">struct </span><a class="code" href="group__group-Sequence.html#ga28037560e8f224c53cf6ac168d03a067">reverse</a> {</div><div class="line">    <span class="keyword">using</span> type = decltype(<a class="code" href="group__group-Sequence.html#ga28037560e8f224c53cf6ac168d03a067">hana::reverse</a>(hana::to_tuple(Sequence{})));</div><div class="line">};</div><div class="line"></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="comment">// Runtime algorithms</span><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="keyword">template</span> &lt;<span class="keyword">typename</span> Sequence, <span class="keyword">typename</span> F&gt;</div><div class="line"><span class="keywordtype">void</span> <a class="code" href="group__group-Foldable.html#ga2af382f7e644ce3707710bbad313e9c2">for_each</a>(F f) {</div><div class="line">    <a class="code" href="group__group-Foldable.html#ga2af382f7e644ce3707710bbad313e9c2">hana::for_each</a>(Sequence{}, [&amp;f](<span class="keyword">auto</span> t) {</div><div class="line">        f(<span class="keyword">typename</span> decltype(t)::type{});</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">typename</span> Sequence, <span class="keyword">typename</span> TransformOp, <span class="keyword">typename</span> F&gt;</div><div class="line"><span class="keywordtype">void</span> <a class="code" href="group__group-Foldable.html#ga2af382f7e644ce3707710bbad313e9c2">for_each</a>(F f) {</div><div class="line">    for_each&lt;typename transform&lt;Sequence, TransformOp&gt;::type&gt;(f);</div><div class="line">}</div><div class="line"></div><div class="line">} <span class="comment">// end namespace hpl</span></div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">template</span> &lt;<span class="keyword">typename</span> N&gt;</div><div class="line"><span class="keyword">struct </span>is_odd</div><div class="line">    : hpl::bool_&lt;(N::value % 2)&gt;</div><div class="line">{ };</div><div class="line"></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main() {</div><div class="line"><span class="keyword">using namespace </span>hpl;</div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="comment">// Misc</span><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">// pair</span></div><div class="line">{</div><div class="line">    static_assert(std::is_same&lt;<a class="code" href="group__group-Product.html#ga34bbf4281de06dc3540441e8b2bd24f4">first</a>&lt;pair&lt;int, float&gt;&gt;::type, <span class="keywordtype">int</span>&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(std::is_same&lt;<a class="code" href="group__group-Product.html#ga7bb979d59ffc3ab862cb7d9dc7730077">second</a>&lt;pair&lt;int, float&gt;&gt;::type, <span class="keywordtype">float</span>&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="comment">// Intrinsics</span><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">// at</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> range = range_c&lt;long,10,50&gt;;</div><div class="line">    static_assert(at&lt;range, int_&lt;0&gt;&gt;::<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">value</a> == 10, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(at&lt;range, int_&lt;10&gt;&gt;::<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">value</a> == 20, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(at&lt;range, int_&lt;40&gt;&gt;::<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">value</a> == 50, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// at_c</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> range = range_c&lt;long, 10, 50&gt;;</div><div class="line">    static_assert(<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">at_c&lt;range, 0&gt;::value</a> == 10, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">at_c&lt;range, 10&gt;::value</a> == 20, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">at_c&lt;range, 40&gt;::value</a> == 50, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// back</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> range1 = range_c&lt;int,0,1&gt;;</div><div class="line">    <span class="keyword">using</span> range2 = range_c&lt;int,0,10&gt;;</div><div class="line">    <span class="keyword">using</span> range3 = range_c&lt;int,-10,0&gt;;</div><div class="line">    <span class="keyword">using</span> types = vector&lt;int, char, float&gt;;</div><div class="line">    static_assert(<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">back&lt;range1&gt;::value</a> == 0, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">back&lt;range2&gt;::value</a> == 9, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">back&lt;range3&gt;::value</a> == -1, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(std::is_same&lt;back&lt;types&gt;::type, <span class="keywordtype">float</span>&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// empty</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> empty_range = range_c&lt;int,0,0&gt;;</div><div class="line">    <span class="keyword">using</span> types = vector&lt;long,float,double&gt;;</div><div class="line">    static_assert(empty&lt;empty_range&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(!empty&lt;types&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// front</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> types1 = vector&lt;long&gt;;</div><div class="line">    <span class="keyword">using</span> types2 = vector&lt;int,long&gt;;</div><div class="line">    <span class="keyword">using</span> types3 = vector&lt;char,int,long&gt;;</div><div class="line">    static_assert(std::is_same&lt;front&lt;types1&gt;::type, <span class="keywordtype">long</span>&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(std::is_same&lt;front&lt;types2&gt;::type, <span class="keywordtype">int</span>&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(std::is_same&lt;front&lt;types3&gt;::type, <span class="keywordtype">char</span>&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// pop_back</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> types1 = vector&lt;long&gt;;</div><div class="line">    <span class="keyword">using</span> types2 = vector&lt;long,int&gt;;</div><div class="line">    <span class="keyword">using</span> types3 = vector&lt;long,int,char&gt;;</div><div class="line"></div><div class="line"></div><div class="line">    <span class="keyword">using</span> result1 = pop_back&lt;types1&gt;::type;</div><div class="line">    <span class="keyword">using</span> result2 = pop_back&lt;types2&gt;::type;</div><div class="line">    <span class="keyword">using</span> result3 = pop_back&lt;types3&gt;::type;</div><div class="line"></div><div class="line">    static_assert(<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">size&lt;result1&gt;::value</a> == 0, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">size&lt;result2&gt;::value</a> == 1, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">size&lt;result3&gt;::value</a> == 2, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line"></div><div class="line">    static_assert(std::is_same&lt; back&lt;result2&gt;::type, <span class="keywordtype">long</span>&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(std::is_same&lt; back&lt;result3&gt;::type, <span class="keywordtype">int</span>&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// pop_front</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> types1 = vector&lt;long&gt;;</div><div class="line">    <span class="keyword">using</span> types2 = vector&lt;int,long&gt;;</div><div class="line">    <span class="keyword">using</span> types3 = vector&lt;char,int,long&gt;;</div><div class="line"></div><div class="line">    <span class="keyword">using</span> result1 = pop_front&lt;types1&gt;::type;</div><div class="line">    <span class="keyword">using</span> result2 = pop_front&lt;types2&gt;::type;</div><div class="line">    <span class="keyword">using</span> result3 = pop_front&lt;types3&gt;::type;</div><div class="line"></div><div class="line">    static_assert(<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">size&lt;result1&gt;::value</a> == 0, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">size&lt;result2&gt;::value</a> == 1, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">size&lt;result3&gt;::value</a> == 2, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line"></div><div class="line">    static_assert(std::is_same&lt;front&lt;result2&gt;::type, <span class="keywordtype">long</span>&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(std::is_same&lt;front&lt;result3&gt;::type, <span class="keywordtype">int</span>&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// push_back</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> bools = vector_c&lt;bool,false,false,false,true,true,true,false,false&gt;;</div><div class="line">    <span class="keyword">using</span> message = push_back&lt;bools, false_&gt;::type;</div><div class="line">    static_assert(<a class="code" href="group__group-Constant.html#ga1687520692a6b0c49e3a69de2980f388">back&lt;message&gt;::type::value</a> == <span class="keyword">false</span>, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(<a class="code" href="group__group-Foldable.html#ga39d71be65d5b98e7d035a3e5c607e1b4">count_if</a>&lt;message, equal_to&lt;mpl::_1, false_&gt;&gt;{} == 6u, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// push_front</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> v = vector_c&lt;int,1,2,3,5,8,13,21&gt;;</div><div class="line">    static_assert(size&lt;v&gt;{} == 7u, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line"></div><div class="line">    <span class="keyword">using</span> fibonacci = push_front&lt;v, int_&lt;1&gt;&gt;::type;</div><div class="line">    static_assert(size&lt;fibonacci&gt;{} == 8u, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line"></div><div class="line">    static_assert(<a class="code" href="group__group-Comparable.html#gacaf1ebea6b3ab96ac9dcb82f0e64e547">equal</a>&lt;</div><div class="line">        fibonacci,</div><div class="line">        vector_c&lt;int,1,1,2,3,5,8,13,21&gt;,</div><div class="line">        equal_to&lt;mpl::_, mpl::_&gt;</div><div class="line">    &gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// size</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> empty_list = vector&lt;&gt;;</div><div class="line">    <span class="keyword">using</span> numbers = vector_c&lt;int,0,1,2,3,4,5&gt;;</div><div class="line">    <span class="keyword">using</span> more_numbers = range_c&lt;int,0,100&gt;;</div><div class="line"></div><div class="line">    static_assert(size&lt;empty_list&gt;{} == 0u, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(size&lt;numbers&gt;{} == 6u, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(size&lt;more_numbers&gt;{} == 100u, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="comment">// Iteration algorithms</span><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">// fold</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> types = vector&lt;long,float,short,double,float,long,long double&gt;;</div><div class="line">    <span class="keyword">using</span> number_of_floats = fold&lt;types, int_&lt;0&gt;,</div><div class="line">        mpl::if_&lt;std::is_floating_point&lt;mpl::_2&gt;,</div><div class="line">            next&lt;mpl::_1&gt;,</div><div class="line">            mpl::_1</div><div class="line">        &gt;</div><div class="line">    &gt;::type;</div><div class="line">    static_assert(number_of_floats{} == 4, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// reverse_fold</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> numbers = vector_c&lt;int,5,-1,0,-7,-2,0,-5,4&gt;;</div><div class="line">    <span class="keyword">using</span> negatives = vector_c&lt;int,-1,-7,-2,-5&gt;;</div><div class="line">    <span class="keyword">using</span> result = reverse_fold&lt;numbers, vector_c&lt;int&gt;,</div><div class="line">        mpl::if_&lt;less&lt;mpl::_2, int_&lt;0&gt;&gt;,</div><div class="line">            push_front&lt;mpl::_1, mpl::_2&gt;,</div><div class="line">            mpl::_1</div><div class="line">        &gt;</div><div class="line">    &gt;::type;</div><div class="line">    static_assert(equal&lt;negatives, result&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="comment">// Query algorithms</span><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">// find_if</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> types = vector&lt;char,int,unsigned,long,unsigned long&gt;;</div><div class="line">    <span class="keyword">using</span> found = find_if&lt;types, std::is_same&lt;mpl::_1, unsigned&gt;&gt;::type;</div><div class="line">    static_assert(std::is_same&lt;found, unsigned&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// find</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> types = vector&lt;char,int,unsigned,long,unsigned long&gt;;</div><div class="line">    static_assert(std::is_same&lt;find&lt;types, unsigned&gt;::type, <span class="keywordtype">unsigned</span>&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// contains</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> types = vector&lt;char,int,unsigned,long,unsigned long&gt;;</div><div class="line">    static_assert(!contains&lt;types, bool&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// count</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> types = vector&lt;int,char,long,short,char,short,double,long&gt;;</div><div class="line">    static_assert(count&lt;types, short&gt;{} == 2u, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// count_if</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> types = vector&lt;int,char,long,short,char,long,double,long&gt;;</div><div class="line">    static_assert(<a class="code" href="group__group-Foldable.html#ga39d71be65d5b98e7d035a3e5c607e1b4">count_if</a>&lt;types, std::is_floating_point&lt;mpl::_&gt;&gt;{} == 1u, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(<a class="code" href="group__group-Foldable.html#ga39d71be65d5b98e7d035a3e5c607e1b4">count_if</a>&lt;types, std::is_same&lt;mpl::_, char&gt;&gt;{} == 2u, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(<a class="code" href="group__group-Foldable.html#ga39d71be65d5b98e7d035a3e5c607e1b4">count_if</a>&lt;types, std::is_same&lt;mpl::_, void&gt;&gt;{} == 0u, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// min_element (MPL&#39;s example is completely broken)</span></div><div class="line">{</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// max_element (MPL&#39;s example is completely broken)</span></div><div class="line">{</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// equal</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> s1 = vector&lt;char,int,unsigned,long,unsigned long&gt;;</div><div class="line">    <span class="keyword">using</span> s2 = vector&lt;char,int,unsigned,long&gt;;</div><div class="line">    static_assert(!equal&lt;s1,s2&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="comment">// Transformaton algorithms</span><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="comment">// copy</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> numbers = vector_c&lt;int,10, 11, 12, 13, 14, 15, 16, 17, 18, 19&gt;;</div><div class="line">    <span class="keyword">using</span> result = copy&lt;range_c&lt;int, 10, 20&gt;&gt;::type;</div><div class="line">    static_assert(size&lt;result&gt;{} == 10u, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(<a class="code" href="group__group-Comparable.html#gacaf1ebea6b3ab96ac9dcb82f0e64e547">equal</a>&lt;result, numbers, mpl::quote2&lt;equal_to&gt;&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// copy_if</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> result = copy_if&lt;range_c&lt;int, 0, 10&gt;, less&lt;mpl::_1, int_&lt;5&gt;&gt;&gt;::type;</div><div class="line">    static_assert(size&lt;result&gt;{} == 5u, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(<a class="code" href="group__group-Comparable.html#gacaf1ebea6b3ab96ac9dcb82f0e64e547">equal</a>&lt;result, range_c&lt;int, 0, 5&gt;&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// transform</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> types = vector&lt;char,short,int,long,float,double&gt;;</div><div class="line">    <span class="keyword">using</span> pointers = vector&lt;char*,short*,int*,long*,float*,double*&gt;;</div><div class="line">    <span class="keyword">using</span> result = transform&lt;types,std::add_pointer&lt;mpl::_1&gt;&gt;::type;</div><div class="line">    static_assert(equal&lt;result, pointers&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// replace</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> types = vector&lt;int,float,char,float,float,double&gt;;</div><div class="line">    <span class="keyword">using</span> expected = vector&lt;int,double,char,double,double,double&gt;;</div><div class="line">    <span class="keyword">using</span> result = replace&lt; types,float,double &gt;::type;</div><div class="line">    static_assert(equal&lt;result, expected&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// replace_if</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> numbers = vector_c&lt;int,1,4,5,2,7,5,3,5&gt;;</div><div class="line">    <span class="keyword">using</span> expected = vector_c&lt;int,1,4,0,2,0,0,3,0&gt;;</div><div class="line">    <span class="keyword">using</span> result = replace_if&lt;numbers, greater&lt;mpl::_, int_&lt;4&gt;&gt;, int_&lt;0&gt;&gt;::type;</div><div class="line">    static_assert(<a class="code" href="group__group-Comparable.html#gacaf1ebea6b3ab96ac9dcb82f0e64e547">equal</a>&lt;result, expected, mpl::quote2&lt;equal_to&gt;&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// remove</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> types = vector&lt;int,float,char,float,float,double&gt;;</div><div class="line">    <span class="keyword">using</span> result = hpl::remove&lt;types, float&gt;::type;</div><div class="line">    static_assert(<a class="code" href="group__group-Comparable.html#gacaf1ebea6b3ab96ac9dcb82f0e64e547">equal</a>&lt;result, vector&lt;int, char, double&gt;&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// remove_if</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> numbers = vector_c&lt;int,1,4,5,2,7,5,3,5&gt;;</div><div class="line">    <span class="keyword">using</span> result = remove_if&lt;numbers, greater&lt;mpl::_, int_&lt;4&gt; &gt; &gt;::type;</div><div class="line">    static_assert(<a class="code" href="group__group-Comparable.html#gacaf1ebea6b3ab96ac9dcb82f0e64e547">equal</a>&lt;result, vector_c&lt;int,1,4,2,3&gt;, mpl::quote2&lt;equal_to&gt;&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// unique</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> types = vector&lt;int,float,float,char,int,int,int,double&gt;;</div><div class="line">    <span class="keyword">using</span> expected = vector&lt;int,float,char,int,double&gt;;</div><div class="line">    <span class="keyword">using</span> result = unique&lt;types, std::is_same&lt;mpl::_1, mpl::_2&gt;&gt;::type;</div><div class="line">    static_assert(equal&lt;result, expected&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// partition</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> r = partition&lt;range_c&lt;int,0,10&gt;, is_odd&lt;mpl::_1&gt;&gt;::type;</div><div class="line">    static_assert(<a class="code" href="group__group-Comparable.html#gacaf1ebea6b3ab96ac9dcb82f0e64e547">equal</a>&lt;first&lt;r&gt;::type, vector_c&lt;int,1,3,5,7,9&gt;&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">    static_assert(<a class="code" href="group__group-Comparable.html#gacaf1ebea6b3ab96ac9dcb82f0e64e547">equal</a>&lt;second&lt;r&gt;::type, vector_c&lt;int,0,2,4,6,8&gt;&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// sort</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> numbers = vector_c&lt;int,3,4,0,-5,8,-1,7&gt;;</div><div class="line">    <span class="keyword">using</span> expected = vector_c&lt;int,-5,-1,0,3,4,7,8&gt;;</div><div class="line">    <span class="keyword">using</span> result = sort&lt;numbers&gt;::type;</div><div class="line">    static_assert(<a class="code" href="group__group-Comparable.html#gacaf1ebea6b3ab96ac9dcb82f0e64e547">equal</a>&lt;result, expected, equal_to&lt;mpl::_, mpl::_&gt;&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// reverse</span></div><div class="line">{</div><div class="line">    <span class="keyword">using</span> numbers = vector_c&lt;int,9,8,7,6,5,4,3,2,1,0&gt;;</div><div class="line">    <span class="keyword">using</span> result = reverse&lt;numbers&gt;::type;</div><div class="line">    static_assert(<a class="code" href="group__group-Comparable.html#gacaf1ebea6b3ab96ac9dcb82f0e64e547">equal</a>&lt;result, range_c&lt;int,0,10&gt;&gt;{}, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">}</div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span><span class="comment">// Runtime algorithms</span><span class="comment"></span></div><div class="line"><span class="comment">//////////////////////////////////////////////////////////////////////////////</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">// for_each</span></div><div class="line">{</div><div class="line">    <span class="keyword">auto</span> value_printer = [](<span class="keyword">auto</span> x) {</div><div class="line">        std::cout &lt;&lt; x &lt;&lt; <span class="charliteral">&#39;\n&#39;</span>;</div><div class="line">    };</div><div class="line"></div><div class="line">    for_each&lt;range_c&lt;int, 0, 10&gt; &gt;(value_printer);</div><div class="line">}</div><div class="line"></div><div class="line">}</div></div><!-- fragment --> </div></div><!-- contents -->
1043 </div><!-- doc-content -->
1044 <!--
1045 Copyright Louis Dionne 2013-2017
1046 Distributed under the Boost Software License, Version 1.0.
1047 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
1048 -->
1049 <!-- boost-no-inspect -->
1050 <!-- HTML footer for doxygen 1.8.9.1-->
1051 <!-- start footer part -->
1052 <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
1053   <ul>
1054   </ul>
1055 </div>
1056 </body>
1057 </html>