pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
<p>The general principles upon which Mp11 is built are that algorithms and metafunctions are
template aliases of the form <code>F<T…​></code> and data structures are lists of the form <code>L<T…​></code>,
with the library placing no requirements on <code>L</code>. <code>mp_list<T…​></code> is the built-in list type,
but <code>std::tuple<T…​></code>, <code>std::pair<T1, T2></code> and <code>std::variant<T…​></code> are also perfectly
legitimate list types, although of course <code>std::pair<T1, T2></code>, due to having exactly two elements,
is not resizeable and will consequently not work with algorithms that need to add or remove
elements.</p>
</div>
<divclass="paragraph">
<p>Another distinguishing feature of this approach is that lists (<code>L<T…​></code>) have the same form as
metafunctions (<code>F<T…​></code>) and can therefore be used as such. For example, applying <code>std::add_pointer_t</code>
to the list <code>std::tuple<int, float></code> by way of <code>mp_transform<std::add_pointer_t, std::tuple<int, float>></code>
gives us <code>std::tuple<int*, float*></code>, but we can also apply <code>mp_list</code> to the same tuple:</p>
</div>
<divclass="literalblock">
<divclass="content">
<pre>using R = mp_transform<mp_list, std::tuple<int, float>>;</pre>
</div>
</div>
<divclass="paragraph">
<p>and get <code>std::tuple<mp_list<int>, mp_list<float>></code>.</p>
</div>
</div>
</div>
<divclass="sect1">
<h2id="definitions">Definitions</h2>
<divclass="sectionbody">
<divclass="paragraph">
<p>A <em>list</em> is a — usually but not necessarily variadic — template class whose parameters are all types,
for example <code>mp_list<char[], void></code>, <code>mp_list<></code>, <code>std::tuple<int, float, char></code>, <code>std::pair<int, float></code>, <code>std::shared_ptr<X></code>.</p>
</div>
<divclass="paragraph">
<p>A <em>metafunction</em> is a class template or a template alias whose parameters are all types, for example <code>std::add_pointer_t</code>,
<p><code>mp_product<F, L1, L2></code> calls <code>F<T1, T2></code> where <code>T1</code> varies over the elements of <code>L1</code> and <code>T2</code> varies over
the elements of <code>L2</code>, as if by executing two nested loops. It then returns a list of these results, of the same
type as <code>L1</code>.</p>
</div>
<divclass="paragraph">
<p>In our case, both lists are the same <code>std::tuple</code>, and <code>F</code> is <code>mp_list</code>, so <code>mp_product<mp_list, L, L></code> will get us
<p>We then default-construct this tuple and pass it to <code>tuple_for_each</code>. <code>tuple_for_each(tp, f)</code> calls <code>f</code> for every
tuple element; we use a (C++14) lambda that calls <code>test_result</code>.</p>
</div>
<divclass="paragraph">
<p>In pure C++11, we can’t use a lambda with an <code>auto&&</code> parameter, so we’ll have to make <code>test_result</code> a function object with
a templated <code>operator()</code> and pass that to <code>tuple_for_each</code> directly:</p>
<p>(There is no need to specialize <code>std::common_type</code> for more than two arguments - it takes care of synthesizing the appropriate semantics from
the binary case.)</p>
</div>
<divclass="paragraph">
<p>The subtlety here is the use of <code>mp_defer</code>. We could have defined a nested <code>type</code> to <code>common_tuple<std::tuple<T1…​>, std::tuple<T2…​>></code>,
and it would still have worked in all valid cases. By letting <code>mp_defer</code> define <code>type</code>, though, we make our specialization <em>SFINAE-friendly</em>.</p>
</div>
<divclass="paragraph">
<p>That is, when our <code>common_tuple</code> causes a substitution failure instead of a hard error, <code>mp_defer</code> will not define a nested <code>type</code>,
and <code>common_type_t</code>, which is defined as <code>typename common_type<…​>::type</code>, will also cause a substitution failure.</p>
</div>
<divclass="paragraph">
<p>As another example, consider the hypothetical type <code>expected<T, E…​></code> that represents either a successful return with a value of <code>T</code>,
or an unsucessful return with an error code of some type in the list <code>E…​</code>. The common type of <code>expected<T1, E1, E2, E3></code> and
<code>expected<T2, E1, E4, E5></code> is <code>expected<common_type_t<T1, T2>, E1, E2, E3, E4, E5></code>. That is, the possible return values are
combined into their common type, and we take the union of the set of error types.</p>
</div>
<divclass="paragraph">
<p>Therefore,</p>
</div>
<divclass="listingblock">
<divclass="content">
<preclass="highlight"><code>template<class T1, class E1, class T2, class E2> using common_expected =
<p>Here we’ve taken a different tack; instead of passing the <code>expected</code> types to <code>common_expected</code>, we’re passing the <code>T</code> types and lists of
the <code>E</code> types. This makes our job easier. <code>mp_unique<mp_append<E1, E2>></code> gives us the concatenation of <code>E1</code> and <code>E2</code> with the duplicates
removed; we then add <code>common_type_t<T1, T2></code> to the front via <code>mp_push_front</code>; and finally, we <code>mp_rename</code> the resultant <code>mp_list</code>
<p>And finally, the standard <code>tuple_cat</code> is specified to work on arbitrary tuple-like types (that is, all types
that support <code>tuple_size</code>, <code>tuple_element</code>, and <code>get</code>), while our implementation only works with <code>tuple</code> and
<code>pair</code>. <code>std::array</code>, for example, fails:</p>
<p>Let’s fix these one by one. Support for move-only types is easy, if one knows where to look. The problem is
that <code>Tp</code> that we’re passing to the helper <code>tuple_cat_</code> is (correctly) <code>tuple<unique_ptr<int>&&, unique_ptr<float>&&></code>,
but <code>std::get<0>(tp)</code> still returns <code>unique_ptr<int>&</code>, because <code>tp</code> is an lvalue. This behavior is a bit
surprising, but consistent with how rvalue reference members are treated by the language.</p>
</div>
<divclass="paragraph">
<p>Long story short, we need <code>std::move(tp)</code> in <code>tuple_cat_</code> to make <code>tp</code> an rvalue:</p>
</div>
<divclass="literalblock">
<divclass="content">
<pre>template<class R, class...Is, class... Ks, class Tp>
R tuple_cat_( mp_list<Is...>, mp_list<Ks...>, Tp tp )
<p>Finally, tuple-like types. We’ve so far exploited the fact that <code>std::pair</code> and <code>std::tuple</code> are valid Mp11 lists,
but in general, arbitrary tuple-like types aren’t, so we need to convert them into such. For that, we’ll need to
define a metafunction <code>from_tuple_like</code> that will take an arbitrary tuple-like type and will return, in our case,
the corresponding <code>mp_list</code>.</p>
</div>
<divclass="paragraph">
<p>Technically, a more principled approach would’ve been to return <code>std::tuple</code>, but here <code>mp_list</code> will prove more
convenient.</p>
</div>
<divclass="paragraph">
<p>What we need is, given a tuple-like type <code>Tp</code>, to obtain <code>mp_list<std::tuple_element<0, Tp>::type, std::tuple_element<1, Tp>::type,
…​, std::tuple_element<N-1, Tp>::type></code>, where <code>N</code> is <code>tuple_size<Tp>::value</code>. Here’s one way to do it:</p>
</div>
<divclass="listingblock">
<divclass="content">
<preclass="highlight"><code>template<class T, class I> using tuple_element =
<p>(<code>mp_iota<N></code> is an algorithm that returns an <code>mp_list</code> with elements <code>mp_size_t<0></code>, <code>mp_size_t<1></code>, …​, <code>mp_size_t<N-1></code>.)</p>
</div>
<divclass="paragraph">
<p>Remember that <code>mp_product<F, L1, L2></code> performs the equivalent of two nested loops over the elements of <code>L1</code> and <code>L2</code>,
applying <code>F</code> to the two variables and gathering the result. In our case <code>L1</code> consists of the single element <code>T</code>, so
only the second loop (over <code>mp_iota<N></code>, where <code>N</code> is <code>tuple_size<T></code>), remains, and we get a list of the same type
as <code>L1</code> (an <code>mp_list</code>) with contents <code>tuple_element<T, mp_size_t<0>></code>, <code>tuple_element<T, mp_size_t<1>></code>, …​,
<p>C++17 has a standard variant type, called <code>std::variant</code>. It also defines a function template
<code>std::visit</code> that can be used to apply a function to the contained value of one or more variants.
So for instance, if the variant <code>v1</code> contains <code>1</code>, and the variant <code>v2</code> contains <code>2.0f</code>,
<code>std::visit(f, v1, v2)</code> will call <code>f(1, 2.0f)</code>.</p>
</div>
<divclass="paragraph">
<p>However, <code>std::visit</code> has one limitation: it cannot return a result unless all
possible applications of the function have the same return type. If, for instance, <code>v1</code> and <code>v2</code>
are both of type <code>std::variant<short, int, float></code>,</p>
</div>
<divclass="literalblock">
<divclass="content">
<pre>std::visit( []( auto const& x, auto const& y ){ return x + y; }, v1, v2 );</pre>
</div>
</div>
<divclass="paragraph">
<p>will fail to compile because the result of <code>x + y</code> can be either <code>int</code> or <code>float</code> depending on
what <code>v1</code> and <code>v2</code> hold.</p>
</div>
<divclass="paragraph">
<p>A type that can hold either <code>int</code> or <code>float</code> already exists, called, surprisingly enough, <code>std::variant<int, float></code>.
Let’s write our own function template <code>rvisit</code> that is the same as <code>visit</code> but returns a <code>variant</code>:</p>
</div>
<divclass="listingblock">
<divclass="content">
<preclass="highlight"><code>template<class F, class... V> auto rvisit( F&& f, V&&... v )
<p>What this does is basically calls <code>std::visit</code> to do the work, but instead of passing it <code>f</code>, we pass a lambda that does the same as <code>f</code> except
it converts the result to a common type <code>R</code>. <code>R</code> is supposed to be <code>std::variant<…​></code> where the ellipsis denotes the return types of
calling <code>f</code> with all possible combinations of variant values.</p>
</div>
<divclass="paragraph">
<p>We’ll first define a helper quoted metafunction <code>Qret<F></code> that returns the result of the application of <code>F</code> to arguments of type <code>T…​</code>:</p>
</div>
<divclass="literalblock">
<divclass="content">
<pre>template<class F> struct Qret
{
template<class... T> using fn = decltype( std::declval<F>()( std::declval<T>()... ) );
};</pre>
</div>
</div>
<divclass="paragraph">
<p>(Unfortunately, we can’t just define this metafunction inside <code>rvisit</code>; the language prohibits defining template aliases inside functions.)</p>
</div>
<divclass="paragraph">
<p>With <code>Qret</code> in hand, a <code>variant</code> of the possible return types is just a matter of applying it over the possible combinations of the variant values:</p>
</div>
<divclass="literalblock">
<divclass="content">
<pre>using R = mp_product_q<Qret<F>, std::remove_reference_t<V>...>;</pre>
</div>
</div>
<divclass="paragraph">
<p>Why does this work? <code>mp_product<F, L1<T1…​>, L2<T2…​>, …​, Ln<Tn…​>></code> returns <code>L1<F<U1, U2, …​, Un>, …​></code>, where <code>Ui</code> traverse all
possible combinations of list values. Since in our case all <code>Li</code> are <code>std::variant</code>, the result will also be <code>std::variant</code>. (<code>mp_product_q</code> is
the same as <code>mp_product</code>, but for quoted metafunctions such as our <code>Qret<F></code>.)</p>
</div>
<divclass="paragraph">
<p>One more step remains. Suppose that, as above, we’re passing two variants of type <code>std::variant<short, int, float></code> and <code>F</code> is
<code>[]( auto const& x, auto const& y ){ return x + y; }</code>. This will generate <code>R</code> of length 9, one per each combination, but many of those
elements will be the same, either <code>int</code> or <code>float</code>, and we need to filter out the duplicates. So,</p>
</div>
<divclass="literalblock">
<divclass="content">
<pre>using R = mp_unique<mp_product_q<Qret<F>, std::remove_reference_t<V>...>>;</pre>
<p><code>mp_list</code> is the standard list type of Mp11, although the library is not restricted to it and can operate on arbitrary class templates
such as <code>std::tuple</code> or <code>std::variant</code>. Even <code>std::pair</code> can be used if the transformation does not alter the number of the elements in
the list.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_size_l">mp_size<L></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L> using mp_size = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<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
using R1 = mp_size<L1>; // mp_size_t<0></pre>
</div>
</div>
<divclass="literalblock">
<divclass="content">
<pre>using L2 = std::pair<int, int>;
using R2 = mp_size<L2>; // mp_size_t<2></pre>
</div>
</div>
<divclass="literalblock">
<divclass="content">
<pre>using L3 = std::tuple<float>;
using R3 = mp_size<L3>; // mp_size_t<1></pre>
</div>
</div>
</div>
<divclass="sect3">
<h4id="mp_empty_l">mp_empty<L></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L> using mp_empty = mp_bool<mp_size<L>::value == 0>;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_empty<L></code> is an alias for <code>mp_true</code> if the list <code>L</code> is empty, for <code>mp_false</code> otherwise.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_front_l">mp_front<L></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L> using mp_front = /*...*/;</pre>
</div>
</div>
<divclass="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>
<divclass="literalblock">
<divclass="content">
<pre>using L1 = std::pair<int, float>;
using R1 = mp_front<L1>; // int</pre>
</div>
</div>
<divclass="literalblock">
<divclass="content">
<pre>using L2 = std::tuple<float, double, long double>;
<pre>template<class L> using mp_pop_front = /*...*/;</pre>
</div>
</div>
<divclass="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>
<divclass="literalblock">
<divclass="content">
<pre>using L1 = std::tuple<float, double, long double>;
using R1 = mp_pop_front<L1>; // std::tuple<double, long double></pre>
</div>
</div>
<divclass="literalblock">
<divclass="content">
<pre>using L2 = mp_list<void>;
using R2 = mp_pop_front<L2>; // mp_list<></pre>
</div>
</div>
</div>
<divclass="sect3">
<h4id="mp_first_l">mp_first<L></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L> using mp_first = mp_front<L>;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_first</code> is another name for <code>mp_front</code>.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_rest_l">mp_rest<L></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L> using mp_rest = mp_pop_front<L>;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_rest</code> is another name for <code>mp_pop_front</code>.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_second_l">mp_second<L></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L> using mp_second = /*...*/;</pre>
</div>
</div>
<divclass="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>
<divclass="literalblock">
<divclass="content">
<pre>using L1 = std::pair<int, float>;
using R1 = mp_second<L1>; // float</pre>
</div>
</div>
<divclass="literalblock">
<divclass="content">
<pre>using L2 = std::tuple<float, double, long double>;
<pre>template<class L> using mp_third = /*...*/;</pre>
</div>
</div>
<divclass="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>
<divclass="literalblock">
<divclass="content">
<pre>using L1 = std::tuple<float, double, long double>;
using R1 = mp_third<L1>; // long double</pre>
<pre>template<class L, class... T> using mp_push_front = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<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>
<divclass="literalblock">
<divclass="content">
<pre>using L1 = std::tuple<double, long double>;
using R1 = mp_push_front<L1, float>; // std::tuple<float, double, long double></pre>
</div>
</div>
<divclass="literalblock">
<divclass="content">
<pre>using L2 = mp_list<void>;
using R2 = mp_push_front<L2, char[1], char[2]>; // mp_list<char[1], char[2], void></pre>
<pre>template<class L, class... T> using mp_push_back = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<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>
<divclass="literalblock">
<divclass="content">
<pre>using L1 = std::tuple<double, long double>;
using R1 = mp_push_back<L1, float>; // std::tuple<double, long double, float></pre>
</div>
</div>
<divclass="literalblock">
<divclass="content">
<pre>using L2 = mp_list<void>;
using R2 = mp_push_back<L2, char[1], char[2]>; // mp_list<void, char[1], char[2]></pre>
</div>
</div>
</div>
<divclass="sect3">
<h4id="mp_rename_l_y">mp_rename<L, Y></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L, template<class...> class Y> using mp_rename = /*...*/;</pre>
</div>
</div>
<divclass="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>
<divclass="literalblock">
<divclass="content">
<pre>using L1 = std::pair<double, long double>;
using R1 = mp_rename<L1, std::tuple>; // std::tuple<double, long double></pre>
</div>
</div>
<divclass="literalblock">
<divclass="content">
<pre>using L2 = std::tuple<void>;
using R2 = mp_rename<L2, mp_list>; // mp_list<void></pre>
</div>
</div>
</div>
<divclass="sect3">
<h4id="mp_apply_f_l">mp_apply<F, L></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<template<class...> class F, class L> using mp_apply = mp_rename<L, F>;</pre>
</div>
</div>
<divclass="paragraph">
<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>
<divclass="literalblock">
<divclass="content">
<pre>using L1 = std::pair<double, long double>;
using R1 = mp_apply<std::is_same, L1>; // std::is_same<double, long double></pre>
<pre>template<class... L> using mp_append = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<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>
<divclass="listingblock">
<divclass="content">
<preclass="highlight"><code>using L1 = std::tuple<double, long double>;
<pre>template<class L, class T> using mp_replace_front = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<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>
<divclass="literalblock">
<divclass="content">
<pre>using L1 = std::pair<int, float>;
using R1 = mp_replace_front<L1, void>; // std::pair<void, float></pre>
</div>
</div>
<divclass="literalblock">
<divclass="content">
<pre>using L2 = std::tuple<float, double, long double>;
using R2 = mp_replace_front<L2, void>; // std::tuple<void, double, long double></pre>
<pre>template<class L, class T> using mp_replace_second = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<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>
<divclass="literalblock">
<divclass="content">
<pre>using L1 = std::pair<int, float>;
using R1 = mp_replace_second<L1, void>; // std::pair<int, void></pre>
</div>
</div>
<divclass="literalblock">
<divclass="content">
<pre>using L2 = std::tuple<float, double, long double>;
using R2 = mp_replace_second<L2, void>; // std::tuple<float, void, long double></pre>
<pre>template<class L, class T> using mp_replace_third = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<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>
<divclass="literalblock">
<divclass="content">
<pre>using L1 = std::tuple<float, double, long double>;
using R1 = mp_replace_third<L1, void>; // std::tuple<float, double, void></pre>
<pre>template<bool C, class T, class... E> using mp_if_c = /*...*/;</pre>
</div>
</div>
<divclass="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>
<divclass="literalblock">
<divclass="content">
<pre>using R1 = mp_if_c<true, int, void>; // int
using R2 = mp_if_c<flase, int, void>; // void</pre>
</div>
</div>
<divclass="literalblock">
<divclass="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>template<bool C, class T, template<class...> class F, class... U> using mp_eval_if_c = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_eval_if_c<C, T, F, U…​></code> is an alias for <code>T</code> when <code>C</code> is <code>true</code>, for <code>F<U…​></code> otherwise. Its purpose
is to avoid evaluating <code>F<U…​></code> when the condition is <code>true</code> as it may not be valid in this case.</p>
<pre>template<template<class...> class F, class... T> using mp_valid = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_valid<F, T…​></code> is an alias for <code>mp_true</code> when <code>F<T…​></code> is a valid expression, for <code>mp_false</code> otherwise.</p>
<pre>template<template<class...> class F, class... T> using mp_defer = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p>When <code>mp_valid<F, T…​></code> is <code>mp_true</code>, <code>mp_defer<F, T…​></code> is a struct with a nested type <code>type</code> which is an alias for <code>F<T…​></code>. Otherwise,
<code>mp_defer<F, T…​></code> is an empty struct.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_quote_f">mp_quote<F></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<template<class...> class F> struct mp_quote
{
template<class... T> using fn = F<T...>;
};</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_quote<F></code> transforms the template <code>F</code> into a type with a nested template <code>fn</code> such that <code>fn<T…​></code> returns <code>F<T…​></code>.</p>
<pre>template<class Q, class... T> using mp_invoke = typename Q::template fn<T...>;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_invoke<Q, T…​></code> evaluates the nested template <code>fn</code> of a quoted metafunction. <code>mp_invoke<mp_quote<F>, T…​></code> returns <code>F<T…​></code>.</p>
<pre>template<class L1, class L2> using mp_assign = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_assign<L1<T1…​>, L2<T2…​>></code> is an alias for <code>L1<T2…​></code>. That is, it replaces the elements of <code>L1</code> with those of <code>L2</code>.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_clear_l">mp_clear<L></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L> using mp_clear = mp_assign<L, mp_list<>>;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_clear<L<T…​>></code> is an alias for <code>L<></code>, that is, it removes the elements of <code>L</code>.</p>
<pre>template<template<class...> class F, class... L> using mp_transform = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_transform<F, L1<T1…​>, L2<T2…​>, …​, Ln<Tn…​>></code> applies <code>F</code> to each successive tuple of elements and returns <code>L1<F<T1, T2, …​, Tn>…​></code>.</p>
<pre>template<template<class...> class P, template<class...> class F, class L...> using mp_transform_if = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_transform_if<P, F, L1, L2, …​, Ln></code> replaces the elements of the list <code>L1</code> for which <code>mp_to_bool<P<T1, T2, …​, Tn>></code> is <code>mp_true</code> with
<code>F<T1, T2, …​, Tn></code>, and returns the result, where <code>Ti</code> are the corresponding elements of <code>Li</code>.</p>
<pre>template<class Qp, class Qf, class... L> using mp_transform_if_q = mp_transform_if<Qp::template fn, Qf::template fn, L...>;</pre>
</div>
</div>
<divclass="paragraph">
<p>As <code>mp_transform_if</code>, but takes a quoted metafunction.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_fill_l_v">mp_fill<L, V></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L, class V> using mp_fill = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_fill<L<T…​>, V></code> returns <code>L<V, V, …​, V></code>, with the result having the same size as the input.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_count_l_v">mp_count<L, V></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L, class V> using mp_count = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_count<L, V></code> returns <code>mp_size_t<N></code>, where <code>N</code> is the number of elements of <code>L</code> same as <code>V</code>.</p>
<pre>template<class L, template<class...> class P> using mp_count_if = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_count_if<L, P></code> returns <code>mp_size_t<N></code>, where <code>N</code> is the number of elements <code>T</code> of <code>L</code> for which <code>mp_to_bool<P<T>></code> is <code>mp_true</code>.</p>
<pre>template<class L, class V> using mp_contains = mp_to_bool<mp_count<L, V>>;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_contains<L, V></code> is <code>mp_true</code> when <code>L</code> contains an element <code>V</code>, <code>mp_false</code> otherwise.</p>
<pre>template<class L, std::size_t N> using mp_repeat_c = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_repeat_c<L, N></code> returns a list of the same type as <code>L</code> that consists of <code>N</code> concatenated copies of <code>L</code>.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_repeat_l_n">mp_repeat<L, N></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L, class N> using mp_repeat = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p>Same as <code>mp_repeat_c</code> but with a type argument <code>N</code>. The number of copies is <code>N::value</code> and must be nonnegative.</p>
<pre>template<template<class...> class F, class... L> using mp_product = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_product<F, L1<T1…​>, L2<T2…​>, …​, Ln<Tn…​>></code> evaluates <code>F<U1, U2, …​, Un></code> for values <code>Ui</code> taken from
the Cartesian product of the lists, as if the elements <code>Ui</code> are formed by <code>n</code> nested loops, each traversing <code>Li</code>.
It returns a list of type <code>L1</code> containing the results of the application of <code>F</code>.</p>
<pre>template<class Q, class... L> using mp_product_q = mp_product<Q::template fn, L...>;</pre>
</div>
</div>
<divclass="paragraph">
<p>As <code>mp_product</code>, but takes a quoted metafunction.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_drop_c_l_n">mp_drop_c<L, N></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L, std::size_t N> using mp_drop_c = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_drop_c<L, N></code> removes the first <code>N</code> elements of <code>L</code> and returns the result.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_drop_l_n">mp_drop<L, N></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L, class N> using mp_drop = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p>Same as <code>mp_drop_c</code>, but with a type argument <code>N</code>. <code>N::value</code> must be a nonnegative number.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_iota_c_n">mp_iota_c<N></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<std::size_t N> using mp_iota_c = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_iota_c<N></code> is an alias for <code>mp_list<mp_size_t<0>, mp_size_t<1>, …​, mp_size_t<N-1>></code>.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_iota_n">mp_iota<N></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class N> using mp_iota = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p>Same as <code>mp_iota_c</code>, but with a type argument <code>N</code>. <code>N::value</code> must be a nonnegative number. Returns
where <code>T</code> is the type of <code>N::value</code>.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_at_c_l_i">mp_at_c<L, I></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L, std::size_t I> using mp_at_c = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_at_c<L, I></code> returns the <code>I`th element of `L</code>, zero-based.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_at_l_i">mp_at<L, I></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L, class I> using mp_at = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p>Same as <code>mp_at_c</code>, but with a type argument <code>I</code>. <code>I::value</code> must be a nonnegative number.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_take_c_l_n">mp_take_c<L, N></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L, std::size_t N> using mp_take_c = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_take_c<L, N></code> returns a list of the same type as <code>L</code> containing the first <code>N</code> elements of <code>L</code>.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_take_l_n">mp_take<L, N></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L, class N> using mp_take = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p>Same as <code>mp_take_c</code>, but with a type argument <code>N</code>. <code>N::value</code> must be a nonnegative number.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_insert_c_l_i_t">mp_insert_c<L, I, T…​></h4>
<divclass="literalblock">
<divclass="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>
</div>
</div>
<divclass="paragraph">
<p>Inserts the elements <code>T…​</code> into the list <code>L</code> at position <code>I</code> (a zero-based index).</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_insert_l_i_t">mp_insert<L, I, T…​></h4>
<divclass="literalblock">
<divclass="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>
</div>
</div>
<divclass="paragraph">
<p>Same as <code>mp_insert_c</code>, but with a type argument <code>I</code>.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_erase_c_l_i_j">mp_erase_c<L, I, J></h4>
<divclass="literalblock">
<divclass="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>
</div>
</div>
<divclass="paragraph">
<p>Removes from the list <code>L</code> the elements with indices from <code>I</code> (inclusive) to <code>J</code> (exclusive).</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_erase_l_i_j">mp_erase<L, I, J></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L, class I, class J> using mp_erase = mp_append<mp_take<L, I>, mp_drop<L, J>>;</pre>
</div>
</div>
<divclass="paragraph">
<p>Same as <code>mp_erase_c</code>, but with a type arguments <code>I</code> and <code>J</code>.</p>
<pre>template<class L, template<class...> class P, class W> using mp_replace_if = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p>Replaces all <code>T</code> elements of <code>L</code> for which <code>mp_to_bool<P<T>></code> is <code>mp_true</code> with <code>W</code> and returns the result.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_replace_at_c_l_i_w">mp_replace_at_c<L, I, W></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L, std::size_t I, class W> using mp_replace_at_c = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p>Replaces the element of <code>L</code> at zero-based index <code>I</code> with <code>W</code> and returns the result.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_replace_at_l_i_w">mp_replace_at<L, I, W></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L, class I, class W> using mp_replace_at = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p>Same as <code>mp_replace_at_c</code>, but with a type argument <code>I</code>. <code>I::value</code> must be a nonnegative number.</p>
<pre>template<class L, template<class...> class P> using mp_copy_if = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p>Copies the elements <code>T</code> of <code>L</code> for which <code>mp_to_bool<P<T>></code> is <code>mp_true</code> to a new list of the same type and returns it.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_remove_l_v">mp_remove<L, V></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L, class V> using mp_remove = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p>Removes all <code>V</code> elements of <code>L</code> and returns the result.</p>
<pre>template<class L, template<class...> class P> using mp_remove_if = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p>Removes all elements <code>T</code> of <code>L</code> for which <code>mp_to_bool<P<T>></code> is <code>mp_true</code> and returns the result.</p>
<pre>template<class L, template<class...> class P> using mp_partition = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_partition<L<T…​>, P></code> partitions <code>L</code> into two lists <code>L<U1…​></code> and <code>L<U2…​></code> such that <code>mp_to_bool<P<T>></code> is <code>mp_true</code>
for the elements of <code>L<U1…​></code> and <code>mp_false</code> for the elements of <code>L<U2…​></code>. Returns <code>L<L<U1…​>, L<U2…​>></code>.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_sort_l_p">mp_sort<L, P></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L, template<class...> class P> using mp_sort = /*...*/;</pre>
</div>
</div>
<divclass="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>
<divclass="sect3">
<h4id="mp_find_l_v">mp_find<L, V></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L, class V> using mp_find = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_find<L, V></code> returns the index at which the type <code>V</code> is located in the list <code>L</code>. It’s an alias for <code>mp_size_t<I></code>,
where <code>I</code> is the zero-based index of the first occurence of <code>V</code> in <code>L</code>. If <code>L</code> does not contain <code>V</code>, <code>mp_find<L, V></code>
<pre>template<class L, template<class...> class P> using mp_find_if = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_find_f<L, P></code> is an alias for <code>mp_size_t<I></code>, where <code>I</code> is the zero-based index of the first element <code>T</code> in <code>L</code> for which
<code>mp_to_bool<P<T>></code> is <code>mp_true</code>. If there is no such element, <code>mp_find_if<L, P></code> is <code>mp_size<L></code>.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_reverse_l">mp_reverse<L></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L> using mp_reverse = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_reverse<L<T1, T2, …​, Tn>></code> is <code>L<Tn, …​, T2, T1></code>.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_fold_l_v_f">mp_fold<L, V, F></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L, class V, template<class...> class F> using mp_fold = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_fold<L<T1, T2, …​, Tn>, V, F></code> is <code>F< F< F< F<V, T1>, T2>, …​>, Tn></code>, or <code>V</code>, if <code>L</code> is empty.</p>
<pre>template<class L, class V, template<class...> class F> using mp_reverse_fold = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_reverse_fold<L<T1, T2, …​, Tn>, V, F></code> is <code>F<T1, F<T2, F<…​, F<Tn, V>>>></code>, or <code>V</code>, if <code>L</code> is empty.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_unique_l">mp_unique<L></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L> using mp_unique = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_unique<L></code> returns a list of the same type as <code>L</code> with the duplicate elements removed.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_all_of_l_p">mp_all_of<L, P></h4>
<divclass="literalblock">
<divclass="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>
</div>
</div>
<divclass="paragraph">
<p><code>mp_all_of<L, P></code> is <code>mp_true</code> when <code>P</code> holds for all elements of <code>L</code>, <code>mp_false</code> otherwise. When <code>L</code> is empty, the result is <code>mp_true</code>.</p>
<pre>template<class L, template<class...> class P> using mp_none_of = mp_bool< mp_count_if<L, P>::value == 0 >;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_none_of<L, P></code> is <code>mp_true</code> when <code>P</code> holds for no element of <code>L</code>, <code>mp_false</code> otherwise. When <code>L</code> is empty, the result is <code>mp_true</code>.</p>
</div>
</div>
<divclass="sect3">
<h4id="mp_any_of_l_p">mp_any_of<L, P></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class L, template<class...> class P> using mp_any_of = mp_bool< mp_count_if<L, P>::value != 0 >;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_any_of<L, P></code> is <code>mp_true</code> when <code>P</code> holds for at least one element of <code>L</code>, <code>mp_false</code> otherwise. When <code>L</code> is empty, the result is <code>mp_false</code>.</p>
<pre>template<class L, class F> constexpr F mp_for_each(F&& f);</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_for_each<L>(f)</code> calls <code>f</code> with <code>T()</code> for each element <code>T</code> of the list <code>L</code>, in order.</p>
<pre>template<std::size_t N, class F> decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) mp_with_index( std::size_t i, F && f );</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_with_index<N>(i, f)</code> calls <code>f</code> with <code>mp_size_t<i>()</code> and returns the result. <code>i</code> must be less than <code>N</code>.</p>
</div>
<divclass="literalblock">
<divclass="content">
<pre>template<class N, class F> decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) mp_with_index( std::size_t i, F && f );</pre>
<pre>template<class S, class V> using mp_set_contains = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_set_contains<S, V></code> is <code>mp_true</code> if the type <code>V</code> is an element of the set <code>S</code>, <code>mp_false</code> otherwise.</p>
<pre>template<class S, class... T> using mp_set_push_back = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p>For each <code>T1</code> in <code>T…​</code>, <code>mp_set_push_back<S, T…​></code> appends <code>T1</code> to the end of <code>S</code> if it’s not already an element of <code>S</code>.</p>
<pre>template<class S, class... T> using mp_set_push_front = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_set_push_front<S, T…​></code> inserts at the front of <code>S</code> those elements of <code>T…​</code> for which <code>S</code> does not already contain the same type.</p>
<pre>template<class M, class K> using mp_map_find = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_map_find<M, K></code> is an alias for the element of the map <code>M</code> with a key <code>K</code>, or for <code>void</code>, if there is no such element.</p>
<pre>template<class M, class K> using mp_map_contains = mp_not<std::is_same<mp_map_find<M, K>, void>>;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_map_contains<M, K></code> is <code>mp_true</code> if the map <code>M</code> contains an element with a key <code>K</code>, <code>mp_false</code> otherwise.</p>
<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>
<divclass="paragraph">
<p>Inserts the element <code>T</code> into the map <code>M</code>, if an element with a key <code>mp_first<T></code> is not already in <code>M</code>.</p>
<pre>template<class M, class T> using mp_map_replace = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p>If the map <code>M</code> does not contain an element with a key <code>mp_first<T></code>, inserts it (using <code>mp_push_back<M, T></code>); otherwise,
replaces the existing element with <code>T</code>.</p>
<pre>template<class M, class T, template<class...> class F> using mp_map_update = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p>If the map <code>M</code> does not contain an element with a key <code>mp_first<T></code>, inserts it (using <code>mp_push_back<M, T></code>); otherwise,
replaces the existing element <code>L<X, Y…​></code> with <code>L<X, F<X, Y…​>></code>.</p>
<pre>template<class... T> using mp_and = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_and<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_false</code>, <code>mp_and</code>
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>
<pre>template<class... T> using mp_all = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_all<T…​></code> is <code>mp_true</code> if <code>mp_to_bool<U></code> is <code>mp_true</code> for all types <code>U</code> in <code>T…​</code>, <code>mp_false</code> otherwise. Same as
<code>mp_and</code>, but does not perform short-circuit evaluation. <code>mp_and<mp_false, void></code> is <code>mp_false</code>, but <code>mp_all<mp_false, void></code>
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>
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>
</div>
</div>
</div>
<divclass="sect3">
<h4id="mp_or_t">mp_or<T…​></h4>
<divclass="literalblock">
<divclass="content">
<pre>template<class... T> using mp_or = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<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>
<pre>template<class... T> using mp_any = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<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>
<pre>template<class... T> using mp_same = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_same<T…​></code> is <code>mp_true</code> if all the types in <code>T…​</code> are the same type, <code>mp_false</code> otherwise. <code>mp_same<></code> is <code>mp_true</code>.</p>
<pre>template<class... T> using mp_plus = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_plus<T…​></code> is an integral constant type with a value that is the sum of <code>U::value</code> for all types <code>U</code> in <code>T…​</code>.
<code>mp_plus<></code> is <code>mp_int<0></code>.</p>
<p><code>mp_arg<I></code> is a quoted metafunction whose nested template <code>fn<T…​></code> returns the <code>I</code>-th zero-based element of <code>T…​</code>.</p>
</div>
</div>
<divclass="sect3">
<h4id="1_9">_1, …​, _9</h4>
<divclass="literalblock">
<divclass="content">
<pre>using _1 = mp_arg<0>;
using _2 = mp_arg<1>;
using _3 = mp_arg<2>;
using _4 = mp_arg<3>;
using _5 = mp_arg<4>;
using _6 = mp_arg<5>;
using _7 = mp_arg<6>;
using _8 = mp_arg<7>;
using _9 = mp_arg<8>;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>_1</code> to <code>_9</code> are placeholder types, the equivalent to the placeholders of <code>boost::bind</code>.</p>
<pre>template<template<class...> class F, class... T> struct mp_bind;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_bind<F, T…​></code> is a quoted metafunction that implements the type-based equivalent of <code>boost::bind</code>. Its nested
template <code>fn<U…​></code> returns <code>F<V…​></code>, where <code>V…​</code> is <code>T…​</code> with the placeholders replaced by the corresponding element
of <code>U…​</code> and the <code>mp_bind</code> expressions replaced with their corresponding evaluations against <code>U…​</code>.</p>
</div>
<divclass="paragraph">
<p>For example, <code>mp_bind<F, int, _2, mp_bind<G, _1>>::fn<float, void></code> is <code>F<int, void, G<float>></code>.</p>
<pre>template<template<class...> class F, class... T> struct mp_bind_front;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_bind_front<F, T…​></code> binds the leftmost arguments of <code>F</code> to <code>T…​</code>. Its nested template <code>fn<U…​></code> returns <code>F<T…​, U…​></code>.</p>
<pre>template<template<class...> class F, class... T> struct mp_bind_back;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>mp_bind_back<F, T…​></code> binds the rightmost arguments of <code>F</code> to <code>T…​</code>. Its nested template <code>fn<U…​></code> returns <code>F<U…​, T…​></code>.</p>
<p><code>integer_sequence<T, I…​></code> holds a sequence of integers of type <code>T</code>. Same as C++14’s <code>std::integer_sequence</code>.</p>
<pre>template<class T, T N> using make_integer_sequence = /*...*/;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>make_integer_sequence<T, N></code> is <code>integer_sequence<T, 0, 1, …​, N-1></code>. Same as C++14’s <code>std::make_integer_sequence</code>.</p>
<pre>template<std::size_t... I> using index_sequence = integer_sequence<std::size_t, I...>;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>index_sequence<I…​></code> is an alias for <code>integer_sequence<size_t, I…​></code>. Same as C++14’s <code>std::index_sequence</code>.</p>
<pre>template<std::size_t N> using make_index_sequence = make_integer_sequence<std::size_t, N>;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>make_index_sequence<N></code> is <code>index_sequence<0, 1, …​, N-1></code>. Same as C++14’s <code>std::make_index_sequence</code>.</p>
<pre>template<class... T> using index_sequence_for = make_integer_sequence<std::size_t, sizeof...(T)>;</pre>
</div>
</div>
<divclass="paragraph">
<p><code>index_sequence_for<N></code> is <code>make_index_sequence<sizeof…​(T)></code>. Same as C++14’s <code>std::index_sequence_for</code>.</p>
<pre>template<class F, class Tp> constexpr /*...*/ tuple_apply(F&& f, Tp&& tp);</pre>
</div>
</div>
<divclass="paragraph">
<p><code>tuple_apply(f, tp)</code> returns <code>std::forward<F>(f)(std::get<J>(std::forward<Tp>(tp))…​)</code> for <code>J</code> in 0..<code>N-1</code>,
where <code>N</code> is <code>std::tuple_size<typename std::remove_reference<Tp>::type>::value</code>. Same as <code>std::apply</code> in C++17.</p>
<pre>template<class T, class Tp> T make_from_tuple(Tp&& tp);</pre>
</div>
</div>
<divclass="paragraph">
<p><code>make_from_tuple<T>(tp)</code> returns <code>T(std::get<J>(std::forward<Tp>(tp))…​)</code> for <code>J</code> in 0..<code>N-1</code>,
where <code>N</code> is <code>std::tuple_size<typename std::remove_reference<Tp>::type>::value</code>. Same as <code>std::make_from_tuple</code> in C++17.</p>
<pre>template<class Tp, class F> constexpr F tuple_for_each(Tp&& tp, F&& f);</pre>
</div>
</div>
<divclass="paragraph">
<p><code>tuple_for_each(tp, f)</code> applies the function object <code>f</code> to each element of <code>tp</code> by evaluating the
expression <code>f(std::get<J>(std::forward<Tp>(tp)))</code> for <code>J</code> in 0..<code>N-1</code>, where <code>N</code> is <code>std::tuple_size<typename std::remove_reference<Tp>::type>::value</code>.</p>