forked from boostorg/mp11
Merge branch 'develop'
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
For background, please see the article ["Simple C++11 metaprogramming"](http://pdimov.com/cpp2/simple_cxx11_metaprogramming.html).
|
||||
|
||||
The library should be placed in a subdirectory `libs/mp11` in a Boost distribution. There is reference documentation in `doc/html/mp11.html`.
|
||||
The library should be placed in a subdirectory `libs/mp11` in a Boost distribution. There is [documentation](https://rawgit.com/pdimov/mp11/master/doc/html/mp11.html) in `doc/html/mp11.html`.
|
||||
|
||||
Supported compilers:
|
||||
|
||||
|
@@ -166,11 +166,13 @@
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="mp11.html#mp11.reference.function">Helper Metafunctions, <code class="computeroutput"><span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">mp11</span><span class="special">/</span><span class="identifier">function</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code></a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="mp11.html#mp11.reference.function.mp_void_t"><code class="computeroutput"><span class="identifier">mp_void</span><span class="special"><</span><span class="identifier">T</span><span class="special">...></span></code></a></span></dt>
|
||||
<dt><span class="section"><a href="mp11.html#mp11.reference.function.mp_and_t"><code class="computeroutput"><span class="identifier">mp_and</span><span class="special"><</span><span class="identifier">T</span><span class="special">...></span></code></a></span></dt>
|
||||
<dt><span class="section"><a href="mp11.html#mp11.reference.function.mp_all_t"><code class="computeroutput"><span class="identifier">mp_all</span><span class="special"><</span><span class="identifier">T</span><span class="special">...></span></code></a></span></dt>
|
||||
<dt><span class="section"><a href="mp11.html#mp11.reference.function.mp_or_t"><code class="computeroutput"><span class="identifier">mp_or</span><span class="special"><</span><span class="identifier">T</span><span class="special">...></span></code></a></span></dt>
|
||||
<dt><span class="section"><a href="mp11.html#mp11.reference.function.mp_any_t"><code class="computeroutput"><span class="identifier">mp_any</span><span class="special"><</span><span class="identifier">T</span><span class="special">...></span></code></a></span></dt>
|
||||
<dt><span class="section"><a href="mp11.html#mp11.reference.function.mp_same_t"><code class="computeroutput"><span class="identifier">mp_same</span><span class="special"><</span><span class="identifier">T</span><span class="special">...></span></code></a></span></dt>
|
||||
<dt><span class="section"><a href="mp11.html#mp11.reference.function.mp_plus_t"><code class="computeroutput"><span class="identifier">mp_plus</span><span class="special"><</span><span class="identifier">T</span><span class="special">...></span></code></a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="mp11.html#mp11.reference.bind">Bind, <code class="computeroutput"><span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">mp11</span><span class="special">/</span><span class="identifier">bind</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code></a></span></dt>
|
||||
<dd><dl>
|
||||
@@ -187,7 +189,7 @@
|
||||
<dt><span class="section"><a href="mp11.html#mp11.reference.bind.mp_bind_back_q_q_t"><code class="computeroutput"><span class="identifier">mp_bind_back_q</span><span class="special"><</span><span class="identifier">Q</span><span class="special">,</span> <span class="identifier">T</span><span class="special">...></span></code></a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="mp11.html#mp11.reference.integer_sequence">Integer Sequences,
|
||||
<code class="computeroutput"><span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">integer_sequence</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code></a></span></dt>
|
||||
<code class="computeroutput"><span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">mp11</span><span class="special">/</span><span class="identifier">integer_sequence</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code></a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="mp11.html#mp11.reference.integer_sequence.integer_sequence_t_i"><code class="computeroutput"><span class="identifier">integer_sequence</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">I</span><span class="special">...></span></code></a></span></dt>
|
||||
<dt><span class="section"><a href="mp11.html#mp11.reference.integer_sequence.make_integer_sequence_t_n"><code class="computeroutput"><span class="identifier">make_integer_sequence</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">N</span><span class="special">></span></code></a></span></dt>
|
||||
@@ -196,7 +198,7 @@
|
||||
<dt><span class="section"><a href="mp11.html#mp11.reference.integer_sequence.index_sequence_for_t"><code class="computeroutput"><span class="identifier">index_sequence_for</span><span class="special"><</span><span class="identifier">T</span><span class="special">...></span></code></a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="mp11.html#mp11.reference.tuple_for_each">A "for each"
|
||||
algorithm for tuple-like types, <code class="computeroutput"><span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">tuple_for_each</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code></a></span></dt>
|
||||
algorithm for tuple-like types, <code class="computeroutput"><span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">mp11</span><span class="special">/</span><span class="identifier">tuple_for_each</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code></a></span></dt>
|
||||
<dd><dl><dt><span class="section"><a href="mp11.html#mp11.reference.tuple_for_each.tuple_for_each"><code class="computeroutput"><span class="identifier">tuple_for_each</span></code></a></span></dt></dl></dd>
|
||||
</dl></dd>
|
||||
</dl>
|
||||
@@ -304,8 +306,8 @@
|
||||
Let's suppose that we have written a metafunction <code class="computeroutput"><span class="identifier">result</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span>
|
||||
<span class="identifier">U</span><span class="special">></span></code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">using</span> <span class="identifier">promote</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">common_type_t</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="keyword">int</span><span class="special">>;</span>
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> <span class="keyword">using</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">common_type_t</span><span class="special"><</span><span class="identifier">promote</span><span class="special"><</span><span class="identifier">T</span><span class="special">>,</span> <span class="identifier">promote</span><span class="special"><</span><span class="identifier">U</span><span class="special">>>;</span>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">using</span> <span class="identifier">promote</span> <span class="special">=</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">common_type</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="keyword">int</span><span class="special">>::</span><span class="identifier">type</span><span class="special">;</span>
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> <span class="keyword">using</span> <span class="identifier">result</span> <span class="special">=</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">common_type</span><span class="special"><</span><span class="identifier">promote</span><span class="special"><</span><span class="identifier">T</span><span class="special">>,</span> <span class="identifier">promote</span><span class="special"><</span><span class="identifier">U</span><span class="special">>>::</span><span class="identifier">type</span><span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
that ought to represent the result of an arithmetic operation on the integer
|
||||
@@ -341,7 +343,6 @@
|
||||
worst of all, boring. This is how we can leverage Mp11 to automate the task:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">mp11</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">tuple_for_each</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">core</span><span class="special">/</span><span class="identifier">demangle</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">type_traits</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
@@ -354,8 +355,8 @@
|
||||
<span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">demangle</span><span class="special">(</span> <span class="keyword">typeid</span><span class="special">(</span><span class="identifier">T</span><span class="special">).</span><span class="identifier">name</span><span class="special">()</span> <span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">using</span> <span class="identifier">promote</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">common_type_t</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="keyword">int</span><span class="special">>;</span>
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> <span class="keyword">using</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">common_type_t</span><span class="special"><</span><span class="identifier">promote</span><span class="special"><</span><span class="identifier">T</span><span class="special">>,</span> <span class="identifier">promote</span><span class="special"><</span><span class="identifier">U</span><span class="special">>>;</span>
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">using</span> <span class="identifier">promote</span> <span class="special">=</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">common_type</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="keyword">int</span><span class="special">>::</span><span class="identifier">type</span><span class="special">;</span>
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> <span class="keyword">using</span> <span class="identifier">result</span> <span class="special">=</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">common_type</span><span class="special"><</span><span class="identifier">promote</span><span class="special"><</span><span class="identifier">T</span><span class="special">>,</span> <span class="identifier">promote</span><span class="special"><</span><span class="identifier">U</span><span class="special">>>::</span><span class="identifier">type</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T2</span><span class="special">></span> <span class="keyword">void</span> <span class="identifier">test_result</span><span class="special">(</span> <span class="identifier">mp_list</span><span class="special"><</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
@@ -369,7 +370,7 @@
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">using</span> <span class="identifier">L</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span> <span class="keyword">short</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">unsigned</span><span class="special">,</span> <span class="keyword">long</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">long</span><span class="special">>;</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">tuple_for_each</span><span class="special">(</span> <span class="identifier">mp_product</span><span class="special"><</span><span class="identifier">mp_list</span><span class="special">,</span> <span class="identifier">L</span><span class="special">,</span> <span class="identifier">L</span><span class="special">>(),</span> <span class="special">[](</span><span class="keyword">auto</span><span class="special">&&</span> <span class="identifier">x</span><span class="special">){</span> <span class="identifier">test_result</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> <span class="special">}</span> <span class="special">);</span>
|
||||
<span class="identifier">tuple_for_each</span><span class="special">(</span> <span class="identifier">mp_product</span><span class="special"><</span><span class="identifier">mp_list</span><span class="special">,</span> <span class="identifier">L</span><span class="special">,</span> <span class="identifier">L</span><span class="special">>(),</span> <span class="special">[](</span><span class="keyword">auto</span><span class="special">&&</span> <span class="identifier">x</span><span class="special">){</span> <span class="identifier">test_result</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span> <span class="special">}</span> <span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
@@ -397,11 +398,33 @@
|
||||
<p>
|
||||
We then default-construct this tuple and pass it to <code class="computeroutput"><span class="identifier">tuple_for_each</span></code>.
|
||||
<code class="computeroutput"><span class="identifier">tuple_for_each</span><span class="special">(</span><span class="identifier">tp</span><span class="special">,</span> <span class="identifier">f</span><span class="special">)</span></code> calls <code class="computeroutput"><span class="identifier">f</span></code>
|
||||
for every tuple element; we use a (C++14) lambda that calls <code class="computeroutput"><span class="identifier">test_result</span></code>. (In pure C++11, we'd need
|
||||
to make <code class="computeroutput"><span class="identifier">test_result</span></code> a function
|
||||
object with a templated <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> and pass that to <code class="computeroutput"><span class="identifier">tuple_for_each</span></code>
|
||||
directly.)
|
||||
for every tuple element; we use a (C++14) lambda that calls <code class="computeroutput"><span class="identifier">test_result</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
In pure C++11, we can't use a lambda with an <code class="computeroutput"><span class="keyword">auto</span><span class="special">&&</span></code> parameter, so we'll have to make
|
||||
<code class="computeroutput"><span class="identifier">test_result</span></code> a function object
|
||||
with a templated <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code>
|
||||
and pass that to <code class="computeroutput"><span class="identifier">tuple_for_each</span></code>
|
||||
directly:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">test_result</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T2</span><span class="special">></span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="identifier">mp_list</span><span class="special"><</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="special">)</span> <span class="keyword">const</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">using</span> <span class="identifier">T3</span> <span class="special">=</span> <span class="keyword">decltype</span><span class="special">(</span> <span class="identifier">T1</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">T2</span><span class="special">()</span> <span class="special">);</span>
|
||||
<span class="keyword">using</span> <span class="identifier">T4</span> <span class="special">=</span> <span class="identifier">result</span><span class="special"><</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">>;</span>
|
||||
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special"><</span><span class="identifier">T3</span><span class="special">,</span> <span class="identifier">T4</span><span class="special">>::</span><span class="identifier">value</span><span class="special">?</span> <span class="string">"[PASS] "</span><span class="special">:</span> <span class="string">"[FAIL] "</span> <span class="special">)</span>
|
||||
<span class="special"><<</span> <span class="identifier">name</span><span class="special"><</span><span class="identifier">T1</span><span class="special">>()</span> <span class="special"><<</span> <span class="string">" + "</span> <span class="special"><<</span> <span class="identifier">name</span><span class="special"><</span><span class="identifier">T2</span><span class="special">>()</span> <span class="special"><<</span> <span class="string">" -> "</span> <span class="special"><<</span> <span class="identifier">name</span><span class="special"><</span><span class="identifier">T3</span><span class="special">>()</span> <span class="special"><<</span> <span class="string">", result: "</span> <span class="special"><<</span> <span class="identifier">name</span><span class="special"><</span><span class="identifier">T4</span><span class="special">>()</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">using</span> <span class="identifier">L</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span> <span class="keyword">short</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">unsigned</span><span class="special">,</span> <span class="keyword">long</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">long</span><span class="special">>;</span>
|
||||
<span class="identifier">tuple_for_each</span><span class="special">(</span> <span class="identifier">mp_product</span><span class="special"><</span><span class="identifier">mp_list</span><span class="special">,</span> <span class="identifier">L</span><span class="special">,</span> <span class="identifier">L</span><span class="special">>(),</span> <span class="identifier">test_result</span><span class="special">()</span> <span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
@@ -420,7 +443,9 @@
|
||||
arguments. For that, we need a metafunction that applies <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">common_type</span></code>
|
||||
to each pair of elements and gathers the results into a tuple:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">Tp1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Tp2</span><span class="special">></span> <span class="keyword">using</span> <span class="identifier">common_tuple</span> <span class="special">=</span> <span class="identifier">mp_transform</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">common_type_t</span><span class="special">,</span> <span class="identifier">Tp1</span><span class="special">,</span> <span class="identifier">Tp2</span><span class="special">>;</span>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">using</span> <span class="identifier">common_type_t</span> <span class="special">=</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">common_type</span><span class="special"><</span><span class="identifier">T</span><span class="special">...>::</span><span class="identifier">type</span><span class="special">;</span> <span class="comment">// standard in C++14</span>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">Tp1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Tp2</span><span class="special">></span> <span class="keyword">using</span> <span class="identifier">common_tuple</span> <span class="special">=</span> <span class="identifier">mp_transform</span><span class="special"><</span><span class="identifier">common_type_t</span><span class="special">,</span> <span class="identifier">Tp1</span><span class="special">,</span> <span class="identifier">Tp2</span><span class="special">>;</span>
|
||||
</pre>
|
||||
<p>
|
||||
then specialize <code class="computeroutput"><span class="identifier">common_type</span></code>
|
||||
@@ -464,16 +489,15 @@
|
||||
<span class="identifier">E2</span><span class="special">,</span> <span class="identifier">E3</span><span class="special">></span></code>
|
||||
and <code class="computeroutput"><span class="identifier">expected</span><span class="special"><</span><span class="identifier">T2</span><span class="special">,</span> <span class="identifier">E1</span><span class="special">,</span> <span class="identifier">E4</span><span class="special">,</span>
|
||||
<span class="identifier">E5</span><span class="special">></span></code>
|
||||
is <code class="computeroutput"><span class="identifier">expected</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">common_type_t</span><span class="special"><</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">>,</span>
|
||||
<span class="identifier">E1</span><span class="special">,</span> <span class="identifier">E2</span><span class="special">,</span> <span class="identifier">E3</span><span class="special">,</span> <span class="identifier">E4</span><span class="special">,</span>
|
||||
<span class="identifier">E5</span><span class="special">></span></code>.
|
||||
That is, the possible return values are combined into their common type,
|
||||
and we take the union of the set of error types.
|
||||
is <code class="computeroutput"><span class="identifier">expected</span><span class="special"><</span><span class="identifier">common_type_t</span><span class="special"><</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">>,</span> <span class="identifier">E1</span><span class="special">,</span> <span class="identifier">E2</span><span class="special">,</span>
|
||||
<span class="identifier">E3</span><span class="special">,</span> <span class="identifier">E4</span><span class="special">,</span> <span class="identifier">E5</span><span class="special">></span></code>. That is, the possible return values
|
||||
are combined into their common type, and we take the union of the set of
|
||||
error types.
|
||||
</p>
|
||||
<p>
|
||||
Therefore,
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">E1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">E2</span><span class="special">></span> <span class="keyword">using</span> <span class="identifier">common_expected</span> <span class="special">=</span> <span class="identifier">mp_rename</span><span class="special"><</span><span class="identifier">mp_push_front</span><span class="special"><</span><span class="identifier">mp_unique</span><span class="special"><</span><span class="identifier">mp_append</span><span class="special"><</span><span class="identifier">E1</span><span class="special">,</span> <span class="identifier">E2</span><span class="special">>>,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">common_type_t</span><span class="special"><</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">>>,</span> <span class="identifier">expected</span><span class="special">>;</span>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">E1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">E2</span><span class="special">></span> <span class="keyword">using</span> <span class="identifier">common_expected</span> <span class="special">=</span> <span class="identifier">mp_rename</span><span class="special"><</span><span class="identifier">mp_push_front</span><span class="special"><</span><span class="identifier">mp_unique</span><span class="special"><</span><span class="identifier">mp_append</span><span class="special"><</span><span class="identifier">E1</span><span class="special">,</span> <span class="identifier">E2</span><span class="special">>>,</span> <span class="identifier">common_type_t</span><span class="special"><</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">>>,</span> <span class="identifier">expected</span><span class="special">>;</span>
|
||||
|
||||
<span class="keyword">namespace</span> <span class="identifier">std</span>
|
||||
<span class="special">{</span>
|
||||
@@ -492,7 +516,7 @@
|
||||
This makes our job easier. <code class="computeroutput"><span class="identifier">mp_unique</span><span class="special"><</span><span class="identifier">mp_append</span><span class="special"><</span><span class="identifier">E1</span><span class="special">,</span> <span class="identifier">E2</span><span class="special">>></span></code>
|
||||
gives us the concatenation of <code class="computeroutput"><span class="identifier">E1</span></code>
|
||||
and <code class="computeroutput"><span class="identifier">E2</span></code> with the duplicates
|
||||
removed; we then add <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">common_type_t</span><span class="special"><</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">></span></code>
|
||||
removed; we then add <code class="computeroutput"><span class="identifier">common_type_t</span><span class="special"><</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">></span></code>
|
||||
to the front via <code class="computeroutput"><span class="identifier">mp_push_front</span></code>;
|
||||
and finally, we <code class="computeroutput"><span class="identifier">mp_rename</span></code>
|
||||
the resultant <code class="computeroutput"><span class="identifier">mp_list</span></code> to
|
||||
@@ -871,8 +895,7 @@
|
||||
<a name="mp11.reference"></a><a class="link" href="mp11.html#mp11.reference" title="Reference">Reference</a>
|
||||
</h2></div></div></div>
|
||||
<p>
|
||||
The contents of the library are in namespace <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">mp11</span></code>, unless
|
||||
specified otherwise.
|
||||
The contents of the library are in namespace <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">mp11</span></code>.
|
||||
</p>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
@@ -2137,19 +2160,36 @@
|
||||
</h3></div></div></div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="mp11.reference.function.mp_void_t"></a><a class="link" href="mp11.html#mp11.reference.function.mp_void_t" title="mp_void<T...>"><code class="computeroutput"><span class="identifier">mp_void</span><span class="special"><</span><span class="identifier">T</span><span class="special">...></span></code></a>
|
||||
</h4></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">using</span> <span class="identifier">mp_void</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
Same as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">void_t</span></code> from C++17.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="mp11.reference.function.mp_and_t"></a><a class="link" href="mp11.html#mp11.reference.function.mp_and_t" title="mp_and<T...>"><code class="computeroutput"><span class="identifier">mp_and</span><span class="special"><</span><span class="identifier">T</span><span class="special">...></span></code></a>
|
||||
</h4></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">using</span> <span class="identifier">mp_and</span> <span class="special">=</span> <span class="comment">/*...*/</span><span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">mp_and</span><span class="special"><</span><span class="identifier">T</span><span class="special">...></span></code>
|
||||
is an alias for the first type <code class="computeroutput"><span class="identifier">U</span></code>
|
||||
in <code class="computeroutput"><span class="identifier">T</span><span class="special">...</span></code>
|
||||
for which <code class="computeroutput"><span class="identifier">mp_to_bool</span><span class="special"><</span><span class="identifier">U</span><span class="special">></span></code>
|
||||
is <code class="computeroutput"><span class="identifier">mp_false</span></code>. If no such
|
||||
type exists, the last one is returned. <code class="computeroutput"><span class="identifier">mp_and</span><span class="special"><></span></code> is <code class="computeroutput"><span class="identifier">mp_true</span></code>.
|
||||
Similar to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">conjunction</span></code> in C++17.
|
||||
applies <code class="computeroutput"><span class="identifier">mp_to_bool</span></code> to the
|
||||
types in <code class="computeroutput"><span class="identifier">T</span><span class="special">...</span></code>,
|
||||
in order. If the result of an application is <code class="computeroutput"><span class="identifier">mp_false</span></code>,
|
||||
<code class="computeroutput"><span class="identifier">mp_and</span></code> returns <code class="computeroutput"><span class="identifier">mp_false</span></code>. If the application causes a
|
||||
substitution failure, returns <code class="computeroutput"><span class="identifier">mp_false</span></code>.
|
||||
If all results are <code class="computeroutput"><span class="identifier">mp_true</span></code>,
|
||||
returns <code class="computeroutput"><span class="identifier">mp_true</span></code>. <code class="computeroutput"><span class="identifier">mp_and</span><span class="special"><></span></code>
|
||||
is <code class="computeroutput"><span class="identifier">mp_true</span></code>.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">using</span> <span class="identifier">R1</span> <span class="special">=</span> <span class="identifier">mp_and</span><span class="special"><</span><span class="identifier">mp_true</span><span class="special">,</span> <span class="identifier">mp_true</span><span class="special">>;</span> <span class="comment">// mp_true</span>
|
||||
<span class="keyword">using</span> <span class="identifier">R2</span> <span class="special">=</span> <span class="identifier">mp_and</span><span class="special"><</span><span class="identifier">mp_false</span><span class="special">,</span> <span class="keyword">void</span><span class="special">>;</span> <span class="comment">// mp_false, void is not reached</span>
|
||||
<span class="keyword">using</span> <span class="identifier">R3</span> <span class="special">=</span> <span class="identifier">mp_and</span><span class="special"><</span><span class="identifier">mp_false</span><span class="special">,</span> <span class="identifier">mp_false</span><span class="special">>;</span> <span class="comment">// mp_false</span>
|
||||
<span class="keyword">using</span> <span class="identifier">R4</span> <span class="special">=</span> <span class="identifier">mp_and</span><span class="special"><</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">mp_true</span><span class="special">>;</span> <span class="comment">// mp_false (!)</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
@@ -2168,8 +2208,13 @@
|
||||
is an error because <code class="computeroutput"><span class="keyword">void</span></code> does
|
||||
not have a nested <code class="computeroutput"><span class="identifier">value</span></code>.
|
||||
The upside is that <code class="computeroutput"><span class="identifier">mp_all</span></code>
|
||||
is faster.
|
||||
is potentially faster and does not mask substitution failures as <code class="computeroutput"><span class="identifier">mp_and</span></code> does.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">using</span> <span class="identifier">R1</span> <span class="special">=</span> <span class="identifier">mp_and</span><span class="special"><</span><span class="identifier">mp_true</span><span class="special">,</span> <span class="identifier">mp_true</span><span class="special">>;</span> <span class="comment">// mp_true</span>
|
||||
<span class="keyword">using</span> <span class="identifier">R2</span> <span class="special">=</span> <span class="identifier">mp_and</span><span class="special"><</span><span class="identifier">mp_false</span><span class="special">,</span> <span class="keyword">void</span><span class="special">>;</span> <span class="comment">// compile-time error</span>
|
||||
<span class="keyword">using</span> <span class="identifier">R3</span> <span class="special">=</span> <span class="identifier">mp_and</span><span class="special"><</span><span class="identifier">mp_false</span><span class="special">,</span> <span class="identifier">mp_false</span><span class="special">>;</span> <span class="comment">// mp_false</span>
|
||||
<span class="keyword">using</span> <span class="identifier">R4</span> <span class="special">=</span> <span class="identifier">mp_and</span><span class="special"><</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">mp_true</span><span class="special">>;</span> <span class="comment">// compile-time error</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
@@ -2179,13 +2224,18 @@
|
||||
</pre>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">mp_or</span><span class="special"><</span><span class="identifier">T</span><span class="special">...></span></code>
|
||||
is an alias for the first type <code class="computeroutput"><span class="identifier">U</span></code>
|
||||
in <code class="computeroutput"><span class="identifier">T</span><span class="special">...</span></code>
|
||||
for which <code class="computeroutput"><span class="identifier">mp_to_bool</span><span class="special"><</span><span class="identifier">U</span><span class="special">></span></code>
|
||||
is <code class="computeroutput"><span class="identifier">mp_true</span></code>. If no such
|
||||
type exists, the last one is returned. <code class="computeroutput"><span class="identifier">mp_or</span><span class="special"><></span></code> is <code class="computeroutput"><span class="identifier">mp_false</span></code>.
|
||||
Similar to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">disjunction</span></code> in C++17.
|
||||
applies <code class="computeroutput"><span class="identifier">mp_to_bool</span></code> to the
|
||||
types in <code class="computeroutput"><span class="identifier">T</span><span class="special">...</span></code>,
|
||||
in order. If the result of an application is <code class="computeroutput"><span class="identifier">mp_true</span></code>,
|
||||
<code class="computeroutput"><span class="identifier">mp_or</span></code> returns <code class="computeroutput"><span class="identifier">mp_true</span></code>. If all results are <code class="computeroutput"><span class="identifier">mp_false</span></code>, returns <code class="computeroutput"><span class="identifier">mp_false</span></code>.
|
||||
<code class="computeroutput"><span class="identifier">mp_or</span><span class="special"><></span></code>
|
||||
is <code class="computeroutput"><span class="identifier">mp_false</span></code>.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">using</span> <span class="identifier">R1</span> <span class="special">=</span> <span class="identifier">mp_or</span><span class="special"><</span><span class="identifier">mp_true</span><span class="special">,</span> <span class="identifier">mp_false</span><span class="special">>;</span> <span class="comment">// mp_true</span>
|
||||
<span class="keyword">using</span> <span class="identifier">R2</span> <span class="special">=</span> <span class="identifier">mp_or</span><span class="special"><</span><span class="identifier">mp_true</span><span class="special">,</span> <span class="keyword">void</span><span class="special">>;</span> <span class="comment">// mp_true, void is not reached</span>
|
||||
<span class="keyword">using</span> <span class="identifier">R3</span> <span class="special">=</span> <span class="identifier">mp_or</span><span class="special"><</span><span class="identifier">mp_false</span><span class="special">,</span> <span class="identifier">mp_false</span><span class="special">>;</span> <span class="comment">// mp_false</span>
|
||||
<span class="keyword">using</span> <span class="identifier">R4</span> <span class="special">=</span> <span class="identifier">mp_or</span><span class="special"><</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">mp_true</span><span class="special">>;</span> <span class="comment">// compile-time error</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
@@ -2201,6 +2251,11 @@
|
||||
otherwise. Same as <code class="computeroutput"><span class="identifier">mp_or</span></code>,
|
||||
but does not perform short-circuit evaluation.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">using</span> <span class="identifier">R1</span> <span class="special">=</span> <span class="identifier">mp_any</span><span class="special"><</span><span class="identifier">mp_true</span><span class="special">,</span> <span class="identifier">mp_false</span><span class="special">>;</span> <span class="comment">// mp_true</span>
|
||||
<span class="keyword">using</span> <span class="identifier">R2</span> <span class="special">=</span> <span class="identifier">mp_any</span><span class="special"><</span><span class="identifier">mp_true</span><span class="special">,</span> <span class="keyword">void</span><span class="special">>;</span> <span class="comment">// compile-time error</span>
|
||||
<span class="keyword">using</span> <span class="identifier">R3</span> <span class="special">=</span> <span class="identifier">mp_any</span><span class="special"><</span><span class="identifier">mp_false</span><span class="special">,</span> <span class="identifier">mp_false</span><span class="special">>;</span> <span class="comment">// mp_false</span>
|
||||
<span class="keyword">using</span> <span class="identifier">R4</span> <span class="special">=</span> <span class="identifier">mp_any</span><span class="special"><</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">mp_true</span><span class="special">>;</span> <span class="comment">// compile-time error</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
@@ -2217,6 +2272,20 @@
|
||||
is <code class="computeroutput"><span class="identifier">mp_true</span></code>.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="mp11.reference.function.mp_plus_t"></a><a class="link" href="mp11.html#mp11.reference.function.mp_plus_t" title="mp_plus<T...>"><code class="computeroutput"><span class="identifier">mp_plus</span><span class="special"><</span><span class="identifier">T</span><span class="special">...></span></code></a>
|
||||
</h4></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">using</span> <span class="identifier">mp_plus</span> <span class="special">=</span> <span class="comment">/*...*/</span><span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">mp_plus</span><span class="special"><</span><span class="identifier">T</span><span class="special">...></span></code>
|
||||
is an integral constant type with a value that is the sum of <code class="computeroutput"><span class="identifier">U</span><span class="special">::</span><span class="identifier">value</span></code>
|
||||
for all types <code class="computeroutput"><span class="identifier">U</span></code> in <code class="computeroutput"><span class="identifier">T</span><span class="special">...</span></code>.
|
||||
<code class="computeroutput"><span class="identifier">mp_plus</span><span class="special"><></span></code>
|
||||
is <code class="computeroutput"><span class="identifier">mp_int</span><span class="special"><</span><span class="number">0</span><span class="special">></span></code>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
@@ -2332,12 +2401,9 @@
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="mp11.reference.integer_sequence"></a><a class="link" href="mp11.html#mp11.reference.integer_sequence" title="Integer Sequences, <boost/integer_sequence.hpp>">Integer Sequences,
|
||||
<code class="computeroutput"><span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">integer_sequence</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code></a>
|
||||
<a name="mp11.reference.integer_sequence"></a><a class="link" href="mp11.html#mp11.reference.integer_sequence" title="Integer Sequences, <boost/mp11/integer_sequence.hpp>">Integer Sequences,
|
||||
<code class="computeroutput"><span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">mp11</span><span class="special">/</span><span class="identifier">integer_sequence</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code></a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
The contents of this header are defined in namespace <code class="computeroutput"><span class="identifier">boost</span></code>.
|
||||
</p>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="mp11.reference.integer_sequence.integer_sequence_t_i"></a><a class="link" href="mp11.html#mp11.reference.integer_sequence.integer_sequence_t_i" title="integer_sequence<T, I...>"><code class="computeroutput"><span class="identifier">integer_sequence</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">I</span><span class="special">...></span></code></a>
|
||||
@@ -2401,12 +2467,9 @@
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="mp11.reference.tuple_for_each"></a><a class="link" href="mp11.html#mp11.reference.tuple_for_each" title='A "for each" algorithm for tuple-like types, <boost/tuple_for_each.hpp>'>A "for each"
|
||||
algorithm for tuple-like types, <code class="computeroutput"><span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">tuple_for_each</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code></a>
|
||||
<a name="mp11.reference.tuple_for_each"></a><a class="link" href="mp11.html#mp11.reference.tuple_for_each" title='A "for each" algorithm for tuple-like types, <boost/mp11/tuple_for_each.hpp>'>A "for each"
|
||||
algorithm for tuple-like types, <code class="computeroutput"><span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">mp11</span><span class="special">/</span><span class="identifier">tuple_for_each</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code></a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
The contents of this header are defined in namespace <code class="computeroutput"><span class="identifier">boost</span></code>.
|
||||
</p>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="mp11.reference.tuple_for_each.tuple_for_each"></a><a class="link" href="mp11.html#mp11.reference.tuple_for_each.tuple_for_each" title="tuple_for_each"><code class="computeroutput"><span class="identifier">tuple_for_each</span></code></a>
|
||||
@@ -2429,7 +2492,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"><p><small>Last revised: May 22, 2017 at 13:46:31 GMT</small></p></td>
|
||||
<td align="left"><p><small>Last revised: May 24, 2017 at 02:43:53 GMT</small></p></td>
|
||||
<td align="right"><div class="copyright-footer"></div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
|
@@ -29,7 +29,7 @@
|
||||
|
||||
[section Reference]
|
||||
|
||||
The contents of the library are in namespace `boost::mp11`, unless specified otherwise.
|
||||
The contents of the library are in namespace `boost::mp11`.
|
||||
|
||||
[include mp11/integral.qbk]
|
||||
[include mp11/list.qbk]
|
||||
|
@@ -12,8 +12,8 @@
|
||||
|
||||
Let's suppose that we have written a metafunction `result<T, U>`:
|
||||
|
||||
template<class T> using promote = std::common_type_t<T, int>;
|
||||
template<class T, class U> using result = std::common_type_t<promote<T>, promote<U>>;
|
||||
template<class T> using promote = typename std::common_type<T, int>::type;
|
||||
template<class T, class U> using result = typename std::common_type<promote<T>, promote<U>>::type;
|
||||
|
||||
that ought to represent the result of an arithmetic operation on the integer types `T` and `U`,
|
||||
for example `t + u`. We want to test whether `result<T, U>` gives correct results for various combinations
|
||||
@@ -42,7 +42,6 @@ Writing all those type combinations by hand is unwieldy, error prone, and worst
|
||||
how we can leverage Mp11 to automate the task:
|
||||
|
||||
#include <boost/mp11.hpp>
|
||||
#include <boost/tuple_for_each.hpp>
|
||||
#include <boost/core/demangle.hpp>
|
||||
#include <type_traits>
|
||||
#include <iostream>
|
||||
@@ -55,8 +54,8 @@ how we can leverage Mp11 to automate the task:
|
||||
return boost::core::demangle( typeid(T).name() );
|
||||
}
|
||||
|
||||
template<class T> using promote = std::common_type_t<T, int>;
|
||||
template<class T, class U> using result = std::common_type_t<promote<T>, promote<U>>;
|
||||
template<class T> using promote = typename std::common_type<T, int>::type;
|
||||
template<class T, class U> using result = typename std::common_type<promote<T>, promote<U>>::type;
|
||||
|
||||
template<class T1, class T2> void test_result( mp_list<T1, T2> const& )
|
||||
{
|
||||
@@ -70,7 +69,7 @@ how we can leverage Mp11 to automate the task:
|
||||
int main()
|
||||
{
|
||||
using L = std::tuple<char, short, int, unsigned, long, unsigned long>;
|
||||
boost::tuple_for_each( mp_product<mp_list, L, L>(), [](auto&& x){ test_result(x); } );
|
||||
tuple_for_each( mp_product<mp_list, L, L>(), [](auto&& x){ test_result(x); } );
|
||||
}
|
||||
|
||||
How does it work?
|
||||
@@ -83,8 +82,29 @@ In our case, both lists are the same `std::tuple`, and `F` is `mp_list`, so `mp_
|
||||
`std::tuple<mp_list<char, char>, mp_list<char, short>, mp_list<char, int>, ..., mp_list<unsigned long, long>, mp_list<unsigned long, unsigned long>>`.
|
||||
|
||||
We then default-construct this tuple and pass it to `tuple_for_each`. `tuple_for_each(tp, f)` calls `f` for every
|
||||
tuple element; we use a (C++14) lambda that calls `test_result`. (In pure C++11, we'd need to make `test_result` a
|
||||
function object with a templated `operator()` and pass that to `tuple_for_each` directly.)
|
||||
tuple element; we use a (C++14) lambda that calls `test_result`.
|
||||
|
||||
In pure C++11, we can't use a lambda with an `auto&&` parameter, so we'll have to make `test_result` a function object with
|
||||
a templated `operator()` and pass that to `tuple_for_each` directly:
|
||||
|
||||
struct test_result
|
||||
{
|
||||
template<class T1, class T2> void operator()( mp_list<T1, T2> const& ) const
|
||||
{
|
||||
using T3 = decltype( T1() + T2() );
|
||||
using T4 = result<T1, T2>;
|
||||
|
||||
std::cout << ( std::is_same<T3, T4>::value? "[PASS] ": "[FAIL] " )
|
||||
<< name<T1>() << " + " << name<T2>() << " -> " << name<T3>() << ", result: " << name<T4>() << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
using L = std::tuple<char, short, int, unsigned, long, unsigned long>;
|
||||
tuple_for_each( mp_product<mp_list, L, L>(), test_result() );
|
||||
}
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Writing `common_type` specializations]
|
||||
@@ -96,7 +116,9 @@ operator) is unsuitable.
|
||||
Let's write a `common_type` specialization for two `std::tuple` arguments. For that, we need a metafunction that
|
||||
applies `std::common_type` to each pair of elements and gathers the results into a tuple:
|
||||
|
||||
template<class Tp1, class Tp2> using common_tuple = mp_transform<std::common_type_t, Tp1, Tp2>;
|
||||
template<class... T> using common_type_t = typename std::common_type<T...>::type; // standard in C++14
|
||||
|
||||
template<class Tp1, class Tp2> using common_tuple = mp_transform<common_type_t, Tp1, Tp2>;
|
||||
|
||||
then specialize `common_type` to use it:
|
||||
|
||||
@@ -120,12 +142,12 @@ and `common_type_t`, which is defined as `typename common_type<...>::type`, will
|
||||
|
||||
As another example, consider the hypothetical type `expected<T, E...>` that represents either a successful return with a value of `T`,
|
||||
or an unsucessful return with an error code of some type in the list `E...`. The common type of `expected<T1, E1, E2, E3>` and
|
||||
`expected<T2, E1, E4, E5>` is `expected<std::common_type_t<T1, T2>, E1, E2, E3, E4, E5>`. That is, the possible return values are
|
||||
`expected<T2, E1, E4, E5>` is `expected<common_type_t<T1, T2>, E1, E2, E3, E4, E5>`. That is, the possible return values are
|
||||
combined into their common type, and we take the union of the set of error types.
|
||||
|
||||
Therefore,
|
||||
|
||||
template<class T1, class E1, class T2, class E2> using common_expected = mp_rename<mp_push_front<mp_unique<mp_append<E1, E2>>, std::common_type_t<T1, T2>>, expected>;
|
||||
template<class T1, class E1, class T2, class E2> using common_expected = mp_rename<mp_push_front<mp_unique<mp_append<E1, E2>>, common_type_t<T1, T2>>, expected>;
|
||||
|
||||
namespace std
|
||||
{
|
||||
@@ -138,7 +160,7 @@ Therefore,
|
||||
|
||||
Here we've taken a different tack; instead of passing the `expected` types to `common_expected`, we're passing the `T` types and lists of
|
||||
the `E` types. This makes our job easier. `mp_unique<mp_append<E1, E2>>` gives us the concatenation of `E1` and `E2` with the duplicates
|
||||
removed; we then add `std::common_type_t<T1, T2>` to the front via `mp_push_front`; and finally, we `mp_rename` the resultant `mp_list`
|
||||
removed; we then add `common_type_t<T1, T2>` to the front via `mp_push_front`; and finally, we `mp_rename` the resultant `mp_list`
|
||||
to `expected`.
|
||||
|
||||
[endsect]
|
||||
@@ -192,10 +214,10 @@ trying to concatenate tuples containing move-only elements such as `unique_ptr`
|
||||
|
||||
Trying to concatenate `const` tuples fails:
|
||||
|
||||
std::tuple<int> const t1;
|
||||
std::tuple<float> const t2;
|
||||
std::tuple<int> const t1;
|
||||
std::tuple<float> const t2;
|
||||
|
||||
auto result = ::tuple_cat( t1, t2 );
|
||||
auto result = ::tuple_cat( t1, t2 );
|
||||
|
||||
And finally, the standard `tuple_cat` is specified to work on arbitrary tuple-like types (that is, all types
|
||||
that support `tuple_size`, `tuple_element`, and `get`), while our implementation only works with `tuple` and
|
||||
|
@@ -8,11 +8,23 @@
|
||||
|
||||
[section:function Helper Metafunctions, `<boost/mp11/function.hpp>`]
|
||||
|
||||
[section `mp_void<T...>`]
|
||||
template<class... T> using mp_void = void;
|
||||
|
||||
Same as `std::void_t` from C++17.
|
||||
[endsect]
|
||||
|
||||
[section `mp_and<T...>`]
|
||||
template<class... T> using mp_and = /*...*/;
|
||||
|
||||
`mp_and<T...>` is an alias for the first type `U` in `T...` for which `mp_to_bool<U>` is `mp_false`.
|
||||
If no such type exists, the last one is returned. `mp_and<>` is `mp_true`. Similar to `std::conjunction` in C++17.
|
||||
`mp_and<T...>` applies `mp_to_bool` to the types in `T...`, in order. If the result of an application is `mp_false`, `mp_and`
|
||||
returns `mp_false`. If the application causes a substitution failure, returns `mp_false`. If all results are `mp_true`,
|
||||
returns `mp_true`. `mp_and<>` is `mp_true`.
|
||||
|
||||
using R1 = mp_and<mp_true, mp_true>; // mp_true
|
||||
using R2 = mp_and<mp_false, void>; // mp_false, void is not reached
|
||||
using R3 = mp_and<mp_false, mp_false>; // mp_false
|
||||
using R4 = mp_and<void, mp_true>; // mp_false (!)
|
||||
[endsect]
|
||||
|
||||
[section `mp_all<T...>`]
|
||||
@@ -20,14 +32,25 @@ If no such type exists, the last one is returned. `mp_and<>` is `mp_true`. Simil
|
||||
|
||||
`mp_all<T...>` is `mp_true` if `mp_to_bool<U>` is `mp_true` for all types `U` in `T...`, `mp_false` otherwise. Same as
|
||||
`mp_and`, but does not perform short-circuit evaluation. `mp_and<mp_false, void>` is `mp_false`, but `mp_all<mp_false, void>`
|
||||
is an error because `void` does not have a nested `value`. The upside is that `mp_all` is faster.
|
||||
is an error because `void` does not have a nested `value`. The upside is that `mp_all` is potentially faster and does not
|
||||
mask substitution failures as `mp_and` does.
|
||||
|
||||
using R1 = mp_and<mp_true, mp_true>; // mp_true
|
||||
using R2 = mp_and<mp_false, void>; // compile-time error
|
||||
using R3 = mp_and<mp_false, mp_false>; // mp_false
|
||||
using R4 = mp_and<void, mp_true>; // compile-time error
|
||||
[endsect]
|
||||
|
||||
[section `mp_or<T...>`]
|
||||
template<class... T> using mp_or = /*...*/;
|
||||
|
||||
`mp_or<T...>` is an alias for the first type `U` in `T...` for which `mp_to_bool<U>` is `mp_true`.
|
||||
If no such type exists, the last one is returned. `mp_or<>` is `mp_false`. Similar to `std::disjunction` in C++17.
|
||||
`mp_or<T...>` applies `mp_to_bool` to the types in `T...`, in order. If the result of an application is `mp_true`, `mp_or`
|
||||
returns `mp_true`. If all results are `mp_false`, returns `mp_false`. `mp_or<>` is `mp_false`.
|
||||
|
||||
using R1 = mp_or<mp_true, mp_false>; // mp_true
|
||||
using R2 = mp_or<mp_true, void>; // mp_true, void is not reached
|
||||
using R3 = mp_or<mp_false, mp_false>; // mp_false
|
||||
using R4 = mp_or<void, mp_true>; // compile-time error
|
||||
[endsect]
|
||||
|
||||
[section `mp_any<T...>`]
|
||||
@@ -35,6 +58,11 @@ If no such type exists, the last one is returned. `mp_or<>` is `mp_false`. Simil
|
||||
|
||||
`mp_any<T...>` is `mp_true` if `mp_to_bool<U>` is `mp_true` for any type `U` in `T...`, `mp_false` otherwise. Same as
|
||||
`mp_or`, but does not perform short-circuit evaluation.
|
||||
|
||||
using R1 = mp_any<mp_true, mp_false>; // mp_true
|
||||
using R2 = mp_any<mp_true, void>; // compile-time error
|
||||
using R3 = mp_any<mp_false, mp_false>; // mp_false
|
||||
using R4 = mp_any<void, mp_true>; // compile-time error
|
||||
[endsect]
|
||||
|
||||
[section `mp_same<T...>`]
|
||||
@@ -43,4 +71,11 @@ If no such type exists, the last one is returned. `mp_or<>` is `mp_false`. Simil
|
||||
`mp_same<T...>` is `mp_true` if all the types in `T...` are the same type, `mp_false` otherwise. `mp_same<>` is `mp_true`.
|
||||
[endsect]
|
||||
|
||||
[section `mp_plus<T...>`]
|
||||
template<class... T> using mp_plus = /*...*/;
|
||||
|
||||
`mp_plus<T...>` is an integral constant type with a value that is the sum of `U::value` for all types `U` in `T...`.
|
||||
`mp_plus<>` is `mp_int<0>`.
|
||||
[endsect]
|
||||
|
||||
[endsect:function]
|
||||
|
@@ -6,9 +6,7 @@
|
||||
/ http://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:integer_sequence Integer Sequences, `<boost/integer_sequence.hpp>`]
|
||||
|
||||
The contents of this header are defined in namespace `boost`.
|
||||
[section:integer_sequence Integer Sequences, `<boost/mp11/integer_sequence.hpp>`]
|
||||
|
||||
[section `integer_sequence<T, I...>`]
|
||||
template<class T, T... I> struct integer_sequence
|
||||
|
@@ -6,9 +6,7 @@
|
||||
/ http://www.boost.org/LICENSE_1_0.txt)
|
||||
/]
|
||||
|
||||
[section:tuple_for_each A "for each" algorithm for tuple-like types, `<boost/tuple_for_each.hpp>`]
|
||||
|
||||
The contents of this header are defined in namespace `boost`.
|
||||
[section:tuple_for_each A "for each" algorithm for tuple-like types, `<boost/mp11/tuple_for_each.hpp>`]
|
||||
|
||||
[section `tuple_for_each`]
|
||||
template<class Tp, class F> constexpr F tuple_for_each(Tp&& tp, F&& f);
|
||||
|
@@ -16,5 +16,7 @@
|
||||
#include <boost/mp11/map.hpp>
|
||||
#include <boost/mp11/set.hpp>
|
||||
#include <boost/mp11/bind.hpp>
|
||||
#include <boost/mp11/integer_sequence.hpp>
|
||||
#include <boost/mp11/tuple_for_each.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_MP11_HPP_INCLUDED
|
||||
|
@@ -17,7 +17,7 @@
|
||||
#include <boost/mp11/detail/mp_plus.hpp>
|
||||
#include <boost/mp11/detail/mp_map_find.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
#include <boost/integer_sequence.hpp>
|
||||
#include <boost/mp11/integer_sequence.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <type_traits>
|
||||
@@ -499,7 +499,7 @@ namespace detail
|
||||
|
||||
template<class L, class V> struct mp_find_impl;
|
||||
|
||||
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
|
||||
#if defined( BOOST_CLANG ) && defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
|
||||
|
||||
struct mp_index_holder
|
||||
{
|
||||
@@ -589,7 +589,7 @@ namespace detail
|
||||
|
||||
template<class L, template<class...> class P> struct mp_find_if_impl;
|
||||
|
||||
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
|
||||
#if defined( BOOST_CLANG ) && defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
|
||||
|
||||
template<template<class...> class L, class... T, template<class...> class P> struct mp_find_if_impl<L<T...>, P>
|
||||
{
|
||||
|
@@ -21,7 +21,11 @@
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_CLANG) && defined(__has_cpp_attribute)
|
||||
#if defined(__cpp_fold_expressions) && __cpp_fold_expressions >= 201603
|
||||
|
||||
# define BOOST_MP11_HAS_FOLD_EXPRESSIONS
|
||||
|
||||
#elif defined(BOOST_CLANG) && defined(__has_cpp_attribute)
|
||||
# if __has_cpp_attribute(fallthrough) && __cplusplus >= 201406L // Clang 3.9+ in c++1z mode
|
||||
|
||||
# define BOOST_MP11_HAS_FOLD_EXPRESSIONS
|
||||
|
@@ -8,7 +8,8 @@
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
@@ -20,6 +21,16 @@ namespace mp11
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
|
||||
|
||||
template<class... T> struct mp_plus_impl
|
||||
{
|
||||
static const auto _v = (T::value + ... + 0);
|
||||
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<class... T> struct mp_plus_impl;
|
||||
|
||||
template<> struct mp_plus_impl<>
|
||||
@@ -27,18 +38,40 @@ template<> struct mp_plus_impl<>
|
||||
using type = std::integral_constant<int, 0>;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND( BOOST_GCC, < 40800 )
|
||||
|
||||
template<class T1, class... T> struct mp_plus_impl<T1, T...>
|
||||
{
|
||||
static const/*expr*/ auto _v = T1::value + mp_plus_impl<T...>::type::value;
|
||||
static const decltype(T1::value + mp_plus_impl<T...>::type::value) _v = T1::value + mp_plus_impl<T...>::type::value;
|
||||
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||
};
|
||||
|
||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T> struct mp_plus_impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>
|
||||
{
|
||||
static const/*expr*/ auto _v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value;
|
||||
static const
|
||||
decltype(T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value)
|
||||
_v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value;
|
||||
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<class T1, class... T> struct mp_plus_impl<T1, T...>
|
||||
{
|
||||
static const auto _v = T1::value + mp_plus_impl<T...>::type::value;
|
||||
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||
};
|
||||
|
||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T> struct mp_plus_impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>
|
||||
{
|
||||
static const auto _v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value;
|
||||
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_plus = typename detail::mp_plus_impl<T...>::type;
|
||||
|
@@ -12,6 +12,7 @@
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/mp11/detail/mp_list.hpp>
|
||||
#include <boost/mp11/detail/mp_count.hpp>
|
||||
#include <boost/mp11/detail/mp_plus.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
@@ -19,10 +20,22 @@ namespace boost
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_all<T...>
|
||||
template<class... T> using mp_all = mp_bool< mp_count_if< mp_list<T...>, mp_to_bool >::value == sizeof...(T) >;
|
||||
// mp_void<T...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class... T> struct mp_void_impl
|
||||
{
|
||||
using type = void;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_void = typename detail::mp_void_impl<T...>::type;
|
||||
|
||||
// mp_and<T...>
|
||||
#if BOOST_WORKAROUND( BOOST_MSVC, < 1910 )
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
@@ -30,7 +43,7 @@ template<class... T> struct mp_and_impl;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_and = typename detail::mp_and_impl<T...>::type;
|
||||
template<class... T> using mp_and = mp_to_bool< typename detail::mp_and_impl<T...>::type >;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
@@ -52,8 +65,41 @@ template<class T1, class... T> struct mp_and_impl<T1, T...>
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// mp_any<T...>
|
||||
template<class... T> using mp_any = mp_bool< mp_count_if< mp_list<T...>, mp_to_bool >::value != 0 >;
|
||||
#else
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class E = void> struct mp_and_impl
|
||||
{
|
||||
using type = mp_false;
|
||||
};
|
||||
|
||||
template<class... T> struct mp_and_impl< mp_list<T...>, mp_void<mp_if<T, void>...> >
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_and = typename detail::mp_and_impl<mp_list<T...>>::type;
|
||||
|
||||
#endif
|
||||
|
||||
// mp_all<T...>
|
||||
#if BOOST_WORKAROUND( BOOST_MSVC, <= 1910 ) || BOOST_WORKAROUND( BOOST_GCC, < 40800 )
|
||||
|
||||
template<class... T> using mp_all = mp_bool< mp_count_if< mp_list<T...>, mp_to_bool >::value == sizeof...(T) >;
|
||||
|
||||
#elif defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
|
||||
|
||||
template<class... T> using mp_all = mp_bool<(static_cast<bool>(T::value) && ...)>;
|
||||
|
||||
#else
|
||||
|
||||
template<class... T> using mp_all = mp_and<mp_to_bool<T>...>;
|
||||
|
||||
#endif
|
||||
|
||||
// mp_or<T...>
|
||||
namespace detail
|
||||
@@ -63,7 +109,7 @@ template<class... T> struct mp_or_impl;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_or = typename detail::mp_or_impl<T...>::type;
|
||||
template<class... T> using mp_or = mp_to_bool< typename detail::mp_or_impl<T...>::type >;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
@@ -85,6 +131,17 @@ template<class T1, class... T> struct mp_or_impl<T1, T...>
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// mp_any<T...>
|
||||
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS )
|
||||
|
||||
template<class... T> using mp_any = mp_bool<(static_cast<bool>(T::value) || ...)>;
|
||||
|
||||
#else
|
||||
|
||||
template<class... T> using mp_any = mp_bool< mp_count_if< mp_list<T...>, mp_to_bool >::value != 0 >;
|
||||
|
||||
#endif
|
||||
|
||||
// mp_same<T...>
|
||||
namespace detail
|
||||
{
|
||||
|
@@ -1,10 +1,19 @@
|
||||
#ifndef BOOST_INTEGER_SEQUENCE_HPP_INCLUDED
|
||||
#define BOOST_INTEGER_SEQUENCE_HPP_INCLUDED
|
||||
#ifndef BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED
|
||||
#define BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015, 2017 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// integer_sequence
|
||||
template<class T, T... I> struct integer_sequence
|
||||
@@ -82,6 +91,7 @@ template<std::size_t N> using make_index_sequence = make_integer_sequence<std::s
|
||||
// index_sequence_for
|
||||
template<class... T> using index_sequence_for = make_integer_sequence<std::size_t, sizeof...(T)>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_INTEGER_SEQUENCE_HPP_INCLUDED
|
||||
#endif // #ifndef BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED
|
@@ -1,7 +1,14 @@
|
||||
#ifndef BOOST_TUPLE_FOR_EACH_HPP_INCLUDED
|
||||
#define BOOST_TUPLE_FOR_EACH_HPP_INCLUDED
|
||||
#ifndef BOOST_MP11_TUPLE_FOR_EACH_HPP_INCLUDED
|
||||
#define BOOST_MP11_TUPLE_FOR_EACH_HPP_INCLUDED
|
||||
|
||||
#include <boost/integer_sequence.hpp>
|
||||
// Copyright 2015, 2017 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/integer_sequence.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <tuple>
|
||||
@@ -11,11 +18,13 @@
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class Tp, std::size_t... J, class F> BOOST_CONSTEXPR F tuple_for_each_impl( Tp && tp, boost::integer_sequence<std::size_t, J...>, F && f )
|
||||
template<class Tp, std::size_t... J, class F> BOOST_CONSTEXPR F tuple_for_each_impl( Tp && tp, integer_sequence<std::size_t, J...>, F && f )
|
||||
{
|
||||
using A = int[sizeof...(J)];
|
||||
return (void)A{ ((void)f(std::get<J>(std::forward<Tp>(tp))), 0)... }, std::forward<F>(f);
|
||||
@@ -23,7 +32,7 @@ template<class Tp, std::size_t... J, class F> BOOST_CONSTEXPR F tuple_for_each_i
|
||||
|
||||
#if BOOST_WORKAROUND( BOOST_MSVC, <= 1800 )
|
||||
|
||||
template<class Tp, class F> BOOST_CONSTEXPR F tuple_for_each_impl( Tp && tp, boost::integer_sequence<std::size_t>, F && f )
|
||||
template<class Tp, class F> BOOST_CONSTEXPR F tuple_for_each_impl( Tp && tp, integer_sequence<std::size_t>, F && f )
|
||||
{
|
||||
return std::forward<F>(f);
|
||||
}
|
||||
@@ -34,10 +43,11 @@ template<class Tp, class F> BOOST_CONSTEXPR F tuple_for_each_impl( Tp && tp, boo
|
||||
|
||||
template<class Tp, class F> BOOST_CONSTEXPR F tuple_for_each( Tp && tp, F && f )
|
||||
{
|
||||
using seq = boost::make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>;
|
||||
using seq = make_index_sequence<std::tuple_size<typename std::remove_reference<Tp>::type>::value>;
|
||||
return detail::tuple_for_each_impl( std::forward<Tp>(tp), seq(), std::forward<F>(f) );
|
||||
}
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_TUPLE_FOR_EACH_HPP_INCLUDED
|
@@ -103,6 +103,7 @@ run mp_and.cpp : : : $(REQ) ;
|
||||
run mp_any.cpp : : : $(REQ) ;
|
||||
run mp_or.cpp : : : $(REQ) ;
|
||||
run mp_same.cpp : : : $(REQ) ;
|
||||
run mp_plus.cpp : : : $(REQ) ;
|
||||
|
||||
# map
|
||||
run mp_map_find.cpp : : : $(REQ) ;
|
||||
|
@@ -7,47 +7,53 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
|
||||
#include <boost/integer_sequence.hpp>
|
||||
#include <boost/mp11/integer_sequence.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
int main()
|
||||
{
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<int, 0>, boost::integer_sequence<int>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<int, 1>, boost::integer_sequence<int, 0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<int, 2>, boost::integer_sequence<int, 0, 1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<int, 3>, boost::integer_sequence<int, 0, 1, 2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<int, 4>, boost::integer_sequence<int, 0, 1, 2, 3>>));
|
||||
using boost::mp11::integer_sequence;
|
||||
using boost::mp11::make_integer_sequence;
|
||||
using boost::mp11::index_sequence;
|
||||
using boost::mp11::make_index_sequence;
|
||||
using boost::mp11::index_sequence_for;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<char, 0>, boost::integer_sequence<char>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<char, 1>, boost::integer_sequence<char, 0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<char, 2>, boost::integer_sequence<char, 0, 1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<char, 3>, boost::integer_sequence<char, 0, 1, 2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<char, 4>, boost::integer_sequence<char, 0, 1, 2, 3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_integer_sequence<int, 0>, integer_sequence<int>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_integer_sequence<int, 1>, integer_sequence<int, 0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_integer_sequence<int, 2>, integer_sequence<int, 0, 1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_integer_sequence<int, 3>, integer_sequence<int, 0, 1, 2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_integer_sequence<int, 4>, integer_sequence<int, 0, 1, 2, 3>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<std::size_t, 0>, boost::integer_sequence<std::size_t>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<std::size_t, 1>, boost::integer_sequence<std::size_t, 0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<std::size_t, 2>, boost::integer_sequence<std::size_t, 0, 1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<std::size_t, 3>, boost::integer_sequence<std::size_t, 0, 1, 2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<std::size_t, 4>, boost::integer_sequence<std::size_t, 0, 1, 2, 3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_integer_sequence<char, 0>, integer_sequence<char>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_integer_sequence<char, 1>, integer_sequence<char, 0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_integer_sequence<char, 2>, integer_sequence<char, 0, 1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_integer_sequence<char, 3>, integer_sequence<char, 0, 1, 2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_integer_sequence<char, 4>, integer_sequence<char, 0, 1, 2, 3>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_index_sequence<0>, boost::integer_sequence<std::size_t>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_index_sequence<1>, boost::integer_sequence<std::size_t, 0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_index_sequence<2>, boost::integer_sequence<std::size_t, 0, 1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_index_sequence<3>, boost::integer_sequence<std::size_t, 0, 1, 2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_index_sequence<4>, boost::integer_sequence<std::size_t, 0, 1, 2, 3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_integer_sequence<std::size_t, 0>, integer_sequence<std::size_t>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_integer_sequence<std::size_t, 1>, integer_sequence<std::size_t, 0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_integer_sequence<std::size_t, 2>, integer_sequence<std::size_t, 0, 1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_integer_sequence<std::size_t, 3>, integer_sequence<std::size_t, 0, 1, 2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_integer_sequence<std::size_t, 4>, integer_sequence<std::size_t, 0, 1, 2, 3>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_index_sequence<0>, boost::index_sequence<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_index_sequence<1>, boost::index_sequence<0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_index_sequence<2>, boost::index_sequence<0, 1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_index_sequence<3>, boost::index_sequence<0, 1, 2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_index_sequence<4>, boost::index_sequence<0, 1, 2, 3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_index_sequence<0>, integer_sequence<std::size_t>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_index_sequence<1>, integer_sequence<std::size_t, 0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_index_sequence<2>, integer_sequence<std::size_t, 0, 1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_index_sequence<3>, integer_sequence<std::size_t, 0, 1, 2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_index_sequence<4>, integer_sequence<std::size_t, 0, 1, 2, 3>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::index_sequence_for<>, boost::index_sequence<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::index_sequence_for<void>, boost::index_sequence<0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::index_sequence_for<void, void>, boost::index_sequence<0, 1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::index_sequence_for<void, void, void>, boost::index_sequence<0, 1, 2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::index_sequence_for<void, void, void, void>, boost::index_sequence<0, 1, 2, 3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_index_sequence<0>, index_sequence<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_index_sequence<1>, index_sequence<0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_index_sequence<2>, index_sequence<0, 1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_index_sequence<3>, index_sequence<0, 1, 2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<make_index_sequence<4>, index_sequence<0, 1, 2, 3>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<index_sequence_for<>, index_sequence<>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<index_sequence_for<void>, index_sequence<0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<index_sequence_for<void, void>, index_sequence<0, 1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<index_sequence_for<void, void, void>, index_sequence<0, 1, 2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<index_sequence_for<void, void, void, void>, index_sequence<0, 1, 2, 3>>));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
@@ -25,23 +25,23 @@ int main()
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_false>, mp_false>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<-7>>, mp_int<-7>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<0>>, mp_int<0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<-7>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<0>>, mp_false>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<7>>, mp_size_t<7>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<0>>, mp_size_t<0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<7>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<0>>, mp_false>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true, mp_true>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true, mp_false>, mp_false>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_false, void>, mp_false>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<-4>, mp_int<5>>, mp_int<5>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<-4>, mp_int<0>>, mp_int<0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<0>, void>, mp_int<0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<-4>, mp_int<5>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<-4>, mp_int<0>>, mp_false>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<0>, void>, mp_false>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<7>, mp_size_t<8>>, mp_size_t<8>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<7>, mp_size_t<0>>, mp_size_t<0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<0>, void>, mp_size_t<0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<7>, mp_size_t<8>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<7>, mp_size_t<0>>, mp_false>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<0>, void>, mp_false>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true, mp_true, mp_true>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true, mp_true, mp_false>, mp_false>));
|
||||
@@ -54,11 +54,11 @@ int main()
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true, mp_false, void, void>, mp_false>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_false, void, void, void>, mp_false>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<1>, mp_int<2>, mp_int<-11>, mp_int<14>>, mp_int<14>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<1>, mp_int<0>, void, void>, mp_int<0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<1>, mp_int<2>, mp_int<-11>, mp_int<14>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<1>, mp_int<0>, void, void>, mp_false>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<1>, mp_size_t<2>, mp_size_t<114>, mp_size_t<8>, mp_size_t<94>>, mp_size_t<94>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<1>, mp_size_t<2>, mp_size_t<0>, void, void>, mp_size_t<0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<1>, mp_size_t<2>, mp_size_t<114>, mp_size_t<8>, mp_size_t<94>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<1>, mp_size_t<2>, mp_size_t<0>, void, void>, mp_false>));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
@@ -23,16 +23,8 @@ struct X4 {};
|
||||
|
||||
template<class T1, class T2> struct F {};
|
||||
|
||||
#if BOOST_WORKAROUND( BOOST_GCC, < 40800 )
|
||||
|
||||
template<class A, class B> using mp_plus = std::integral_constant<typename std::remove_const<decltype( A::value + B::value )>::type, A::value + B::value>;
|
||||
|
||||
#else
|
||||
|
||||
using boost::mp11::mp_plus;
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_list;
|
||||
|
@@ -25,23 +25,23 @@ int main()
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_true>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false>, mp_false>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<-7>>, mp_int<-7>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>>, mp_int<0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<-7>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>>, mp_false>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<7>>, mp_size_t<7>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>>, mp_size_t<0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<7>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>>, mp_false>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_true, void>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_true>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_false>, mp_false>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>>, mp_int<0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<5>>, mp_int<5>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<-4>, void>, mp_int<-4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>>, mp_false>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<5>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<-4>, void>, mp_true>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<7>, void>, mp_size_t<7>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<4>>, mp_size_t<4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>>, mp_size_t<0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<7>, void>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<4>>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>>, mp_false>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_true, void, void>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_true, void>, mp_true>));
|
||||
@@ -54,19 +54,19 @@ int main()
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_false, mp_false, mp_true>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_false, mp_false, mp_false>, mp_false>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<1>, void, void, void>, mp_int<1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<2>, void, void, void>, mp_int<2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>, mp_int<3>, void, void, void>, mp_int<3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>, mp_int<0>, mp_int<4>, void, void, void>, mp_int<4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>, mp_int<0>, mp_int<0>, mp_int<0>>, mp_int<0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<1>, void, void, void>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<2>, void, void, void>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>, mp_int<3>, void, void, void>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>, mp_int<0>, mp_int<4>, void, void, void>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>, mp_int<0>, mp_int<0>, mp_int<0>>, mp_false>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<1>, void, void, void>, mp_size_t<1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<2>, void, void, void>, mp_size_t<2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>, mp_size_t<3>, void, void, void>, mp_size_t<3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>, mp_size_t<0>, mp_size_t<4>, void, void, void>, mp_size_t<4>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>, mp_size_t<0>, mp_size_t<0>, mp_size_t<0>>, mp_size_t<0>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<1>, void, void, void>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<2>, void, void, void>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>, mp_size_t<3>, void, void, void>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>, mp_size_t<0>, mp_size_t<4>, void, void, void>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>, mp_size_t<0>, mp_size_t<0>, mp_size_t<0>>, mp_false>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_int<0>, mp_false, mp_size_t<141>, void, void, void>, mp_size_t<141>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_int<0>, mp_false, mp_size_t<141>, void, void, void>, mp_true>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_int<0>, mp_false>, mp_false>));
|
||||
|
||||
return boost::report_errors();
|
||||
|
32
test/mp_plus.cpp
Normal file
32
test/mp_plus.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
// Copyright 2015-2017 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
|
||||
#include <boost/mp11/function.hpp>
|
||||
#include <boost/core/lightweight_test_trait.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
template<class T, T N> using integral = std::integral_constant<T, N>;
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_plus;
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_plus<>, integral<int, 0>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_plus<integral<char, 1>>, integral<int, 1>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_plus<integral<short, 2>>, integral<int, 2>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_plus<integral<int, 3>>, integral<int, 3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_plus<integral<unsigned, 4>>, integral<unsigned, 4>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_plus<integral<char, 1>, integral<char, 2>>, integral<int, 3>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_plus<integral<short, 1>, integral<short, 2>, integral<short, 3>>, integral<int, 6>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_plus<integral<int, 1>, integral<int, 2>, integral<int, 3>, integral<long, 4>>, integral<long, 10>>));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@@ -29,16 +29,8 @@ struct X10 {};
|
||||
struct X11 {};
|
||||
struct X12 {};
|
||||
|
||||
#if BOOST_WORKAROUND( BOOST_GCC, < 40800 )
|
||||
|
||||
template<class A, class B> using mp_plus = std::integral_constant<typename std::remove_const<decltype( A::value + B::value )>::type, A::value + B::value>;
|
||||
|
||||
#else
|
||||
|
||||
using boost::mp11::mp_plus;
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_list;
|
||||
|
@@ -29,16 +29,8 @@ using boost::mp11::mp_push_front;
|
||||
template<class T, class L> using rev_push_back = mp_push_back<L, T>;
|
||||
template<class T, class L> using rev_push_front = mp_push_front<L, T>;
|
||||
|
||||
#if BOOST_WORKAROUND( BOOST_GCC, < 40800 )
|
||||
|
||||
template<class A, class B> using mp_plus = std::integral_constant<typename std::remove_const<decltype( A::value + B::value )>::type, A::value + B::value>;
|
||||
|
||||
#else
|
||||
|
||||
using boost::mp11::mp_plus;
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::mp_list;
|
||||
|
@@ -7,7 +7,7 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
|
||||
#include <boost/tuple_for_each.hpp>
|
||||
#include <boost/mp11/tuple_for_each.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <tuple>
|
||||
#include <memory>
|
||||
@@ -16,13 +16,15 @@
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mp11::tuple_for_each;
|
||||
|
||||
{
|
||||
std::tuple<int, short, char> tp{ 1, 2, 3 };
|
||||
|
||||
{
|
||||
int s = 0;
|
||||
|
||||
boost::tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
|
||||
tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
|
||||
|
||||
BOOST_TEST_EQ( s, 123 );
|
||||
}
|
||||
@@ -30,7 +32,7 @@ int main()
|
||||
{
|
||||
int s = 0;
|
||||
|
||||
boost::tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
|
||||
tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
|
||||
|
||||
BOOST_TEST_EQ( s, 123 );
|
||||
}
|
||||
@@ -44,7 +46,7 @@ int main()
|
||||
|
||||
int s = 0;
|
||||
|
||||
boost::tuple_for_each( std::move(tp), [&]( std::unique_ptr<int> p ){ s = s * 10 + *p; } );
|
||||
tuple_for_each( std::move(tp), [&]( std::unique_ptr<int> p ){ s = s * 10 + *p; } );
|
||||
|
||||
BOOST_TEST_EQ( s, 123 );
|
||||
}
|
||||
@@ -57,7 +59,7 @@ int main()
|
||||
{
|
||||
int s = 0;
|
||||
|
||||
boost::tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
|
||||
tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
|
||||
|
||||
BOOST_TEST_EQ( s, 12 );
|
||||
}
|
||||
@@ -65,7 +67,7 @@ int main()
|
||||
{
|
||||
int s = 0;
|
||||
|
||||
boost::tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
|
||||
tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
|
||||
|
||||
BOOST_TEST_EQ( s, 12 );
|
||||
}
|
||||
@@ -77,7 +79,7 @@ int main()
|
||||
{
|
||||
int s = 0;
|
||||
|
||||
boost::tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
|
||||
tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } );
|
||||
|
||||
BOOST_TEST_EQ( s, 123 );
|
||||
}
|
||||
@@ -85,7 +87,7 @@ int main()
|
||||
{
|
||||
int s = 0;
|
||||
|
||||
boost::tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
|
||||
tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } );
|
||||
|
||||
BOOST_TEST_EQ( s, 123 );
|
||||
}
|
||||
@@ -94,15 +96,15 @@ int main()
|
||||
{
|
||||
std::tuple<> tp;
|
||||
|
||||
BOOST_TEST_EQ( boost::tuple_for_each( tp, 11 ), 11 );
|
||||
BOOST_TEST_EQ( boost::tuple_for_each( std::move( tp ), 12 ), 12 );
|
||||
BOOST_TEST_EQ( tuple_for_each( tp, 11 ), 11 );
|
||||
BOOST_TEST_EQ( tuple_for_each( std::move( tp ), 12 ), 12 );
|
||||
}
|
||||
|
||||
{
|
||||
std::array<int, 0> tp;
|
||||
|
||||
BOOST_TEST_EQ( boost::tuple_for_each( tp, 11 ), 11 );
|
||||
BOOST_TEST_EQ( boost::tuple_for_each( std::move( tp ), 12 ), 12 );
|
||||
BOOST_TEST_EQ( tuple_for_each( tp, 11 ), 11 );
|
||||
BOOST_TEST_EQ( tuple_for_each( std::move( tp ), 12 ), 12 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
|
@@ -6,7 +6,7 @@
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/tuple_for_each.hpp>
|
||||
#include <boost/mp11/tuple_for_each.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
// Technically std::tuple isn't constexpr enabled in C++11, but it works with libstdc++
|
||||
@@ -33,7 +33,7 @@ int main()
|
||||
{
|
||||
{
|
||||
constexpr std::tuple<int, short, char> tp{ 1, 2, 3 };
|
||||
constexpr auto r = boost::tuple_for_each( tp, assert_is_integral() );
|
||||
constexpr auto r = boost::mp11::tuple_for_each( tp, assert_is_integral() );
|
||||
(void)r;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ int main()
|
||||
|
||||
{
|
||||
constexpr std::tuple<> tp;
|
||||
constexpr auto r = boost::tuple_for_each( tp, 11 );
|
||||
constexpr auto r = boost::mp11::tuple_for_each( tp, 11 );
|
||||
static_assert( r == 11, "r == 11" );
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user