1
0
forked from boostorg/mp11

Merge branch 'develop'

This commit is contained in:
Peter Dimov
2017-03-17 14:20:41 +02:00
88 changed files with 1640 additions and 475 deletions

View File

@@ -1,4 +1,5 @@
# mp11
Simple C++11 metaprogramming library
# mp11, a simple C++11 metaprogramming library
For background, please see the article ["Simple C++11 metaprogramming"](http://pdimov.com/cpp2/simple_cxx11_metaprogramming.html)
For background, please see the article ["Simple C++11 metaprogramming"](http://pdimov.com/cpp2/simple_cxx11_metaprogramming.html).
The library should be placed in a subdirectory `libs/mp11` in a Boost distribution. There is reference documentation in `doc/html/mp11.html`.

File diff suppressed because it is too large Load Diff

View File

@@ -23,19 +23,22 @@
[template endsimplesect[]
[block '''</simplesect>''']]
[section Overview]
...
[endsect]
[include mp11/overview.qbk]
[include mp11/definitions.qbk]
[include mp11/examples.qbk]
[section Reference]
The contents of the library are in namespace `boost::mp11`, unless specified otherwise.
[include mp11/integral.qbk]
[include mp11/list.qbk]
[include mp11/utility.qbk]
[include mp11/algorithm.qbk]
[include mp11/set.qbk]
[include mp11/map.qbk]
[include mp11/function.qbk]
[include mp11/integer_sequence.qbk]
[include mp11/tuple_for_each.qbk]
[endsect]

View File

@@ -10,150 +10,219 @@
[section `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`.
[endsect]
[section `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`.
[endsect]
[section `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>...>`.
[endsect]
[section `mp_transform_if<P, F, L>`]
template<template<class...> class P, template<class...> class F, class L> using mp_transform_if = /*...*/;
`mp_transform_if` replaces the elements `T` of `L` for which `mp_to_bool<P<T>>` is `mp_true` with `F<T>`, and returns the result.
[endsect]
[section `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.
[endsect]
[section `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`.
[endsect]
[section `mp_count_if<L, P>`]
template<class L, template<class...> class P> using mp_count_if = /*...*/;
`mp_count_f<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`.
[endsect]
[section `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.
[endsect]
[section `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`.
[endsect]
[section `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.
[endsect]
[section `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`.
[endsect]
[section `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.
[endsect]
[section `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.
[endsect]
[section `mp_iota_c<L, N>`]
[section `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>>`.
[endsect]
[section `mp_iota<L, N>`]
[section `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`.
[endsect]
[section `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.
[endsect]
[section `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.
[endsect]
[section `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`.
[endsect]
[section `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.
[endsect]
[section `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.
[endsect]
[section `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.
[endsect]
[section `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.
[endsect]
[section `mp_remove<L, V>`]
template<class L, class V> using mp_remove = /*...*/;
Removes all `V` elements of `L` and returns the result.
[endsect]
[section `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.
[endsect]
[section `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...>>`.
[endsect]
[section `mp_sort<L, P>`]
template<class L, template<class...> class P> using mp_sort = /*...*/;
[endsect]
[section `mp_find_index<L, V>`]
template<class L, class V> using mp_find_index = /*...*/;
[endsect]
[section `mp_find_index_if<L, P>`]
template<class L, template<class...> class P> using mp_find_index_if = /*...*/;
`mp_sort<L, P>` sorts the list `L` according to the strict weak ordering `mp_to_bool<P<T, U>>`.
[endsect]
[section `mp_find<L, V>`]
template<class L, class V> using mp_find = mp_drop<L, mp_find_index<L, V>>;
template<class L, class V> using mp_find = /*...*/;
`mp_find<L, V>` is 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>`.
[endsect]
[section `mp_find_if<L, P>`]
template<class L, template<class...> class P> using mp_find_if = mp_drop<L, mp_find_index_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<L, V>` is `mp_size<L>`.
[endsect]
[section `mp_reverse<L>`]
template<class L> using mp_reverse = /*...*/;
`mp_reverse<L<T1, T2, ..., Tn>>` is `L<Tn, ..., T2, T1>`.
[endsect]
[section `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.
[endsect]
[section `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.
[endsect]
[section `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.
[endsect]
[section `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`.
[endsect]
[section `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`.
[endsect]
[section `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`.
[endsect]
[endsect]

32
doc/mp11/definitions.qbk Normal file
View File

@@ -0,0 +1,32 @@
[/
/ Copyright 2017 Peter Dimov
/
/ Distributed under the Boost Software License, Version 1.0. (See
/ accompanying file LICENSE_1_0.txt or copy at
/ http://www.boost.org/LICENSE_1_0.txt)
/]
[section Definitions]
A /list/ is a '''&mdash;''' possibly but not necessarily variadic '''&mdash;''' 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 called `invoke`, for example
struct Q1 { template<class...> using invoke = void; };
struct Q2 { template<class T> using invoke = T*; };
struct Q3 { template<class... T> using invoke = 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; };
[endsect]

175
doc/mp11/examples.qbk Normal file
View File

@@ -0,0 +1,175 @@
[/
/ Copyright 2017 Peter Dimov
/
/ Distributed under the Boost Software License, Version 1.0. (See
/ accompanying file LICENSE_1_0.txt or copy at
/ http://www.boost.org/LICENSE_1_0.txt)
/]
[section Examples]
[section Generating Test Cases]
Let's suppose that we have written a metafunction `result<T, U>`:
template<class T> using promote = std::common_type_t<T, int>;
template<class T, class U> using result = std::common_type_t<promote<T>, promote<U>>;
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/tuple_for_each.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 = std::common_type_t<T, int>;
template<class T, class U> using result = std::common_type_t<promote<T>, promote<U>>;
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>;
boost::tuple_for_each( mp_product<mp_list, L, L>(), [](auto&& x){ test_result(x); } );
}
[endsect]
[section 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 `variant`s.
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 invoke = 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<Qret<F>::template invoke, 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`.
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,
using R = mp_unique<mp_product<Qret<F>::template invoke, 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 invoke = decltype( std::declval<F>()( std::declval<T>()... ) );
};
template<class F, class... V> auto rvisit( F&& f, V&&... v )
{
using R = mp_unique<mp_product<Qret<F>::template invoke, 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() );
}
int main()
{
std::variant<signed char, unsigned char, signed short, unsigned short, int, unsigned> v1( 1 );
std::cout << "(" << name<decltype(v1)>() << ")v1: ";
std::visit( []( auto const& x ){ std::cout << "(" << name<decltype(x)>() << ")" << x << std::endl; }, v1 );
std::variant<int, float, double> v2( 2.0f );
std::cout << "(" << name<decltype(v2)>() << ")v2: ";
std::visit( []( auto const& x ){ std::cout << "(" << name<decltype(x)>() << ")" << x << std::endl; }, v2 );
auto v3 = rvisit( []( auto const& x, auto const& y ){ return x + y; }, v1, v2 );
std::cout << "(" << name<decltype(v3)>() << ")v3: ";
std::visit( []( auto const& x ){ std::cout << "(" << name<decltype(x)>() << ")" << x << std::endl; }, v3 );
}
[endsect]
[endsect]

40
doc/mp11/function.qbk Normal file
View File

@@ -0,0 +1,40 @@
[/
/ Copyright 2017 Peter Dimov
/
/ Distributed under the Boost Software License, Version 1.0. (See
/ accompanying file LICENSE_1_0.txt or copy at
/ http://www.boost.org/LICENSE_1_0.txt)
/]
[section:function Helper Metafunctions, `<boost/mp11/function.hpp>`]
[section `mp_and<T...>`]
template<class... T> using mp_and = /*...*/;
`mp_and<T...>` is an alias for the first type `U` in `T...` for which `mp_to_bool<U>` is `mp_false`.
If no such type exists, the last one is returned. `mp_and<>` is `mp_true`. Similar to `std::conjunction` in C++17.
[endsect]
[section `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 faster.
[endsect]
[section `mp_or<T...>`]
template<class... T> using mp_or = /*...*/;
`mp_or<T...>` is an alias for the first type `U` in `T...` for which `mp_to_bool<U>` is `mp_true`.
If no such type exists, the last one is returned. `mp_or<>` is `mp_false`. Similar to `std::disjunction` in C++17.
[endsect]
[section `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.
[endsect]
[endsect]

View File

@@ -0,0 +1,45 @@
[/
/ Copyright 2017 Peter Dimov
/
/ Distributed under the Boost Software License, Version 1.0. (See
/ accompanying file LICENSE_1_0.txt or copy at
/ http://www.boost.org/LICENSE_1_0.txt)
/]
[section:integer_sequence Integer Sequences, `<boost/integer_sequence.hpp>`]
The contents of this header are defined in namespace `boost`.
[section `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`.
[endsect]
[section `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`.
[endsect]
[section `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`.
[endsect]
[section `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`.
[endsect]
[section `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`.
[endsect]
[endsect]

View File

@@ -8,6 +8,8 @@
[section:integral Integral Constants, `<boost/mp11/integral.hpp>`]
For an Mp11 integral constant type `T`, `T::value` is an integral constant in the C++ sense.
[section `mp_bool<B>`]
template<bool B> using mp_bool = std::integral_constant<bool, B>;
[endsect]

33
doc/mp11/overview.qbk Normal file
View File

@@ -0,0 +1,33 @@
[/
/ Copyright 2017 Peter Dimov
/
/ Distributed under the Boost Software License, Version 1.0. (See
/ accompanying file LICENSE_1_0.txt or copy at
/ http://www.boost.org/LICENSE_1_0.txt)
/]
[section Overview]
Mp11 is a C++11 metaprogramming library based on template aliases and variadic templates.
It implements the approach outlined in the article
[@http://pdimov.com/cpp2/simple_cxx11_metaprogramming.html Simple C++11 metaprogramming]
([@http://pdimov.com/cpp2/simple_cxx11_metaprogramming_2.html part 2]).
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>>`.
[endsect]

View File

@@ -0,0 +1,22 @@
[/
/ Copyright 2017 Peter Dimov
/
/ Distributed under the Boost Software License, Version 1.0. (See
/ accompanying file LICENSE_1_0.txt or copy at
/ http://www.boost.org/LICENSE_1_0.txt)
/]
[section:tuple_for_each A "for each" algorithm for tuple-like types, `<boost/tuple_for_each.hpp>`]
The contents of this header are defined in namespace `boost`.
[section `tuple_for_each`]
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<std::remove_reference_t<Tp>>::value`.
Returns `std::forward<F>(f)`.
[endsect]
[endsect]

View File

@@ -61,19 +61,20 @@ When `mp_valid<F, T...>` is `mp_true`, `mp_defer<F, T...>` is a struct with a ne
`mp_defer<F, T...>` is an empty struct.
[endsect]
[section `mp_quote<F>`]
template<template<class...> class F> struct mp_quote
[section `mp_quote<F, T...>`]
template<template<class...> class F, class... T> struct mp_quote
{
template<class... T> using apply = F<T...>;
template<class... U> using invoke = F<T..., U...>;
};
`mp_quote<F>` transforms the template `F` into a type. The nested template `apply` of the result is an alias for `F`.
`mp_quote<F, T...>` transforms the template `F` into a type. In the common case `mp_quote<F>`, the nested template `invoke` of the result is an alias for `F`;
otherwise, `invoke<U...>` is an alias for `F<T..., U...>`, allowing partial application.
[endsect]
[section `mp_unquote<Q, T...>`]
template<class Q, class... T> using mp_unquote = typename Q::template apply<T...>;
[section `mp_invoke<Q, T...>`]
template<class Q, class... T> using mp_invoke = typename Q::template invoke<T...>;
`mp_unquote<Q, T...>`, where `Q` is `mp_quote<F>`, is an alias for `F<T...>`.
`mp_invoke<Q, T...>` evaluates the nested template `invoke` of a quoted metafunction. `mp_invoke<mp_quote<F>, T...>` is an alias for `F<T...>`. `mp_invoke<mp_quote<F, T...>, U...>` is an alias for `F<T..., U...>`.
[endsect]
[endsect]

View File

@@ -23,6 +23,8 @@
namespace boost
{
namespace mp11
{
// mp_assign<L1, L2>
namespace detail
@@ -490,15 +492,15 @@ template<template<class...> class L, class T1, class... T, template<class...> cl
template<class L, template<class...> class P> using mp_sort = typename detail::mp_sort_impl<L, P>::type;
// mp_find_index<L, V>
// mp_find<L, V>
namespace detail
{
template<class L, class V> struct mp_find_index_impl;
template<class L, class V> struct mp_find_impl;
#if !defined( BOOST_MP11_NO_CONSTEXPR )
template<template<class...> class L, class V> struct mp_find_index_impl<L<>, V>
template<template<class...> class L, class V> struct mp_find_impl<L<>, V>
{
using type = mp_size_t<0>;
};
@@ -508,7 +510,7 @@ constexpr std::size_t cx_find_index( bool const * first, bool const * last )
return first == last || *first? 0: 1 + cx_find_index( first + 1, last );
}
template<template<class...> class L, class... T, class V> struct mp_find_index_impl<L<T...>, V>
template<template<class...> class L, class... T, class V> struct mp_find_impl<L<T...>, V>
{
static constexpr bool _v[] = { std::is_same<T, V>::value... };
using type = mp_size_t< cx_find_index( _v, _v + sizeof...(T) ) >;
@@ -518,7 +520,7 @@ template<template<class...> class L, class... T, class V> struct mp_find_index_i
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 )
template<template<class...> class L, class... T, class V> struct mp_find_index_impl<L<T...>, V>
template<template<class...> class L, class... T, class V> struct mp_find_impl<L<T...>, V>
{
static_assert( sizeof...(T) == 0, "T... must be empty" );
using type = mp_size_t<0>;
@@ -526,21 +528,21 @@ template<template<class...> class L, class... T, class V> struct mp_find_index_i
#else
template<template<class...> class L, class V> struct mp_find_index_impl<L<>, V>
template<template<class...> class L, class V> struct mp_find_impl<L<>, V>
{
using type = mp_size_t<0>;
};
#endif
template<template<class...> class L, class... T, class V> struct mp_find_index_impl<L<V, T...>, V>
template<template<class...> class L, class... T, class V> struct mp_find_impl<L<V, T...>, V>
{
using type = mp_size_t<0>;
};
template<template<class...> class L, class T1, class... T, class V> struct mp_find_index_impl<L<T1, T...>, V>
template<template<class...> class L, class T1, class... T, class V> struct mp_find_impl<L<T1, T...>, V>
{
using _r = typename mp_find_index_impl<mp_list<T...>, V>::type;
using _r = typename mp_find_impl<mp_list<T...>, V>::type;
using type = mp_size_t<1 + _r::value>;
};
@@ -548,22 +550,22 @@ template<template<class...> class L, class T1, class... T, class V> struct mp_fi
} // namespace detail
template<class L, class V> using mp_find_index = typename detail::mp_find_index_impl<L, V>::type;
template<class L, class V> using mp_find = typename detail::mp_find_impl<L, V>::type;
// mp_find_index_if<L, P>
// mp_find_if<L, P>
namespace detail
{
template<class L, template<class...> class P> struct mp_find_index_if_impl;
template<class L, template<class...> class P> struct mp_find_if_impl;
#if !defined( BOOST_MP11_NO_CONSTEXPR )
template<template<class...> class L, template<class...> class P> struct mp_find_index_if_impl<L<>, P>
template<template<class...> class L, template<class...> class P> struct mp_find_if_impl<L<>, P>
{
using type = mp_size_t<0>;
};
template<template<class...> class L, class... T, template<class...> class P> struct mp_find_index_if_impl<L<T...>, P>
template<template<class...> class L, class... T, template<class...> class P> struct mp_find_if_impl<L<T...>, P>
{
static constexpr bool _v[] = { P<T>::value... };
using type = mp_size_t< cx_find_index( _v, _v + sizeof...(T) ) >;
@@ -573,7 +575,7 @@ template<template<class...> class L, class... T, template<class...> class P> str
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 )
template<template<class...> class L, class... T, template<class...> class P> struct mp_find_index_if_impl<L<T...>, P>
template<template<class...> class L, class... T, template<class...> class P> struct mp_find_if_impl<L<T...>, P>
{
static_assert( sizeof...(T) == 0, "T... must be empty" );
using type = mp_size_t<0>;
@@ -581,35 +583,29 @@ template<template<class...> class L, class... T, template<class...> class P> str
#else
template<template<class...> class L, template<class...> class P> struct mp_find_index_if_impl<L<>, P>
template<template<class...> class L, template<class...> class P> struct mp_find_if_impl<L<>, P>
{
using type = mp_size_t<0>;
};
#endif
template<class L, template<class...> class P> struct mp_find_index_if_impl_2
template<class L, template<class...> class P> struct mp_find_if_impl_2
{
using _r = typename mp_find_index_if_impl<L, P>::type;
using _r = typename mp_find_if_impl<L, P>::type;
using type = mp_size_t<1 + _r::value>;
};
template<template<class...> class L, class T1, class... T, template<class...> class P> struct mp_find_index_if_impl<L<T1, T...>, P>
template<template<class...> class L, class T1, class... T, template<class...> class P> struct mp_find_if_impl<L<T1, T...>, P>
{
using type = typename mp_if<P<T1>, mp_identity<mp_size_t<0>>, mp_find_index_if_impl_2<mp_list<T...>, P>>::type;
using type = typename mp_if<P<T1>, mp_identity<mp_size_t<0>>, mp_find_if_impl_2<mp_list<T...>, P>>::type;
};
#endif
} // namespace detail
template<class L, template<class...> class P> using mp_find_index_if = typename detail::mp_find_index_if_impl<L, P>::type;
// mp_find<L, V>
template<class L, class V> using mp_find = mp_drop<L, mp_find_index<L, V>>;
// mp_find_if<L, P>
template<class L, template<class...> class P> using mp_find_if = mp_drop<L, mp_find_index_if<L, P>>;
template<class L, template<class...> class P> using mp_find_if = typename detail::mp_find_if_impl<L, P>::type;
// mp_reverse<L>
namespace detail
@@ -757,6 +753,7 @@ template<class L, template<class...> class P> using mp_none_of = mp_bool< mp_cou
// 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 >;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_ALGORITHM_HPP_INCLUDED

View File

@@ -15,6 +15,8 @@
namespace boost
{
namespace mp11
{
// mp_count<L, V>
namespace detail
@@ -87,6 +89,7 @@ template<template<class...> class L, class... T, template<class...> class P> str
template<class L, template<class...> class P> using mp_count_if = typename detail::mp_count_if_impl<L, P>::type;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED

View File

@@ -10,12 +10,15 @@
namespace boost
{
namespace mp11
{
// mp_list<T...>
template<class... T> struct mp_list
{
};
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED

View File

@@ -12,6 +12,8 @@
namespace boost
{
namespace mp11
{
// mp_map_find
namespace detail
@@ -35,6 +37,7 @@ template<template<class...> class M, class... T, class K> struct mp_map_find_imp
template<class M, class K> using mp_map_find = typename detail::mp_map_find_impl<M, K>::type;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED

View File

@@ -13,6 +13,8 @@
namespace boost
{
namespace mp11
{
// mp_plus
namespace detail
@@ -41,6 +43,7 @@ template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, c
template<class... T> using mp_plus = typename detail::mp_plus_impl<T...>::type;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED

View File

@@ -1,7 +1,7 @@
#ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED
#define BOOST_MP11_FUNCTION_HPP_INCLUDED
// Copyright 2015, 2016 Peter Dimov.
// Copyright 2015-2017 Peter Dimov.
//
// Distributed under the Boost Software License, Version 1.0.
//
@@ -15,9 +15,8 @@
namespace boost
{
// mp_equal_to<T1, T2>
template<class T1, class T2> using mp_equal_to = mp_bool< T1::value == T2::value >;
namespace mp11
{
// mp_all<T...>
template<class... T> using mp_all = mp_bool< mp_count_if< mp_list<T...>, mp_to_bool >::value == sizeof...(T) >;
@@ -40,9 +39,14 @@ template<> struct mp_and_impl<>
using type = mp_true;
};
template<class T> struct mp_and_impl<T>
{
using type = T;
};
template<class T1, class... T> struct mp_and_impl<T1, T...>
{
using type = mp_eval_if< mp_not<T1>, mp_false, mp_and, T... >;
using type = mp_eval_if< mp_not<T1>, T1, mp_and, T... >;
};
} // namespace detail
@@ -68,13 +72,19 @@ template<> struct mp_or_impl<>
using type = mp_false;
};
template<class T> struct mp_or_impl<T>
{
using type = T;
};
template<class T1, class... T> struct mp_or_impl<T1, T...>
{
using type = mp_eval_if< T1, mp_true, mp_or, T... >;
using type = mp_eval_if< T1, T1, mp_or, T... >;
};
} // namespace detail
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED

View File

@@ -13,6 +13,8 @@
namespace boost
{
namespace mp11
{
// mp_bool
template<bool B> using mp_bool = std::integral_constant<bool, B>;
@@ -32,6 +34,7 @@ template<int I> using mp_int = std::integral_constant<int, I>;
// mp_size_t
template<std::size_t N> using mp_size_t = std::integral_constant<std::size_t, N>;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_INTEGRAL_HPP_INCLUDED

View File

@@ -13,6 +13,8 @@
namespace boost
{
namespace mp11
{
// mp_size<L>
namespace detail
@@ -168,6 +170,7 @@ template<template<class...> class L1, class... T1, template<class...> class L2,
template<class... L> using mp_append = typename detail::mp_append_impl<L...>::type;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_LIST_HPP_INCLUDED

View File

@@ -17,6 +17,8 @@
namespace boost
{
namespace mp11
{
// 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>>;
@@ -77,6 +79,7 @@ template<class M, class K> struct mp_map_erase_impl
template<class M, class K> using mp_map_erase = typename detail::mp_map_erase_impl<M, K>::type;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_MAP_HPP_INCLUDED

View File

@@ -13,6 +13,8 @@
namespace boost
{
namespace mp11
{
// mp_set_contains<S, V>
namespace detail
@@ -76,6 +78,7 @@ template<template<class...> class L, class... U, class T1, class... T> struct mp
template<class S, class... T> using mp_set_push_front = typename detail::mp_set_push_front_impl<S, T...>::type;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_SET_HPP_INCLUDED

View File

@@ -1,7 +1,7 @@
#ifndef BOOST_MP11_UTILITY_HPP_INCLUDED
#define BOOST_MP11_UTILITY_HPP_INCLUDED
// Copyright 2015 Peter Dimov.
// Copyright 2015, 2017 Peter Dimov.
//
// Distributed under the Boost Software License, Version 1.0.
//
@@ -12,6 +12,8 @@
namespace boost
{
namespace mp11
{
// mp_identity
template<class T> struct mp_identity
@@ -102,29 +104,30 @@ struct mp_no_type
template<template<class...> class F, class... T> using mp_defer = mp_if<mp_valid<F, T...>, detail::mp_defer_impl<F, T...>, detail::mp_no_type>;
// mp_quote
template<template<class...> class F> struct mp_quote
template<template<class...> class F, class... T> struct mp_quote
{
template<class... T> using apply = F<T...>;
template<class... U> using invoke = F<T..., U...>;
};
// mp_unquote
namespace detail
{
template<class Q, class... T> struct mp_unquote_impl
template<class Q, class... T> struct mp_invoke_impl
{
using type = typename Q::template apply<T...>;
using type = typename Q::template invoke<T...>;
};
template<template<class...> class F, class... T> struct mp_unquote_impl<mp_quote<F>, T...>
template<template<class...> class F, class... T, class... U> struct mp_invoke_impl<mp_quote<F, T...>, U...>
{
using type = F<T...>;
using type = F<T..., U...>;
};
} // namespace detail
template<class Q, class... T> using mp_unquote = typename detail::mp_unquote_impl<Q, T...>::type;
template<class Q, class... T> using mp_invoke = typename detail::mp_invoke_impl<Q, T...>::type;
} // namespace mp11
} // namespace boost
#endif // #ifndef BOOST_MP11_UTILITY_HPP_INCLUDED

View File

@@ -48,8 +48,6 @@ run mp_remove.cpp : : : $(REQ) ;
run mp_remove_if.cpp : : : $(REQ) ;
run mp_partition.cpp : : : $(REQ) ;
run mp_sort.cpp : : : $(REQ) ;
run mp_find_index.cpp : : : $(REQ) ;
run mp_find_index_if.cpp : : : $(REQ) ;
run mp_find.cpp : : : $(REQ) ;
run mp_find_if.cpp : : : $(REQ) ;
run mp_reverse.cpp : : : $(REQ) ;
@@ -71,6 +69,7 @@ run mp_eval_if.cpp : : : $(REQ) ;
run mp_valid.cpp : : : $(REQ) ;
run mp_defer.cpp : : : $(REQ) ;
run mp_quote.cpp : : : $(REQ) ;
run mp_invoke.cpp : : : $(REQ) ;
# integer_sequence
run integer_sequence.cpp : : : $(REQ) ;

View File

@@ -14,29 +14,29 @@
int main()
{
using boost::mp_bool;
using boost::mp11::mp_bool;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_bool<false>, std::integral_constant<bool, false>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_bool<true>, std::integral_constant<bool, true>>));
using boost::mp_true;
using boost::mp_false;
using boost::mp11::mp_true;
using boost::mp11::mp_false;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_false, std::integral_constant<bool, false>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_true, std::integral_constant<bool, true>>));
using boost::mp_int;
using boost::mp11::mp_int;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_int<0>, std::integral_constant<int, 0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_int<814>, std::integral_constant<int, 814>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_int<-144>, std::integral_constant<int, -144>>));
using boost::mp_size_t;
using boost::mp11::mp_size_t;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_size_t<0>, std::integral_constant<std::size_t, 0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_size_t<1972>, std::integral_constant<std::size_t, 1972>>));
using boost::mp_to_bool;
using boost::mp11::mp_to_bool;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_to_bool<mp_false>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_to_bool<mp_true>, mp_true>));
@@ -51,7 +51,7 @@ int main()
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_to_bool<mp_size_t<1>>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_to_bool<mp_size_t<442>>, mp_true>));
using boost::mp_not;
using boost::mp11::mp_not;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_not<mp_false>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_not<mp_true>, mp_false>));

View File

@@ -14,11 +14,11 @@
int main()
{
using boost::mp_all;
using boost::mp_true;
using boost::mp_false;
using boost::mp_int;
using boost::mp_size_t;
using boost::mp11::mp_all;
using boost::mp11::mp_true;
using boost::mp11::mp_false;
using boost::mp11::mp_int;
using boost::mp11::mp_size_t;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_all<>, mp_true>));

View File

@@ -19,10 +19,10 @@ struct X1 {};
int main()
{
using boost::mp_list;
using boost::mp_all_of;
using boost::mp_true;
using boost::mp_false;
using boost::mp11::mp_list;
using boost::mp11::mp_all_of;
using boost::mp11::mp_true;
using boost::mp11::mp_false;
{
using L1 = mp_list<>;

View File

@@ -1,5 +1,5 @@
// Copyright 2015, 2016 Peter Dimov.
// Copyright 2015-2017 Peter Dimov.
//
// Distributed under the Boost Software License, Version 1.0.
//
@@ -14,34 +14,34 @@
int main()
{
using boost::mp_and;
using boost::mp_true;
using boost::mp_false;
using boost::mp_int;
using boost::mp_size_t;
using boost::mp11::mp_and;
using boost::mp11::mp_true;
using boost::mp11::mp_false;
using boost::mp11::mp_int;
using boost::mp11::mp_size_t;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_false>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<-7>>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<0>>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<-7>>, mp_int<-7>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<0>>, mp_int<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<7>>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<0>>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<7>>, mp_size_t<7>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<0>>, mp_size_t<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true, mp_true>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true, mp_false>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_false, void>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<-4>, mp_int<5>>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<-4>, mp_int<0>>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<0>, void>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<-4>, mp_int<5>>, mp_int<5>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<-4>, mp_int<0>>, mp_int<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<0>, void>, mp_int<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<7>, mp_size_t<8>>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<7>, mp_size_t<0>>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<0>, void>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<7>, mp_size_t<8>>, mp_size_t<8>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<7>, mp_size_t<0>>, mp_size_t<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<0>, void>, mp_size_t<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true, mp_true, mp_true>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true, mp_true, mp_false>, mp_false>));
@@ -54,11 +54,11 @@ int main()
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true, mp_false, void, void>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_false, void, void, void>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<1>, mp_int<2>, mp_int<-11>, mp_int<14>>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<1>, mp_int<0>, void, void>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<1>, mp_int<2>, mp_int<-11>, mp_int<14>>, mp_int<14>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<1>, mp_int<0>, void, void>, mp_int<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<1>, mp_size_t<2>, mp_size_t<114>, mp_size_t<8>, mp_size_t<94>>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<1>, mp_size_t<2>, mp_size_t<0>, void, void>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<1>, mp_size_t<2>, mp_size_t<114>, mp_size_t<8>, mp_size_t<94>>, mp_size_t<94>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<1>, mp_size_t<2>, mp_size_t<0>, void, void>, mp_size_t<0>>));
return boost::report_errors();
}

View File

@@ -14,11 +14,11 @@
int main()
{
using boost::mp_any;
using boost::mp_true;
using boost::mp_false;
using boost::mp_int;
using boost::mp_size_t;
using boost::mp11::mp_any;
using boost::mp11::mp_true;
using boost::mp11::mp_false;
using boost::mp11::mp_int;
using boost::mp11::mp_size_t;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_any<>, mp_false>));

View File

@@ -19,10 +19,10 @@ struct X1 {};
int main()
{
using boost::mp_list;
using boost::mp_any_of;
using boost::mp_true;
using boost::mp_false;
using boost::mp11::mp_list;
using boost::mp11::mp_any_of;
using boost::mp11::mp_true;
using boost::mp11::mp_false;
{
using L1 = mp_list<>;

View File

@@ -22,8 +22,8 @@ struct X6 {};
int main()
{
using boost::mp_list;
using boost::mp_append;
using boost::mp11::mp_list;
using boost::mp11::mp_append;
using L1 = mp_list<char[1], char[1]>;
using L2 = mp_list<char[2], char[2]>;

View File

@@ -20,8 +20,8 @@ struct X3 {};
int main()
{
using boost::mp_list;
using boost::mp_assign;
using boost::mp11::mp_list;
using boost::mp11::mp_assign;
using L1 = mp_list<int, void(), float[]>;

View File

@@ -23,10 +23,10 @@ struct X5 {};
int main()
{
using boost::mp_list;
using boost::mp_at;
using boost::mp_at_c;
using boost::mp_size_t;
using boost::mp11::mp_list;
using boost::mp11::mp_at;
using boost::mp11::mp_at_c;
using boost::mp11::mp_size_t;
{
using L1 = mp_list<X1, X2, X3, X4, X5>;

View File

@@ -16,8 +16,8 @@
int main()
{
using boost::mp_list;
using boost::mp_clear;
using boost::mp11::mp_list;
using boost::mp11::mp_clear;
using L1 = mp_list<int, void(), float[]>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_clear<L1>, mp_list<>>));

View File

@@ -21,10 +21,10 @@ struct X3 {};
int main()
{
using boost::mp_list;
using boost::mp_contains;
using boost::mp_true;
using boost::mp_false;
using boost::mp11::mp_list;
using boost::mp11::mp_contains;
using boost::mp11::mp_true;
using boost::mp11::mp_false;
{
using L1 = mp_list<>;

View File

@@ -19,8 +19,8 @@ struct X3 {};
int main()
{
using boost::mp_list;
using boost::mp_copy_if;
using boost::mp11::mp_list;
using boost::mp11::mp_copy_if;
{
using L1 = mp_list<>;

View File

@@ -21,9 +21,9 @@ struct X3 {};
int main()
{
using boost::mp_list;
using boost::mp_count;
using boost::mp_size_t;
using boost::mp11::mp_list;
using boost::mp11::mp_count;
using boost::mp11::mp_size_t;
{
using L1 = mp_list<>;

View File

@@ -19,9 +19,9 @@ struct X1 {};
int main()
{
using boost::mp_list;
using boost::mp_count_if;
using boost::mp_size_t;
using boost::mp11::mp_list;
using boost::mp11::mp_count_if;
using boost::mp11::mp_size_t;
{
using L1 = mp_list<>;

View File

@@ -12,17 +12,21 @@
#include <boost/core/lightweight_test_trait.hpp>
#include <type_traits>
using boost::mp11::mp_identity;
using boost::mp11::mp_true;
using boost::mp11::mp_false;
template<class T> struct has_type
{
template<class U> static boost::mp_true f( boost::mp_identity<typename U::type>* );
template<class U> static boost::mp_false f( ... );
template<class U> static mp_true f( mp_identity<typename U::type>* );
template<class U> static mp_false f( ... );
using type = decltype( f<T>(0) );
static const auto value = type::value;
};
using boost::mp_defer;
using boost::mp11::mp_defer;
template<class T> using add_pointer = T*;
template<class... T> using add_pointer_impl = mp_defer<add_pointer, T...>;

View File

@@ -23,10 +23,10 @@ struct X5 {};
int main()
{
using boost::mp_list;
using boost::mp_drop;
using boost::mp_drop_c;
using boost::mp_size_t;
using boost::mp11::mp_list;
using boost::mp11::mp_drop;
using boost::mp11::mp_drop_c;
using boost::mp11::mp_size_t;
{
using L1 = mp_list<>;

View File

@@ -16,10 +16,10 @@
int main()
{
using boost::mp_list;
using boost::mp_empty;
using boost::mp_true;
using boost::mp_false;
using boost::mp11::mp_list;
using boost::mp11::mp_empty;
using boost::mp11::mp_true;
using boost::mp11::mp_false;
using L1 = mp_list<>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_empty<L1>, mp_true>));

View File

@@ -14,23 +14,23 @@
int main()
{
using boost::mp_eval_if_c;
using boost::mp_identity;
using boost::mp11::mp_eval_if_c;
using boost::mp11::mp_identity;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_eval_if_c<true, char[], mp_identity, void, void, void>, char[]>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_eval_if_c<false, char[], mp_identity, void()>, mp_identity<void()>>));
using boost::mp_eval_if;
using boost::mp11::mp_eval_if;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_eval_if<std::true_type, char[], mp_identity, void, void, void>, char[]>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_eval_if<std::false_type, char[], mp_identity, void()>, mp_identity<void()>>));
using boost::mp_int;
using boost::mp11::mp_int;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_eval_if<mp_int<-7>, char[], mp_identity, void, void, void>, char[]>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_eval_if<mp_int<0>, char[], mp_identity, void()>, mp_identity<void()>>));
using boost::mp_size_t;
using boost::mp11::mp_size_t;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_eval_if<mp_size_t<14>, char[], mp_identity, void, void, void>, char[]>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_eval_if<mp_size_t<0>, char[], mp_identity, void()>, mp_identity<void()>>));

View File

@@ -18,8 +18,8 @@ struct X1 {};
int main()
{
using boost::mp_list;
using boost::mp_fill;
using boost::mp11::mp_list;
using boost::mp11::mp_fill;
using L1 = mp_list<int, void(), float[]>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_fill<L1, X1>, mp_list<X1, X1, X1>>));

View File

@@ -21,33 +21,42 @@ struct X3 {};
int main()
{
using boost::mp_list;
using boost::mp_find;
using boost::mp11::mp_list;
using boost::mp11::mp_find;
using boost::mp11::mp_size_t;
{
using L1 = mp_list<>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L1, void>, L1>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L1, void>, mp_size_t<0>>));
using L2 = mp_list<X1, X2, X2, X3, X3, X3>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L2, void>, mp_list<>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L2, X1>, L2>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L2, X2>, mp_list<X2, X2, X3, X3, X3>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L2, X3>, mp_list<X3, X3, X3>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L2, void>, mp_size_t<6>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L2, X1>, mp_size_t<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L2, X2>, mp_size_t<1>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L2, X3>, mp_size_t<3>>));
}
{
using L3 = std::tuple<>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L3, void>, L3>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L3, void>, mp_size_t<0>>));
using L4 = std::tuple<X1, X2, X2, X3, X3, X3>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L4, void>, std::tuple<>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L4, X1>, L4>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L4, X2>, std::tuple<X2, X2, X3, X3, X3>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L4, X3>, std::tuple<X3, X3, X3>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L4, void>, mp_size_t<6>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L4, X1>, mp_size_t<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L4, X2>, mp_size_t<1>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L4, X3>, mp_size_t<3>>));
}
{
using L5 = std::pair<X1, X2>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L5, void>, mp_size_t<2>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L5, X1>, mp_size_t<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L5, X2>, mp_size_t<1>>));
}
return boost::report_errors();

View File

@@ -19,31 +19,40 @@ struct X1 {};
int main()
{
using boost::mp_list;
using boost::mp_find_if;
using boost::mp11::mp_list;
using boost::mp11::mp_find_if;
using boost::mp11::mp_size_t;
{
using L1 = mp_list<>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L1, std::is_const>, L1>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L1, std::is_const>, mp_size_t<0>>));
using L2 = mp_list<X1, X1 const, X1 const, X1*, X1*, X1*>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L2, std::is_volatile>, mp_list<>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L2, std::is_const>, mp_list<X1 const, X1 const, X1*, X1*, X1*>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L2, std::is_pointer>, mp_list<X1*, X1*, X1*>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L2, std::is_volatile>, mp_size_t<6>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L2, std::is_const>, mp_size_t<1>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L2, std::is_pointer>, mp_size_t<3>>));
}
{
using L1 = std::tuple<>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L1, std::is_const>, L1>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L1, std::is_const>, mp_size_t<0>>));
using L2 = std::tuple<X1, X1 const, X1 const, X1*, X1*, X1*>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L2, std::is_volatile>, std::tuple<>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L2, std::is_const>, std::tuple<X1 const, X1 const, X1*, X1*, X1*>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L2, std::is_pointer>, std::tuple<X1*, X1*, X1*>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L2, std::is_volatile>, mp_size_t<6>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L2, std::is_const>, mp_size_t<1>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L2, std::is_pointer>, mp_size_t<3>>));
}
{
using L2 = std::pair<X1 const, X1*>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L2, std::is_volatile>, mp_size_t<2>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L2, std::is_const>, mp_size_t<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_if<L2, std::is_pointer>, mp_size_t<1>>));
}
return boost::report_errors();

View File

@@ -1,63 +0,0 @@
// Copyright 2015 Peter Dimov.
//
// Distributed under the Boost Software License, Version 1.0.
//
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/algorithm.hpp>
#include <boost/mp11/list.hpp>
#include <boost/mp11/integral.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <type_traits>
#include <tuple>
#include <utility>
struct X1 {};
struct X2 {};
struct X3 {};
int main()
{
using boost::mp_list;
using boost::mp_find_index;
using boost::mp_size_t;
{
using L1 = mp_list<>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index<L1, void>, mp_size_t<0>>));
using L2 = mp_list<X1, X2, X2, X3, X3, X3>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index<L2, void>, mp_size_t<6>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index<L2, X1>, mp_size_t<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index<L2, X2>, mp_size_t<1>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index<L2, X3>, mp_size_t<3>>));
}
{
using L3 = std::tuple<>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index<L3, void>, mp_size_t<0>>));
using L4 = std::tuple<X1, X2, X2, X3, X3, X3>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index<L4, void>, mp_size_t<6>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index<L4, X1>, mp_size_t<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index<L4, X2>, mp_size_t<1>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index<L4, X3>, mp_size_t<3>>));
}
{
using L5 = std::pair<X1, X2>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index<L5, void>, mp_size_t<2>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index<L5, X1>, mp_size_t<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index<L5, X2>, mp_size_t<1>>));
}
return boost::report_errors();
}

View File

@@ -1,59 +0,0 @@
// Copyright 2015 Peter Dimov.
//
// Distributed under the Boost Software License, Version 1.0.
//
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/algorithm.hpp>
#include <boost/mp11/list.hpp>
#include <boost/mp11/integral.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <type_traits>
#include <tuple>
#include <utility>
struct X1 {};
int main()
{
using boost::mp_list;
using boost::mp_find_index_if;
using boost::mp_size_t;
{
using L1 = mp_list<>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index_if<L1, std::is_const>, mp_size_t<0>>));
using L2 = mp_list<X1, X1 const, X1 const, X1*, X1*, X1*>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index_if<L2, std::is_volatile>, mp_size_t<6>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index_if<L2, std::is_const>, mp_size_t<1>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index_if<L2, std::is_pointer>, mp_size_t<3>>));
}
{
using L1 = std::tuple<>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index_if<L1, std::is_const>, mp_size_t<0>>));
using L2 = std::tuple<X1, X1 const, X1 const, X1*, X1*, X1*>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index_if<L2, std::is_volatile>, mp_size_t<6>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index_if<L2, std::is_const>, mp_size_t<1>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index_if<L2, std::is_pointer>, mp_size_t<3>>));
}
{
using L2 = std::pair<X1 const, X1*>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index_if<L2, std::is_volatile>, mp_size_t<2>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index_if<L2, std::is_const>, mp_size_t<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find_index_if<L2, std::is_pointer>, mp_size_t<1>>));
}
return boost::report_errors();
}

View File

@@ -22,8 +22,8 @@ template<class T1, class T2> struct F {};
int main()
{
using boost::mp_list;
using boost::mp_fold;
using boost::mp11::mp_list;
using boost::mp11::mp_fold;
{
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_fold<mp_list<>, void, F>, void>));
@@ -41,13 +41,13 @@ int main()
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_fold<std::tuple<X1, X2, X3, X4>, void, F>, F<F<F<F<void, X1>, X2>, X3>, X4>>));
}
using boost::mp_push_back;
using boost::mp11::mp_push_back;
{
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_fold<std::tuple<X1, X2, X3, X4>, mp_list<>, mp_push_back>, mp_list<X1, X2, X3, X4>>));
}
using boost::mp_push_front;
using boost::mp11::mp_push_front;
{
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_fold<std::tuple<X1, X2, X3, X4>, mp_list<>, mp_push_front>, mp_list<X4, X3, X2, X1>>));

View File

@@ -15,9 +15,9 @@
int main()
{
using boost::mp_list;
using boost::mp_front;
using boost::mp_first;
using boost::mp11::mp_list;
using boost::mp11::mp_front;
using boost::mp11::mp_first;
using L1 = mp_list<void>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_front<L1>, void>));

View File

@@ -15,14 +15,14 @@ struct X {};
int main()
{
using boost::mp_identity;
using boost::mp11::mp_identity;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_identity<void const volatile>::type, void const volatile>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_identity<void()>::type, void()>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_identity<int const[]>::type, int const[]>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_identity<X>::type, X>));
using boost::mp_identity_t;
using boost::mp11::mp_identity_t;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_identity_t<void const volatile>, void const volatile>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_identity_t<void()>, void()>));

View File

@@ -14,22 +14,22 @@
int main()
{
using boost::mp_if_c;
using boost::mp11::mp_if_c;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_if_c<true, char[], void()>, char[]>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_if_c<false, char[], void()>, void()>));
using boost::mp_if;
using boost::mp11::mp_if;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_if<std::true_type, char[], void()>, char[]>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_if<std::false_type, char[], void()>, void()>));
using boost::mp_int;
using boost::mp11::mp_int;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_if<mp_int<-7>, char[], void()>, char[]>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_if<mp_int<0>, char[], void()>, void()>));
using boost::mp_size_t;
using boost::mp11::mp_size_t;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_if<mp_size_t<14>, char[], void()>, char[]>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_if<mp_size_t<0>, char[], void()>, void()>));

View File

@@ -17,7 +17,7 @@ struct X3 {};
int main()
{
using boost::mp_inherit;
using boost::mp11::mp_inherit;
BOOST_TEST_TRAIT_TRUE((std::is_base_of<X1, mp_inherit<X1, X2, X3>>));
BOOST_TEST_TRAIT_TRUE((std::is_base_of<X2, mp_inherit<X1, X2, X3>>));

56
test/mp_invoke.cpp Normal file
View File

@@ -0,0 +1,56 @@
// Copyright 2015, 2017 Peter Dimov.
//
// Distributed under the Boost Software License, Version 1.0.
//
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/utility.hpp>
#include <boost/mp11/integral.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <type_traits>
using boost::mp11::mp_invoke;
using boost::mp11::mp_size_t;
struct Q1
{
template<class...> using invoke = void;
};
struct Q2
{
template<class...> class invoke;
};
struct Q3
{
template<class... T> using invoke = mp_size_t<sizeof...(T)>;
};
struct Q4
{
template<class T1, class... T> using invoke = T1;
};
int main()
{
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_invoke<Q1>, void>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_invoke<Q1, int>, void>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_invoke<Q1, int[], char[]>, void>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_invoke<Q2>, Q2::invoke<>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_invoke<Q2, int>, Q2::invoke<int>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_invoke<Q2, int[], char[]>, Q2::invoke<int[], char[]>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_invoke<Q3>, mp_size_t<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_invoke<Q3, int>, mp_size_t<1>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_invoke<Q3, int[], char[]>, mp_size_t<2>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_invoke<Q4, int>, int>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_invoke<Q4, int[], char[]>, int[]>));
return boost::report_errors();
}

View File

@@ -14,11 +14,11 @@
int main()
{
using boost::mp_list;
using boost::mp_iota;
using boost::mp_iota_c;
using boost::mp_int;
using boost::mp_size_t;
using boost::mp11::mp_list;
using boost::mp11::mp_iota;
using boost::mp11::mp_iota_c;
using boost::mp11::mp_int;
using boost::mp11::mp_size_t;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota_c<0>, mp_list<>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota_c<1>, mp_list<mp_size_t<0>>>));

View File

@@ -17,10 +17,10 @@
int main()
{
using boost::mp_map_contains;
using boost::mp_list;
using boost::mp_true;
using boost::mp_false;
using boost::mp11::mp_map_contains;
using boost::mp11::mp_list;
using boost::mp11::mp_true;
using boost::mp11::mp_false;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_map_contains<mp_list<>, char>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_map_contains<std::tuple<>, int>, mp_false>));

View File

@@ -16,8 +16,8 @@
int main()
{
using boost::mp_map_erase;
using boost::mp_list;
using boost::mp11::mp_map_erase;
using boost::mp11::mp_list;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_map_erase<mp_list<>, void>, mp_list<>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_map_erase<std::tuple<>, int>, std::tuple<>>));

View File

@@ -16,8 +16,8 @@
int main()
{
using boost::mp_map_find;
using boost::mp_list;
using boost::mp11::mp_map_find;
using boost::mp11::mp_list;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_map_find<mp_list<>, char>, void>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_map_find<std::tuple<>, int>, void>));

View File

@@ -16,9 +16,9 @@
int main()
{
using boost::mp_map_insert;
using boost::mp_list;
using boost::mp_push_back;
using boost::mp11::mp_map_insert;
using boost::mp11::mp_list;
using boost::mp11::mp_push_back;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_map_insert<mp_list<>, mp_list<void>>, mp_list<mp_list<void>>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_map_insert<std::tuple<>, std::tuple<int>>, std::tuple<std::tuple<int>>>));

View File

@@ -16,9 +16,9 @@
int main()
{
using boost::mp_map_replace;
using boost::mp_list;
using boost::mp_push_back;
using boost::mp11::mp_map_replace;
using boost::mp11::mp_list;
using boost::mp11::mp_push_back;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_map_replace<mp_list<>, mp_list<void>>, mp_list<mp_list<void>>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_map_replace<std::tuple<>, std::tuple<int>>, std::tuple<std::tuple<int>>>));

View File

@@ -15,14 +15,14 @@
#include <tuple>
#include <utility>
using boost::mp_int;
using boost::mp11::mp_int;
template<class T, class U> using inc = mp_int<U::value + 1>;
int main()
{
using boost::mp_map_update;
using boost::mp_list;
using boost::mp11::mp_map_update;
using boost::mp11::mp_list;
using M1 = mp_list<>;

View File

@@ -19,10 +19,10 @@ struct X1 {};
int main()
{
using boost::mp_list;
using boost::mp_none_of;
using boost::mp_true;
using boost::mp_false;
using boost::mp11::mp_list;
using boost::mp11::mp_none_of;
using boost::mp11::mp_true;
using boost::mp11::mp_false;
{
using L1 = mp_list<>;

View File

@@ -1,5 +1,5 @@
// Copyright 2015, 2016 Peter Dimov.
// Copyright 2015-2017 Peter Dimov.
//
// Distributed under the Boost Software License, Version 1.0.
//
@@ -14,34 +14,34 @@
int main()
{
using boost::mp_or;
using boost::mp_true;
using boost::mp_false;
using boost::mp_int;
using boost::mp_size_t;
using boost::mp11::mp_or;
using boost::mp11::mp_true;
using boost::mp11::mp_false;
using boost::mp11::mp_int;
using boost::mp11::mp_size_t;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_true>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<-7>>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<-7>>, mp_int<-7>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>>, mp_int<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<7>>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<7>>, mp_size_t<7>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>>, mp_size_t<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_true, void>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_true>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_false>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<5>>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<-4>, void>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>>, mp_int<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<5>>, mp_int<5>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<-4>, void>, mp_int<-4>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<7>, void>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<4>>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<7>, void>, mp_size_t<7>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<4>>, mp_size_t<4>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>>, mp_size_t<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_true, void, void>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_true, void>, mp_true>));
@@ -54,19 +54,19 @@ int main()
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_false, mp_false, mp_true>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_false, mp_false, mp_false>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<1>, void, void, void>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<2>, void, void, void>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>, mp_int<3>, void, void, void>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>, mp_int<0>, mp_int<4>, void, void, void>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>, mp_int<0>, mp_int<0>, mp_int<0>>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<1>, void, void, void>, mp_int<1>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<2>, void, void, void>, mp_int<2>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>, mp_int<3>, void, void, void>, mp_int<3>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>, mp_int<0>, mp_int<4>, void, void, void>, mp_int<4>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>, mp_int<0>, mp_int<0>, mp_int<0>>, mp_int<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<1>, void, void, void>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<2>, void, void, void>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>, mp_size_t<3>, void, void, void>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>, mp_size_t<0>, mp_size_t<4>, void, void, void>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>, mp_size_t<0>, mp_size_t<0>, mp_size_t<0>>, mp_false>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<1>, void, void, void>, mp_size_t<1>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<2>, void, void, void>, mp_size_t<2>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>, mp_size_t<3>, void, void, void>, mp_size_t<3>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>, mp_size_t<0>, mp_size_t<4>, void, void, void>, mp_size_t<4>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>, mp_size_t<0>, mp_size_t<0>, mp_size_t<0>>, mp_size_t<0>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_int<0>, mp_false, mp_size_t<141>, void, void, void>, mp_true>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_int<0>, mp_false, mp_size_t<141>, void, void, void>, mp_size_t<141>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_int<0>, mp_false>, mp_false>));
return boost::report_errors();

View File

@@ -19,8 +19,8 @@ struct X3 {};
int main()
{
using boost::mp_list;
using boost::mp_partition;
using boost::mp11::mp_list;
using boost::mp11::mp_partition;
{
using L1 = mp_list<>;

View File

@@ -15,9 +15,9 @@
int main()
{
using boost::mp_list;
using boost::mp_pop_front;
using boost::mp_rest;
using boost::mp11::mp_list;
using boost::mp11::mp_pop_front;
using boost::mp11::mp_rest;
using L1 = mp_list<void>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pop_front<L1>, mp_list<>>));

View File

@@ -27,8 +27,8 @@ template<class T1, class T2, class T3> struct F {};
int main()
{
using boost::mp_list;
using boost::mp_product;
using boost::mp11::mp_list;
using boost::mp11::mp_product;
{
using L1 = std::tuple<X1, X2, X3>;

View File

@@ -15,8 +15,8 @@
int main()
{
using boost::mp_list;
using boost::mp_push_back;
using boost::mp11::mp_list;
using boost::mp11::mp_push_back;
using L1 = mp_list<>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_push_back<L1>, mp_list<>>));

View File

@@ -15,8 +15,8 @@
int main()
{
using boost::mp_list;
using boost::mp_push_front;
using boost::mp11::mp_list;
using boost::mp11::mp_push_front;
using L1 = mp_list<>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_push_front<L1>, mp_list<>>));

View File

@@ -1,5 +1,5 @@
// Copyright 2015 Peter Dimov.
// Copyright 2015, 2017 Peter Dimov.
//
// Distributed under the Boost Software License, Version 1.0.
//
@@ -11,18 +11,76 @@
#include <boost/core/lightweight_test_trait.hpp>
#include <type_traits>
struct X {};
using boost::mp11::mp_invoke;
template<class...> struct X {};
template<template<class...> class F, class... T> using Y = X<F<T>...>;
template<class Q, class... T> using Z = X<mp_invoke<Q, T>...>;
struct B {};
struct D1: B {};
struct D2: B {};
struct ND {};
template<class... T> using is_base_of_t = typename std::is_base_of<T...>::type;
int main()
{
using boost::mp_identity_t;
using boost::mp_quote;
using boost::mp_unquote;
using boost::mp11::mp_identity_t;
using boost::mp11::mp_quote;
using Q = mp_quote<mp_identity_t>;
{
using Q = mp_quote<mp_identity_t>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unquote<Q, void>, void>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unquote<Q, int[]>, int[]>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_invoke<Q, void>, void>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_invoke<Q, int[]>, int[]>));
}
{
using Q = mp_quote<std::is_same, void>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_invoke<Q, void>, std::is_same<void, void>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_invoke<Q, int[]>, std::is_same<void, int[]>>));
}
{
using Q = mp_quote<X, char[1], char[2], char[3]>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_invoke<Q, int[1], int[2], int[3]>, X<char[1], char[2], char[3], int[1], int[2], int[3]>>));
}
{
using Q = mp_quote<mp_identity_t>;
// using R1 = Y<Q::template invoke, void, char, int>;
// BOOST_TEST_TRAIT_TRUE((std::is_same<R1, X<void, char, int>>));
//
// error: pack expansion used as argument for non-pack parameter of alias template
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 && BOOST_MSVC >= 1900 )
#else
using R2 = Z<Q, void, char, int>;
BOOST_TEST_TRAIT_TRUE((std::is_same<R2, X<void, char, int>>));
#endif
}
{
using Q = mp_quote<is_base_of_t, B>;
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 )
#else
using R1 = Y<Q::template invoke, D1, D2, ND, int>;
BOOST_TEST_TRAIT_TRUE((std::is_same<R1, X<std::true_type, std::true_type, std::false_type, std::false_type>>));
#endif
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 && BOOST_MSVC >= 1900 )
#else
using R2 = Z<Q, D1, D2, ND, int>;
BOOST_TEST_TRAIT_TRUE((std::is_same<R2, X<std::true_type, std::true_type, std::false_type, std::false_type>>));
#endif
}
return boost::report_errors();
}

View File

@@ -19,8 +19,8 @@ struct X3 {};
int main()
{
using boost::mp_list;
using boost::mp_remove;
using boost::mp11::mp_list;
using boost::mp11::mp_remove;
{
using L1 = mp_list<>;

View File

@@ -19,8 +19,8 @@ struct X3 {};
int main()
{
using boost::mp_list;
using boost::mp_remove_if;
using boost::mp11::mp_list;
using boost::mp11::mp_remove_if;
{
using L1 = mp_list<>;

View File

@@ -18,8 +18,8 @@ template<class... T> using Y = X<T...>;
int main()
{
using boost::mp_list;
using boost::mp_rename;
using boost::mp11::mp_list;
using boost::mp11::mp_rename;
using L1 = mp_list<>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rename<L1, mp_list>, mp_list<>>));

View File

@@ -20,13 +20,13 @@ struct X2 {};
int main()
{
using boost::mp_list;
using boost::mp_repeat;
using boost::mp_repeat_c;
using boost::mp_true;
using boost::mp_false;
using boost::mp_int;
using boost::mp_size_t;
using boost::mp11::mp_list;
using boost::mp11::mp_repeat;
using boost::mp11::mp_repeat_c;
using boost::mp11::mp_true;
using boost::mp11::mp_false;
using boost::mp11::mp_int;
using boost::mp11::mp_size_t;
using L1 = mp_list<>;

View File

@@ -20,8 +20,8 @@ struct X3 {};
int main()
{
using boost::mp_list;
using boost::mp_replace;
using boost::mp11::mp_list;
using boost::mp11::mp_replace;
{
using L1 = mp_list<>;

View File

@@ -18,8 +18,8 @@ struct X1 {};
int main()
{
using boost::mp_list;
using boost::mp_replace_if;
using boost::mp11::mp_list;
using boost::mp11::mp_replace_if;
{
using L1 = mp_list<>;

View File

@@ -25,8 +25,8 @@ struct X9 {};
int main()
{
using boost::mp_list;
using boost::mp_reverse;
using boost::mp11::mp_list;
using boost::mp11::mp_reverse;
{
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_reverse<mp_list<>>, mp_list<>>));

View File

@@ -20,13 +20,16 @@ struct X4 {};
template<class T1, class T2> struct F {};
template<class T, class L> using rev_push_back = boost::mp_push_back<L, T>;
template<class T, class L> using rev_push_front = boost::mp_push_front<L, T>;
using boost::mp11::mp_push_back;
using boost::mp11::mp_push_front;
template<class T, class L> using rev_push_back = mp_push_back<L, T>;
template<class T, class L> using rev_push_front = mp_push_front<L, T>;
int main()
{
using boost::mp_list;
using boost::mp_reverse_fold;
using boost::mp11::mp_list;
using boost::mp11::mp_reverse_fold;
{
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_reverse_fold<mp_list<>, void, F>, void>));

View File

@@ -15,8 +15,8 @@
int main()
{
using boost::mp_list;
using boost::mp_second;
using boost::mp11::mp_list;
using boost::mp11::mp_second;
using L1 = mp_list<void, char[]>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_second<L1>, char[]>));

View File

@@ -16,10 +16,10 @@
int main()
{
using boost::mp_list;
using boost::mp_set_contains;
using boost::mp_true;
using boost::mp_false;
using boost::mp11::mp_list;
using boost::mp11::mp_set_contains;
using boost::mp11::mp_true;
using boost::mp11::mp_false;
{
using L1 = mp_list<>;

View File

@@ -15,8 +15,8 @@
int main()
{
using boost::mp_list;
using boost::mp_set_push_back;
using boost::mp11::mp_list;
using boost::mp11::mp_set_push_back;
{
using L1 = mp_list<>;

View File

@@ -15,8 +15,8 @@
int main()
{
using boost::mp_list;
using boost::mp_set_push_front;
using boost::mp11::mp_list;
using boost::mp11::mp_set_push_front;
{
using L1 = mp_list<>;

View File

@@ -16,9 +16,9 @@
int main()
{
using boost::mp_list;
using boost::mp_size;
using boost::mp_size_t;
using boost::mp11::mp_list;
using boost::mp11::mp_size;
using boost::mp11::mp_size_t;
using L1 = mp_list<>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_size<L1>, mp_size_t<0>>));

View File

@@ -14,14 +14,14 @@
#include <type_traits>
#include <tuple>
using boost::mp_bool;
using boost::mp11::mp_bool;
template<class T, class U> using sizeof_less = mp_bool<(sizeof(T) < sizeof(U))>;
int main()
{
using boost::mp_list;
using boost::mp_sort;
using boost::mp11::mp_list;
using boost::mp11::mp_sort;
{
using L1 = mp_list<>;

View File

@@ -23,10 +23,10 @@ struct X5 {};
int main()
{
using boost::mp_list;
using boost::mp_take;
using boost::mp_take_c;
using boost::mp_size_t;
using boost::mp11::mp_list;
using boost::mp11::mp_take;
using boost::mp11::mp_take_c;
using boost::mp11::mp_size_t;
{
using L1 = mp_list<>;

View File

@@ -15,8 +15,8 @@
int main()
{
using boost::mp_list;
using boost::mp_third;
using boost::mp11::mp_list;
using boost::mp11::mp_third;
using L1 = mp_list<int[], void, float[]>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_third<L1>, float[]>));

View File

@@ -34,8 +34,8 @@ template<class T, class U> using is_same = typename std::is_same<T, U>::type;
int main()
{
using boost::mp_list;
using boost::mp_transform;
using boost::mp11::mp_list;
using boost::mp11::mp_transform;
using L1 = mp_list<X1, X2, X3, X4>;

View File

@@ -20,13 +20,15 @@ struct X2 {};
struct X3 {};
struct X4 {};
using boost::mp11::mp_not;
template<class T> using add_pointer = T*;
template<class T> using is_not_ref = boost::mp_not<std::is_reference<T>>;
template<class T> using is_not_ref = mp_not<std::is_reference<T>>;
int main()
{
using boost::mp_list;
using boost::mp_transform_if;
using boost::mp11::mp_list;
using boost::mp11::mp_transform_if;
using L1 = mp_list<X1, X2&, X3 const, X4 const&>;

View File

@@ -15,8 +15,8 @@
int main()
{
using boost::mp_list;
using boost::mp_unique;
using boost::mp11::mp_list;
using boost::mp11::mp_unique;
{
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique<mp_list<>>, mp_list<>>));

View File

@@ -27,8 +27,8 @@ template<class T> using add_extents = T[];
int main()
{
using boost::mp_valid;
using boost::mp_identity;
using boost::mp11::mp_valid;
using boost::mp11::mp_identity;
BOOST_TEST_TRAIT_FALSE((mp_valid<mp_identity>));
BOOST_TEST_TRAIT_TRUE((mp_valid<mp_identity, void>));