1
0
forked from boostorg/mp11

Merge branch 'develop'

This commit is contained in:
Peter Dimov
2017-05-24 06:38:16 +03:00
24 changed files with 450 additions and 201 deletions

View File

@@ -2,7 +2,7 @@
For background, please see the article ["Simple C++11 metaprogramming"](http://pdimov.com/cpp2/simple_cxx11_metaprogramming.html). 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: Supported compilers:

View File

@@ -166,11 +166,13 @@
</dl></dd> </dl></dd>
<dt><span class="section"><a href="mp11.html#mp11.reference.function">Helper Metafunctions, <code class="computeroutput"><span class="special">&lt;</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">&gt;</span></code></a></span></dt> <dt><span class="section"><a href="mp11.html#mp11.reference.function">Helper Metafunctions, <code class="computeroutput"><span class="special">&lt;</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">&gt;</span></code></a></span></dt>
<dd><dl> <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">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</span></code></a></span></dt>
</dl></dd> </dl></dd>
<dt><span class="section"><a href="mp11.html#mp11.reference.bind">Bind, <code class="computeroutput"><span class="special">&lt;</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">&gt;</span></code></a></span></dt> <dt><span class="section"><a href="mp11.html#mp11.reference.bind">Bind, <code class="computeroutput"><span class="special">&lt;</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">&gt;</span></code></a></span></dt>
<dd><dl> <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">&lt;</span><span class="identifier">Q</span><span class="special">,</span> <span class="identifier">T</span><span class="special">...&gt;</span></code></a></span></dt> <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">&lt;</span><span class="identifier">Q</span><span class="special">,</span> <span class="identifier">T</span><span class="special">...&gt;</span></code></a></span></dt>
</dl></dd> </dl></dd>
<dt><span class="section"><a href="mp11.html#mp11.reference.integer_sequence">Integer Sequences, <dt><span class="section"><a href="mp11.html#mp11.reference.integer_sequence">Integer Sequences,
<code class="computeroutput"><span class="special">&lt;</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">&gt;</span></code></a></span></dt> <code class="computeroutput"><span class="special">&lt;</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">&gt;</span></code></a></span></dt>
<dd><dl> <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">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">I</span><span class="special">...&gt;</span></code></a></span></dt> <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">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">I</span><span class="special">...&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">N</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">N</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</span></code></a></span></dt> <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">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</span></code></a></span></dt>
</dl></dd> </dl></dd>
<dt><span class="section"><a href="mp11.html#mp11.reference.tuple_for_each">A "for each" <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">&lt;</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">&gt;</span></code></a></span></dt> algorithm for tuple-like types, <code class="computeroutput"><span class="special">&lt;</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">&gt;</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> <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></dd>
</dl> </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">&lt;</span><span class="identifier">T</span><span class="special">,</span> Let's suppose that we have written a metafunction <code class="computeroutput"><span class="identifier">result</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span>
<span class="identifier">U</span><span class="special">&gt;</span></code>: <span class="identifier">U</span><span class="special">&gt;</span></code>:
</p> </p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;;</span> <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">type</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</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">&gt;</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">&lt;</span><span class="identifier">promote</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;,</span> <span class="identifier">promote</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;&gt;;</span> <span class="keyword">template</span><span class="special">&lt;</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">&gt;</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">&lt;</span><span class="identifier">promote</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;,</span> <span class="identifier">promote</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;&gt;::</span><span class="identifier">type</span><span class="special">;</span>
</pre> </pre>
<p> <p>
that ought to represent the result of an arithmetic operation on the integer 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: worst of all, boring. This is how we can leverage Mp11 to automate the task:
</p> </p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span> <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span> <span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">type_traits</span><span class="special">&gt;</span> <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">type_traits</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span> <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</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="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="special">}</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;;</span> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">type</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</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">&gt;</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">&lt;</span><span class="identifier">promote</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;,</span> <span class="identifier">promote</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;&gt;;</span> <span class="keyword">template</span><span class="special">&lt;</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">&gt;</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">&lt;</span><span class="identifier">promote</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;,</span> <span class="identifier">promote</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;&gt;::</span><span class="identifier">type</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</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">&gt;</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">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">)</span> <span class="keyword">template</span><span class="special">&lt;</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">&gt;</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">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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="keyword">int</span> <span class="identifier">main</span><span class="special">()</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">&lt;</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">&gt;;</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">&lt;</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">&gt;;</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">&lt;</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">&gt;(),</span> <span class="special">[](</span><span class="keyword">auto</span><span class="special">&amp;&amp;</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">&lt;</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">&gt;(),</span> <span class="special">[](</span><span class="keyword">auto</span><span class="special">&amp;&amp;</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> <span class="special">}</span>
</pre> </pre>
<p> <p>
@@ -397,11 +398,33 @@
<p> <p>
We then default-construct this tuple and pass it to <code class="computeroutput"><span class="identifier">tuple_for_each</span></code>. 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> <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 for every tuple element; we use a (C++14) lambda that calls <code class="computeroutput"><span class="identifier">test_result</span></code>.
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> </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">&amp;&amp;</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">&lt;</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">&gt;</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="identifier">mp_list</span><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">&gt;;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special">&lt;</span><span class="identifier">T3</span><span class="special">,</span> <span class="identifier">T4</span><span class="special">&gt;::</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">&lt;&lt;</span> <span class="identifier">name</span><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">&gt;()</span> <span class="special">&lt;&lt;</span> <span class="string">" + "</span> <span class="special">&lt;&lt;</span> <span class="identifier">name</span><span class="special">&lt;</span><span class="identifier">T2</span><span class="special">&gt;()</span> <span class="special">&lt;&lt;</span> <span class="string">" -&gt; "</span> <span class="special">&lt;&lt;</span> <span class="identifier">name</span><span class="special">&lt;</span><span class="identifier">T3</span><span class="special">&gt;()</span> <span class="special">&lt;&lt;</span> <span class="string">", result: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">name</span><span class="special">&lt;</span><span class="identifier">T4</span><span class="special">&gt;()</span> <span class="special">&lt;&lt;</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">&lt;</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">&gt;;</span>
<span class="identifier">tuple_for_each</span><span class="special">(</span> <span class="identifier">mp_product</span><span class="special">&lt;</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">&gt;(),</span> <span class="identifier">test_result</span><span class="special">()</span> <span class="special">);</span>
<span class="special">}</span>
</pre>
</div> </div>
<div class="section"> <div class="section">
<div class="titlepage"><div><div><h3 class="title"> <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> 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: to each pair of elements and gathers the results into a tuple:
</p> </p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</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">&gt;</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">&lt;</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">&gt;;</span> <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">...&gt;::</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">&lt;</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">&gt;</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">&lt;</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">&gt;;</span>
</pre> </pre>
<p> <p>
then specialize <code class="computeroutput"><span class="identifier">common_type</span></code> 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">&gt;</span></code> <span class="identifier">E2</span><span class="special">,</span> <span class="identifier">E3</span><span class="special">&gt;</span></code>
and <code class="computeroutput"><span class="identifier">expected</span><span class="special">&lt;</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> and <code class="computeroutput"><span class="identifier">expected</span><span class="special">&lt;</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">&gt;</span></code> <span class="identifier">E5</span><span class="special">&gt;</span></code>
is <code class="computeroutput"><span class="identifier">expected</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">common_type_t</span><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">&gt;,</span> is <code class="computeroutput"><span class="identifier">expected</span><span class="special">&lt;</span><span class="identifier">common_type_t</span><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">&gt;,</span> <span class="identifier">E1</span><span class="special">,</span> <span class="identifier">E2</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">E3</span><span class="special">,</span> <span class="identifier">E4</span><span class="special">,</span> <span class="identifier">E5</span><span class="special">&gt;</span></code>. That is, the possible return values
<span class="identifier">E5</span><span class="special">&gt;</span></code>. are combined into their common type, and we take the union of the set of
That is, the possible return values are combined into their common type, error types.
and we take the union of the set of error types.
</p> </p>
<p> <p>
Therefore, Therefore,
</p> </p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</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">&gt;</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">&lt;</span><span class="identifier">mp_push_front</span><span class="special">&lt;</span><span class="identifier">mp_unique</span><span class="special">&lt;</span><span class="identifier">mp_append</span><span class="special">&lt;</span><span class="identifier">E1</span><span class="special">,</span> <span class="identifier">E2</span><span class="special">&gt;&gt;,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">common_type_t</span><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">&gt;&gt;,</span> <span class="identifier">expected</span><span class="special">&gt;;</span> <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</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">&gt;</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">&lt;</span><span class="identifier">mp_push_front</span><span class="special">&lt;</span><span class="identifier">mp_unique</span><span class="special">&lt;</span><span class="identifier">mp_append</span><span class="special">&lt;</span><span class="identifier">E1</span><span class="special">,</span> <span class="identifier">E2</span><span class="special">&gt;&gt;,</span> <span class="identifier">common_type_t</span><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">&gt;&gt;,</span> <span class="identifier">expected</span><span class="special">&gt;;</span>
<span class="keyword">namespace</span> <span class="identifier">std</span> <span class="keyword">namespace</span> <span class="identifier">std</span>
<span class="special">{</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">&lt;</span><span class="identifier">mp_append</span><span class="special">&lt;</span><span class="identifier">E1</span><span class="special">,</span> <span class="identifier">E2</span><span class="special">&gt;&gt;</span></code> This makes our job easier. <code class="computeroutput"><span class="identifier">mp_unique</span><span class="special">&lt;</span><span class="identifier">mp_append</span><span class="special">&lt;</span><span class="identifier">E1</span><span class="special">,</span> <span class="identifier">E2</span><span class="special">&gt;&gt;</span></code>
gives us the concatenation of <code class="computeroutput"><span class="identifier">E1</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 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">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">&gt;</span></code> removed; we then add <code class="computeroutput"><span class="identifier">common_type_t</span><span class="special">&lt;</span><span class="identifier">T1</span><span class="special">,</span> <span class="identifier">T2</span><span class="special">&gt;</span></code>
to the front via <code class="computeroutput"><span class="identifier">mp_push_front</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> 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 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> <a name="mp11.reference"></a><a class="link" href="mp11.html#mp11.reference" title="Reference">Reference</a>
</h2></div></div></div> </h2></div></div></div>
<p> <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 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>.
specified otherwise.
</p> </p>
<div class="section"> <div class="section">
<div class="titlepage"><div><div><h3 class="title"> <div class="titlepage"><div><div><h3 class="title">
@@ -2137,19 +2160,36 @@
</h3></div></div></div> </h3></div></div></div>
<div class="section"> <div class="section">
<div class="titlepage"><div><div><h4 class="title"> <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&lt;T...&gt;"><code class="computeroutput"><span class="identifier">mp_void</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</span></code></a>
</h4></div></div></div>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">T</span><span class="special">&gt;</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&lt;T...&gt;"><code class="computeroutput"><span class="identifier">mp_and</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</span></code></a> <a name="mp11.reference.function.mp_and_t"></a><a class="link" href="mp11.html#mp11.reference.function.mp_and_t" title="mp_and&lt;T...&gt;"><code class="computeroutput"><span class="identifier">mp_and</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</span></code></a>
</h4></div></div></div> </h4></div></div></div>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">T</span><span class="special">&gt;</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 class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">T</span><span class="special">&gt;</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> </pre>
<p> <p>
<code class="computeroutput"><span class="identifier">mp_and</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</span></code> <code class="computeroutput"><span class="identifier">mp_and</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</span></code>
is an alias for the first type <code class="computeroutput"><span class="identifier">U</span></code> applies <code class="computeroutput"><span class="identifier">mp_to_bool</span></code> to the
in <code class="computeroutput"><span class="identifier">T</span><span class="special">...</span></code> types 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">&lt;</span><span class="identifier">U</span><span class="special">&gt;</span></code> in order. If the result of an application is <code class="computeroutput"><span class="identifier">mp_false</span></code>,
is <code class="computeroutput"><span class="identifier">mp_false</span></code>. If no such <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
type exists, the last one is returned. <code class="computeroutput"><span class="identifier">mp_and</span><span class="special">&lt;&gt;</span></code> is <code class="computeroutput"><span class="identifier">mp_true</span></code>. substitution failure, returns <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">conjunction</span></code> in C++17. 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">&lt;&gt;</span></code>
is <code class="computeroutput"><span class="identifier">mp_true</span></code>.
</p> </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">&lt;</span><span class="identifier">mp_true</span><span class="special">,</span> <span class="identifier">mp_true</span><span class="special">&gt;;</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">&lt;</span><span class="identifier">mp_false</span><span class="special">,</span> <span class="keyword">void</span><span class="special">&gt;;</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">&lt;</span><span class="identifier">mp_false</span><span class="special">,</span> <span class="identifier">mp_false</span><span class="special">&gt;;</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">&lt;</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">mp_true</span><span class="special">&gt;;</span> <span class="comment">// mp_false (!)</span>
</pre>
</div> </div>
<div class="section"> <div class="section">
<div class="titlepage"><div><div><h4 class="title"> <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 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>. 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> 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> </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">&lt;</span><span class="identifier">mp_true</span><span class="special">,</span> <span class="identifier">mp_true</span><span class="special">&gt;;</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">&lt;</span><span class="identifier">mp_false</span><span class="special">,</span> <span class="keyword">void</span><span class="special">&gt;;</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">&lt;</span><span class="identifier">mp_false</span><span class="special">,</span> <span class="identifier">mp_false</span><span class="special">&gt;;</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">&lt;</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">mp_true</span><span class="special">&gt;;</span> <span class="comment">// compile-time error</span>
</pre>
</div> </div>
<div class="section"> <div class="section">
<div class="titlepage"><div><div><h4 class="title"> <div class="titlepage"><div><div><h4 class="title">
@@ -2179,13 +2224,18 @@
</pre> </pre>
<p> <p>
<code class="computeroutput"><span class="identifier">mp_or</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</span></code> <code class="computeroutput"><span class="identifier">mp_or</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</span></code>
is an alias for the first type <code class="computeroutput"><span class="identifier">U</span></code> applies <code class="computeroutput"><span class="identifier">mp_to_bool</span></code> to the
in <code class="computeroutput"><span class="identifier">T</span><span class="special">...</span></code> types 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">&lt;</span><span class="identifier">U</span><span class="special">&gt;</span></code> in order. If the result of an application is <code class="computeroutput"><span class="identifier">mp_true</span></code>,
is <code class="computeroutput"><span class="identifier">mp_true</span></code>. If no such <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>.
type exists, the last one is returned. <code class="computeroutput"><span class="identifier">mp_or</span><span class="special">&lt;&gt;</span></code> is <code class="computeroutput"><span class="identifier">mp_false</span></code>. <code class="computeroutput"><span class="identifier">mp_or</span><span class="special">&lt;&gt;</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. is <code class="computeroutput"><span class="identifier">mp_false</span></code>.
</p> </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">&lt;</span><span class="identifier">mp_true</span><span class="special">,</span> <span class="identifier">mp_false</span><span class="special">&gt;;</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">&lt;</span><span class="identifier">mp_true</span><span class="special">,</span> <span class="keyword">void</span><span class="special">&gt;;</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">&lt;</span><span class="identifier">mp_false</span><span class="special">,</span> <span class="identifier">mp_false</span><span class="special">&gt;;</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">&lt;</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">mp_true</span><span class="special">&gt;;</span> <span class="comment">// compile-time error</span>
</pre>
</div> </div>
<div class="section"> <div class="section">
<div class="titlepage"><div><div><h4 class="title"> <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>, otherwise. Same as <code class="computeroutput"><span class="identifier">mp_or</span></code>,
but does not perform short-circuit evaluation. but does not perform short-circuit evaluation.
</p> </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">&lt;</span><span class="identifier">mp_true</span><span class="special">,</span> <span class="identifier">mp_false</span><span class="special">&gt;;</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">&lt;</span><span class="identifier">mp_true</span><span class="special">,</span> <span class="keyword">void</span><span class="special">&gt;;</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">&lt;</span><span class="identifier">mp_false</span><span class="special">,</span> <span class="identifier">mp_false</span><span class="special">&gt;;</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">&lt;</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">mp_true</span><span class="special">&gt;;</span> <span class="comment">// compile-time error</span>
</pre>
</div> </div>
<div class="section"> <div class="section">
<div class="titlepage"><div><div><h4 class="title"> <div class="titlepage"><div><div><h4 class="title">
@@ -2217,6 +2272,20 @@
is <code class="computeroutput"><span class="identifier">mp_true</span></code>. is <code class="computeroutput"><span class="identifier">mp_true</span></code>.
</p> </p>
</div> </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&lt;T...&gt;"><code class="computeroutput"><span class="identifier">mp_plus</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</span></code></a>
</h4></div></div></div>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</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">&lt;&gt;</span></code>
is <code class="computeroutput"><span class="identifier">mp_int</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;</span></code>.
</p>
</div>
</div> </div>
<div class="section"> <div class="section">
<div class="titlepage"><div><div><h3 class="title"> <div class="titlepage"><div><div><h3 class="title">
@@ -2332,12 +2401,9 @@
</div> </div>
<div class="section"> <div class="section">
<div class="titlepage"><div><div><h3 class="title"> <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, &lt;boost/integer_sequence.hpp&gt;">Integer Sequences, <a name="mp11.reference.integer_sequence"></a><a class="link" href="mp11.html#mp11.reference.integer_sequence" title="Integer Sequences, &lt;boost/mp11/integer_sequence.hpp&gt;">Integer Sequences,
<code class="computeroutput"><span class="special">&lt;</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">&gt;</span></code></a> <code class="computeroutput"><span class="special">&lt;</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">&gt;</span></code></a>
</h3></div></div></div> </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="section">
<div class="titlepage"><div><div><h4 class="title"> <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&lt;T, I...&gt;"><code class="computeroutput"><span class="identifier">integer_sequence</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">I</span><span class="special">...&gt;</span></code></a> <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&lt;T, I...&gt;"><code class="computeroutput"><span class="identifier">integer_sequence</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">I</span><span class="special">...&gt;</span></code></a>
@@ -2401,12 +2467,9 @@
</div> </div>
<div class="section"> <div class="section">
<div class="titlepage"><div><div><h3 class="title"> <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, &lt;boost/tuple_for_each.hpp&gt;'>A "for each" <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, &lt;boost/mp11/tuple_for_each.hpp&gt;'>A "for each"
algorithm for tuple-like types, <code class="computeroutput"><span class="special">&lt;</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">&gt;</span></code></a> algorithm for tuple-like types, <code class="computeroutput"><span class="special">&lt;</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">&gt;</span></code></a>
</h3></div></div></div> </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="section">
<div class="titlepage"><div><div><h4 class="title"> <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> <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>
</div> </div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> <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> <td align="right"><div class="copyright-footer"></div></td>
</tr></table> </tr></table>
<hr> <hr>

View File

@@ -29,7 +29,7 @@
[section Reference] [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/integral.qbk]
[include mp11/list.qbk] [include mp11/list.qbk]

View File

@@ -12,8 +12,8 @@
Let's suppose that we have written a metafunction `result<T, U>`: 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> using promote = typename std::common_type<T, int>::type;
template<class T, class U> using result = std::common_type_t<promote<T>, promote<U>>; 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`, 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 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: how we can leverage Mp11 to automate the task:
#include <boost/mp11.hpp> #include <boost/mp11.hpp>
#include <boost/tuple_for_each.hpp>
#include <boost/core/demangle.hpp> #include <boost/core/demangle.hpp>
#include <type_traits> #include <type_traits>
#include <iostream> #include <iostream>
@@ -55,8 +54,8 @@ how we can leverage Mp11 to automate the task:
return boost::core::demangle( typeid(T).name() ); return boost::core::demangle( typeid(T).name() );
} }
template<class T> using promote = std::common_type_t<T, int>; template<class T> using promote = typename std::common_type<T, int>::type;
template<class T, class U> using result = std::common_type_t<promote<T>, promote<U>>; 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& ) 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() int main()
{ {
using L = std::tuple<char, short, int, unsigned, long, unsigned long>; 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? 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>>`. `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 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 tuple element; we use a (C++14) lambda that calls `test_result`.
function object with a templated `operator()` and pass that to `tuple_for_each` directly.)
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] [endsect]
[section Writing `common_type` specializations] [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 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: 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: 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`, 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 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. combined into their common type, and we take the union of the set of error types.
Therefore, 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 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 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 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`. to `expected`.
[endsect] [endsect]
@@ -192,10 +214,10 @@ trying to concatenate tuples containing move-only elements such as `unique_ptr`
Trying to concatenate `const` tuples fails: Trying to concatenate `const` tuples fails:
std::tuple<int> const t1; std::tuple<int> const t1;
std::tuple<float> const t2; 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 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 that support `tuple_size`, `tuple_element`, and `get`), while our implementation only works with `tuple` and

View File

@@ -8,11 +8,23 @@
[section:function Helper Metafunctions, `<boost/mp11/function.hpp>`] [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...>`] [section `mp_and<T...>`]
template<class... T> using mp_and = /*...*/; 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`. `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`
If no such type exists, the last one is returned. `mp_and<>` is `mp_true`. Similar to `std::conjunction` in C++17. 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] [endsect]
[section `mp_all<T...>`] [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_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>` `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] [endsect]
[section `mp_or<T...>`] [section `mp_or<T...>`]
template<class... T> using mp_or = /*...*/; 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`. `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`
If no such type exists, the last one is returned. `mp_or<>` is `mp_false`. Similar to `std::disjunction` in C++17. 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] [endsect]
[section `mp_any<T...>`] [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_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. `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] [endsect]
[section `mp_same<T...>`] [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`. `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] [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] [endsect:function]

View File

@@ -6,9 +6,7 @@
/ http://www.boost.org/LICENSE_1_0.txt) / http://www.boost.org/LICENSE_1_0.txt)
/] /]
[section:integer_sequence Integer Sequences, `<boost/integer_sequence.hpp>`] [section:integer_sequence Integer Sequences, `<boost/mp11/integer_sequence.hpp>`]
The contents of this header are defined in namespace `boost`.
[section `integer_sequence<T, I...>`] [section `integer_sequence<T, I...>`]
template<class T, T... I> struct integer_sequence template<class T, T... I> struct integer_sequence

View File

@@ -6,9 +6,7 @@
/ http://www.boost.org/LICENSE_1_0.txt) / 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>`] [section:tuple_for_each A "for each" algorithm for tuple-like types, `<boost/mp11/tuple_for_each.hpp>`]
The contents of this header are defined in namespace `boost`.
[section `tuple_for_each`] [section `tuple_for_each`]
template<class Tp, class F> constexpr F tuple_for_each(Tp&& tp, F&& f); template<class Tp, class F> constexpr F tuple_for_each(Tp&& tp, F&& f);

View File

@@ -16,5 +16,7 @@
#include <boost/mp11/map.hpp> #include <boost/mp11/map.hpp>
#include <boost/mp11/set.hpp> #include <boost/mp11/set.hpp>
#include <boost/mp11/bind.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 #endif // #ifndef BOOST_MP11_HPP_INCLUDED

View File

@@ -17,7 +17,7 @@
#include <boost/mp11/detail/mp_plus.hpp> #include <boost/mp11/detail/mp_plus.hpp>
#include <boost/mp11/detail/mp_map_find.hpp> #include <boost/mp11/detail/mp_map_find.hpp>
#include <boost/mp11/detail/config.hpp> #include <boost/mp11/detail/config.hpp>
#include <boost/integer_sequence.hpp> #include <boost/mp11/integer_sequence.hpp>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/detail/workaround.hpp> #include <boost/detail/workaround.hpp>
#include <type_traits> #include <type_traits>
@@ -499,7 +499,7 @@ namespace detail
template<class L, class V> struct mp_find_impl; 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 struct mp_index_holder
{ {
@@ -589,7 +589,7 @@ namespace detail
template<class L, template<class...> class P> struct mp_find_if_impl; 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> template<template<class...> class L, class... T, template<class...> class P> struct mp_find_if_impl<L<T...>, P>
{ {

View File

@@ -21,7 +21,11 @@
#endif #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 # if __has_cpp_attribute(fallthrough) && __cplusplus >= 201406L // Clang 3.9+ in c++1z mode
# define BOOST_MP11_HAS_FOLD_EXPRESSIONS # define BOOST_MP11_HAS_FOLD_EXPRESSIONS

View File

@@ -8,7 +8,8 @@
// See accompanying file LICENSE_1_0.txt or copy at // See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt // 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> #include <type_traits>
namespace boost namespace boost
@@ -20,6 +21,16 @@ namespace mp11
namespace detail 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<class... T> struct mp_plus_impl;
template<> 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>; using type = std::integral_constant<int, 0>;
}; };
#if BOOST_WORKAROUND( BOOST_GCC, < 40800 )
template<class T1, class... T> struct mp_plus_impl<T1, T...> 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>; 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...> 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>; 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 } // namespace detail
template<class... T> using mp_plus = typename detail::mp_plus_impl<T...>::type; template<class... T> using mp_plus = typename detail::mp_plus_impl<T...>::type;

View File

@@ -12,6 +12,7 @@
#include <boost/mp11/utility.hpp> #include <boost/mp11/utility.hpp>
#include <boost/mp11/detail/mp_list.hpp> #include <boost/mp11/detail/mp_list.hpp>
#include <boost/mp11/detail/mp_count.hpp> #include <boost/mp11/detail/mp_count.hpp>
#include <boost/mp11/detail/mp_plus.hpp>
#include <type_traits> #include <type_traits>
namespace boost namespace boost
@@ -19,10 +20,22 @@ namespace boost
namespace mp11 namespace mp11
{ {
// mp_all<T...> // mp_void<T...>
template<class... T> using mp_all = mp_bool< mp_count_if< mp_list<T...>, mp_to_bool >::value == sizeof...(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...> // mp_and<T...>
#if BOOST_WORKAROUND( BOOST_MSVC, < 1910 )
namespace detail namespace detail
{ {
@@ -30,7 +43,7 @@ template<class... T> struct mp_and_impl;
} // namespace detail } // 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 namespace detail
{ {
@@ -52,8 +65,41 @@ template<class T1, class... T> struct mp_and_impl<T1, T...>
} // namespace detail } // namespace detail
// mp_any<T...> #else
template<class... T> using mp_any = mp_bool< mp_count_if< mp_list<T...>, mp_to_bool >::value != 0 >;
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...> // mp_or<T...>
namespace detail namespace detail
@@ -63,7 +109,7 @@ template<class... T> struct mp_or_impl;
} // namespace detail } // 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 namespace detail
{ {
@@ -85,6 +131,17 @@ template<class T1, class... T> struct mp_or_impl<T1, T...>
} // namespace detail } // 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...> // mp_same<T...>
namespace detail namespace detail
{ {

View File

@@ -1,10 +1,19 @@
#ifndef BOOST_INTEGER_SEQUENCE_HPP_INCLUDED #ifndef BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED
#define BOOST_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> #include <cstddef>
namespace boost namespace boost
{ {
namespace mp11
{
// integer_sequence // integer_sequence
template<class T, T... I> struct 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 // index_sequence_for
template<class... T> using index_sequence_for = make_integer_sequence<std::size_t, sizeof...(T)>; template<class... T> using index_sequence_for = make_integer_sequence<std::size_t, sizeof...(T)>;
} // namespace mp11
} // namespace boost } // namespace boost
#endif // #ifndef BOOST_INTEGER_SEQUENCE_HPP_INCLUDED #endif // #ifndef BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED

View File

@@ -1,7 +1,14 @@
#ifndef BOOST_TUPLE_FOR_EACH_HPP_INCLUDED #ifndef BOOST_MP11_TUPLE_FOR_EACH_HPP_INCLUDED
#define BOOST_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/config.hpp>
#include <boost/detail/workaround.hpp> #include <boost/detail/workaround.hpp>
#include <tuple> #include <tuple>
@@ -11,11 +18,13 @@
namespace boost namespace boost
{ {
namespace mp11
{
namespace detail 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)]; using A = int[sizeof...(J)];
return (void)A{ ((void)f(std::get<J>(std::forward<Tp>(tp))), 0)... }, std::forward<F>(f); 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 ) #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); 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 ) 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) ); return detail::tuple_for_each_impl( std::forward<Tp>(tp), seq(), std::forward<F>(f) );
} }
} // namespace mp11
} // namespace boost } // namespace boost
#endif // #ifndef BOOST_TUPLE_FOR_EACH_HPP_INCLUDED #endif // #ifndef BOOST_TUPLE_FOR_EACH_HPP_INCLUDED

View File

@@ -103,6 +103,7 @@ run mp_and.cpp : : : $(REQ) ;
run mp_any.cpp : : : $(REQ) ; run mp_any.cpp : : : $(REQ) ;
run mp_or.cpp : : : $(REQ) ; run mp_or.cpp : : : $(REQ) ;
run mp_same.cpp : : : $(REQ) ; run mp_same.cpp : : : $(REQ) ;
run mp_plus.cpp : : : $(REQ) ;
# map # map
run mp_map_find.cpp : : : $(REQ) ; run mp_map_find.cpp : : : $(REQ) ;

View File

@@ -7,47 +7,53 @@
// http://www.boost.org/LICENSE_1_0.txt // 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 <boost/core/lightweight_test_trait.hpp>
#include <type_traits> #include <type_traits>
int main() int main()
{ {
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<int, 0>, boost::integer_sequence<int>>)); using boost::mp11::integer_sequence;
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<int, 1>, boost::integer_sequence<int, 0>>)); using boost::mp11::make_integer_sequence;
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<int, 2>, boost::integer_sequence<int, 0, 1>>)); using boost::mp11::index_sequence;
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<int, 3>, boost::integer_sequence<int, 0, 1, 2>>)); using boost::mp11::make_index_sequence;
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_integer_sequence<int, 4>, boost::integer_sequence<int, 0, 1, 2, 3>>)); 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<make_integer_sequence<int, 0>, integer_sequence<int>>));
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<make_integer_sequence<int, 1>, integer_sequence<int, 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<make_integer_sequence<int, 2>, integer_sequence<int, 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<make_integer_sequence<int, 3>, integer_sequence<int, 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, 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<make_integer_sequence<char, 0>, integer_sequence<char>>));
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<make_integer_sequence<char, 1>, integer_sequence<char, 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<make_integer_sequence<char, 2>, integer_sequence<char, 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<make_integer_sequence<char, 3>, integer_sequence<char, 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, 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<make_integer_sequence<std::size_t, 0>, 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<make_integer_sequence<std::size_t, 1>, 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<make_integer_sequence<std::size_t, 2>, 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<make_integer_sequence<std::size_t, 3>, 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, 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<make_index_sequence<0>, integer_sequence<std::size_t>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<boost::make_index_sequence<1>, boost::index_sequence<0>>)); BOOST_TEST_TRAIT_TRUE((std::is_same<make_index_sequence<1>, integer_sequence<std::size_t, 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<make_index_sequence<2>, integer_sequence<std::size_t, 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<make_index_sequence<3>, integer_sequence<std::size_t, 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<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<make_index_sequence<0>, 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<make_index_sequence<1>, 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<make_index_sequence<2>, 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<make_index_sequence<3>, 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<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(); return boost::report_errors();
} }

View File

@@ -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_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_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<-7>>, mp_true>));
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<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<7>>, mp_true>));
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<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_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_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_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<5>>, mp_true>));
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<-4>, mp_int<0>>, mp_false>));
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<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<8>>, mp_true>));
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<7>, mp_size_t<0>>, mp_false>));
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<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_true>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true, mp_true, mp_false>, mp_false>)); 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_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_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<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_int<0>>)); 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<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_size_t<0>>)); 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(); return boost::report_errors();
} }

View File

@@ -23,16 +23,8 @@ struct X4 {};
template<class T1, class T2> struct F {}; 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; using boost::mp11::mp_plus;
#endif
int main() int main()
{ {
using boost::mp11::mp_list; using boost::mp11::mp_list;

View File

@@ -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_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_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<-7>>, mp_true>));
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<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<7>>, mp_true>));
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<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_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_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_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<0>>, mp_false>));
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<0>, mp_int<5>>, mp_true>));
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<-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<7>, void>, mp_true>));
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<4>>, mp_true>));
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<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_true, void, void>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_true, 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_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_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<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_int<2>>)); 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_int<3>>)); 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_int<4>>)); 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_int<0>>)); 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<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_size_t<2>>)); 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_size_t<3>>)); 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_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<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_size_t<0>>)); 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>)); BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_int<0>, mp_false>, mp_false>));
return boost::report_errors(); return boost::report_errors();

32
test/mp_plus.cpp Normal file
View 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();
}

View File

@@ -29,16 +29,8 @@ struct X10 {};
struct X11 {}; struct X11 {};
struct X12 {}; 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; using boost::mp11::mp_plus;
#endif
int main() int main()
{ {
using boost::mp11::mp_list; using boost::mp11::mp_list;

View File

@@ -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_back = mp_push_back<L, T>;
template<class T, class L> using rev_push_front = mp_push_front<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; using boost::mp11::mp_plus;
#endif
int main() int main()
{ {
using boost::mp11::mp_list; using boost::mp11::mp_list;

View File

@@ -7,7 +7,7 @@
// http://www.boost.org/LICENSE_1_0.txt // 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 <boost/core/lightweight_test.hpp>
#include <tuple> #include <tuple>
#include <memory> #include <memory>
@@ -16,13 +16,15 @@
int main() int main()
{ {
using boost::mp11::tuple_for_each;
{ {
std::tuple<int, short, char> tp{ 1, 2, 3 }; std::tuple<int, short, char> tp{ 1, 2, 3 };
{ {
int s = 0; 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 ); BOOST_TEST_EQ( s, 123 );
} }
@@ -30,7 +32,7 @@ int main()
{ {
int s = 0; 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 ); BOOST_TEST_EQ( s, 123 );
} }
@@ -44,7 +46,7 @@ int main()
int s = 0; 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 ); BOOST_TEST_EQ( s, 123 );
} }
@@ -57,7 +59,7 @@ int main()
{ {
int s = 0; 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 ); BOOST_TEST_EQ( s, 12 );
} }
@@ -65,7 +67,7 @@ int main()
{ {
int s = 0; 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 ); BOOST_TEST_EQ( s, 12 );
} }
@@ -77,7 +79,7 @@ int main()
{ {
int s = 0; 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 ); BOOST_TEST_EQ( s, 123 );
} }
@@ -85,7 +87,7 @@ int main()
{ {
int s = 0; 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 ); BOOST_TEST_EQ( s, 123 );
} }
@@ -94,15 +96,15 @@ int main()
{ {
std::tuple<> tp; std::tuple<> tp;
BOOST_TEST_EQ( boost::tuple_for_each( tp, 11 ), 11 ); BOOST_TEST_EQ( tuple_for_each( tp, 11 ), 11 );
BOOST_TEST_EQ( boost::tuple_for_each( std::move( tp ), 12 ), 12 ); BOOST_TEST_EQ( tuple_for_each( std::move( tp ), 12 ), 12 );
} }
{ {
std::array<int, 0> tp; std::array<int, 0> tp;
BOOST_TEST_EQ( boost::tuple_for_each( tp, 11 ), 11 ); BOOST_TEST_EQ( tuple_for_each( tp, 11 ), 11 );
BOOST_TEST_EQ( boost::tuple_for_each( std::move( tp ), 12 ), 12 ); BOOST_TEST_EQ( tuple_for_each( std::move( tp ), 12 ), 12 );
} }
return boost::report_errors(); return boost::report_errors();

View File

@@ -6,7 +6,7 @@
// See accompanying file LICENSE_1_0.txt or copy at // See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt // 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> #include <boost/config.hpp>
// Technically std::tuple isn't constexpr enabled in C++11, but it works with libstdc++ // 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 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; (void)r;
} }
@@ -42,7 +42,7 @@ int main()
{ {
constexpr std::tuple<> tp; 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" ); static_assert( r == 11, "r == 11" );
} }