# Boost.Mp11: A C++11 metaprogramming library

Peter Dimov

## Overview

Mp11 is a C++11 metaprogramming library for compile-time manipulation of data structures that contain types. It’s based on template aliases and variadic templates and implements the approach outlined in the article "Simple C++ metaprogramming" and its sequel. Reading these articles before proceeding with this documentation is highly recommended.

The general principles upon which Mp11 is built are that algorithms and metafunctions are template aliases of the form `F<T…​>` and data structures are lists of the form `L<T…​>`, with the library placing no requirements on `L`. `mp_list<T…​>` is the built-in list type, but `std::tuple<T…​>`, `std::pair<T1, T2>` and `std::variant<T…​>` are also perfectly legitimate list types, although of course `std::pair<T1, T2>`, due to having exactly two elements, is not resizeable and will consequently not work with algorithms that need to add or remove elements.

Another distinguishing feature of this approach is that lists (`L<T…​>`) have the same form as metafunctions (`F<T…​>`) and can therefore be used as such. For example, applying `std::add_pointer_t` to the list `std::tuple<int, float>` by way of `mp_transform<std::add_pointer_t, std::tuple<int, float>>` gives us `std::tuple<int*, float*>`, but we can also apply `mp_list` to the same tuple:

    using R = mp_transform<mp_list, std::tuple<int, float>>;

and get `std::tuple<mp_list<int>, mp_list<float>>`.

## Definitions

A list is a — usually but not necessarily variadic — template class whose parameters are all types, for example `mp_list<char[], void>`, `mp_list<>`, `std::tuple<int, float, char>`, `std::pair<int, float>`, `std::shared_ptr<X>`.

A metafunction is a class template or a template alias whose parameters are all types, for example `std::add_pointer_t`, `std::is_const`, `mp_second`, `mp_push_front`, `mp_list`, `std::tuple`, `std::pair`, `std::shared_ptr`, or

    template<class...> using F1 = void;

    template<class T> using F2 = T*;

    template<class... T> using F3 = std::integral_constant<std::size_t, sizeof...(T)>;

A quoted metafunction is a class with a public metafunction member called `fn`, for example

    struct Q1 { template<class...> using fn = void; };

    struct Q2 { template<class T> using fn = T*; };

    struct Q3 { template<class... T> using fn =
      std::integral_constant<std::size_t, sizeof...(T)>; };

An integral constant type is a class with a public member `value` that is an integral constant in the C++ sense. For example, `std::integral_constant<int, 7>`, or

    struct N { static int constexpr value = 2; };

A set is a list whose elements are unique.

A map is a list of lists, the inner lists having at least one element (the key.) The keys of the map must be unique. For example,

    using M1 = std::tuple<std::pair<int, int*>, std::pair<float, float*>,
        std::pair<void, void*>>;

    using M2 = mp_list<mp_list<int, int*>, mp_list<float>,
        mp_list<char, char[1], char[2]>>;

## Examples

### Generating Test Cases

Let’s suppose that we have written a metafunction `result<T, U>`:

    template<class T> using promote = typename std::common_type<T, int>::type;

    template<class T, class U> using result =
        typename std::common_type<promote<T>, promote<U>>::type;

that ought to represent the result of an arithmetic operation on the integer types `T` and `U`, for example `t + u`. We want to test whether `result<T, U>` gives correct results for various combinations of `T` and `U`, so we write the function

    template<class T1, class T2> void test_result()
    {
        using T3 = decltype( T1() + T2() );
        using T4 = result<T1, T2>;

        std::cout << ( std::is_same<T3, T4>::value? "[PASS]": "[FAIL]" ) << std::endl;
    }

and then need to call it a substantial number of times:

    int main()
    {
        test_result<char, char>();
        test_result<char, short>();
        test_result<char, int>();
        test_result<char, unsigned>();
        // ...
    }

Writing all those type combinations by hand is unwieldy, error prone, and worst of all, boring. This is how we can leverage Mp11 to automate the task:

    #include <boost/mp11.hpp>
    #include <boost/core/demangle.hpp>
    #include <type_traits>
    #include <iostream>
    #include <typeinfo>

    using namespace boost::mp11;

    template<class T> std::string name()
    {
        return boost::core::demangle( typeid(T).name() );
    }

    template<class T> using promote = typename std::common_type<T, int>::type;

    template<class T, class U> using result =
        typename std::common_type<promote<T>, promote<U>>::type;

    template<class T1, class T2> void test_result( mp_list<T1, T2> const& )
    {
        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>(), [](auto&& x){ test_result(x); } );
    }

How does it work?

`mp_product<F, L1, L2>` calls `F<T1, T2>` where `T1` varies over the elements of `L1` and `T2` varies over the elements of `L2`, as if by executing two nested loops. It then returns a list of these results, of the same type as `L1`.

In our case, both lists are the same `std::tuple`, and `F` is `mp_list`, so `mp_product<mp_list, L, L>` will get us `std::tuple<mp_list<char, char>, mp_list<char, short>, mp_list<char, int>, …​, mp_list<unsigned long, long>, mp_list<unsigned long, unsigned long>>`.

We then default-construct this tuple and pass it to `tuple_for_each`. `tuple_for_each(tp, f)` calls `f` for every tuple element; we use a (C++14) lambda that calls `test_result`.

In pure C++11, we 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() );
    }

### Writing common_type Specializations

The standard trait `std::common_type`, used to obtain a type to which all of its arguments can convert without unnecessary loss of precision, can be user-specialized when its default implementation (based on the ternary `?:` operator) is unsuitable.

Let’s write a `common_type` specialization for two `std::tuple` arguments. For that, we need a metafunction that applies `std::common_type` to each pair of elements and gathers the results into a tuple:

    template<class... 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:

    namespace std
    {

        template<class... T1, class... T2>
        struct common_type<std::tuple<T1...>, std::tuple<T2...>>:
            mp_defer<common_tuple, std::tuple<T1...>, std::tuple<T2...>>
        {
        };

    } // std

(There is no need to specialize `std::common_type` for more than two arguments - it takes care of synthesizing the appropriate semantics from the binary case.)

The subtlety here is the use of `mp_defer`. We could have defined a nested `type` to `common_tuple<std::tuple<T1…​>, std::tuple<T2…​>>`, and it would still have worked in all valid cases. By letting `mp_defer` define `type`, though, we make our specialization SFINAE-friendly.

That is, when our `common_tuple` causes a substitution failure instead of a hard error, `mp_defer` will not define a nested `type`, and `common_type_t`, which is defined as `typename common_type<…​>::type`, will also cause a substitution failure.

As another example, consider the hypothetical type `expected<T, E…​>` that represents either a successful return with a value of `T`, or an unsucessful return with an error code of some type in the list `E…​`. The common type of `expected<T1, E1, E2, E3>` and `expected<T2, E1, E4, E5>` is `expected<common_type_t<T1, T2>, E1, E2, E3, E4, E5>`. That is, the possible return values are combined into their common type, and we take the union of the set of error types.

Therefore,

    template<class T1, class E1, class T2, class E2> using common_expected =
        mp_rename<mp_push_front<mp_unique<mp_append<E1, E2>>, common_type_t<T1, T2>>,
            expected>;

    namespace std
    {

        template<class T1, class... E1, class T2, class... E2>
        struct common_type<expected<T1, E1...>, expected<T2, E2...>>:
            mp_defer<common_expected, T1, mp_list<E1...>, T2, mp_list<E2...>>
        {
        };

    } // std

Here we’ve taken a different tack; instead of passing the `expected` types to `common_expected`, we’re passing the `T` types and lists of the `E` types. This makes our job easier. `mp_unique<mp_append<E1, E2>>` gives us the concatenation of `E1` and `E2` with the duplicates removed; we then add `common_type_t<T1, T2>` to the front via `mp_push_front`; and finally, we `mp_rename` the resultant `mp_list` to `expected`.

### Fixing tuple_cat

The article Simple C++11 metaprogramming builds an implementation of the standard function `tuple_cat`, with the end result given below:

    template<class L> using F = mp_iota<mp_size<L>>;

    template<class R, class...Is, class... Ks, class Tp>
    R tuple_cat_( mp_list<Is...>, mp_list<Ks...>, Tp tp )
    {
        return R{ std::get<Ks::value>(std::get<Is::value>(tp))... };
    }

    template<class... Tp,
        class R = mp_append<std::tuple<>, typename std::remove_reference<Tp>::type...>>
        R tuple_cat( Tp &&... tp )
    {
        std::size_t const N = sizeof...(Tp);

        // inner

        using list1 = mp_list<
            mp_rename<typename std::remove_reference<Tp>::type, mp_list>...>;

        using list2 = mp_iota_c<N>;

        using list3 = mp_transform<mp_fill, list1, list2>;

        using inner = mp_apply<mp_append, list3>;

        // outer

        using list4 = mp_transform<F, list1>;

        using outer = mp_apply<mp_append, list4>;

        //

        return tuple_cat_<R>( inner(), outer(),
            std::forward_as_tuple( std::forward<Tp>(tp)... ) );
    }

This function, however, is not entirely correct, in that it doesn’t handle some cases properly. For example, trying to concatenate tuples containing move-only elements such as `unique_ptr` fails:

    std::tuple<std::unique_ptr<int>> t1;
    std::tuple<std::unique_ptr<float>> t2;

    auto result = ::tuple_cat( std::move( t1 ), std::move( t2 ) );

Trying to concatenate `const` tuples fails:

    std::tuple<int> const t1;
    std::tuple<float> const t2;

    auto result = ::tuple_cat( t1, t2 );

And finally, the standard `tuple_cat` is specified to work on arbitrary tuple-like types (that is, all types that support `tuple_size`, `tuple_element`, and `get`), while our implementation only works with `tuple` and `pair`. `std::array`, for example, fails:

    std::array<int, 2> t1{ 1, 2 };
    std::array<float, 3> t2{ 3.0f, 4.0f, 5.0f };

    auto result = ::tuple_cat( t1, t2 );

Let’s fix these one by one. Support for move-only types is easy, if one knows where to look. The problem is that `Tp` that we’re passing to the helper `tuple_cat_` is (correctly) `tuple<unique_ptr<int>&&, unique_ptr<float>&&>`, but `std::get<0>(tp)` still returns `unique_ptr<int>&`, because `tp` is an lvalue. This behavior is a bit surprising, but is intended to prevent inadvertent double moves.

Long story short, we need `std::move(tp)` in `tuple_cat_` to make `tp` an rvalue:

    template<class R, class...Is, class... Ks, class Tp>
    R tuple_cat_( mp_list<Is...>, mp_list<Ks...>, Tp tp )
    {
        return R{ std::get<Ks::value>(std::get<Is::value>(std::move(tp)))... };
    }

Next, `const`-qualified tuples. The issue here is that we’re stripping references from the input tuples, but not `const`. As a result, we’re trying to manipulate types such as `tuple<int> const` with Mp11 algorithms, and these types do not fit the list concept. We just need to strip qualifiers as well, by defining the useful `remove_cv_ref` primitive that is inexplicably missing from the standard library:

    template<class T> using remove_cv_ref = typename std::remove_cv<
        typename std::remove_reference<T>::type>::type;

and then by using `remove_cv_ref<Tp>` in place of `typename std::remove_reference<Tp>::type`:

    template<class... Tp,
        class R = mp_append<std::tuple<>, remove_cv_ref<Tp>...>>
        R tuple_cat( Tp &&... tp )
    {
        std::size_t const N = sizeof...(Tp);

        // inner

        using list1 = mp_list<mp_rename<remove_cv_ref<Tp>, mp_list>...>;

        // ...

Finally, tuple-like types. We’ve so far exploited the fact that `std::pair` and `std::tuple` 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 `from_tuple_like` that will take an arbitrary tuple-like type and will return, in our case, the corresponding `mp_list`.

Technically, a more principled approach would’ve been to return `std::tuple`, but here `mp_list` will prove more convenient.

What we need is, given a tuple-like type `Tp`, to obtain `mp_list<std::tuple_element<0, Tp>::type, std::tuple_element<1, Tp>::type, …​, std::tuple_element<N-1, Tp>::type>`, where `N` is `tuple_size<Tp>::value`. Here’s one way to do it:

    template<class T, class I> using tuple_element =
        typename std::tuple_element<I::value, T>::type;

    template<class T> using from_tuple_like =
        mp_product<tuple_element, mp_list<T>, mp_iota<std::tuple_size<T>>>;

(`mp_iota<N>` is an algorithm that returns an `mp_list` with elements `mp_size_t<0>`, `mp_size_t<1>`, …​, `mp_size_t<N-1>`.)

Remember that `mp_product<F, L1, L2>` performs the equivalent of two nested loops over the elements of `L1` and `L2`, applying `F` to the two variables and gathering the result. In our case `L1` consists of the single element `T`, so only the second loop (over `mp_iota<N>`, where `N` is `tuple_size<T>`), remains, and we get a list of the same type as `L1` (an `mp_list`) with contents `tuple_element<T, mp_size_t<0>>`, `tuple_element<T, mp_size_t<1>>`, …​, `tuple_element<T, mp_size_t<N-1>>`.

For completeness’s sake, here’s another, more traditional way to achieve the same result:

    template<class T> using from_tuple_like =
        mp_transform_q<mp_bind_front<tuple_element, T>, mp_iota<std::tuple_size<T>>>;

With all these fixes applied, our fully operational `tuple_cat` now looks like this:

    template<class L> using F = mp_iota<mp_size<L>>;

    template<class R, class...Is, class... Ks, class Tp>
    R tuple_cat_( mp_list<Is...>, mp_list<Ks...>, Tp tp )
    {
        return R{ std::get<Ks::value>(std::get<Is::value>(std::move(tp)))... };
    }

    template<class T> using remove_cv_ref = typename std::remove_cv<
        typename std::remove_reference<T>::type>::type;

    template<class T, class I> using tuple_element =
        typename std::tuple_element<I::value, T>::type;

    template<class T> using from_tuple_like =
        mp_product<tuple_element, mp_list<T>, mp_iota<std::tuple_size<T>>>;

    template<class... Tp,
        class R = mp_append<std::tuple<>, from_tuple_like<remove_cv_ref<Tp>>...>>
        R tuple_cat( Tp &&... tp )
    {
        std::size_t const N = sizeof...(Tp);

        // inner

        using list1 = mp_list<from_tuple_like<remove_cv_ref<Tp>>...>;
        using list2 = mp_iota_c<N>;

        using list3 = mp_transform<mp_fill, list1, list2>;

        using inner = mp_apply<mp_append, list3>;

        // outer

        using list4 = mp_transform<F, list1>;

        using outer = mp_apply<mp_append, list4>;

        //

        return tuple_cat_<R>( inner(), outer(),
            std::forward_as_tuple( std::forward<Tp>(tp)... ) );
    }

### Computing Return Types

C++17 has a standard variant type, called `std::variant`. It also defines a function template `std::visit` that can be used to apply a function to the contained value of one or more variants. So for instance, if the variant `v1` contains `1`, and the variant `v2` contains `2.0f`, `std::visit(f, v1, v2)` will call `f(1, 2.0f)`.

However, `std::visit` has one limitation: it cannot return a result unless all possible applications of the function have the same return type. If, for instance, `v1` and `v2` are both of type `std::variant<short, int, float>`,

    std::visit( []( auto const& x, auto const& y ){ return x + y; }, v1, v2 );

will fail to compile because the result of `x + y` can be either `int` or `float` depending on what `v1` and `v2` hold.

A type that can hold either `int` or `float` already exists, called, surprisingly enough, `std::variant<int, float>`. Let’s write our own function template `rvisit` that is the same as `visit` but returns a `variant`:

    template<class F, class... V> auto rvisit( F&& f, V&&... v )
    {
        using R = /*...*/;

        return std::visit( [&]( auto&&... x )
            { return R( std::forward<F>(f)( std::forward<decltype(x)>(x)... ) ); },
            std::forward<V>( v )... );
    }

What this does is basically calls `std::visit` to do the work, but instead of passing it `f`, we pass a lambda that does the same as `f` except it converts the result to a common type `R`. `R` is supposed to be `std::variant<…​>` where the ellipsis denotes the return types of calling `f` with all possible combinations of variant values.

We’ll first define a helper quoted metafunction `Qret<F>` that returns the result of the application of `F` to arguments of type `T…​`:

    template<class F> struct Qret
    {
        template<class... T> using fn =
            decltype( std::declval<F>()( std::declval<T>()... ) );
    };

(Unfortunately, we can’t just define this metafunction inside `rvisit`; the language prohibits defining template aliases inside functions.)

With `Qret` in hand, a `variant` of the possible return types is just a matter of applying it over the possible combinations of the variant values:

    using R = mp_product_q<Qret<F>, std::remove_reference_t<V>...>;

Why does this work? `mp_product<F, L1<T1…​>, L2<T2…​>, …​, Ln<Tn…​>>` returns `L1<F<U1, U2, …​, Un>, …​>`, where `Ui` traverse all possible combinations of list values. Since in our case all `Li` are `std::variant`, the result will also be `std::variant`. (`mp_product_q` is the same as `mp_product`, but for quoted metafunctions such as our `Qret<F>`.)

One more step remains. Suppose that, as above, we’re passing two variants of type `std::variant<short, int, float>` and `F` is `[]( auto const& x, auto const& y ){ return x + y; }`. This will generate `R` of length 9, one per each combination, but many of those elements will be the same, either `int` or `float`, and we need to filter out the duplicates. So, we pass the result to `mp_unique`:

    using R = mp_unique<mp_product_q<Qret<F>, std::remove_reference_t<V>...>>;

and we’re done:

    #include <boost/mp11.hpp>
    #include <boost/core/demangle.hpp>
    #include <variant>
    #include <type_traits>
    #include <typeinfo>
    #include <iostream>

    using namespace boost::mp11;

    template<class F> struct Qret
    {
        template<class... T> using fn =
            decltype( std::declval<F>()( std::declval<T>()... ) );
    };

    template<class F, class... V> auto rvisit( F&& f, V&&... v )
    {
        using R = mp_unique<mp_product_q<Qret<F>, std::remove_reference_t<V>...>>;

        return std::visit( [&]( auto&&... x )
            { return R( std::forward<F>(f)( std::forward<decltype(x)>(x)... ) ); },
            std::forward<V>( v )... );
    }

    template<class T> std::string name()
    {
        return boost::core::demangle( typeid(T).name() );
    }

    template<class V> void print_variant( char const * n, V const& v )
    {
        std::cout << "(" << name<decltype(v)>() << ")" << n << ": ";

        std::visit( []( auto const& x )
            { std::cout << "(" << name<decltype(x)>() << ")" << x << std::endl; }, v );
    }

    int main()
    {
        std::variant<char, int, float> v1( 1 );

        print_variant( "v1", v1 );

        std::variant<short, int, double> v2( 3.14 );

        print_variant( "v2", v2 );

        auto v3 = rvisit( []( auto const& x, auto const& y ){ return x + y; }, v1, v2 );

        print_variant( "v3", v3 );
    }

## Reference

The contents of the library are in namespace `boost::mp11`.

### Integral Constants, <boost/mp11/integral.hpp>

For an Mp11 integral constant type `T`, `T::value` is an integral constant in the C++ sense.

#### mp_bool<B>

    template<bool B> using mp_bool = std::integral_constant<bool, B>;

Same as `std::bool_constant` in C++17.

#### mp_true

    using mp_true = mp_bool<true>;

Same as `std::true_type`.

#### mp_false

    using mp_false = mp_bool<false>;

Same as `std::false_type`.

#### mp_to_bool<T>

    template<class T> using mp_to_bool = mp_bool<static_cast<bool>(T::value)>;

#### mp_not<T>

    template<class T> using mp_not = mp_bool< !T::value >;

#### mp_int<I>

    template<int I> using mp_int = std::integral_constant<int, I>;

#### mp_size_t<N>

    template<std::size_t N> using mp_size_t = std::integral_constant<std::size_t, N>;

### List Operations, <boost/mp11/list.hpp>

#### mp_list<T…​>

    template<class... T> struct mp_list {};

`mp_list` is the standard list type of Mp11, although the library is not restricted to it and can operate on arbitrary class templates such as `std::tuple` or `std::variant`. Even `std::pair` can be used if the transformation does not alter the number of the elements in the list.

#### mp_list_c<T, I…​>

    template<class T, T... I> using mp_list_c =
        mp_list<std::integral_constant<T, I>...>;

`mp_list_c` produces an `mp_list` of the `std::integral_constant` types corresponding to its integer template arguments.

Code Example 1. Using mp_list_c

    using L1 = mp_list_c<int, 2, 3>; // mp_list<mp_int<2>, mp_int<3>>

#### mp_is_list<L>

    template<class L> using mp_is_list = /*...*/;

`mp_is_list<L>` is `mp_true` if `L` is a list (an instantiation of a class template whose template parameters are types), `mp_false` otherwise.

#### mp_size<L>

    template<class L> using mp_size = /*...*/;

`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)>`.

Code Example 2. Using mp_size with mp_list

    using L1 = mp_list<>;
    using R1 = mp_size<L1>; // mp_size_t<0>

Code Example 3. Using mp_size with std::pair

    using L2 = std::pair<int, int>;
    using R2 = mp_size<L2>; // mp_size_t<2>

Code Example 4. Using mp_size with std::tuple

    using L3 = std::tuple<float>;
    using R3 = mp_size<L3>; // mp_size_t<1>

#### mp_empty<L>

    template<class L> using mp_empty = mp_bool<mp_size<L>::value == 0>;

`mp_empty<L>` is an alias for `mp_true` if the list `L` is empty, for `mp_false` otherwise.

Code Example 5. Using mp_empty with std::tuple

    using L1 = std::tuple<float>;
    using R1 = mp_empty<L1>; // mp_false

    using L2 = std::tuple<>;
    using R2 = mp_empty<L2>; // mp_true

#### mp_assign<L1, L2>

    template<class L1, class L2> using mp_assign = /*...*/;

`mp_assign<L1<T1…​>, L2<T2…​>>` is an alias for `L1<T2…​>`. That is, it replaces the elements of `L1` with those of `L2`.

Code Example 6. Using mp_assign with mp_list and std::tuple

    using L1 = std::tuple<long>;
    using L2 = mp_list<int, float>;

    using R1 = mp_assign<L1, L2>; // std::tuple<int, float>

Code Example 7. Using mp_assign with mp_list and std::pair

    using L1 = std::pair<long, char>;
    using L2 = mp_list<int, float>;

    using R1 = mp_assign<L1, L2>; // std::pair<int, float>

#### mp_clear<L>

    template<class L> using mp_clear = mp_assign<L, mp_list<>>;

`mp_clear<L<T…​>>` is an alias for `L<>`, that is, it removes the elements of `L`.

Code Example 8. Using mp_clear with std::tuple

    using L1 = std::tuple<int, float>;
    using R1 = mp_clear<L1>; // std::tuple<>

#### mp_front<L>

    template<class L> using mp_front = /*...*/;

`mp_front<L>` is the first element of the list `L`. That is, `mp_front<L<T1, T…​>>` is an alias for `T1`.

Code Example 9. Using mp_front with std::pair

    using L1 = std::pair<int, float>;
    using R1 = mp_front<L1>; // int

Code Example 10. Using mp_front with std::tuple

    using L2 = std::tuple<float, double, long double>;
    using R2 = mp_front<L2>; // float

Code Example 11. Using mp_front with mp_list

    using L3 = mp_list<char[1], char[2], char[3], char[4]>;
    using R3 = mp_front<L3>; // char[1]

#### mp_pop_front<L>

    template<class L> using mp_pop_front = /*...*/;

`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…​>`.

Code Example 12. Using mp_pop_front with std::tuple

    using L1 = std::tuple<float, double, long double>;
    using R1 = mp_pop_front<L1>; // std::tuple<double, long double>

Code Example 13. Using mp_pop_front with mp_list

    using L2 = mp_list<void>;
    using R2 = mp_pop_front<L2>; // mp_list<>

#### mp_first<L>

    template<class L> using mp_first = mp_front<L>;

`mp_first` is another name for `mp_front`.

#### mp_rest<L>

    template<class L> using mp_rest = mp_pop_front<L>;

`mp_rest` is another name for `mp_pop_front`.

#### mp_second<L>

    template<class L> using mp_second = /*...*/;

`mp_second<L>` is the second element of the list `L`. That is, `mp_second<L<T1, T2, T…​>>` is an alias for `T2`.

Code Example 14. Using mp_second with std::pair

    using L1 = std::pair<int, float>;
    using R1 = mp_second<L1>; // float

Code Example 15. Using mp_second with std::tuple

    using L2 = std::tuple<float, double, long double>;
    using R2 = mp_second<L2>; // double

Code Example 16. Using mp_second with mp_list

    using L3 = mp_list<char[1], char[2], char[3], char[4]>;
    using R3 = mp_second<L3>; // char[2]

#### mp_third<L>

    template<class L> using mp_third = /*...*/;

`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`.

Code Example 17. Using mp_third with std::tuple

    using L1 = std::tuple<float, double, long double>;
    using R1 = mp_third<L1>; // long double

Code Example 18. Using mp_third with mp_list

    using L2 = mp_list<char[1], char[2], char[3], char[4]>;
    using R2 = mp_third<L2>; // char[3]

#### mp_push_front<L, T…​>

    template<class L, class... T> using mp_push_front = /*...*/;

`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…​>`.

Code Example 19. Using mp_push_front with std::tuple

    using L1 = std::tuple<double, long double>;
    using R1 = mp_push_front<L1, float>; // std::tuple<float, double, long double>

Code Example 20. Using mp_push_front with mp_list

    using L2 = mp_list<void>;
    using R2 = mp_push_front<L2, char[1], char[2]>; // mp_list<char[1], char[2], void>

#### mp_push_back<L, T…​>

    template<class L, class... T> using mp_push_back = /*...*/;

`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…​>`.

Code Example 21. Using mp_push_back with std::tuple

    using L1 = std::tuple<double, long double>;
    using R1 = mp_push_back<L1, float>; // std::tuple<double, long double, float>

Code Example 22. Using mp_push_back with mp_list

    using L2 = mp_list<void>;
    using R2 = mp_push_back<L2, char[1], char[2]>; // mp_list<void, char[1], char[2]>

#### mp_rename<L, Y>

    template<class L, template<class...> class Y> using mp_rename = /*...*/;

`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…​>`.

Code Example 23. Using mp_rename to rename std::pair to std::tuple

    using L1 = std::pair<double, long double>;
    using R1 = mp_rename<L1, std::tuple>; // std::tuple<double, long double>

Code Example 24. Using mp_rename to rename std::tuple to mp_list

    using L2 = std::tuple<void>;
    using R2 = mp_rename<L2, mp_list>; // mp_list<void>

#### mp_apply<F, L>

    template<template<class...> class F, class L> using mp_apply = mp_rename<L, F>;

`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.)

Code Example 25. Using mp_apply with std::pair

    using L1 = std::pair<double, long double>;
    using R1 = mp_apply<std::is_same, L1>; // std::is_same<double, long double>

#### mp_apply_q<Q, L>

    template<class Q, class L> using mp_apply_q = mp_apply<Q::template fn, L>;

Same as `mp_apply`, but takes a quoted metafunction.

Code Example 26. Using mp_apply_q with mp_bind_front

    using L1 = std::tuple<double, long double>;
    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…​>`.

Code Example 27. Using mp_append with lists of various types

    using L1 = std::tuple<double, long double>;
    using L2 = mp_list<int>;
    using L3 = std::pair<short, long>;
    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 = /*...*/;

`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…​>`.

Code Example 28. Using mp_replace_front with std::pair

    using L1 = std::pair<int, float>;
    using R1 = mp_replace_front<L1, void>; // std::pair<void, float>

Code Example 29. Using mp_replace_front with std::tuple

    using L2 = std::tuple<float, double, long double>;
    using R2 = mp_replace_front<L2, void>; // std::tuple<void, double, long double>

Code Example 30. Using mp_replace_front with mp_list

    using L3 = mp_list<char[1], char[2], char[3], char[4]>;
    using R3 = mp_replace_front<L3, void>; // mp_list<void, char[2], char[3], char[4]>;

#### mp_replace_first<L, T>

    template<class L, class T> using mp_replace_first = mp_replace_front<L, T>;

`mp_replace_first` is another name for `mp_replace_front`.

#### mp_replace_second<L, T>

    template<class L, class T> using mp_replace_second = /*...*/;

`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…​>`.

Code Example 31. Using mp_replace_second with std::pair

    using L1 = std::pair<int, float>;
    using R1 = mp_replace_second<L1, void>; // std::pair<int, void>

Code Example 32. Using mp_replace_second with std::tuple

    using L2 = std::tuple<float, double, long double>;
    using R2 = mp_replace_second<L2, void>; // std::tuple<float, void, long double>

Code Example 33. Using mp_replace_front with mp_list

    using L3 = mp_list<char[1], char[2], char[3], char[4]>;
    using R3 = mp_replace_second<L3, void>; // mp_list<char[1], void, char[3], char[4]>;

#### mp_replace_third<L, T>

    template<class L, class T> using mp_replace_third = /*...*/;

`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…​>`.

Code Example 34. Using mp_replace_third with std::tuple

    using L1 = std::tuple<float, double, long double>;
    using R1 = mp_replace_third<L1, void>; // std::tuple<float, double, void>

Code Example 35. Using mp_replace_third with mp_list

    using L2 = mp_list<char[1], char[2], char[3], char[4]>;
    using R2 = mp_replace_third<L2, void>; // mp_list<char[1], char[2], void, char[4]>;

### Utility Components, <boost/mp11/utility.hpp>

#### mp_identity<T>

    template<class T> struct mp_identity
    {
        using type = T;
    };

`mp_identity` is a simple transformation type trait (as per the C++ standard) that just returns the same type. It’s useful both as such, and as a type wrapper for passing types as values to functions.

Code Example 36. Using mp_identity as a type trait

    template<class T> using addp_if_not_ref =
        typename mp_if<std::is_reference<T>, mp_identity<T>, std::add_pointer<T>>::type;

Code Example 37. Using mp_identity to protect qualifiers and references

    template<class T> void print1()
    {
        std::cout << typeid(T).name() << std::endl;
    }

    template<class T> void print2()
    {
        std::cout << typeid(mp_identity<T>).name() << std::endl;
    }

    int main()
    {
        print1<int const&>(); // 'int'
        print2<int const&>(); // 'mp_identity<int const &>'
    }

#### mp_identity_t<T>

    template<class T> using mp_identity_t = typename mp_identity<T>::type;

#### mp_inherit<T…​>

    template<class... T> struct mp_inherit: T... {};

#### mp_if_c<C, T, E…​>

    template<bool C, class T, class... E> using mp_if_c = /*...*/;

`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.

Code Example 38. Using mp_if_c to select between two alternatives

    using R1 = mp_if_c<true, int, void>;  // int

    using R2 = mp_if_c<false, int, void>; // void

Code Example 39. Using mp_if_c to fail substitution when a condition is not met

    template<class I> using void_if_5 = mp_if_c<I::value == 5, void>;

This example returns `void` when `I::value` is 5, and generates a substitution failure otherwise. It’s the same as `std::enable_if_t<I::value == 5>` in C++14, or `typename std::enable_if<I::value == 5>::type` in C++11.

#### 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...>;

Like `mp_if_c`, but the first argument is a type.

Code Example 40. Using mp_if to select between two alternatives

    using R1 = mp_if<mp_true, int, void>;  // int

    using R2 = mp_if<mp_false, int, void>; // void

Code Example 41. Using mp_if to fail substitution when a condition is not met

    template<class T> using void_if_const = mp_if<std::is_const<T>, void>;

    template<class... T> using void_if_all_const =
        mp_if<mp_all<std::is_const<T>...>, void>;

    template<class T> using if_non_const = mp_if<mp_not<std::is_const<T>>, T>;

#### mp_eval_if_c<C, T, F, U…​>

    template<bool C, class T, template<class...> class F, class... U> using mp_eval_if_c =
        /*...*/;

`mp_eval_if_c<C, T, F, U…​>` is an alias for `T` when `C` is `true`, for `F<U…​>` otherwise. Its purpose is to avoid evaluating `F<U…​>` when the condition is `true` as it may not be valid in this case.

Code Example 42. Using mp_eval_if_c to select the first pack element, or void

    template<class... T> using first_or_void =
        mp_eval_if_c<sizeof...(T) == 0, void, mp_apply, mp_first, mp_list<T...>>;

#### 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...>;

Like `mp_eval_if_c`, but the first argument is a type.

Code Example 43. Using mp_eval_if to select the first list element, or void

    template<class L> using first_or_void = mp_eval_if<mp_empty<L>, void, mp_first, L>;

#### 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...>;

Like `mp_eval_if`, but takes a quoted metafunction.

#### mp_cond<C, T, R…​>

    template<class C, class T, class... R> using mp_cond = /*...*/;

`mp_cond<C, T, R…​>` is an alias for `T` when `static_cast<bool>(C::value)` is `true`. When `static_cast<bool>(C::value)` is `false`, it’s an alias for `mp_cond<R…​>`.

(If `static_cast<bool>(C::value)` is a substitution failure, the result is too a substitution failure.)

Code Example 44. Using mp_cond

    template<int N> using unsigned_ = mp_cond<
        mp_bool<N ==  8>, uint8_t,
        mp_bool<N == 16>, uint16_t,
        mp_bool<N == 32>, uint32_t,
        mp_bool<N == 64>, uint64_t,
        mp_true, unsigned // default case
    >;

#### mp_valid<F, T…​>

    template<template<class...> class F, class... T> using mp_valid = /*...*/;

`mp_valid<F, T…​>` is an alias for `mp_true` when `F<T…​>` is a valid expression, for `mp_false` otherwise.

Code Example 45. Using mp_valid to write a metafunction that checks for the existence of a nested type

    template<class T> using get_nested_type = typename T::type;

    template<class T> struct has_nested_type: mp_valid<get_nested_type, T> {};

#### mp_defer<F, T…​>

    template<template<class...> class F, class... T> using mp_defer = /*...*/;

When `mp_valid<F, T…​>` is `mp_true`, `mp_defer<F, T…​>` is a struct with a nested type `type` which is an alias for `F<T…​>`. Otherwise, `mp_defer<F, T…​>` is an empty struct.

#### mp_quote<F>

    template<template<class...> class F> struct mp_quote
    {
        template<class... T> using fn = F<T...>;
    };

`mp_quote<F>` transforms the template `F` into a type with a nested template `fn` such that `fn<T…​>` returns `F<T…​>`.

Code Example 46. Using mp_quote to make a list of metafunctions

    using LQ = mp_list<mp_quote<std::is_const>, mp_quote<std::is_volatile>>;

#### mp_quote_trait<F>

    template<template<class...> class F> struct mp_quote_trait
    {
        template<class... T> using fn = typename F<T...>::type;
    };

`mp_quote_trait<F>` transforms the C++03-style trait `F` into a quoted metafunction.

Code Example 47. Using mp_quote_trait with std::add_pointer

    using L1 = mp_list<int, void, float>;
    using R1 = mp_transform_q<mp_quote_trait<std::add_pointer>, L1>;
      // mp_list<int*, void*, float*>

#### mp_invoke<Q, T…​>

    template<class Q, class... T> using mp_invoke = typename Q::template fn<T...>;

`mp_invoke<Q, T…​>` evaluates the nested template `fn` of a quoted metafunction. `mp_invoke<mp_quote<F>, T…​>` returns `F<T…​>`.

Code Example 48. Using mp_invoke to invoke a list of metafunctions, technique 1

    using LQ = mp_list<mp_quote<std::is_const>, mp_quote<std::is_volatile>>;

    template<class T> using is_const_and_volatile =
        mp_all<mp_product<mp_invoke, LQ, mp_list<T>>>;

Code Example 49. Using mp_invoke to invoke a list of metafunctions, technique 2

    template<class T> using is_const_and_volatile =
        mp_all<mp_transform_q<mp_bind_back<mp_invoke, T>, LQ>>;

Code Example 50. Using mp_invoke to invoke a list of metafunctions, technique 3

    template<class T> using is_const_and_volatile =
        mp_all<mp_transform<mp_invoke, LQ, mp_fill<LQ, T>>>;

### Algorithms, <boost/mp11/algorithm.hpp>

#### mp_transform<F, L…​>

    template<template<class...> class F, class... L> using mp_transform = /*...*/;

`mp_transform<F, L1<T1…​>, L2<T2…​>, …​, Ln<Tn…​>>` applies `F` to each successive tuple of elements and returns `L1<F<T1, T2, …​, Tn>…​>`.

Code Example 51. Using mp_transform to produce a list of pointers from a list of pointees

    template<class T> using add_pointer_t =
        typename std::add_pointer<T>::type;  // std::add_pointer_t in C++14

    using L1 = std::tuple<void, int, float>;
    using R1 = mp_transform<add_pointer_t, L1>; // std::tuple<void*, int*, float*>

Code Example 52. Using mp_transform to compare the contents of two lists of types

    using L1 = std::tuple<void, int, float>;
    using L2 = mp_list<void, int, float>;

    using R1 = mp_all<mp_transform<std::is_same, L1, L2>>; // mp_true

Code Example 53. Using mp_transform to compare the contents of two lists of integral constants

    template<class T1, class T2> using eq = mp_bool<T1::value == T2::value>;

    using L1 = std::tuple<mp_int<1>, mp_int<2>, mp_int<3>>;
    using L2 = mp_list<mp_size_t<1>, mp_size_t<2>, mp_size_t<3>>;

    using R1 = mp_all<mp_transform<eq, L1, L2>>; // mp_true

Illustration 1. mp_transform on one list
`L1` | `A1` | `A2` | `…​` | `An`
`mp_transform<F, L1>` | `F<A1>` | `F<A2>` | `…​` | `F<An>`

Illustration 2. mp_transform on two lists
`L1` | `A1` | `A2` | `…​` | `An`
`L2` | `B1` | `B2` | `…​` | `Bn`
`mp_transform<F, L1, L2>` | `F<A1,B1>` | `F<A2,B2>` | `…​` | `F<An,Bn>`

#### mp_transform_q<Q, L…​>

    template<class Q, class... L> using mp_transform_q =
        mp_transform<Q::template fn, L...>;

As `mp_transform`, but takes a quoted metafunction.

Code Example 54. Using mp_transform_q to count the occurences of `void` in a list

    using L1 = std::tuple<void, int, float, void, int>;

    using R1 = mp_apply<mp_plus,
        mp_transform_q<mp_bind_front<std::is_same, void>, L1>>; // mp_int<2>

Illustration 3. mp_transform_q on two lists
`L1` | `A1` | `A2` | `…​` | `An`
`L2` | `B1` | `B2` | `…​` | `Bn`
`mp_transform_q<Q, L1, L2>` | `Q::fn<A1,B1>` | `Q::fn<A2,B2>` | `…​` | `Q::fn<An,Bn>`

#### mp_transform_if<P, F, L…​>

    template<template<class...> class P, template<class...> class F, class L...>
        using mp_transform_if = /*...*/;

`mp_transform_if<P, F, L1, L2, …​, Ln>` replaces the elements of the list `L1` for which `mp_to_bool<P<T1, T2, …​, Tn>>` is `mp_true` with `F<T1, T2, …​, Tn>`, and returns the result, where `Ti` are the corresponding elements of `Li`.

Code Example 55. Using mp_transform_if to replace the occurences of 'void' in a list with the corresponding elements of a second list

    using L1 = std::tuple<void, int, float, void, int>;
    using L2 = std::tuple<char[1], char[2], char[3], char[4], char[5]>;

    template<class T1, class T2> using first_is_void = std::is_same<T1, void>;
    template<class T1, class T2> using second = T2;

    using R1 = mp_transform_if<first_is_void, second, L1, L2>;
      // std::tuple<char[1], int, float, char[4], int>

Illustration 4. mp_transform_if
`L1` | `A1` | `A2` | `…​` | `An`
`P<Ai>` | `mp_false` | `mp_true` | `…​` | `mp_false`
`L2` | `B1` | `B2` | `…​` | `Bn`
`mp_transform_if<P, F, L1, L2>` | `A1` | `F<A2,B2>` | `…​` | `An`

#### mp_transform_if_q<Qp, Qf, L…​>

    template<class Qp, class Qf, class... L> using mp_transform_if_q =
        mp_transform_if<Qp::template fn, Qf::template fn, L...>;

As `mp_transform_if`, but takes quoted metafunctions.

Code Example 56. Using mp_transform_if_q to replace the occurences of 'void' in a list with the corresponding elements of a second list

    using L1 = std::tuple<void, int, float, void, int>;
    using L2 = std::tuple<char[1], char[2], char[3], char[4], char[5]>;

    using R1 = mp_transform_if_q<mp_bind<std::is_same, _1, void>, _2, L1, L2>;
      // std::tuple<char[1], int, float, char[4], int>

Illustration 5. mp_transform_if_q
`L1` | `A1` | `A2` | `…​` | `An`
`Qp::fn<Ai>` | `mp_false` | `mp_true` | `…​` | `mp_false`
`L2` | `B1` | `B2` | `…​` | `Bn`
`mp_transform_if_q<Qp, _2, L1, L2>` | `A1` | `B2` | `…​` | `An`

#### mp_fill<L, V>

    template<class L, class V> using mp_fill = /*...*/;

`mp_fill<L<T…​>, V>` returns `L<V, V, …​, V>`, with the result having the same size as the input.

Code Example 57. Using mp_fill with std::tuple

    using L1 = std::tuple<void, int, float>;
    using R1 = mp_fill<L1, double>; // std::tuple<double, double, double>

Code Example 58. Using mp_fill with std::pair

    using L1 = std::pair<int, float>;
    using R1 = mp_fill<L1, void>; // std::pair<void, void>

Illustration 6. mp_fill
`L1` | `A1` | `A2` | `…​` | `An`
`mp_fill<L1, V>` | `V` | `V` | `…​` | `V`

#### mp_count<L, V>

    template<class L, class V> using mp_count = /*...*/;

`mp_count<L, V>` returns `mp_size_t<N>`, where `N` is the number of elements of `L` same as `V`.

#### mp_count_if<L, P>

    template<class L, template<class...> class P> using mp_count_if = /*...*/;

`mp_count_if<L, P>` returns `mp_size_t<N>`, where `N` is the number of elements `T` of `L` for which `mp_to_bool<P<T>>` is `mp_true`.

#### mp_count_if_q<L, Q>

    template<class L, class Q> using mp_count_if_q = mp_count_if<L, Q::template fn>;

As `mp_count_if`, but takes a quoted metafunction.

#### mp_contains<L, V>

    template<class L, class V> using mp_contains = mp_to_bool<mp_count<L, V>>;

`mp_contains<L, V>` is `mp_true` when `L` contains an element `V`, `mp_false` otherwise.

#### mp_repeat_c<L, N>

    template<class L, std::size_t N> using mp_repeat_c = /*...*/;

`mp_repeat_c<L, N>` returns a list of the same type as `L` that consists of `N` concatenated copies of `L`.

#### mp_repeat<L, N>

    template<class L, class N> using mp_repeat = /*...*/;

Same as `mp_repeat_c` but with a type argument `N`. The number of copies is `N::value` and must be nonnegative.

#### mp_product<F, L…​>

    template<template<class...> class F, class... L> using mp_product = /*...*/;

`mp_product<F, L1<T1…​>, L2<T2…​>, …​, Ln<Tn…​>>` evaluates `F<U1, U2, …​, Un>` for values `Ui` taken from the Cartesian product of the lists, as if the elements `Ui` are formed by `n` nested loops, each traversing `Li`. It returns a list of type `L1` containing the results of the application of `F`.

Illustration 7. mp_product on two lists
`L1` | `A1` | `A2` | `…​` | `An`
`L2` | `B1` | `B2` | `…​` | `Bm`
`mp_product<F, L1, L2>` | `F<A1,B1>` | `F<A1,B2>` | `…​` | `F<A1,Bm>`
| `F<A2,B1>` | `F<A2,B2>` | `…​` | `F<A2,Bm>`
| `…​`
| `F<An,B1>` | `F<An,B2>` | `…​` | `F<An,Bm>`

#### mp_product_q<Q, L…​>

    template<class Q, class... L> using mp_product_q = mp_product<Q::template fn, L...>;

As `mp_product`, but takes a quoted metafunction.

#### mp_drop_c<L, N>

    template<class L, std::size_t N> using mp_drop_c = /*...*/;

`mp_drop_c<L, N>` removes the first `N` elements of `L` and returns the result.

Illustration 8. mp_drop_c
`L1` | `A1` | `…​` | `Am` | `Am+1` | `…​` | `An`
`mp_drop_c<L1, M>` | `Am+1` | `…​` | `An` |

#### mp_drop<L, N>

    template<class L, class N> using mp_drop = /*...*/;

Same as `mp_drop_c`, but with a type argument `N`. `N::value` must be a nonnegative number.

#### mp_from_sequence<S>

    template<class S> using mp_from_sequence = /*...*/

`mp_from_sequence` transforms an integer sequence produced by `make_integer_sequence` into an `mp_list` of the corresponding `std::integral_constant` types. Given

    template<class T, class... I> struct S;

`mp_from_sequence<S<T, I…​>>` is an alias for `mp_list<std::integral_constant<T, I>…​>`.

#### mp_iota_c<N>

    template<std::size_t N> using mp_iota_c = /*...*/;

`mp_iota_c<N>` is an alias for `mp_list<mp_size_t<0>, mp_size_t<1>, …​, mp_size_t<N-1>>`.

#### mp_iota<N>

    template<class N> using mp_iota = /*...*/;

Same as `mp_iota_c`, but with a type argument `N`. `N::value` must be a nonnegative number. Returns `mp_list<std::integral_constant<T, 0>, std::integral_constant<T, 1>, …​, std::integral_constant<T, N::value-1>>` where `T` is the type of `N::value`.

Illustration 9. mp_iota
`mp_iota<mp_int<4>>` | `mp_int<0>` | `mp_int<1>` | `mp_int<2>` | `mp_int<3>`

#### mp_at_c<L, I>

    template<class L, std::size_t I> using mp_at_c = /*...*/;

`mp_at_c<L, I>` returns the `I`-th element of `L`, zero-based.

#### mp_at<L, I>

    template<class L, class I> using mp_at = /*...*/;

Same as `mp_at_c`, but with a type argument `I`. `I::value` must be a nonnegative number.

#### mp_take_c<L, N>

    template<class L, std::size_t N> using mp_take_c = /*...*/;

`mp_take_c<L, N>` returns a list of the same type as `L` containing the first `N` elements of `L`.

Illustration 10. mp_take_c
`L1` | `A1` | `…​` | `Am` | `Am+1` | `…​` | `An`
`mp_take_c<L1, M>` | `A1` | `…​` | `Am` |

#### mp_take<L, N>

    template<class L, class N> using mp_take = /*...*/;

Same as `mp_take_c`, but with a type argument `N`. `N::value` must be a nonnegative number.

#### 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...>>;

Inserts the elements `T…​` into the list `L` at position `I` (a zero-based index).

Illustration 11. mp_insert_c with two elements
`L1` | `A1` | `…​` | `Am` | `Am+1` | `…​` | `An` |
`mp_insert_c<L1, M, B1, B2>` | `A1` | `…​` | `Am` | `B1` | `B2` | `Am+1` | `…​` | `An`

#### 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...>>;

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_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).

Illustration 12. mp_erase_c
`L1` | `A0` | `…​` | `Ai-1` | `Ai` | `…​` | `Aj-1` | `Aj` | `…​` | `An-1`
`mp_erase_c<L1, I, J>` | `A0` | `…​` | `Ai-1` | `Aj` | `…​` | `An-1` |

#### 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>>;

Same as `mp_erase_c`, but with a type arguments `I` and `J`.

#### mp_replace<L, V, W>

    template<class L, class V, class W> using mp_replace = /*...*/;

Replaces all `V` elements of `L` with `W` and returns the result.

Illustration 13. mp_replace
`L1` | `A1` | `V` | `…​` | `An`
`mp_replace<L1, V, W>` | `A1` | `W` | `…​` | `An`

#### mp_replace_if<L, P, W>

    template<class L, template<class...> class P, class W> using mp_replace_if = /*...*/;

Replaces all `T` elements of `L` for which `mp_to_bool<P<T>>` is `mp_true` with `W` and returns the result.

Illustration 14. mp_replace_if
`L1` | `A1` | `A2` | `…​` | `An`
`P<Ai>` | `mp_false` | `mp_true` | `…​` | `mp_false`
`mp_replace_if<L1, P, W>` | `A1` | `W` | `…​` | `An`

#### mp_replace_if_q<L, Q, W>

    template<class L, class Q, class W> using mp_replace_if_q =
        mp_replace_if<L, Q::template fn, W>;

As `mp_replace_if`, but takes a quoted metafunction.

#### mp_replace_at_c<L, I, W>

    template<class L, std::size_t I, class W> using mp_replace_at_c = /*...*/;

Replaces the element of `L` at zero-based index `I` with `W` and returns the result.

#### mp_replace_at<L, I, W>

    template<class L, class I, class W> using mp_replace_at = /*...*/;

Same as `mp_replace_at_c`, but with a type argument `I`. `I::value` must be a nonnegative number.

#### mp_copy_if<L, P>

    template<class L, template<class...> class P> using mp_copy_if = /*...*/;

Copies the elements `T` of `L` for which `mp_to_bool<P<T>>` is `mp_true` to a new list of the same type and returns it.

#### mp_copy_if_q<L, Q>

    template<class L, class Q> using mp_copy_if_q = mp_copy_if<L, Q::template fn>;

As `mp_copy_if`, but takes a quoted metafunction.

#### mp_remove<L, V>

    template<class L, class V> using mp_remove = /*...*/;

Removes all `V` elements of `L` and returns the result.

#### mp_remove_if<L, P>

    template<class L, template<class...> class P> using mp_remove_if = /*...*/;

Removes all elements `T` of `L` for which `mp_to_bool<P<T>>` is `mp_true` and returns the result.

#### mp_remove_if_q<L, Q>

    template<class L, class Q> using mp_remove_if_q = mp_remove_if<L, Q::template fn>;

As `mp_remove_if`, but takes a quoted metafunction.

#### mp_partition<L, P>

    template<class L, template<class...> class P> using mp_partition = /*...*/;

`mp_partition<L<T…​>, P>` partitions `L` into two lists `L<U1…​>` and `L<U2…​>` such that `mp_to_bool<P<T>>` is `mp_true` for the elements of `L<U1…​>` and `mp_false` for the elements of `L<U2…​>`. Returns `L<L<U1…​>, L<U2…​>>`.

#### mp_partition_q<L, Q>

    template<class L, class Q> using mp_partition_q = mp_partition<L, Q::template fn>;

As `mp_partition`, but takes a quoted metafunction.

#### mp_sort<L, P>

    template<class L, template<class...> class P> using mp_sort = /*...*/;

`mp_sort<L, P>` sorts the list `L` according to the strict weak ordering `mp_to_bool<P<T, U>>`.

Code Example 59. Using mp_sort to sort a list of std::ratio values

    #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_sort_q<L, Q>

    template<class L, class Q> using mp_sort_q = mp_sort<L, Q::template fn>;

As `mp_sort`, but takes a quoted metafunction.

#### mp_nth_element_c<L, I, P>

    template<class L, std::size_t I, template<class...> class P> using mp_nth_element_c =
        /*...*/;

Returns the element at position `I` in `mp_sort<L, P>`.

#### mp_nth_element<L, I, P>

    template<class L, class I, template<class...> class P> using mp_nth_element = /*...*/;

Like `mp_nth_element_c`, but with a type argument `I`. `I::value` must be a nonnegative number.

#### mp_nth_element_q<L, I, Q>

    template<class L, class I, class Q> using mp_nth_element_q =
        mp_nth_element<L, I, Q::template fn>;

Like `mp_nth_element`, but takes a quoted metafunction.

#### mp_min_element<L, P>

    template<class L, template<class...> class P> using mp_min_element = /*...*/;

`mp_min_element<L, P>` returns the minimal element of the list `L` according to the ordering `mp_to_bool<P<T, U>>`.

It’s equivalent to `mp_fold<mp_rest<L>, mp_first<L>, F>`, where `F<T, U>` returns `mp_if<P<T, U>, T, U>`.

#### mp_min_element_q<L, Q>

    template<class L, class Q> using mp_min_element_q = mp_min_element<L, Q::template fn>;

As `mp_min_element`, but takes a quoted metafunction.

#### mp_max_element<L, P>

    template<class L, template<class...> class P> using mp_max_element = /*...*/;

`mp_max_element<L, P>` returns the maximal element of the list `L` according to the ordering `mp_to_bool<P<T, U>>`.

It’s equivalent to `mp_fold<mp_rest<L>, mp_first<L>, F>`, where `F<T, U>` returns `mp_if<P<U, T>, T, U>`.

#### mp_max_element_q<L, Q>

    template<class L, class Q> using mp_max_element_q = mp_max_element<L, Q::template fn>;

As `mp_max_element`, but takes a quoted metafunction.

#### mp_find<L, V>

    template<class L, class V> using mp_find = /*...*/;

`mp_find<L, V>` returns the index at which the type `V` is located in the list `L`. It’s an alias for `mp_size_t<I>`, where `I` is the zero-based index of the first occurence of `V` in `L`. If `L` does not contain `V`, `mp_find<L, V>` is `mp_size<L>`.

#### mp_find_if<L, P>

    template<class L, template<class...> class P> using mp_find_if = /*...*/;

`mp_find_f<L, P>` is an alias for `mp_size_t<I>`, where `I` is the zero-based index of the first element `T` in `L` for which `mp_to_bool<P<T>>` is `mp_true`. If there is no such element, `mp_find_if<L, P>` is `mp_size<L>`.

#### mp_find_if_q<L, Q>

    template<class L, class Q> using mp_find_if_q = mp_find_if<L, Q::template fn>;

As `mp_find_if`, but takes a quoted metafunction.

#### mp_reverse<L>

    template<class L> using mp_reverse = /*...*/;

`mp_reverse<L<T1, T2, …​, Tn>>` is `L<Tn, …​, T2, T1>`.

Illustration 15. mp_reverse
`L1` | `A1` | `A2` | `…​` | `An`
`mp_reverse<L1>` | `An` | `An-1` | `…​` | `A1`

#### mp_fold<L, V, F>

    template<class L, class V, template<class...> class F> using mp_fold = /*...*/;

`mp_fold<L<T1, T2, …​, Tn>, V, F>` is `F< F< F< F<V, T1>, T2>, …​>, Tn>`, or `V`, if `L` is empty.

Code Example 60. Using mp_fold to add the contents of a list of std::ratio values

    #include <ratio>

    using L1 = mp_list<std::ratio<1,8>, std::ratio<1,4>, std::ratio<1,2>>;
    using R1 = mp_fold<L1, std::ratio<0,1>, std::ratio_add>; // std::ratio<7,8>

#### mp_fold_q<L, V, Q>

    template<class L, class V, class Q> using mp_fold_q =
        mp_fold<L, V, Q::template fn>;

As `mp_fold`, but takes a quoted metafunction.

#### mp_reverse_fold<L, V, F>

    template<class L, class V, template<class...> class F> using mp_reverse_fold =
        /*...*/;

`mp_reverse_fold<L<T1, T2, …​, Tn>, V, F>` is `F<T1, F<T2, F<…​, F<Tn, V>>>>`, or `V`, if `L` is empty.

#### mp_reverse_fold_q<L, V, Q>

    template<class L, class V, class Q> using mp_reverse_fold_q =
        mp_reverse_fold<L, V, Q::template fn>;

As `mp_reverse_fold`, but takes a quoted metafunction.

#### mp_unique<L>

    template<class L> using mp_unique = /*...*/;

`mp_unique<L>` returns a list of the same type as `L` with the duplicate elements removed.

#### 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 >;

`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_all_of_q<L, Q>

    template<class L, class Q> using mp_all_of_q = mp_all_of<L, Q::template fn>;

As `mp_all_of`, but takes a quoted metafunction.

#### 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 >;

`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_none_of_q<L, Q>

    template<class L, class Q> using mp_none_of_q = mp_none_of<L, Q::template fn>;

As `mp_none_of`, but takes a quoted metafunction.

#### 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 >;

`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`.

#### mp_any_of_q<L, Q>

    template<class L, class Q> using mp_any_of_q = mp_any_of<L, Q::template fn>;

As `mp_any_of`, but takes a quoted metafunction.

#### mp_for_each<L>(f)

    template<class L, class F> constexpr F mp_for_each(F&& f);

`mp_for_each<L>(f)` calls `f` with `T()` for each element `T` of the list `L`, in order.

Returns `std::forward<F>(f)`.

Code Example 61. Using mp_for_each and a C++14 lambda to print a tuple

    template<class... T> void print( std::tuple<T...> const & tp )
    {
        std::size_t const N = sizeof...(T);

        mp_for_each<mp_iota_c<N>>( [&]( auto I ){

            // I is mp_size_t<0>, mp_size_t<1>, ..., mp_size_t<N-1>

            std::cout << std::get<I>(tp) << std::endl;

        });
    }

#### mp_with_index<N>(i, f)

    template<std::size_t N, class F>
      constexpr auto mp_with_index( std::size_t i, F && f )
        -> decltype(std::declval<F>()(std::declval<mp_size_t<0>>()));

`mp_with_index<N>(i, f)` calls `f` with `mp_size_t<i>()` and returns the result. `i` must be less than `N`. Only `constexpr` on C++14 and higher.

    template<class N, class F>
      constexpr auto mp_with_index( std::size_t i, F && f )
        -> decltype(std::declval<F>()(std::declval<mp_size_t<0>>()));

Returns `mp_with_index<N::value>(i, f)`.

Code Example 62. Using mp_with_index and a C++14 lambda to print the active element of a variant

    template<class... T> void print( std::variant<T...> const& v )
    {
        mp_with_index<sizeof...(T)>( v.index(), [&]( auto I ) {

            // I is mp_size_t<v.index()> here

            std::cout << std::get<I>( v ) << std::endl;

        });
    }

### Set Operations, <boost/mp11/set.hpp>

A set is a list whose elements are unique.

#### mp_is_set<S>

    template<class S> using mp_is_set = /*...*/;

`mp_is_set<S>` is `mp_true` if `S` is a set, `mp_false` otherwise.

#### mp_set_contains<S, V>

    template<class S, class V> using mp_set_contains = /*...*/;

`mp_set_contains<S, V>` is `mp_true` if the type `V` is an element of the set `S`, `mp_false` otherwise.

#### mp_set_push_back<S, T…​>

    template<class S, class... T> using mp_set_push_back = /*...*/;

For each `T1` in `T…​`, `mp_set_push_back<S, T…​>` appends `T1` to the end of `S` if it’s not already an element of `S`.

#### mp_set_push_front<S, T…​>

    template<class S, class... T> using mp_set_push_front = /*...*/;

`mp_set_push_front<S, T…​>` inserts at the front of `S` those elements of `T…​` for which `S` does not already contain the same type.

### Map Operations, <boost/mp11/map.hpp>

A map is a list of lists, the inner lists having at least one element (the key.) The keys of the map must be unique.

#### mp_is_map<M>

    template<class M> using mp_is_map = /*...*/;

`mp_is_map<M>` is `mp_true` if `M` is a map, `mp_false` otherwise.

#### mp_map_find<M, K>

    template<class M, class K> using mp_map_find = /*...*/;

`mp_map_find<M, K>` is an alias for the element of the map `M` with a key `K`, or for `void`, if there is no such element.

#### mp_map_contains<M, K>

    template<class M, class K> using mp_map_contains =
        mp_not<std::is_same<mp_map_find<M, K>, void>>;

`mp_map_contains<M, K>` is `mp_true` if the map `M` contains an element with a key `K`, `mp_false` otherwise.

#### 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> >;

Inserts the element `T` into the map `M`, if an element with a key `mp_first<T>` is not already in `M`.

#### mp_map_replace<M, T>

    template<class M, class T> using mp_map_replace = /*...*/;

If the map `M` does not contain an element with a key `mp_first<T>`, inserts it (using `mp_push_back<M, T>`); otherwise, replaces the existing element with `T`.

#### mp_map_update<M, T, F>

    template<class M, class T, template<class...> class F> using mp_map_update = /*...*/;

If the map `M` does not contain an element with a key `mp_first<T>`, inserts it (using `mp_push_back<M, T>`); otherwise, replaces the existing element `L<X, Y…​>` with `L<X, F<X, Y…​>>`.

Code Example 63. Using mp_map_update to count the number of occurences of types in a list

    template<class T, class U> using inc2nd = mp_int<U::value + 1>;

    template<class M, class T> using count_types =
        mp_map_update<M, std::pair<T, mp_int<1>>, inc2nd>;

    using L1 = mp_list<float, char, float, float, float, float, char, float>;

    using R1 = mp_fold<L1, std::tuple<>, count_types>;
    // std::tuple<std::pair<float, mp_int<6>>, std::pair<char, mp_int<2>>>

#### mp_map_update_q<M, T, Q>

    template<class M, class T, class Q> using mp_map_update_q =
        mp_map_update<M, T, Q::template fn>;

As `mp_map_update`, but takes a quoted metafunction.

#### mp_map_erase<M, K>

    template<class M, class K> using mp_map_erase = /*...*/;

If the map `M` contains an element with a key `K`, removes it.

#### mp_map_keys<M>

    template<class M> using mp_map_keys = mp_transform<mp_first, M>;

`mp_map_keys<M>` returns a list of the keys of `M`. When `M` is a valid map, the keys are unique, so the result is a set.

### Helper Metafunctions, <boost/mp11/function.hpp>

#### mp_void<T…​>

    template<class... T> using mp_void = void;

Same as `std::void_t` from C++17.

#### mp_and<T…​>

    template<class... T> using mp_and = /*...*/;

`mp_and<T…​>` applies `mp_to_bool` to the types in `T…​`, in order. If the result of an application is `mp_false`, `mp_and` returns `mp_false`. If the application causes a substitution failure, returns `mp_false`. If all results are `mp_true`, returns `mp_true`. `mp_and<>` is `mp_true`.

Code Example 64. mp_and behavior

    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…​>

    template<class... T> using mp_all = /*...*/;

`mp_all<T…​>` is `mp_true` if `mp_to_bool<U>` is `mp_true` for all types `U` in `T…​`, `mp_false` otherwise. Same as `mp_and`, but does not perform short-circuit evaluation. `mp_and<mp_false, void>` is `mp_false`, but `mp_all<mp_false, void>` is an error because `void` does not have a nested `value`. The upside is that `mp_all` is potentially faster and does not mask substitution failures as `mp_and` does.

Code Example 65. mp_all behavior

    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…​>

    template<class... T> using mp_or = /*...*/;

`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`.

Code Example 66. mp_or behavior

    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…​>

    template<class... T> using mp_any = /*...*/;

`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.

Code Example 67. mp_any behavior

    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…​>

    template<class... T> using mp_same = /*...*/;

`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_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>`.

#### mp_less<T1, T2>

    template<class T1, class T2> using mp_less = /*...*/;

`mp_less<T1, T2>` is `mp_true` when the numeric value of `T1::value` is less than the numeric value of `T2::value`, `mp_false` otherwise.

(Note that this is not necessarily the same as `T1::value < T2::value` when comparing between signed and unsigned types; `-1 < 1u` is `false`, but `mp_less<mp_int<-1>, mp_size_t<1>>` is `mp_true`.)

#### mp_min<T1, T…​>

    template<class T1, class... T> using mp_min = mp_min_element<mp_list<T1, T...>, mp_less>;

`mp_min<T…​>` returns the type `U` in `T…​` with the lowest `U::value`.

#### mp_max<T1, T…​>

    template<class T1, class... T> using mp_max = mp_max_element<mp_list<T1, T...>, mp_less>;

`mp_max<T…​>` returns the type `U` in `T…​` with the highest `U::value`.

### Bind, <boost/mp11/bind.hpp>

#### mp_arg<I>

    template<std::size_t I> struct mp_arg;

`mp_arg<I>` is a quoted metafunction whose nested template `fn<T…​>` returns the `I`-th zero-based element of `T…​`.

#### _1, …​, _9

    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>;

`_1` to `_9` are placeholder types, the equivalent to the placeholders of `boost::bind`.

#### mp_bind<F, T…​>

    template<template<class...> class F, class... T> struct mp_bind;

`mp_bind<F, T…​>` is a quoted metafunction that implements the type-based equivalent of `boost::bind`. Its nested template `fn<U…​>` returns `F<V…​>`, where `V…​` is `T…​` with the placeholders replaced by the corresponding element of `U…​` and the `mp_bind` expressions replaced with their corresponding evaluations against `U…​`.

For example, `mp_bind<F, int, _2, mp_bind<G, _1>>::fn<float, void>` is `F<int, void, G<float>>`.

#### mp_bind_q<Q, T…​>

    template<class Q, class... T> using mp_bind_q = mp_bind<Q::template fn, T...>;

As `mp_bind`, but takes a quoted metafunction.

#### mp_bind_front<F, T…​>

    template<template<class...> class F, class... T> struct mp_bind_front;

`mp_bind_front<F, T…​>` binds the leftmost arguments of `F` to `T…​`. Its nested template `fn<U…​>` returns `F<T…​, U…​>`.

#### mp_bind_front_q<Q, T…​>

    template<class Q, class... T> using mp_bind_front_q =
        mp_bind_front<Q::template fn, T...>;

As `mp_bind_front`, but takes a quoted metafunction.

#### mp_bind_back<F, T…​>

    template<template<class...> class F, class... T> struct mp_bind_back;

`mp_bind_back<F, T…​>` binds the rightmost arguments of `F` to `T…​`. Its nested template `fn<U…​>` returns `F<U…​, T…​>`.

#### mp_bind_back_q<Q, T…​>

    template<class Q, class... T> using mp_bind_back_q =
        mp_bind_back<Q::template fn, T...>;

As `mp_bind_back`, but takes a quoted metafunction.

### Integer Sequences, <boost/mp11/integer_sequence.hpp>

#### integer_sequence<T, I…​>

    template<class T, T... I> struct integer_sequence
    {
    };

`integer_sequence<T, I…​>` holds a sequence of integers of type `T`. Same as C++14’s `std::integer_sequence`.

#### make_integer_sequence<T, N>

    template<class T, T N> using make_integer_sequence = /*...*/;

`make_integer_sequence<T, N>` is `integer_sequence<T, 0, 1, …​, N-1>`. Same as C++14’s `std::make_integer_sequence`.

#### index_sequence<I…​>

    template<std::size_t... I> using index_sequence = integer_sequence<std::size_t, I...>;

`index_sequence<I…​>` is an alias for `integer_sequence<size_t, I…​>`. Same as C++14’s `std::index_sequence`.

#### make_index_sequence<N>

    template<std::size_t N> using make_index_sequence =
        make_integer_sequence<std::size_t, N>;

`make_index_sequence<N>` is `index_sequence<0, 1, …​, N-1>`. Same as C++14’s `std::make_index_sequence`.

#### index_sequence_for<T…​>

    template<class... T> using index_sequence_for =
        make_integer_sequence<std::size_t, sizeof...(T)>;

`index_sequence_for<N>` is `make_index_sequence<sizeof…​(T)>`. Same as C++14’s `std::index_sequence_for`.

### Tuple Operations, <boost/mp11/tuple.hpp>

#### tuple_apply(f, tp)

    template<class F, class Tp> constexpr /*...*/ tuple_apply(F&& f, Tp&& tp);

`tuple_apply(f, tp)` returns `std::forward<F>(f)(std::get<J>(std::forward<Tp>(tp))…​)` for `J` in 0..`N-1`, where `N` is `std::tuple_size<typename std::remove_reference<Tp>::type>::value`. Same as `std::apply` in C++17.

#### construct_from_tuple<T>(tp)

    template<class T, class Tp> T construct_from_tuple(Tp&& tp);

`construct_from_tuple<T>(tp)` returns `T(std::get<J>(std::forward<Tp>(tp))…​)` for `J` in 0..`N-1`, where `N` is `std::tuple_size<typename std::remove_reference<Tp>::type>::value`. Same as `std::make_from_tuple` in C++17. The name of the function doesn’t match the C++17 one to avoid ambiguities when both are visible or in unqualified calls.

#### tuple_for_each(tp, f)

    template<class Tp, class F> constexpr F tuple_for_each(Tp&& tp, F&& f);

`tuple_for_each(tp, f)` applies the function object `f` to each element of `tp` by evaluating the expression `f(std::get<J>(std::forward<Tp>(tp)))` for `J` in 0..`N-1`, where `N` is `std::tuple_size<typename std::remove_reference<Tp>::type>::value`.

Returns `std::forward<F>(f)`.

### Convenience Header, <boost/mp11.hpp>

The convenience header `<boost/mp11.hpp>` includes all of the headers listed previously in this reference.

### MPL Support, <boost/mp11/mpl.hpp>

The header `<boost/mp11/mpl.hpp>`, when included, defines the necessary support infrastructure for `mp_list` and `std::tuple` to be valid MPL sequences.

Note | `mpl.hpp` is not included by `<boost/mp11.hpp>`.

## Appendix A: Copyright, License, and Acknowledgments

This documentation is

- Copyright 2017 Peter Dimov

- Copyright 2017 Bjørn Reese

and is distributed under the Boost Software License, Version 1.0.

The "Simple C++11 metaprogramming" articles have been graciously converted to Asciidoc format for incorporation into this documentation by Glen Fernandes.