forked from boostorg/mp11
Update documentation
This commit is contained in:
@@ -1354,6 +1354,9 @@ the list.</p>
|
||||
<p><code>mp_size<L></code> returns the number of elements in the list <code>L</code>, as a <code>mp_size_t</code>. In other words, <code>mp_size<L<T…​>></code> is an alias for
|
||||
<code>mp_size_t<sizeof…​(T)></code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Examples:</p>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using L1 = mp_list<>;
|
||||
@@ -1394,6 +1397,9 @@ using R3 = mp_size<L3>; // mp_size_t<1></pre>
|
||||
<div class="paragraph">
|
||||
<p><code>mp_front<L></code> is the first element of the list <code>L</code>. That is, <code>mp_front<L<T1, T…​>></code> is an alias for <code>T1</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Examples:</p>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using L1 = std::pair<int, float>;
|
||||
@@ -1423,6 +1429,9 @@ using R3 = mp_front<L3>; // char[1]</pre>
|
||||
<div class="paragraph">
|
||||
<p><code>mp_pop_front<L></code> removes the first element of the list <code>L</code>. That is, <code>mp_pop_front<L<T1, T…​>></code> is an alias for <code>L<T…​></code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Examples:</p>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using L1 = std::tuple<float, double, long double>;
|
||||
@@ -1468,6 +1477,9 @@ using R2 = mp_pop_front<L2>; // mp_list<></pre>
|
||||
<div class="paragraph">
|
||||
<p><code>mp_second<L></code> is the second element of the list <code>L</code>. That is, <code>mp_second<L<T1, T2, T…​>></code> is an alias for <code>T2</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Examples:</p>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using L1 = std::pair<int, float>;
|
||||
@@ -1497,6 +1509,9 @@ using R3 = mp_second<L3>; // char[2]</pre>
|
||||
<div class="paragraph">
|
||||
<p><code>mp_third<L></code> is the third element of the list <code>L</code>. That is, <code>mp_third<L<T1, T2, T3, T…​>></code> is an alias for <code>T3</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Examples:</p>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using L1 = std::tuple<float, double, long double>;
|
||||
@@ -1521,6 +1536,9 @@ using R2 = mp_third<L2>; // char[3]</pre>
|
||||
<p><code>mp_push_front<L, T…​></code> inserts the elements <code>T…​</code> at the front of the list <code>L</code>. That is, <code>mp_push_front<L<U…​>, T…​></code>
|
||||
is an alias for <code>L<T…​, U…​></code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Examples:</p>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using L1 = std::tuple<double, long double>;
|
||||
@@ -1545,6 +1563,9 @@ using R2 = mp_push_front<L2, char[1], char[2]>; // mp_list<char[1], cha
|
||||
<p><code>mp_push_back<L, T…​></code> inserts the elements <code>T…​</code> at the back of the list <code>L</code>. That is, <code>mp_push_back<L<U…​>, T…​></code>
|
||||
is an alias for <code>L<U…​, T…​></code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Examples:</p>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using L1 = std::tuple<double, long double>;
|
||||
@@ -1568,6 +1589,9 @@ using R2 = mp_push_back<L2, char[1], char[2]>; // mp_list<void, char[1]
|
||||
<div class="paragraph">
|
||||
<p><code>mp_rename<L, Y></code> changes the type of the list <code>L</code> to <code>Y</code>. That is, <code>mp_rename<L<T…​>, Y></code> is an alias for <code>Y<T…​></code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Examples:</p>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using L1 = std::pair<double, long double>;
|
||||
@@ -1592,6 +1616,9 @@ using R2 = mp_rename<L2, mp_list>; // mp_list<void></pre>
|
||||
<p><code>mp_apply<F, L></code> applies the metafunction <code>F</code> to the contents of the list <code>L</code>, that is, <code>mp_apply<F, L<T…​>></code> is an alias for <code>F<T…​></code>.
|
||||
(<code>mp_apply</code> is the same as <code>mp_rename</code> with the arguments reversed.)</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Example:</p>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using L1 = std::pair<double, long double>;
|
||||
@@ -1609,6 +1636,9 @@ using R1 = mp_apply<std::is_same, L1>; // std::is_same<double, long dou
|
||||
<div class="paragraph">
|
||||
<p>Same as <code>mp_apply</code>, but takes a quoted metafunction.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Example:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlight"><code>using L1 = std::tuple<double, long double>;
|
||||
@@ -1630,6 +1660,9 @@ using R1 = mp_apply_q<mp_bind_front<mp_push_back, L1>, L2>;
|
||||
<p><code>mp_append<L…​></code> concatenates the lists in <code>L…​</code> into a single list that has the same type as the first list. <code>mp_append<></code>
|
||||
is an alias for <code>mp_list<></code>. <code>mp_append<L1<T1…​>, L2<T2…​>, …​, Ln<Tn…​>></code> is an alias for <code>L1<T1…​, T2…​, …​, Tn…​></code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Example:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlight"><code>using L1 = std::tuple<double, long double>;
|
||||
@@ -1652,6 +1685,9 @@ using R1 = mp_append<L1, L2, L3, L4>; // std::tuple<double, long double
|
||||
<p><code>mp_replace_front<L, T></code> replaces the first element of the list <code>L</code> with <code>T</code>. That is, <code>mp_replace_front<L<U1, U…​>, T></code> is
|
||||
an alias for <code>L<T, U…​></code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Examples:</p>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using L1 = std::pair<int, float>;
|
||||
@@ -1693,6 +1729,9 @@ using R3 = mp_replace_front<L3, void>; // mp_list<void, char[2], char[3
|
||||
<p><code>mp_replace_second<L, T></code> replaces the second element of the list <code>L</code> with <code>T</code>. That is, <code>mp_replace_second<L<U1, U2, U…​>, T></code>
|
||||
is an alias for <code>L<U1, T, U…​></code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Examples:</p>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using L1 = std::pair<int, float>;
|
||||
@@ -1723,6 +1762,9 @@ using R3 = mp_replace_second<L3, void>; // mp_list<char[1], void, char[
|
||||
<p><code>mp_replace_third<L, T></code> replaces the third element of the list <code>L</code> with <code>T</code>. That is, <code>mp_replace_third<L<U1, U2, U3, U…​>, T></code>
|
||||
is an alias for <code>L<U1, U2, T, U…​></code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Examples:</p>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using L1 = std::tuple<float, double, long double>;
|
||||
@@ -1776,15 +1818,23 @@ using R2 = mp_replace_third<L2, void>; // mp_list<char[1], char[2], voi
|
||||
<div class="paragraph">
|
||||
<p><code>mp_if_c<true, T, E…​></code> is an alias for <code>T</code>. <code>mp_if_c<false, T, E></code> is an alias for <code>E</code>. Otherwise, the result is a substitution failure.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Examples:</p>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using R1 = mp_if_c<true, int, void>; // int
|
||||
using R2 = mp_if_c<flase, int, void>; // void</pre>
|
||||
<pre>using R1 = mp_if_c<true, int, void>; // int</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>template<class I> using void_if_5 = mp_if_c<I::value == 5, void>; // `void` when `I::value` is 5, substitution failure otherwise</pre>
|
||||
<pre>using R2 = mp_if_c<flase, int, void>; // void</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>template<class I> using void_if_5 = mp_if_c<I::value == 5, void>;
|
||||
// `void` when `I::value` is 5, substitution failure otherwise</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1792,7 +1842,8 @@ using R2 = mp_if_c<flase, int, void>; // void</pre>
|
||||
<h4 id="mp_if_c_t_e">mp_if<C, T, E…​></h4>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>template<class C, class T, class E...> using mp_if = mp_if_c<static_cast<bool>(C::value), T, E...>;</pre>
|
||||
<pre>template<class C, class T, class E...> using mp_if =
|
||||
mp_if_c<static_cast<bool>(C::value), T, E...>;</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -1815,7 +1866,8 @@ is to avoid evaluating <code>F<U…​></code> when the condition
|
||||
<h4 id="mp_eval_if_c_t_f_u">mp_eval_if<C, T, F, U…​></h4>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>template<class C, class T, template<class...> class F, class... U> using mp_eval_if = mp_eval_if_c<static_cast<bool>(C::value), T, F, U...>;</pre>
|
||||
<pre>template<class C, class T, template<class...> class F, class... U> using mp_eval_if =
|
||||
mp_eval_if_c<static_cast<bool>(C::value), T, F, U...>;</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -1826,7 +1878,8 @@ is to avoid evaluating <code>F<U…​></code> when the condition
|
||||
<h4 id="mp_eval_if_q_c_t_q_u">mp_eval_if_q<C, T, Q, U…​></h4>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>template<class C, class T, class Q, class... U> using mp_eval_if_q = mp_eval_if<C, T, Q::template fn, U...>;</pre>
|
||||
<pre>template<class C, class T, class Q, class... U> using mp_eval_if_q =
|
||||
mp_eval_if<C, T, Q::template fn, U...>;</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -2135,7 +2188,8 @@ where <code>T</code> is the type of <code>N::value</code>.</p>
|
||||
<h4 id="mp_insert_c_l_i_t">mp_insert_c<L, I, T…​></h4>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>template<class L, std::size_t I, class... T> using mp_insert_c = mp_append<mp_take_c<L, I>, mp_push_front<mp_drop_c<L, I>, T...>>;</pre>
|
||||
<pre>template<class L, std::size_t I, class... T> using mp_insert_c =
|
||||
mp_append<mp_take_c<L, I>, mp_push_front<mp_drop_c<L, I>, T...>>;</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -2146,7 +2200,8 @@ where <code>T</code> is the type of <code>N::value</code>.</p>
|
||||
<h4 id="mp_insert_l_i_t">mp_insert<L, I, T…​></h4>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>template<class L, class I, class... T> using mp_insert = mp_append<mp_take<L, I>, mp_push_front<mp_drop<L, I>, T...>>;</pre>
|
||||
<pre>template<class L, class I, class... T> using mp_insert =
|
||||
mp_append<mp_take<L, I>, mp_push_front<mp_drop<L, I>, T...>>;</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -2157,7 +2212,8 @@ where <code>T</code> is the type of <code>N::value</code>.</p>
|
||||
<h4 id="mp_erase_c_l_i_j">mp_erase_c<L, I, J></h4>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>template<class L, std::size_t I, std::size_t J> using mp_erase = mp_append<mp_take_c<L, I>, mp_drop_c<L, J>>;</pre>
|
||||
<pre>template<class L, std::size_t I, std::size_t J> using mp_erase_c =
|
||||
mp_append<mp_take_c<L, I>, mp_drop_c<L, J>>;</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -2168,7 +2224,8 @@ where <code>T</code> is the type of <code>N::value</code>.</p>
|
||||
<h4 id="mp_erase_l_i_j">mp_erase<L, I, J></h4>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>template<class L, class I, class J> using mp_erase = mp_append<mp_take<L, I>, mp_drop<L, J>>;</pre>
|
||||
<pre>template<class L, class I, class J> using mp_erase =
|
||||
mp_append<mp_take<L, I>, mp_drop<L, J>>;</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -2274,6 +2331,17 @@ for the elements of <code>L<U1…​></code> and <code>mp_false</c
|
||||
<div class="paragraph">
|
||||
<p><code>mp_sort<L, P></code> sorts the list <code>L</code> according to the strict weak ordering <code>mp_to_bool<P<T, U>></code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Example:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="highlight"><code>#include <ratio>
|
||||
|
||||
using L1 = mp_list<std::ratio<1,2>, std::ratio<1,4>>;
|
||||
using R1 = mp_sort<L1, std::ratio_less>; // mp_list<ratio<1,4>, ratio<1,2>></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sect3">
|
||||
<h4 id="mp_find_l_v">mp_find<L, V></h4>
|
||||
@@ -2348,7 +2416,8 @@ is <code>mp_size<L></code>.</p>
|
||||
<h4 id="mp_all_of_l_p">mp_all_of<L, P></h4>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>template<class L, template<class...> class P> using mp_all_of = mp_bool< mp_count_if<L, P>::value == mp_size<L>::value >;</pre>
|
||||
<pre>template<class L, template<class...> class P> using mp_all_of =
|
||||
mp_bool< mp_count_if<L, P>::value == mp_size<L>::value >;</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -2359,7 +2428,8 @@ is <code>mp_size<L></code>.</p>
|
||||
<h4 id="mp_none_of_l_p">mp_none_of<L, P></h4>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>template<class L, template<class...> class P> using mp_none_of = mp_bool< mp_count_if<L, P>::value == 0 >;</pre>
|
||||
<pre>template<class L, template<class...> class P> using mp_none_of =
|
||||
mp_bool< mp_count_if<L, P>::value == 0 >;</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -2370,7 +2440,8 @@ is <code>mp_size<L></code>.</p>
|
||||
<h4 id="mp_any_of_l_p">mp_any_of<L, P></h4>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>template<class L, template<class...> class P> using mp_any_of = mp_bool< mp_count_if<L, P>::value != 0 >;</pre>
|
||||
<pre>template<class L, template<class...> class P> using mp_any_of =
|
||||
mp_bool< mp_count_if<L, P>::value != 0 >;</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -2481,7 +2552,8 @@ is <code>mp_size<L></code>.</p>
|
||||
<h4 id="mp_map_insert_m_t">mp_map_insert<M, T></h4>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>template<class M, class T> using mp_map_insert = mp_if< mp_map_contains<M, mp_first<T>>, M, mp_push_back<M, T> >;</pre>
|
||||
<pre>template<class M, class T> using mp_map_insert =
|
||||
mp_if< mp_map_contains<M, mp_first<T>>, M, mp_push_back<M, T> >;</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -2549,12 +2621,27 @@ replaces the existing element <code>L<X, Y…​></code> with <cod
|
||||
returns <code>mp_false</code>. If the application causes a substitution failure, returns <code>mp_false</code>. If all results are <code>mp_true</code>,
|
||||
returns <code>mp_true</code>. <code>mp_and<></code> is <code>mp_true</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Examples:</p>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>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 (!)</pre>
|
||||
<pre>using R1 = mp_and<mp_true, mp_true>; // mp_true</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using R2 = mp_and<mp_false, void>; // mp_false, void is not reached</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using R3 = mp_and<mp_false, mp_false>; // mp_false</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using R4 = mp_and<void, mp_true>; // mp_false (!)</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2571,12 +2658,27 @@ using R4 = mp_and<void, mp_true>; // mp_false (!)</pre>
|
||||
is an error because <code>void</code> does not have a nested <code>value</code>. The upside is that <code>mp_all</code> is potentially faster and does not
|
||||
mask substitution failures as <code>mp_and</code> does.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Examples:</p>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>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</pre>
|
||||
<pre>using R1 = mp_all<mp_true, mp_true>; // mp_true</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using R2 = mp_all<mp_false, void>; // compile-time error</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using R3 = mp_all<mp_false, mp_false>; // mp_false</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using R4 = mp_all<void, mp_true>; // compile-time error</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2591,12 +2693,27 @@ using R4 = mp_and<void, mp_true>; // compile-time error</pre>
|
||||
<p><code>mp_or<T…​></code> applies <code>mp_to_bool</code> to the types in <code>T…​</code>, in order. If the result of an application is <code>mp_true</code>, <code>mp_or</code>
|
||||
returns <code>mp_true</code>. If all results are <code>mp_false</code>, returns <code>mp_false</code>. <code>mp_or<></code> is <code>mp_false</code>.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Examples:</p>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>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</pre>
|
||||
<pre>using R1 = mp_or<mp_true, mp_false>; // mp_true</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using R2 = mp_or<mp_true, void>; // mp_true, void is not reached</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using R3 = mp_or<mp_false, mp_false>; // mp_false</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using R4 = mp_or<void, mp_true>; // compile-time error</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2611,12 +2728,27 @@ using R4 = mp_or<void, mp_true>; // compile-time error</pre>
|
||||
<p><code>mp_any<T…​></code> is <code>mp_true</code> if <code>mp_to_bool<U></code> is <code>mp_true</code> for any type <code>U</code> in <code>T…​</code>, <code>mp_false</code> otherwise. Same as
|
||||
<code>mp_or</code>, but does not perform short-circuit evaluation.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Examples:</p>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>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</pre>
|
||||
<pre>using R1 = mp_any<mp_true, mp_false>; // mp_true</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using R2 = mp_any<mp_true, void>; // compile-time error</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using R3 = mp_any<mp_false, mp_false>; // mp_false</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>using R4 = mp_any<void, mp_true>; // compile-time error</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -152,25 +152,29 @@ Same as `mp_take_c`, but with a type argument `N`. `N::value` must be a nonnegat
|
||||
|
||||
## mp_insert_c<L, I, T...>
|
||||
|
||||
template<class L, std::size_t I, class... T> using mp_insert_c = mp_append<mp_take_c<L, I>, mp_push_front<mp_drop_c<L, I>, T...>>;
|
||||
template<class L, std::size_t I, class... T> using mp_insert_c =
|
||||
mp_append<mp_take_c<L, I>, mp_push_front<mp_drop_c<L, I>, T...>>;
|
||||
|
||||
Inserts the elements `T...` into the list `L` at position `I` (a zero-based index).
|
||||
|
||||
## mp_insert<L, I, T...>
|
||||
|
||||
template<class L, class I, class... T> using mp_insert = mp_append<mp_take<L, I>, mp_push_front<mp_drop<L, I>, T...>>;
|
||||
template<class L, class I, class... T> using mp_insert =
|
||||
mp_append<mp_take<L, I>, mp_push_front<mp_drop<L, I>, T...>>;
|
||||
|
||||
Same as `mp_insert_c`, but with a type argument `I`.
|
||||
|
||||
## mp_erase_c<L, I, J>
|
||||
|
||||
template<class L, std::size_t I, std::size_t J> using mp_erase = mp_append<mp_take_c<L, I>, mp_drop_c<L, J>>;
|
||||
template<class L, std::size_t I, std::size_t J> using mp_erase_c =
|
||||
mp_append<mp_take_c<L, I>, mp_drop_c<L, J>>;
|
||||
|
||||
Removes from the list `L` the elements with indices from `I` (inclusive) to `J` (exclusive).
|
||||
|
||||
## mp_erase<L, I, J>
|
||||
|
||||
template<class L, class I, class J> using mp_erase = mp_append<mp_take<L, I>, mp_drop<L, J>>;
|
||||
template<class L, class I, class J> using mp_erase =
|
||||
mp_append<mp_take<L, I>, mp_drop<L, J>>;
|
||||
|
||||
Same as `mp_erase_c`, but with a type arguments `I` and `J`.
|
||||
|
||||
@@ -229,6 +233,13 @@ for the elements of `L<U1...>` and `mp_false` for the elements of `L<U2...>`. Re
|
||||
|
||||
`mp_sort<L, P>` sorts the list `L` according to the strict weak ordering `mp_to_bool<P<T, U>>`.
|
||||
|
||||
Example:
|
||||
```
|
||||
#include <ratio>
|
||||
|
||||
using L1 = mp_list<std::ratio<1,2>, std::ratio<1,4>>;
|
||||
using R1 = mp_sort<L1, std::ratio_less>; // mp_list<ratio<1,4>, ratio<1,2>>
|
||||
```
|
||||
## mp_find<L, V>
|
||||
|
||||
template<class L, class V> using mp_find = /*...*/;
|
||||
@@ -270,19 +281,22 @@ is `mp_size<L>`.
|
||||
|
||||
## mp_all_of<L, P>
|
||||
|
||||
template<class L, template<class...> class P> using mp_all_of = mp_bool< mp_count_if<L, P>::value == mp_size<L>::value >;
|
||||
template<class L, template<class...> class P> using mp_all_of =
|
||||
mp_bool< mp_count_if<L, P>::value == mp_size<L>::value >;
|
||||
|
||||
`mp_all_of<L, P>` is `mp_true` when `P` holds for all elements of `L`, `mp_false` otherwise. When `L` is empty, the result is `mp_true`.
|
||||
|
||||
## mp_none_of<L, P>
|
||||
|
||||
template<class L, template<class...> class P> using mp_none_of = mp_bool< mp_count_if<L, P>::value == 0 >;
|
||||
template<class L, template<class...> class P> using mp_none_of =
|
||||
mp_bool< mp_count_if<L, P>::value == 0 >;
|
||||
|
||||
`mp_none_of<L, P>` is `mp_true` when `P` holds for no element of `L`, `mp_false` otherwise. When `L` is empty, the result is `mp_true`.
|
||||
|
||||
## mp_any_of<L, P>
|
||||
|
||||
template<class L, template<class...> class P> using mp_any_of = mp_bool< mp_count_if<L, P>::value != 0 >;
|
||||
template<class L, template<class...> class P> using mp_any_of =
|
||||
mp_bool< mp_count_if<L, P>::value != 0 >;
|
||||
|
||||
`mp_any_of<L, P>` is `mp_true` when `P` holds for at least one element of `L`, `mp_false` otherwise. When `L` is empty, the result is `mp_false`.
|
||||
|
||||
|
@@ -27,9 +27,14 @@ Same as `std::void_t` from 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`.
|
||||
|
||||
Examples:
|
||||
|
||||
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 (!)
|
||||
|
||||
## mp_all<T...>
|
||||
@@ -41,10 +46,15 @@ returns `mp_true`. `mp_and<>` is `mp_true`.
|
||||
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
|
||||
Examples:
|
||||
|
||||
using R1 = mp_all<mp_true, mp_true>; // mp_true
|
||||
|
||||
using R2 = mp_all<mp_false, void>; // compile-time error
|
||||
|
||||
using R3 = mp_all<mp_false, mp_false>; // mp_false
|
||||
|
||||
using R4 = mp_all<void, mp_true>; // compile-time error
|
||||
|
||||
## mp_or<T...>
|
||||
|
||||
@@ -53,9 +63,14 @@ mask substitution failures as `mp_and` does.
|
||||
`mp_or<T...>` applies `mp_to_bool` to the types in `T...`, in order. If the result of an application is `mp_true`, `mp_or`
|
||||
returns `mp_true`. If all results are `mp_false`, returns `mp_false`. `mp_or<>` is `mp_false`.
|
||||
|
||||
Examples:
|
||||
|
||||
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
|
||||
|
||||
## mp_any<T...>
|
||||
@@ -65,9 +80,14 @@ returns `mp_true`. If all results are `mp_false`, returns `mp_false`. `mp_or<>`
|
||||
`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.
|
||||
|
||||
Examples:
|
||||
|
||||
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
|
||||
|
||||
## mp_same<T...>
|
||||
|
@@ -28,6 +28,8 @@ the list.
|
||||
`mp_size<L>` returns the number of elements in the list `L`, as a `mp_size_t`. In other words, `mp_size<L<T...>>` is an alias for
|
||||
`mp_size_t<sizeof...(T)>`.
|
||||
|
||||
Examples:
|
||||
|
||||
using L1 = mp_list<>;
|
||||
using R1 = mp_size<L1>; // mp_size_t\<0>
|
||||
|
||||
@@ -49,6 +51,8 @@ the list.
|
||||
|
||||
`mp_front<L>` is the first element of the list `L`. That is, `mp_front<L<T1, T...>>` is an alias for `T1`.
|
||||
|
||||
Examples:
|
||||
|
||||
using L1 = std::pair<int, float>;
|
||||
using R1 = mp_front<L1>; // int
|
||||
|
||||
@@ -64,6 +68,8 @@ the list.
|
||||
|
||||
`mp_pop_front<L>` removes the first element of the list `L`. That is, `mp_pop_front<L<T1, T...>>` is an alias for `L<T...>`.
|
||||
|
||||
Examples:
|
||||
|
||||
using L1 = std::tuple<float, double, long double>;
|
||||
using R1 = mp_pop_front<L1>; // std::tuple<double, long double>
|
||||
|
||||
@@ -88,6 +94,8 @@ the list.
|
||||
|
||||
`mp_second<L>` is the second element of the list `L`. That is, `mp_second<L<T1, T2, T...>>` is an alias for `T2`.
|
||||
|
||||
Examples:
|
||||
|
||||
using L1 = std::pair<int, float>;
|
||||
using R1 = mp_second<L1>; // float
|
||||
|
||||
@@ -103,6 +111,8 @@ the list.
|
||||
|
||||
`mp_third<L>` is the third element of the list `L`. That is, `mp_third<L<T1, T2, T3, T...>>` is an alias for `T3`.
|
||||
|
||||
Examples:
|
||||
|
||||
using L1 = std::tuple<float, double, long double>;
|
||||
using R1 = mp_third<L1>; // long double
|
||||
|
||||
@@ -116,6 +126,8 @@ the list.
|
||||
`mp_push_front<L, T...>` inserts the elements `T...` at the front of the list `L`. That is, `mp_push_front<L<U...>, T...>`
|
||||
is an alias for `L<T..., U...>`.
|
||||
|
||||
Examples:
|
||||
|
||||
using L1 = std::tuple<double, long double>;
|
||||
using R1 = mp_push_front<L1, float>; // std::tuple<float, double, long double>
|
||||
|
||||
@@ -129,6 +141,8 @@ is an alias for `L<T..., U...>`.
|
||||
`mp_push_back<L, T...>` inserts the elements `T...` at the back of the list `L`. That is, `mp_push_back<L<U...>, T...>`
|
||||
is an alias for `L<U..., T...>`.
|
||||
|
||||
Examples:
|
||||
|
||||
using L1 = std::tuple<double, long double>;
|
||||
using R1 = mp_push_back<L1, float>; // std::tuple<double, long double, float>
|
||||
|
||||
@@ -141,6 +155,8 @@ is an alias for `L<U..., T...>`.
|
||||
|
||||
`mp_rename<L, Y>` changes the type of the list `L` to `Y`. That is, `mp_rename<L<T...>, Y>` is an alias for `Y<T...>`.
|
||||
|
||||
Examples:
|
||||
|
||||
using L1 = std::pair<double, long double>;
|
||||
using R1 = mp_rename<L1, std::tuple>; // std::tuple<double, long double>
|
||||
|
||||
@@ -154,6 +170,8 @@ is an alias for `L<U..., T...>`.
|
||||
`mp_apply<F, L>` applies the metafunction `F` to the contents of the list `L`, that is, `mp_apply<F, L<T...>>` is an alias for `F<T...>`.
|
||||
(`mp_apply` is the same as `mp_rename` with the arguments reversed.)
|
||||
|
||||
Example:
|
||||
|
||||
using L1 = std::pair<double, long double>;
|
||||
using R1 = mp_apply<std::is_same, L1>; // std::is_same<double, long double>
|
||||
|
||||
@@ -162,6 +180,9 @@ is an alias for `L<U..., T...>`.
|
||||
template<class Q, class L> using mp_apply_q = mp_apply<Q::template fn, L>;
|
||||
|
||||
Same as `mp_apply`, but takes a quoted metafunction.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
using L1 = std::tuple<double, long double>;
|
||||
using L2 = mp_list<int, long>;
|
||||
@@ -169,12 +190,16 @@ using L2 = mp_list<int, long>;
|
||||
using R1 = mp_apply_q<mp_bind_front<mp_push_back, L1>, L2>;
|
||||
// R1 is std::tuple<double, long double, int, long>
|
||||
```
|
||||
|
||||
## mp_append<L...>
|
||||
|
||||
template<class... L> using mp_append = /*...*/;
|
||||
|
||||
`mp_append<L...>` concatenates the lists in `L...` into a single list that has the same type as the first list. `mp_append<>`
|
||||
is an alias for `mp_list<>`. `mp_append<L1<T1...>, L2<T2...>, ..., Ln<Tn...>>` is an alias for `L1<T1..., T2..., ..., Tn...>`.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
using L1 = std::tuple<double, long double>;
|
||||
using L2 = mp_list<int>;
|
||||
@@ -183,6 +208,7 @@ using L4 = mp_list<>;
|
||||
|
||||
using R1 = mp_append<L1, L2, L3, L4>; // std::tuple<double, long double, int, short, long>
|
||||
```
|
||||
|
||||
## mp_replace_front<L, T>
|
||||
|
||||
template<class L, class T> using mp_replace_front = /*...*/;
|
||||
@@ -190,6 +216,8 @@ using R1 = mp_append<L1, L2, L3, L4>; // std::tuple<double, long double, int, sh
|
||||
`mp_replace_front<L, T>` replaces the first element of the list `L` with `T`. That is, `mp_replace_front<L<U1, U...>, T>` is
|
||||
an alias for `L<T, U...>`.
|
||||
|
||||
Examples:
|
||||
|
||||
using L1 = std::pair<int, float>;
|
||||
using R1 = mp_replace_front<L1, void>; // std::pair<void, float>
|
||||
|
||||
@@ -212,6 +240,8 @@ an alias for `L<T, U...>`.
|
||||
`mp_replace_second<L, T>` replaces the second element of the list `L` with `T`. That is, `mp_replace_second<L<U1, U2, U...>, T>`
|
||||
is an alias for `L<U1, T, U...>`.
|
||||
|
||||
Examples:
|
||||
|
||||
using L1 = std::pair<int, float>;
|
||||
using R1 = mp_replace_second<L1, void>; // std::pair<int, void>
|
||||
|
||||
@@ -228,6 +258,8 @@ is an alias for `L<U1, T, U...>`.
|
||||
`mp_replace_third<L, T>` replaces the third element of the list `L` with `T`. That is, `mp_replace_third<L<U1, U2, U3, U...>, T>`
|
||||
is an alias for `L<U1, U2, T, U...>`.
|
||||
|
||||
Examples:
|
||||
|
||||
using L1 = std::tuple<float, double, long double>;
|
||||
using R1 = mp_replace_third<L1, void>; // std::tuple<float, double, void>
|
||||
|
||||
|
@@ -29,7 +29,8 @@ A map is a list of lists, the inner lists having at least one element (the key.)
|
||||
|
||||
## mp_map_insert<M, T>
|
||||
|
||||
template<class M, class T> using mp_map_insert = mp_if< mp_map_contains<M, mp_first<T>>, M, mp_push_back<M, T> >;
|
||||
template<class M, class T> using mp_map_insert =
|
||||
mp_if< mp_map_contains<M, mp_first<T>>, M, mp_push_back<M, T> >;
|
||||
|
||||
Inserts the element `T` into the map `M`, if an element with a key `mp_first<T>` is not already in `M`.
|
||||
|
||||
|
@@ -34,14 +34,19 @@ http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
`mp_if_c<true, T, E...>` is an alias for `T`. `mp_if_c<false, T, E>` is an alias for `E`. Otherwise, the result is a substitution failure.
|
||||
|
||||
Examples:
|
||||
|
||||
using R1 = mp_if_c<true, int, void>; // int
|
||||
|
||||
using R2 = mp_if_c<flase, int, void>; // void
|
||||
|
||||
template<class I> using void_if_5 = mp_if_c<I::value == 5, void>; // `void` when `I::value` is 5, substitution failure otherwise
|
||||
template<class I> using void_if_5 = mp_if_c<I::value == 5, void>;
|
||||
// `void` when `I::value` is 5, substitution failure otherwise
|
||||
|
||||
## mp_if<C, T, E...>
|
||||
|
||||
template<class C, class T, class E...> using mp_if = mp_if_c<static_cast<bool>(C::value), T, E...>;
|
||||
template<class C, class T, class E...> using mp_if =
|
||||
mp_if_c<static_cast<bool>(C::value), T, E...>;
|
||||
|
||||
Like `mp_if_c`, but the first argument is a type.
|
||||
|
||||
@@ -54,13 +59,15 @@ is to avoid evaluating `F<U...>` when the condition is `true` as it may not be v
|
||||
|
||||
## mp_eval_if<C, T, F, U...>
|
||||
|
||||
template<class C, class T, template<class...> class F, class... U> using mp_eval_if = mp_eval_if_c<static_cast<bool>(C::value), T, F, U...>;
|
||||
template<class C, class T, template<class...> class F, class... U> using mp_eval_if =
|
||||
mp_eval_if_c<static_cast<bool>(C::value), T, F, U...>;
|
||||
|
||||
Like `mp_eval_if_c`, but the first argument is a type.
|
||||
|
||||
## mp_eval_if_q<C, T, Q, U...>
|
||||
|
||||
template<class C, class T, class Q, class... U> using mp_eval_if_q = mp_eval_if<C, T, Q::template fn, U...>;
|
||||
template<class C, class T, class Q, class... U> using mp_eval_if_q =
|
||||
mp_eval_if<C, T, Q::template fn, U...>;
|
||||
|
||||
Like `mp_eval_if`, but takes a quoted metafunction.
|
||||
|
||||
|
Reference in New Issue
Block a user