group__group-Logical.html 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  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.15"/>
  14. <title>Boost.Hana: Logical</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. /* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
  24. $(document).ready(initResizable);
  25. /* @license-end */</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. /* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
  31. $(document).ready(function() { init_search(); });
  32. /* @license-end */
  33. </script>
  34. <script type="text/x-mathjax-config">
  35. MathJax.Hub.Config({
  36. extensions: ["tex2jax.js"],
  37. jax: ["input/TeX","output/HTML-CSS"],
  38. });
  39. // Copyright Louis Dionne 2013-2017
  40. // Distributed under the Boost Software License, Version 1.0.
  41. // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  42. MathJax.Hub.Config({
  43. "HTML-CSS": {
  44. linebreaks: {
  45. automatic: true,
  46. width: "75% container"
  47. }
  48. }
  49. });
  50. </script><script type="text/javascript" async="async" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js"></script>
  51. <link href="doxygen.css" rel="stylesheet" type="text/css" />
  52. <!-- Additional javascript for drawing charts. -->
  53. <script type="text/javascript" src="highcharts.js"></script>
  54. <script type="text/javascript" src="highcharts-data.js"></script>
  55. <script type="text/javascript" src="highcharts-exporting.js"></script>
  56. <script type="text/javascript" src="chart.js"></script>
  57. <script type="text/javascript" src="hana.js"></script>
  58. </head>
  59. <body>
  60. <div id="top"><!-- do not remove this div, it is closed by doxygen! -->
  61. <div id="titlearea">
  62. <table cellspacing="0" cellpadding="0">
  63. <tbody>
  64. <tr style="height: 56px;">
  65. <td id="projectlogo"><img alt="Logo" src="Boost.png"/></td>
  66. <td style="padding-left: 0.5em;">
  67. <div id="projectname">Boost.Hana
  68. &#160;<span id="projectnumber">1.6.0</span>
  69. </div>
  70. <div id="projectbrief">Your standard library for metaprogramming</div>
  71. </td>
  72. <td> <div id="MSearchBox" class="MSearchBoxInactive">
  73. <span class="left">
  74. <img id="MSearchSelect" src="search/mag_sel.png"
  75. onmouseover="return searchBox.OnSearchSelectShow()"
  76. onmouseout="return searchBox.OnSearchSelectHide()"
  77. alt=""/>
  78. <input type="text" id="MSearchField" value="Search" accesskey="S"
  79. onfocus="searchBox.OnSearchFieldFocus(true)"
  80. onblur="searchBox.OnSearchFieldFocus(false)"
  81. onkeyup="searchBox.OnSearchFieldChange(event)"/>
  82. </span><span class="right">
  83. <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
  84. </span>
  85. </div>
  86. </td>
  87. </tr>
  88. </tbody>
  89. </table>
  90. </div>
  91. <!-- end header part -->
  92. <!-- Generated by Doxygen 1.8.15 -->
  93. <script type="text/javascript">
  94. /* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
  95. var searchBox = new SearchBox("searchBox", "search",false,'Search');
  96. /* @license-end */
  97. </script>
  98. </div><!-- top -->
  99. <div id="side-nav" class="ui-resizable side-nav-resizable">
  100. <div id="nav-tree">
  101. <div id="nav-tree-contents">
  102. <div id="nav-sync" class="sync"></div>
  103. </div>
  104. </div>
  105. <div id="splitbar" style="-moz-user-select:none;"
  106. class="ui-resizable-handle">
  107. </div>
  108. </div>
  109. <script type="text/javascript">
  110. /* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
  111. $(document).ready(function(){initNavTree('group__group-Logical.html','');});
  112. /* @license-end */
  113. </script>
  114. <div id="doc-content">
  115. <!-- window showing the filter options -->
  116. <div id="MSearchSelectWindow"
  117. onmouseover="return searchBox.OnSearchSelectShow()"
  118. onmouseout="return searchBox.OnSearchSelectHide()"
  119. onkeydown="return searchBox.OnSearchSelectKey(event)">
  120. </div>
  121. <!-- iframe showing the search results (closed by default) -->
  122. <div id="MSearchResultsWindow">
  123. <iframe src="javascript:void(0)" frameborder="0"
  124. name="MSearchResults" id="MSearchResults">
  125. </iframe>
  126. </div>
  127. <div class="header">
  128. <div class="summary">
  129. <a href="#var-members">Variables</a> </div>
  130. <div class="headertitle">
  131. <div class="title">Logical<div class="ingroups"><a class="el" href="group__group-concepts.html">Concepts</a></div></div> </div>
  132. </div><!--header-->
  133. <div class="contents">
  134. <a name="details" id="details"></a><h2 class="groupheader">Description</h2>
  135. <p>The <code>Logical</code> concept represents types with a truth value. </p>
  136. <p>Intuitively, a <code>Logical</code> is just a <code>bool</code>, or something that can act like one. However, in the context of programming with heterogeneous objects, it becomes extremely important to distinguish between those objects whose truth value is known at compile-time, and those whose truth value is only known at runtime. The reason why this is so important is because it is possible to branch at compile-time on a condition whose truth value is known at compile-time, and hence the return type of the enclosing function can depend on that truth value. However, if the truth value is only known at runtime, then the compiler has to compile both branches (because any or both of them may end up being used), which creates the additional requirement that both branches must evaluate to the same type.</p>
  137. <p>More specifically, <code>Logical</code> (almost) represents a <a href="http://en.wikipedia.org/wiki/Boolean_algebra_(structure)">boolean algebra</a>, which is a mathematical structure encoding the usual properties that allow us to reason with <code>bool</code>. The exact properties that must be satisfied by any model of <code>Logical</code> are rigorously stated in the laws below.</p>
  138. <h2>Truth, falsity and logical equivalence </h2>
  139. <p>A <code>Logical</code> <code>x</code> is said to be <em>true-valued</em>, or sometimes also just <em>true</em> as an abuse of notation, if </p><div class="fragment"><div class="line"><a class="code" href="group__group-Logical.html#gafd655d2222367131e7a63616e93dd080">if_</a>(x, <span class="keyword">true</span>, <span class="keyword">false</span>) == <span class="keyword">true</span></div></div><!-- fragment --><p>Similarly, <code>x</code> is <em>false-valued</em>, or sometimes just <em>false</em>, if </p><div class="fragment"><div class="line"><a class="code" href="group__group-Logical.html#gafd655d2222367131e7a63616e93dd080">if_</a>(x, <span class="keyword">true</span>, <span class="keyword">false</span>) == <span class="keyword">false</span></div></div><!-- fragment --><p>This provides a standard way of converting any <code>Logical</code> to a straight <code>bool</code>. The notion of truth value suggests another definition, which is that of logical equivalence. We will say that two <code>Logical</code>s <code>x</code> and <code>y</code> are <em>logically equivalent</em> if they have the same truth value. To denote that some expressions <code>p</code> and <code>q</code> of a Logical data type are logically equivalent, we will sometimes also write </p><div class="fragment"><div class="line">p <span class="keywordflow">if</span> and only <span class="keywordflow">if</span> q</div></div><!-- fragment --><p> which is very common in mathematics. The intuition behind this notation is that whenever <code>p</code> is true-valued, then <code>q</code> should be; but when <code>p</code> is false-valued, then <code>q</code> should be too. Hence, <code>p</code> should be true-valued when (and only when) <code>q</code> is true-valued.</p>
  140. <h2>Minimal complete definition </h2>
  141. <p><code>eval_if</code>, <code>not_</code> and <code>while_</code></p>
  142. <p>All the other functions can be defined in those terms: </p><div class="fragment"><div class="line"><a class="code" href="group__group-Logical.html#gafd655d2222367131e7a63616e93dd080">if_</a>(cond, x, y) = <a class="code" href="group__group-Logical.html#gab64636f84de983575aac0208f5fa840c">eval_if</a>(cond, lazy(x), lazy(y))</div><div class="line"><a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(x, y) = <a class="code" href="group__group-Logical.html#gafd655d2222367131e7a63616e93dd080">if_</a>(x, y, x)</div><div class="line"><a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(x, y) = <a class="code" href="group__group-Logical.html#gafd655d2222367131e7a63616e93dd080">if_</a>(x, x, y)</div><div class="line">etc...</div></div><!-- fragment --><h2>Laws </h2>
  143. <p>As outlined above, the <code>Logical</code> concept almost represents a boolean algebra. The rationale for this laxity is to allow things like integers to act like <code>Logical</code>s, which is aligned with C++, even though they do not form a boolean algebra. Even though we depart from the usual axiomatization of boolean algebras, we have found through experience that the definition of a Logical given here is largely compatible with intuition.</p>
  144. <p>The following laws must be satisfied for any data type <code>L</code> modeling the <code>Logical</code> concept. Let <code>a</code>, <code>b</code> and <code>c</code> be objects of a <code>Logical</code> data type, and let <code>t</code> and <code>f</code> be arbitrary <em>true-valued</em> and <em>false-valued</em> <code>Logical</code>s of that data type, respectively. Then, </p><div class="fragment"><div class="line"><span class="comment">// associativity</span></div><div class="line"><a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(a, <a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(b, c)) == <a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(<a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(a, b), c)</div><div class="line"><a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(a, <a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(b, c)) == <a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(<a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(a, b), c)</div><div class="line"></div><div class="line"><span class="comment">// equivalence through commutativity</span></div><div class="line"><a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(a, b) <span class="keywordflow">if</span> and only <span class="keywordflow">if</span> <a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(b, a)</div><div class="line"><a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(a, b) <span class="keywordflow">if</span> and only <span class="keywordflow">if</span> <a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(b, a)</div><div class="line"></div><div class="line"><span class="comment">// absorption</span></div><div class="line"><a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(a, <a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(a, b)) == a</div><div class="line"><a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(a, <a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(a, b)) == a</div><div class="line"></div><div class="line"><span class="comment">// left identity</span></div><div class="line"><a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(a, f) == a</div><div class="line"><a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(a, t) == a</div><div class="line"></div><div class="line"><span class="comment">// distributivity</span></div><div class="line"><a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(a, <a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(b, c)) == <a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(<a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(a, b), <a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(a, c))</div><div class="line"><a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(a, <a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(b, c)) == <a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(<a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(a, b), <a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(a, c))</div><div class="line"></div><div class="line"><span class="comment">// complements</span></div><div class="line"><a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(a, <a class="code" href="group__group-Logical.html#ga4a7c9d7037601d5e553fd20777958980">not_</a>(a)) is <span class="keyword">true</span>-valued</div><div class="line"><a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(a, <a class="code" href="group__group-Logical.html#ga4a7c9d7037601d5e553fd20777958980">not_</a>(a)) is <span class="keyword">false</span>-valued</div></div><!-- fragment --><blockquote class="doxtable">
  145. <h4>Why is the above not a boolean algebra?</h4>
  146. <p>If you look closely, you will find that we depart from the usual boolean algebras because:</p><ol type="1">
  147. <li>we do not require the elements representing truth and falsity to be unique</li>
  148. <li>we do not enforce commutativity of the <code>and_</code> and <code>or_</code> operations</li>
  149. <li>because we do not enforce commutativity, the identity laws become left-identity laws </li>
  150. </ol>
  151. </blockquote>
  152. <h2>Concrete models </h2>
  153. <p><code><a class="el" href="structboost_1_1hana_1_1integral__constant.html" title="Compile-time value of an integral type.">hana::integral_constant</a></code></p>
  154. <h2>Free model for arithmetic data types </h2>
  155. <p>A data type <code>T</code> is arithmetic if <code>std::is_arithmetic&lt;T&gt;::value</code> is true. For an arithmetic data type <code>T</code>, a model of <code>Logical</code> is provided automatically by using the result of the builtin implicit conversion to <code>bool</code> as a truth value. Specifically, the minimal complete definition for those data types is </p><div class="fragment"><div class="line"><a class="code" href="group__group-Logical.html#gab64636f84de983575aac0208f5fa840c">eval_if</a>(cond, <a class="code" href="group__group-Monad.html#gaaddd3789de43cf989babb10cdc0b447a">then</a>, else_) = cond ? <a class="code" href="group__group-Monad.html#gaaddd3789de43cf989babb10cdc0b447a">then</a>(<span class="keywordtype">id</span>) : else(<a class="code" href="group__group-functional.html#gaef38cf34324c8edbd3597ae71811d00d">id</a>)</div><div class="line"><a class="code" href="group__group-Logical.html#ga4a7c9d7037601d5e553fd20777958980">not_</a>(cond) = static_cast&lt;T&gt;(cond ? false : true)</div><div class="line"><a class="code" href="group__group-Logical.html#ga08a767b86c330cac67daa891406d2730">while_</a>(pred, state, f) = equivalent <a class="code" href="group__group-core.html#gadc70755c1d059139297814fb3bfeb91e">to</a> a normal while loop</div></div><!-- fragment --><blockquote class="doxtable">
  156. <h4>Rationale for not providing a model for all contextually convertible to bool data types</h4>
  157. <p>The <code>not_</code> method can not be implemented in a meaningful way for all of those types. For example, one can not cast a pointer type <code>T*</code> to bool and then back again to <code>T*</code> in a meaningful way. With an arithmetic type <code>T</code>, however, it is possible to cast from <code>T</code> to bool and then to <code>T</code> again; the result will be <code>0</code> or <code>1</code> depending on the truth value. If you want to use a pointer type or something similar in a conditional, it is suggested to explicitly convert it to bool by using <code>to&lt;bool&gt;</code>. </p>
  158. </blockquote>
  159. <table class="memberdecls">
  160. <tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="var-members"></a>
  161. Variables</h2></td></tr>
  162. <tr class="memitem:ga14066f5672867c123524e0e0978069eb"><td class="memItemLeft" align="right" valign="top">constexpr auto&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">boost::hana::and_</a></td></tr>
  163. <tr class="memdesc:ga14066f5672867c123524e0e0978069eb"><td class="mdescLeft">&#160;</td><td class="mdescRight">Return whether all the arguments are true-valued.<code>and_</code> can be called with one argument or more. When called with two arguments, <code>and_</code> uses tag-dispatching to find the right implementation. Otherwise,. <a href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">More...</a><br /></td></tr>
  164. <tr class="separator:ga14066f5672867c123524e0e0978069eb"><td class="memSeparator" colspan="2">&#160;</td></tr>
  165. <tr class="memitem:gab64636f84de983575aac0208f5fa840c"><td class="memItemLeft" align="right" valign="top">constexpr auto&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__group-Logical.html#gab64636f84de983575aac0208f5fa840c">boost::hana::eval_if</a></td></tr>
  166. <tr class="memdesc:gab64636f84de983575aac0208f5fa840c"><td class="mdescLeft">&#160;</td><td class="mdescRight">Conditionally execute one of two branches based on a condition.Given a condition and two branches in the form of lambdas or <code><a class="el" href="structboost_1_1hana_1_1lazy.html" title="hana::lazy implements superficial laziness via a monadic interface.">hana::lazy</a></code>s, <code>eval_if</code> will evaluate the branch selected by the condition with <code>eval</code> and return the result. The exact requirements for what the branches may be are the same requirements as those for the <code>eval</code> function. <a href="group__group-Logical.html#gab64636f84de983575aac0208f5fa840c">More...</a><br /></td></tr>
  167. <tr class="separator:gab64636f84de983575aac0208f5fa840c"><td class="memSeparator" colspan="2">&#160;</td></tr>
  168. <tr class="memitem:gafd655d2222367131e7a63616e93dd080"><td class="memItemLeft" align="right" valign="top">constexpr auto&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__group-Logical.html#gafd655d2222367131e7a63616e93dd080">boost::hana::if_</a></td></tr>
  169. <tr class="memdesc:gafd655d2222367131e7a63616e93dd080"><td class="mdescLeft">&#160;</td><td class="mdescRight">Conditionally return one of two values based on a condition.Specifically, <code>then</code> is returned iff <code>cond</code> is true-valued, and <code>else_</code> is returned otherwise. Note that some <code>Logical</code> models may allow <code>then</code> and <code>else_</code> to have different types, while others may require both values to have the same type. <a href="group__group-Logical.html#gafd655d2222367131e7a63616e93dd080">More...</a><br /></td></tr>
  170. <tr class="separator:gafd655d2222367131e7a63616e93dd080"><td class="memSeparator" colspan="2">&#160;</td></tr>
  171. <tr class="memitem:ga4a7c9d7037601d5e553fd20777958980"><td class="memItemLeft" align="right" valign="top">constexpr auto&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__group-Logical.html#ga4a7c9d7037601d5e553fd20777958980">boost::hana::not_</a></td></tr>
  172. <tr class="memdesc:ga4a7c9d7037601d5e553fd20777958980"><td class="mdescLeft">&#160;</td><td class="mdescRight">Negates a <code>Logical</code>.This method returns a <code>Logical</code> with the same tag, but whose truth-value is negated. Specifically, <code>not_(x)</code> returns a false-valued <code>Logical</code> if <code>x</code> is a true-valued <code>Logical</code>, and a true-valued one otherwise. <a href="group__group-Logical.html#ga4a7c9d7037601d5e553fd20777958980">More...</a><br /></td></tr>
  173. <tr class="separator:ga4a7c9d7037601d5e553fd20777958980"><td class="memSeparator" colspan="2">&#160;</td></tr>
  174. <tr class="memitem:ga68c00efbeb69339bfa157a78ebdd3f87"><td class="memItemLeft" align="right" valign="top">constexpr auto&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">boost::hana::or_</a></td></tr>
  175. <tr class="memdesc:ga68c00efbeb69339bfa157a78ebdd3f87"><td class="mdescLeft">&#160;</td><td class="mdescRight">Return whether any of the arguments is true-valued.<code>or_</code> can be called with one argument or more. When called with two arguments, <code>or_</code> uses tag-dispatching to find the right implementation. Otherwise,. <a href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">More...</a><br /></td></tr>
  176. <tr class="separator:ga68c00efbeb69339bfa157a78ebdd3f87"><td class="memSeparator" colspan="2">&#160;</td></tr>
  177. <tr class="memitem:ga08a767b86c330cac67daa891406d2730"><td class="memItemLeft" align="right" valign="top">constexpr auto&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__group-Logical.html#ga08a767b86c330cac67daa891406d2730">boost::hana::while_</a></td></tr>
  178. <tr class="memdesc:ga08a767b86c330cac67daa891406d2730"><td class="mdescLeft">&#160;</td><td class="mdescRight">Apply a function to an initial state while some predicate is satisfied.This method is a natural extension of the <code>while</code> language construct to manipulate a state whose type may change from one iteration to another. However, note that having a state whose type changes from one iteration to the other is only possible as long as the predicate returns a <code>Logical</code> whose truth value is known at compile-time. <a href="group__group-Logical.html#ga08a767b86c330cac67daa891406d2730">More...</a><br /></td></tr>
  179. <tr class="separator:ga08a767b86c330cac67daa891406d2730"><td class="memSeparator" colspan="2">&#160;</td></tr>
  180. </table>
  181. <h2 class="groupheader">Variable Documentation</h2>
  182. <a id="ga14066f5672867c123524e0e0978069eb"></a>
  183. <h2 class="memtitle"><span class="permalink"><a href="#ga14066f5672867c123524e0e0978069eb">&#9670;&nbsp;</a></span>and_</h2>
  184. <div class="memitem">
  185. <div class="memproto">
  186. <table class="memname">
  187. <tr>
  188. <td class="memname">constexpr auto boost::hana::and_</td>
  189. </tr>
  190. </table>
  191. </div><div class="memdoc">
  192. <p><code>#include &lt;<a class="el" href="fwd_2and_8hpp.html">boost/hana/fwd/and.hpp</a>&gt;</code></p>
  193. <b>Initial value:</b><div class="fragment"><div class="line">= [](<span class="keyword">auto</span>&amp;&amp; x, <span class="keyword">auto</span>&amp;&amp; ...y) -&gt; decltype(<span class="keyword">auto</span>) {</div><div class="line"> <span class="keywordflow">return</span> tag-dispatched;</div><div class="line"> }</div></div><!-- fragment -->
  194. <p>Return whether all the arguments are true-valued.<code>and_</code> can be called with one argument or more. When called with two arguments, <code>and_</code> uses tag-dispatching to find the right implementation. Otherwise,. </p>
  195. <div class="fragment"><div class="line"><a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(x) == x</div><div class="line"><a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(x, y, ...z) == <a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(<a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">and_</a>(x, y), z...)</div></div><!-- fragment --><h2>Example </h2>
  196. <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="and_8hpp.html">boost/hana/and.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="assert_8hpp.html">boost/hana/assert.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="bool_8hpp.html">boost/hana/bool.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 class="line"></div><div class="line"></div><div class="line"><a class="code" href="group__group-assertions.html#ga2c5006540936d9f8880e3a39f4fcc035">BOOST_HANA_CONSTANT_CHECK</a>(<a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">hana::and_</a>(hana::true_c, hana::true_c, hana::true_c, hana::true_c));</div><div class="line">static_assert(!<a class="code" href="group__group-Logical.html#ga14066f5672867c123524e0e0978069eb">hana::and_</a>(hana::true_c, <span class="keyword">false</span>, hana::true_c, hana::true_c), <span class="stringliteral">&quot;&quot;</span>);</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main() { }</div></div><!-- fragment -->
  197. </div>
  198. </div>
  199. <a id="gab64636f84de983575aac0208f5fa840c"></a>
  200. <h2 class="memtitle"><span class="permalink"><a href="#gab64636f84de983575aac0208f5fa840c">&#9670;&nbsp;</a></span>eval_if</h2>
  201. <div class="memitem">
  202. <div class="memproto">
  203. <table class="memname">
  204. <tr>
  205. <td class="memname">constexpr auto boost::hana::eval_if</td>
  206. </tr>
  207. </table>
  208. </div><div class="memdoc">
  209. <p><code>#include &lt;<a class="el" href="fwd_2eval__if_8hpp.html">boost/hana/fwd/eval_if.hpp</a>&gt;</code></p>
  210. <b>Initial value:</b><div class="fragment"><div class="line">= [](<span class="keyword">auto</span>&amp;&amp; cond, <span class="keyword">auto</span>&amp;&amp; <a class="code" href="group__group-Monad.html#gaaddd3789de43cf989babb10cdc0b447a">then</a>, <span class="keyword">auto</span>&amp;&amp; else_) -&gt; decltype(<span class="keyword">auto</span>) {</div><div class="line"> <span class="keywordflow">return</span> tag-dispatched;</div><div class="line"> }</div><div class="ttc" id="group__group-Monad_html_gaaddd3789de43cf989babb10cdc0b447a"><div class="ttname"><a href="group__group-Monad.html#gaaddd3789de43cf989babb10cdc0b447a">boost::hana::then</a></div><div class="ttdeci">constexpr auto then</div><div class="ttdoc">Sequentially compose two monadic actions, discarding any value produced by the first but not its effe...</div><div class="ttdef"><b>Definition:</b> then.hpp:36</div></div>
  211. </div><!-- fragment -->
  212. <p>Conditionally execute one of two branches based on a condition.Given a condition and two branches in the form of lambdas or <code><a class="el" href="structboost_1_1hana_1_1lazy.html" title="hana::lazy implements superficial laziness via a monadic interface.">hana::lazy</a></code>s, <code>eval_if</code> will evaluate the branch selected by the condition with <code>eval</code> and return the result. The exact requirements for what the branches may be are the same requirements as those for the <code>eval</code> function. </p>
  213. <h2>Deferring compile-time evaluation inside <code>eval_if</code> </h2>
  214. <p>By passing a unary callable to <code>eval_if</code>, it is possible to defer the compile-time evaluation of selected expressions inside the lambda. This is useful when instantiating a branch would trigger a compile-time error; we only want the branch to be instantiated when that branch is selected. Here's how it can be achieved.</p>
  215. <p>For simplicity, we'll use a unary lambda as our unary callable. Our lambda must accept a parameter (usually called <code>_</code>), which can be used to defer the compile-time evaluation of expressions as required. For example, </p><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> fact(N n) {</div><div class="line"> <span class="keywordflow">return</span> <a class="code" href="group__group-Logical.html#gab64636f84de983575aac0208f5fa840c">hana::eval_if</a>(n == hana::int_c&lt;0&gt;,</div><div class="line"> [] { <span class="keywordflow">return</span> hana::int_c&lt;1&gt;; },</div><div class="line"> [=](<span class="keyword">auto</span> <a class="code" href="group__group-functional.html#gaefe9fd152cba94be71c2b5b9de689d23">_</a>) { <span class="keywordflow">return</span> n * fact(<a class="code" href="group__group-functional.html#gaefe9fd152cba94be71c2b5b9de689d23">_</a>(n) - hana::int_c&lt;1&gt;); }</div><div class="line"> );</div><div class="line">}</div></div><!-- fragment --><p>What happens here is that <code>eval_if</code> will call <code>eval</code> on the selected branch. In turn, <code>eval</code> will call the selected branch either with nothing &ndash; for the <em>then</em> branch &ndash; or with <code><a class="el" href="group__group-functional.html#gaef38cf34324c8edbd3597ae71811d00d" title="The identity function – returns its argument unchanged.">hana::id</a></code> &ndash; for the <em>else</em> branch. Hence, <code>_(x)</code> is always the same as <code>x</code>, but the compiler can't tell until the lambda has been called! Hence, the compiler has to wait before it instantiates the body of the lambda and no infinite recursion happens. However, this trick to delay the instantiation of the lambda's body can only be used when the condition is known at compile-time, because otherwise both branches have to be instantiated inside the <code>eval_if</code> anyway.</p>
  216. <p>There are several caveats to note with this approach to lazy branching. First, because we're using lambdas, it means that the function's result can't be used in a constant expression. This is a limitation of the current language.</p>
  217. <p>The second caveat is that compilers currently have several bugs regarding deeply nested lambdas with captures. So you always risk crashing the compiler, but this is a question of time before it is not a problem anymore.</p>
  218. <p>Finally, it means that conditionals can't be written directly inside unevaluated contexts. The reason is that a lambda can't appear in an unevaluated context, for example in <code>decltype</code>. One way to workaround this is to completely lift your type computations into variable templates instead. For example, instead of writing </p><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>pointerize : decltype(</div><div class="line"> hana::eval_if(hana::traits::is_pointer(hana::type_c&lt;T&gt;),</div><div class="line"> [] { return hana::type_c&lt;T&gt;; },</div><div class="line"> [](auto _) { return _(hana::traits::add_pointer)(hana::type_c&lt;T&gt;); }</div><div class="line"> ))</div><div class="line">{ };</div></div><!-- fragment --><p>you could instead write</p>
  219. <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> pointerize_impl(T t) {</div><div class="line"> <span class="keywordflow">return</span> <a class="code" href="group__group-Logical.html#gab64636f84de983575aac0208f5fa840c">hana::eval_if</a>(hana::traits::is_pointer(t),</div><div class="line"> [] { <span class="keywordflow">return</span> hana::type_c&lt;T&gt;; },</div><div class="line"> [](<span class="keyword">auto</span> <a class="code" href="group__group-functional.html#gaefe9fd152cba94be71c2b5b9de689d23">_</a>) { <span class="keywordflow">return</span> <a class="code" href="group__group-functional.html#gaefe9fd152cba94be71c2b5b9de689d23">_</a>(hana::traits::add_pointer)(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> T&gt;</div><div class="line"><span class="keyword">using</span> pointerize = decltype(pointerize_impl(hana::type_c&lt;T&gt;));</div></div><!-- fragment --><blockquote class="doxtable">
  220. <p><b>Note</b>: This example would actually be implemented more easily with partial specializations, but my bag of good examples is empty at the time of writing this. </p>
  221. </blockquote>
  222. <p>Now, this hoop-jumping only has to be done in one place, because you should use normal function notation everywhere else in your metaprogram to perform type computations. So the syntactic cost is amortized over the whole program.</p>
  223. <p>Another way to work around this limitation of the language would be to use <code><a class="el" href="structboost_1_1hana_1_1lazy.html" title="hana::lazy implements superficial laziness via a monadic interface.">hana::lazy</a></code> for the branches. However, this is only suitable when the branches are not too complicated. With <code><a class="el" href="structboost_1_1hana_1_1lazy.html" title="hana::lazy implements superficial laziness via a monadic interface.">hana::lazy</a></code>, you could write the previous example as </p><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>pointerize : decltype(</div><div class="line"> hana::eval_if(hana::traits::is_pointer(hana::type_c&lt;T&gt;),</div><div class="line"> hana::make_lazy(hana::type_c&lt;T&gt;),</div><div class="line"> hana::make_lazy(hana::traits::add_pointer)(hana::type_c&lt;T&gt;)</div><div class="line"> ))</div><div class="line">{ };</div></div><!-- fragment --><dl class="params"><dt>Parameters</dt><dd>
  224. <table class="params">
  225. <tr><td class="paramname">cond</td><td>The condition determining which of the two branches is selected.</td></tr>
  226. <tr><td class="paramname">then</td><td>An expression called as <code>eval(then)</code> if <code>cond</code> is true-valued.</td></tr>
  227. <tr><td class="paramname">else_</td><td>A function called as <code>eval(else_)</code> if <code>cond</code> is false-valued.</td></tr>
  228. </table>
  229. </dd>
  230. </dl>
  231. <h2>Example </h2>
  232. <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="assert_8hpp.html">boost/hana/assert.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="config_8hpp.html">boost/hana/config.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="equal_8hpp.html">boost/hana/equal.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="eval__if_8hpp.html">boost/hana/eval_if.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="lazy_8hpp.html">boost/hana/lazy.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="traits_8hpp.html">boost/hana/traits.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="type_8hpp.html">boost/hana/type.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 class="line"></div><div class="line"></div><div class="line"><span class="comment">// eval_if with heterogeneous branches and a Constant condition</span></div><div class="line">BOOST_HANA_CONSTEXPR_LAMBDA <span class="keyword">auto</span> safe_make_unsigned = [](<span class="keyword">auto</span> t) {</div><div class="line"> <span class="keywordflow">return</span> <a class="code" href="group__group-Logical.html#gab64636f84de983575aac0208f5fa840c">hana::eval_if</a>(hana::traits::is_integral(t),</div><div class="line"> hana::make_lazy(hana::traits::make_unsigned)(t),</div><div class="line"> hana::make_lazy(t)</div><div class="line"> );</div><div class="line">};</div><div class="line"></div><div class="line"><a class="code" href="group__group-assertions.html#ga2c5006540936d9f8880e3a39f4fcc035">BOOST_HANA_CONSTANT_CHECK</a>(safe_make_unsigned(hana::type_c&lt;void&gt;) == hana::type_c&lt;void&gt;);</div><div class="line"><a class="code" href="group__group-assertions.html#ga2c5006540936d9f8880e3a39f4fcc035">BOOST_HANA_CONSTANT_CHECK</a>(safe_make_unsigned(hana::type_c&lt;int&gt;) == hana::type_c&lt;unsigned int&gt;);</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">// eval_if with homogeneous branches and a constexpr or runtime condition</span></div><div class="line">BOOST_HANA_CONSTEXPR_LAMBDA <span class="keyword">auto</span> safe_divide = [](<span class="keyword">auto</span> x, <span class="keyword">auto</span> y) {</div><div class="line"> <span class="keywordflow">return</span> <a class="code" href="group__group-Logical.html#gab64636f84de983575aac0208f5fa840c">hana::eval_if</a>(y == 0,</div><div class="line"> [=](<span class="keyword">auto</span>) { <span class="keywordflow">return</span> 0; },</div><div class="line"> [=](<span class="keyword">auto</span> <a class="code" href="group__group-functional.html#gaefe9fd152cba94be71c2b5b9de689d23">_</a>) { <span class="keywordflow">return</span> <a class="code" href="group__group-functional.html#gaefe9fd152cba94be71c2b5b9de689d23">_</a>(x) / y; }</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"> <a class="code" href="group__group-assertions.html#gac7aafc41e4dcc7d1f1929fb00f010d2a">BOOST_HANA_CONSTEXPR_CHECK</a>(safe_divide(6, 3) == 2);</div><div class="line"> <a class="code" href="group__group-assertions.html#gac7aafc41e4dcc7d1f1929fb00f010d2a">BOOST_HANA_CONSTEXPR_CHECK</a>(safe_divide(6, 0) == 0);</div><div class="line">}</div></div><!-- fragment -->
  233. </div>
  234. </div>
  235. <a id="gafd655d2222367131e7a63616e93dd080"></a>
  236. <h2 class="memtitle"><span class="permalink"><a href="#gafd655d2222367131e7a63616e93dd080">&#9670;&nbsp;</a></span>if_</h2>
  237. <div class="memitem">
  238. <div class="memproto">
  239. <table class="memname">
  240. <tr>
  241. <td class="memname">constexpr auto boost::hana::if_</td>
  242. </tr>
  243. </table>
  244. </div><div class="memdoc">
  245. <p><code>#include &lt;<a class="el" href="fwd_2if_8hpp.html">boost/hana/fwd/if.hpp</a>&gt;</code></p>
  246. <b>Initial value:</b><div class="fragment"><div class="line">= [](<span class="keyword">auto</span>&amp;&amp; cond, <span class="keyword">auto</span>&amp;&amp; <a class="code" href="group__group-Monad.html#gaaddd3789de43cf989babb10cdc0b447a">then</a>, <span class="keyword">auto</span>&amp;&amp; else_) -&gt; decltype(<span class="keyword">auto</span>) {</div><div class="line"> <span class="keywordflow">return</span> tag-dispatched;</div><div class="line"> }</div><div class="ttc" id="group__group-Monad_html_gaaddd3789de43cf989babb10cdc0b447a"><div class="ttname"><a href="group__group-Monad.html#gaaddd3789de43cf989babb10cdc0b447a">boost::hana::then</a></div><div class="ttdeci">constexpr auto then</div><div class="ttdoc">Sequentially compose two monadic actions, discarding any value produced by the first but not its effe...</div><div class="ttdef"><b>Definition:</b> then.hpp:36</div></div>
  247. </div><!-- fragment -->
  248. <p>Conditionally return one of two values based on a condition.Specifically, <code>then</code> is returned iff <code>cond</code> is true-valued, and <code>else_</code> is returned otherwise. Note that some <code>Logical</code> models may allow <code>then</code> and <code>else_</code> to have different types, while others may require both values to have the same type. </p>
  249. <dl class="params"><dt>Parameters</dt><dd>
  250. <table class="params">
  251. <tr><td class="paramname">cond</td><td>The condition determining which of the two values is returned.</td></tr>
  252. <tr><td class="paramname">then</td><td>The value returned when <code>cond</code> is true-valued.</td></tr>
  253. <tr><td class="paramname">else_</td><td>The value returned when <code>cond</code> is false-valued.</td></tr>
  254. </table>
  255. </dd>
  256. </dl>
  257. <h2>Example </h2>
  258. <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="bool_8hpp.html">boost/hana/bool.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="equal_8hpp.html">boost/hana/equal.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="if_8hpp.html">boost/hana/if.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="tuple_8hpp.html">boost/hana/tuple.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 class="line"></div><div class="line"></div><div class="line">static_assert(<a class="code" href="group__group-Logical.html#gafd655d2222367131e7a63616e93dd080">hana::if_</a>(<span class="keyword">true</span>, 1, 2) == 1, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line">static_assert(<a class="code" href="group__group-Logical.html#gafd655d2222367131e7a63616e93dd080">hana::if_</a>(<span class="keyword">false</span>, 1, 2) == 2, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line"></div><div class="line">static_assert(</div><div class="line"> <a class="code" href="group__group-Logical.html#gafd655d2222367131e7a63616e93dd080">hana::if_</a>(hana::true_c,</div><div class="line"> hana::make_tuple(<span class="charliteral">&#39;t&#39;</span>, <span class="charliteral">&#39;r&#39;</span>, <span class="charliteral">&#39;u&#39;</span>, <span class="charliteral">&#39;e&#39;</span>),</div><div class="line"> hana::make_tuple(<span class="charliteral">&#39;f&#39;</span>, <span class="charliteral">&#39;a&#39;</span>, <span class="charliteral">&#39;l&#39;</span>, <span class="charliteral">&#39;s&#39;</span>, <span class="charliteral">&#39;e&#39;</span>)</div><div class="line"> )</div><div class="line"> ==</div><div class="line"> hana::make_tuple(<span class="charliteral">&#39;t&#39;</span>, <span class="charliteral">&#39;r&#39;</span>, <span class="charliteral">&#39;u&#39;</span>, <span class="charliteral">&#39;e&#39;</span>)</div><div class="line">, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main() { }</div></div><!-- fragment -->
  259. </div>
  260. </div>
  261. <a id="ga4a7c9d7037601d5e553fd20777958980"></a>
  262. <h2 class="memtitle"><span class="permalink"><a href="#ga4a7c9d7037601d5e553fd20777958980">&#9670;&nbsp;</a></span>not_</h2>
  263. <div class="memitem">
  264. <div class="memproto">
  265. <table class="memname">
  266. <tr>
  267. <td class="memname">constexpr auto boost::hana::not_</td>
  268. </tr>
  269. </table>
  270. </div><div class="memdoc">
  271. <p><code>#include &lt;<a class="el" href="fwd_2not_8hpp.html">boost/hana/fwd/not.hpp</a>&gt;</code></p>
  272. <b>Initial value:</b><div class="fragment"><div class="line">= [](<span class="keyword">auto</span>&amp;&amp; x) -&gt; decltype(<span class="keyword">auto</span>) {</div><div class="line"> <span class="keywordflow">return</span> tag-dispatched;</div><div class="line"> }</div></div><!-- fragment -->
  273. <p>Negates a <code>Logical</code>.This method returns a <code>Logical</code> with the same tag, but whose truth-value is negated. Specifically, <code>not_(x)</code> returns a false-valued <code>Logical</code> if <code>x</code> is a true-valued <code>Logical</code>, and a true-valued one otherwise. </p>
  274. <h2>Example </h2>
  275. <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="assert_8hpp.html">boost/hana/assert.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="bool_8hpp.html">boost/hana/bool.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="equal_8hpp.html">boost/hana/equal.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="not_8hpp.html">boost/hana/not.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 class="line"></div><div class="line"></div><div class="line"><a class="code" href="group__group-assertions.html#ga2c5006540936d9f8880e3a39f4fcc035">BOOST_HANA_CONSTANT_CHECK</a>(<a class="code" href="group__group-Logical.html#ga4a7c9d7037601d5e553fd20777958980">hana::not_</a>(hana::true_c) == hana::false_c);</div><div class="line">static_assert(<a class="code" href="group__group-Logical.html#ga4a7c9d7037601d5e553fd20777958980">hana::not_</a>(<span class="keyword">false</span>) == <span class="keyword">true</span>, <span class="stringliteral">&quot;&quot;</span>);</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main() { }</div></div><!-- fragment -->
  276. </div>
  277. </div>
  278. <a id="ga68c00efbeb69339bfa157a78ebdd3f87"></a>
  279. <h2 class="memtitle"><span class="permalink"><a href="#ga68c00efbeb69339bfa157a78ebdd3f87">&#9670;&nbsp;</a></span>or_</h2>
  280. <div class="memitem">
  281. <div class="memproto">
  282. <table class="memname">
  283. <tr>
  284. <td class="memname">constexpr auto boost::hana::or_</td>
  285. </tr>
  286. </table>
  287. </div><div class="memdoc">
  288. <p><code>#include &lt;<a class="el" href="fwd_2or_8hpp.html">boost/hana/fwd/or.hpp</a>&gt;</code></p>
  289. <b>Initial value:</b><div class="fragment"><div class="line">= [](<span class="keyword">auto</span>&amp;&amp; x, <span class="keyword">auto</span>&amp;&amp; ...y) -&gt; decltype(<span class="keyword">auto</span>) {</div><div class="line"> <span class="keywordflow">return</span> tag-dispatched;</div><div class="line"> }</div></div><!-- fragment -->
  290. <p>Return whether any of the arguments is true-valued.<code>or_</code> can be called with one argument or more. When called with two arguments, <code>or_</code> uses tag-dispatching to find the right implementation. Otherwise,. </p>
  291. <div class="fragment"><div class="line"><a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(x) == x</div><div class="line"><a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(x, y, ...z) == <a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(<a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">or_</a>(x, y), z...)</div></div><!-- fragment --><h2>Example </h2>
  292. <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="assert_8hpp.html">boost/hana/assert.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="bool_8hpp.html">boost/hana/bool.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="not_8hpp.html">boost/hana/not.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="or_8hpp.html">boost/hana/or.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 class="line"></div><div class="line"></div><div class="line"><a class="code" href="group__group-assertions.html#ga2c5006540936d9f8880e3a39f4fcc035">BOOST_HANA_CONSTANT_CHECK</a>(<a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">hana::or_</a>(hana::false_c, hana::false_c, hana::true_c));</div><div class="line"><a class="code" href="group__group-assertions.html#ga2c5006540936d9f8880e3a39f4fcc035">BOOST_HANA_CONSTANT_CHECK</a>(!<a class="code" href="group__group-Logical.html#ga68c00efbeb69339bfa157a78ebdd3f87">hana::or_</a>(hana::false_c, hana::false_c, hana::false_c));</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main() { }</div></div><!-- fragment -->
  293. </div>
  294. </div>
  295. <a id="ga08a767b86c330cac67daa891406d2730"></a>
  296. <h2 class="memtitle"><span class="permalink"><a href="#ga08a767b86c330cac67daa891406d2730">&#9670;&nbsp;</a></span>while_</h2>
  297. <div class="memitem">
  298. <div class="memproto">
  299. <table class="memname">
  300. <tr>
  301. <td class="memname">constexpr auto boost::hana::while_</td>
  302. </tr>
  303. </table>
  304. </div><div class="memdoc">
  305. <p><code>#include &lt;<a class="el" href="fwd_2while_8hpp.html">boost/hana/fwd/while.hpp</a>&gt;</code></p>
  306. <b>Initial value:</b><div class="fragment"><div class="line">= [](<span class="keyword">auto</span>&amp;&amp; pred, <span class="keyword">auto</span>&amp;&amp; state, <span class="keyword">auto</span>&amp;&amp; f) -&gt; decltype(<span class="keyword">auto</span>) {</div><div class="line"> <span class="keywordflow">return</span> tag-dispatched;</div><div class="line"> }</div></div><!-- fragment -->
  307. <p>Apply a function to an initial state while some predicate is satisfied.This method is a natural extension of the <code>while</code> language construct to manipulate a state whose type may change from one iteration to another. However, note that having a state whose type changes from one iteration to the other is only possible as long as the predicate returns a <code>Logical</code> whose truth value is known at compile-time. </p>
  308. <p>Specifically, <code>while_(pred, state, f)</code> is equivalent to </p><div class="fragment"><div class="line">f(...f(f(state)))</div></div><!-- fragment --><p> where <code>f</code> is iterated as long as <code>pred(f(...))</code> is a true-valued <code>Logical</code>.</p>
  309. <dl class="params"><dt>Parameters</dt><dd>
  310. <table class="params">
  311. <tr><td class="paramname">pred</td><td>A predicate called on the state or on the result of applying <code>f</code> a certain number of times to the state, and returning whether <code>f</code> should be applied one more time.</td></tr>
  312. <tr><td class="paramname">state</td><td>The initial state on which <code>f</code> is applied.</td></tr>
  313. <tr><td class="paramname">f</td><td>A function that is iterated on the initial state. Note that the return type of <code>f</code> may change from one iteration to the other, but only while <code>pred</code> returns a compile-time <code>Logical</code>. In other words, <code>decltype(f(stateN))</code> may differ from <code>decltype(f(stateN+1))</code>, but only if <code>pred(f(stateN))</code> returns a compile-time <code>Logical</code>.</td></tr>
  314. </table>
  315. </dd>
  316. </dl>
  317. <h2>Example </h2>
  318. <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="assert_8hpp.html">boost/hana/assert.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="equal_8hpp.html">boost/hana/equal.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="integral__constant_8hpp.html">boost/hana/integral_constant.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="less_8hpp.html">boost/hana/less.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"><span class="preprocessor">#include &lt;<a class="code" href="while_8hpp.html">boost/hana/while.hpp</a>&gt;</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;vector&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">using namespace </span>hana::literals;</div><div class="line"></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main() {</div><div class="line"> <span class="comment">// while_ with a Constant condition (loop is unrolled at compile-time)</span></div><div class="line"> {</div><div class="line"> std::vector&lt;int&gt; ints;</div><div class="line"> <span class="keyword">auto</span> final_state = <a class="code" href="group__group-Logical.html#ga08a767b86c330cac67daa891406d2730">hana::while_</a>(<a class="code" href="group__group-Orderable.html#gad510011602bdb14686f1c4ec145301c9">hana::less</a>.than(10_c), 0_c, [&amp;](<span class="keyword">auto</span> i) {</div><div class="line"> ints.push_back(i);</div><div class="line"> <span class="keywordflow">return</span> i + 1_c;</div><div class="line"> });</div><div class="line"></div><div class="line"> <span class="comment">// The state is known at compile-time</span></div><div class="line"> <a class="code" href="group__group-assertions.html#ga2c5006540936d9f8880e3a39f4fcc035">BOOST_HANA_CONSTANT_CHECK</a>(final_state == 10_c);</div><div class="line"></div><div class="line"> <a class="code" href="group__group-assertions.html#ga4796ae107d58b67e0bbccd5ae6f70101">BOOST_HANA_RUNTIME_CHECK</a>(ints == std::vector&lt;int&gt;{0, 1, 2, 3, 4, 5, 6, 7, 8, 9});</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// while_ with a constexpr or runtime condition (loop is not unrolled)</span></div><div class="line"> {</div><div class="line"> std::vector&lt;int&gt; ints;</div><div class="line"> <span class="keywordtype">int</span> final_state = <a class="code" href="group__group-Logical.html#ga08a767b86c330cac67daa891406d2730">hana::while_</a>(<a class="code" href="group__group-Orderable.html#gad510011602bdb14686f1c4ec145301c9">hana::less</a>.than(10), 0, [&amp;](<span class="keywordtype">int</span> i) {</div><div class="line"> ints.push_back(i);</div><div class="line"> <span class="keywordflow">return</span> i + 1;</div><div class="line"> });</div><div class="line"></div><div class="line"> <span class="comment">// The state is known only at runtime, or at compile-time if constexpr</span></div><div class="line"> <a class="code" href="group__group-assertions.html#ga4796ae107d58b67e0bbccd5ae6f70101">BOOST_HANA_RUNTIME_CHECK</a>(final_state == 10);</div><div class="line"></div><div class="line"> <a class="code" href="group__group-assertions.html#ga4796ae107d58b67e0bbccd5ae6f70101">BOOST_HANA_RUNTIME_CHECK</a>(ints == std::vector&lt;int&gt;{0, 1, 2, 3, 4, 5, 6, 7, 8, 9});</div><div class="line"> }</div><div class="line">}</div></div><!-- fragment -->
  319. </div>
  320. </div>
  321. </div><!-- contents -->
  322. </div><!-- doc-content -->
  323. <!--
  324. Copyright Louis Dionne 2013-2017
  325. Distributed under the Boost Software License, Version 1.0.
  326. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  327. -->
  328. <!-- boost-no-inspect -->
  329. <!-- HTML footer for doxygen 1.8.9.1-->
  330. <!-- start footer part -->
  331. <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  332. <ul>
  333. </ul>
  334. </div>
  335. </body>
  336. </html>