forked from boostorg/mp11
Merge branch 'develop'
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
# mp11
|
# mp11, a simple C++11 metaprogramming library
|
||||||
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
13
doc/mp11.qbk
13
doc/mp11.qbk
@@ -23,19 +23,22 @@
|
|||||||
[template endsimplesect[]
|
[template endsimplesect[]
|
||||||
[block '''</simplesect>''']]
|
[block '''</simplesect>''']]
|
||||||
|
|
||||||
[section Overview]
|
[include mp11/overview.qbk]
|
||||||
|
[include mp11/definitions.qbk]
|
||||||
...
|
[include mp11/examples.qbk]
|
||||||
|
|
||||||
[endsect]
|
|
||||||
|
|
||||||
[section Reference]
|
[section Reference]
|
||||||
|
|
||||||
|
The contents of the library are in namespace `boost::mp11`, unless specified otherwise.
|
||||||
|
|
||||||
[include mp11/integral.qbk]
|
[include mp11/integral.qbk]
|
||||||
[include mp11/list.qbk]
|
[include mp11/list.qbk]
|
||||||
[include mp11/utility.qbk]
|
[include mp11/utility.qbk]
|
||||||
[include mp11/algorithm.qbk]
|
[include mp11/algorithm.qbk]
|
||||||
[include mp11/set.qbk]
|
[include mp11/set.qbk]
|
||||||
[include mp11/map.qbk]
|
[include mp11/map.qbk]
|
||||||
|
[include mp11/function.qbk]
|
||||||
|
[include mp11/integer_sequence.qbk]
|
||||||
|
[include mp11/tuple_for_each.qbk]
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
@@ -10,150 +10,219 @@
|
|||||||
|
|
||||||
[section `mp_assign<L1, L2>`]
|
[section `mp_assign<L1, L2>`]
|
||||||
template<class L1, class L2> using mp_assign = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_clear<L>`]
|
[section `mp_clear<L>`]
|
||||||
template<class L> using mp_clear = mp_assign<L, mp_list<>>;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_transform<F, L...>`]
|
[section `mp_transform<F, L...>`]
|
||||||
template<template<class...> class F, class... L> using mp_transform = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_transform_if<P, F, L>`]
|
[section `mp_transform_if<P, F, L>`]
|
||||||
template<template<class...> class P, template<class...> class F, class L> using mp_transform_if = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_fill<L, V>`]
|
[section `mp_fill<L, V>`]
|
||||||
template<class L, class V> using mp_fill = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_count<L, V>`]
|
[section `mp_count<L, V>`]
|
||||||
template<class L, class V> using mp_count = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_count_if<L, P>`]
|
[section `mp_count_if<L, P>`]
|
||||||
template<class L, template<class...> class P> using mp_count_if = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_contains<L, V>`]
|
[section `mp_contains<L, V>`]
|
||||||
template<class L, class V> using mp_contains = mp_to_bool<mp_count<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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_repeat_c<L, N>`]
|
[section `mp_repeat_c<L, N>`]
|
||||||
template<class L, std::size_t N> using mp_repeat_c = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_repeat<L, N>`]
|
[section `mp_repeat<L, N>`]
|
||||||
template<class L, class N> using mp_repeat = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_product<F, L...>`]
|
[section `mp_product<F, L...>`]
|
||||||
template<template<class...> class F, class... L> using mp_product = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_drop_c<L, N>`]
|
[section `mp_drop_c<L, N>`]
|
||||||
template<class L, std::size_t N> using mp_drop_c = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_drop<L, N>`]
|
[section `mp_drop<L, N>`]
|
||||||
template<class L, class N> using mp_drop = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_iota_c<L, N>`]
|
[section `mp_iota_c<N>`]
|
||||||
template<std::size_t N> using mp_iota_c = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_iota<L, N>`]
|
[section `mp_iota<N>`]
|
||||||
template<class N> using mp_iota = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_at_c<L, I>`]
|
[section `mp_at_c<L, I>`]
|
||||||
template<class L, std::size_t I> using mp_at_c = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_at<L, I>`]
|
[section `mp_at<L, I>`]
|
||||||
template<class L, class I> using mp_at = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_take_c<L, N>`]
|
[section `mp_take_c<L, N>`]
|
||||||
template<class L, std::size_t N> using mp_take_c = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_take<L, N>`]
|
[section `mp_take<L, N>`]
|
||||||
template<class L, class N> using mp_take = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_replace<L, V, W>`]
|
[section `mp_replace<L, V, W>`]
|
||||||
template<class L, class V, class W> using mp_replace = /*...*/;
|
template<class L, class V, class W> using mp_replace = /*...*/;
|
||||||
|
|
||||||
|
Replaces all `V` elements of `L` with `W` and returns the result.
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_replace_if<L, P, W>`]
|
[section `mp_replace_if<L, P, W>`]
|
||||||
template<class L, template<class...> class P, class W> using mp_replace_if = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_copy_if<L, P>`]
|
[section `mp_copy_if<L, P>`]
|
||||||
template<class L, template<class...> class P> using mp_copy_if = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_remove<L, V>`]
|
[section `mp_remove<L, V>`]
|
||||||
template<class L, class V> using mp_remove = /*...*/;
|
template<class L, class V> using mp_remove = /*...*/;
|
||||||
|
|
||||||
|
Removes all `V` elements of `L` and returns the result.
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_remove_if<L, P>`]
|
[section `mp_remove_if<L, P>`]
|
||||||
template<class L, template<class...> class P> using mp_remove_if = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_partition<L, P>`]
|
[section `mp_partition<L, P>`]
|
||||||
template<class L, template<class...> class P> using mp_partition = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_sort<L, P>`]
|
[section `mp_sort<L, P>`]
|
||||||
template<class L, template<class...> class P> using mp_sort = /*...*/;
|
template<class L, template<class...> class P> using mp_sort = /*...*/;
|
||||||
[endsect]
|
|
||||||
|
|
||||||
[section `mp_find_index<L, V>`]
|
`mp_sort<L, P>` sorts the list `L` according to the strict weak ordering `mp_to_bool<P<T, U>>`.
|
||||||
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 = /*...*/;
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_find<L, V>`]
|
[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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_find_if<L, P>`]
|
[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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_reverse<L>`]
|
[section `mp_reverse<L>`]
|
||||||
template<class L> using mp_reverse = /*...*/;
|
template<class L> using mp_reverse = /*...*/;
|
||||||
|
|
||||||
|
`mp_reverse<L<T1, T2, ..., Tn>>` is `L<Tn, ..., T2, T1>`.
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_fold<L, V, F>`]
|
[section `mp_fold<L, V, F>`]
|
||||||
template<class L, class V, template<class...> class F> using mp_fold = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_reverse_fold<L, V, F>`]
|
[section `mp_reverse_fold<L, V, F>`]
|
||||||
template<class L, class V, template<class...> class F> using mp_reverse_fold = /*...*/;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_unique<L>`]
|
[section `mp_unique<L>`]
|
||||||
template<class L> using mp_unique = /*...*/;
|
template<class L> using mp_unique = /*...*/;
|
||||||
|
|
||||||
|
`mp_unique<L>` returns a list of the same type as `L` with the duplicate elements removed.
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_all_of<L, P>`]
|
[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 >;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_none_of<L, P>`]
|
[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 >;
|
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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_any_of<L, P>`]
|
[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 >;
|
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]
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
32
doc/mp11/definitions.qbk
Normal file
32
doc/mp11/definitions.qbk
Normal 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 '''—''' possibly 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 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
175
doc/mp11/examples.qbk
Normal 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
40
doc/mp11/function.qbk
Normal 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]
|
45
doc/mp11/integer_sequence.qbk
Normal file
45
doc/mp11/integer_sequence.qbk
Normal 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]
|
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
[section:integral Integral Constants, `<boost/mp11/integral.hpp>`]
|
[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>`]
|
[section `mp_bool<B>`]
|
||||||
template<bool B> using mp_bool = std::integral_constant<bool, B>;
|
template<bool B> using mp_bool = std::integral_constant<bool, B>;
|
||||||
[endsect]
|
[endsect]
|
||||||
|
33
doc/mp11/overview.qbk
Normal file
33
doc/mp11/overview.qbk
Normal 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]
|
22
doc/mp11/tuple_for_each.qbk
Normal file
22
doc/mp11/tuple_for_each.qbk
Normal 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]
|
@@ -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.
|
`mp_defer<F, T...>` is an empty struct.
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_quote<F>`]
|
[section `mp_quote<F, T...>`]
|
||||||
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_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]
|
[endsect]
|
||||||
|
|
||||||
[section `mp_unquote<Q, T...>`]
|
[section `mp_invoke<Q, T...>`]
|
||||||
template<class Q, class... T> using mp_unquote = typename Q::template apply<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]
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
@@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
// mp_assign<L1, L2>
|
// mp_assign<L1, L2>
|
||||||
namespace detail
|
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;
|
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
|
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 )
|
#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>;
|
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 );
|
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... };
|
static constexpr bool _v[] = { std::is_same<T, V>::value... };
|
||||||
using type = mp_size_t< cx_find_index( _v, _v + sizeof...(T) ) >;
|
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 )
|
#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" );
|
static_assert( sizeof...(T) == 0, "T... must be empty" );
|
||||||
using type = mp_size_t<0>;
|
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
|
#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>;
|
using type = mp_size_t<0>;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#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>;
|
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>;
|
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
|
} // 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
|
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 )
|
#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>;
|
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... };
|
static constexpr bool _v[] = { P<T>::value... };
|
||||||
using type = mp_size_t< cx_find_index( _v, _v + sizeof...(T) ) >;
|
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 )
|
#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" );
|
static_assert( sizeof...(T) == 0, "T... must be empty" );
|
||||||
using type = mp_size_t<0>;
|
using type = mp_size_t<0>;
|
||||||
@@ -581,35 +583,29 @@ template<template<class...> class L, class... T, template<class...> class P> str
|
|||||||
|
|
||||||
#else
|
#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>;
|
using type = mp_size_t<0>;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#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>;
|
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
|
#endif
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template<class L, template<class...> class P> using mp_find_index_if = typename detail::mp_find_index_if_impl<L, P>::type;
|
template<class L, template<class...> class P> using mp_find_if = typename detail::mp_find_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>>;
|
|
||||||
|
|
||||||
// mp_reverse<L>
|
// mp_reverse<L>
|
||||||
namespace detail
|
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>
|
// mp_any_of<L, P>
|
||||||
template<class L, template<class...> class P> using mp_any_of = mp_bool< mp_count_if<L, P>::value != 0 >;
|
template<class L, template<class...> class P> using mp_any_of = mp_bool< mp_count_if<L, P>::value != 0 >;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #ifndef BOOST_MP11_ALGORITHM_HPP_INCLUDED
|
#endif // #ifndef BOOST_MP11_ALGORITHM_HPP_INCLUDED
|
||||||
|
@@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
// mp_count<L, V>
|
// mp_count<L, V>
|
||||||
namespace detail
|
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;
|
template<class L, template<class...> class P> using mp_count_if = typename detail::mp_count_if_impl<L, P>::type;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED
|
#endif // #ifndef BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED
|
||||||
|
@@ -10,12 +10,15 @@
|
|||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
// mp_list<T...>
|
// mp_list<T...>
|
||||||
template<class... T> struct mp_list
|
template<class... T> struct mp_list
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED
|
#endif // #ifndef BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED
|
||||||
|
@@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
// mp_map_find
|
// mp_map_find
|
||||||
namespace detail
|
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;
|
template<class M, class K> using mp_map_find = typename detail::mp_map_find_impl<M, K>::type;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED
|
#endif // #ifndef BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED
|
||||||
|
@@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
// mp_plus
|
// mp_plus
|
||||||
namespace detail
|
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;
|
template<class... T> using mp_plus = typename detail::mp_plus_impl<T...>::type;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED
|
#endif // #ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
#ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED
|
#ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED
|
||||||
#define 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.
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
//
|
//
|
||||||
@@ -15,9 +15,8 @@
|
|||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
namespace mp11
|
||||||
// mp_equal_to<T1, T2>
|
{
|
||||||
template<class T1, class T2> using mp_equal_to = mp_bool< T1::value == T2::value >;
|
|
||||||
|
|
||||||
// mp_all<T...>
|
// mp_all<T...>
|
||||||
template<class... T> using mp_all = mp_bool< mp_count_if< mp_list<T...>, mp_to_bool >::value == sizeof...(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;
|
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...>
|
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
|
} // namespace detail
|
||||||
@@ -68,13 +72,19 @@ template<> struct mp_or_impl<>
|
|||||||
using type = mp_false;
|
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...>
|
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 detail
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED
|
#endif // #ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED
|
||||||
|
@@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
// mp_bool
|
// mp_bool
|
||||||
template<bool B> using mp_bool = std::integral_constant<bool, B>;
|
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
|
// mp_size_t
|
||||||
template<std::size_t N> using mp_size_t = std::integral_constant<std::size_t, N>;
|
template<std::size_t N> using mp_size_t = std::integral_constant<std::size_t, N>;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #ifndef BOOST_MP11_INTEGRAL_HPP_INCLUDED
|
#endif // #ifndef BOOST_MP11_INTEGRAL_HPP_INCLUDED
|
||||||
|
@@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
// mp_size<L>
|
// mp_size<L>
|
||||||
namespace detail
|
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;
|
template<class... L> using mp_append = typename detail::mp_append_impl<L...>::type;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #ifndef BOOST_MP11_LIST_HPP_INCLUDED
|
#endif // #ifndef BOOST_MP11_LIST_HPP_INCLUDED
|
||||||
|
@@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
// mp_map_contains<M, K>
|
// 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>>;
|
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;
|
template<class M, class K> using mp_map_erase = typename detail::mp_map_erase_impl<M, K>::type;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #ifndef BOOST_MP11_MAP_HPP_INCLUDED
|
#endif // #ifndef BOOST_MP11_MAP_HPP_INCLUDED
|
||||||
|
@@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
// mp_set_contains<S, V>
|
// mp_set_contains<S, V>
|
||||||
namespace detail
|
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;
|
template<class S, class... T> using mp_set_push_front = typename detail::mp_set_push_front_impl<S, T...>::type;
|
||||||
|
|
||||||
|
} // namespace mp11
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #ifndef BOOST_MP11_SET_HPP_INCLUDED
|
#endif // #ifndef BOOST_MP11_SET_HPP_INCLUDED
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
#ifndef BOOST_MP11_UTILITY_HPP_INCLUDED
|
#ifndef BOOST_MP11_UTILITY_HPP_INCLUDED
|
||||||
#define 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.
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
//
|
//
|
||||||
@@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
namespace mp11
|
||||||
|
{
|
||||||
|
|
||||||
// mp_identity
|
// mp_identity
|
||||||
template<class T> struct 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>;
|
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
|
// 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
|
// mp_unquote
|
||||||
namespace detail
|
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
|
} // 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
|
} // namespace boost
|
||||||
|
|
||||||
#endif // #ifndef BOOST_MP11_UTILITY_HPP_INCLUDED
|
#endif // #ifndef BOOST_MP11_UTILITY_HPP_INCLUDED
|
||||||
|
@@ -48,8 +48,6 @@ run mp_remove.cpp : : : $(REQ) ;
|
|||||||
run mp_remove_if.cpp : : : $(REQ) ;
|
run mp_remove_if.cpp : : : $(REQ) ;
|
||||||
run mp_partition.cpp : : : $(REQ) ;
|
run mp_partition.cpp : : : $(REQ) ;
|
||||||
run mp_sort.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.cpp : : : $(REQ) ;
|
||||||
run mp_find_if.cpp : : : $(REQ) ;
|
run mp_find_if.cpp : : : $(REQ) ;
|
||||||
run mp_reverse.cpp : : : $(REQ) ;
|
run mp_reverse.cpp : : : $(REQ) ;
|
||||||
@@ -71,6 +69,7 @@ run mp_eval_if.cpp : : : $(REQ) ;
|
|||||||
run mp_valid.cpp : : : $(REQ) ;
|
run mp_valid.cpp : : : $(REQ) ;
|
||||||
run mp_defer.cpp : : : $(REQ) ;
|
run mp_defer.cpp : : : $(REQ) ;
|
||||||
run mp_quote.cpp : : : $(REQ) ;
|
run mp_quote.cpp : : : $(REQ) ;
|
||||||
|
run mp_invoke.cpp : : : $(REQ) ;
|
||||||
|
|
||||||
# integer_sequence
|
# integer_sequence
|
||||||
run integer_sequence.cpp : : : $(REQ) ;
|
run integer_sequence.cpp : : : $(REQ) ;
|
||||||
|
@@ -14,29 +14,29 @@
|
|||||||
|
|
||||||
int main()
|
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<false>, std::integral_constant<bool, false>>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_bool<true>, std::integral_constant<bool, true>>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_bool<true>, std::integral_constant<bool, true>>));
|
||||||
|
|
||||||
using boost::mp_true;
|
using boost::mp11::mp_true;
|
||||||
using boost::mp_false;
|
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_false, std::integral_constant<bool, false>>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_true, std::integral_constant<bool, true>>));
|
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<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<814>, std::integral_constant<int, 814>>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_int<-144>, std::integral_constant<int, -144>>));
|
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<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>>));
|
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_false>, mp_false>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_to_bool<mp_true>, mp_true>));
|
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<1>>, mp_true>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_to_bool<mp_size_t<442>>, 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_false>, mp_true>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_not<mp_true>, mp_false>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_not<mp_true>, mp_false>));
|
||||||
|
@@ -14,11 +14,11 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_all;
|
using boost::mp11::mp_all;
|
||||||
using boost::mp_true;
|
using boost::mp11::mp_true;
|
||||||
using boost::mp_false;
|
using boost::mp11::mp_false;
|
||||||
using boost::mp_int;
|
using boost::mp11::mp_int;
|
||||||
using boost::mp_size_t;
|
using boost::mp11::mp_size_t;
|
||||||
|
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_all<>, mp_true>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_all<>, mp_true>));
|
||||||
|
|
||||||
|
@@ -19,10 +19,10 @@ struct X1 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_all_of;
|
using boost::mp11::mp_all_of;
|
||||||
using boost::mp_true;
|
using boost::mp11::mp_true;
|
||||||
using boost::mp_false;
|
using boost::mp11::mp_false;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
// Copyright 2015, 2016 Peter Dimov.
|
// Copyright 2015-2017 Peter Dimov.
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
//
|
//
|
||||||
@@ -14,34 +14,34 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_and;
|
using boost::mp11::mp_and;
|
||||||
using boost::mp_true;
|
using boost::mp11::mp_true;
|
||||||
using boost::mp_false;
|
using boost::mp11::mp_false;
|
||||||
using boost::mp_int;
|
using boost::mp11::mp_int;
|
||||||
using boost::mp_size_t;
|
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>));
|
||||||
|
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true>, mp_true>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true>, mp_true>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_false>, mp_false>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_false>, mp_false>));
|
||||||
|
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<-7>>, mp_true>));
|
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_false>));
|
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<7>>, mp_size_t<7>>));
|
||||||
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<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_true>, mp_true>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true, mp_false>, mp_false>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true, mp_false>, mp_false>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_false, void>, mp_false>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_false, void>, mp_false>));
|
||||||
|
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<-4>, mp_int<5>>, mp_true>));
|
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_false>));
|
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_false>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<0>, void>, mp_int<0>>));
|
||||||
|
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_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<8>>, mp_size_t<8>>));
|
||||||
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<7>, mp_size_t<0>>, mp_size_t<0>>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_size_t<0>, void>, mp_false>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_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_true>, mp_true>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true, mp_true, mp_false>, mp_false>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true, mp_true, mp_false>, mp_false>));
|
||||||
@@ -54,11 +54,11 @@ int main()
|
|||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true, mp_false, void, void>, mp_false>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_true, mp_false, void, void>, mp_false>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_false, void, void, void>, mp_false>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_false, void, void, void>, mp_false>));
|
||||||
|
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_and<mp_int<1>, mp_int<2>, mp_int<-11>, mp_int<14>>, mp_true>));
|
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_false>));
|
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<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_false>));
|
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();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
@@ -14,11 +14,11 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_any;
|
using boost::mp11::mp_any;
|
||||||
using boost::mp_true;
|
using boost::mp11::mp_true;
|
||||||
using boost::mp_false;
|
using boost::mp11::mp_false;
|
||||||
using boost::mp_int;
|
using boost::mp11::mp_int;
|
||||||
using boost::mp_size_t;
|
using boost::mp11::mp_size_t;
|
||||||
|
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_any<>, mp_false>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_any<>, mp_false>));
|
||||||
|
|
||||||
|
@@ -19,10 +19,10 @@ struct X1 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_any_of;
|
using boost::mp11::mp_any_of;
|
||||||
using boost::mp_true;
|
using boost::mp11::mp_true;
|
||||||
using boost::mp_false;
|
using boost::mp11::mp_false;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
@@ -22,8 +22,8 @@ struct X6 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_append;
|
using boost::mp11::mp_append;
|
||||||
|
|
||||||
using L1 = mp_list<char[1], char[1]>;
|
using L1 = mp_list<char[1], char[1]>;
|
||||||
using L2 = mp_list<char[2], char[2]>;
|
using L2 = mp_list<char[2], char[2]>;
|
||||||
|
@@ -20,8 +20,8 @@ struct X3 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_assign;
|
using boost::mp11::mp_assign;
|
||||||
|
|
||||||
using L1 = mp_list<int, void(), float[]>;
|
using L1 = mp_list<int, void(), float[]>;
|
||||||
|
|
||||||
|
@@ -23,10 +23,10 @@ struct X5 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_at;
|
using boost::mp11::mp_at;
|
||||||
using boost::mp_at_c;
|
using boost::mp11::mp_at_c;
|
||||||
using boost::mp_size_t;
|
using boost::mp11::mp_size_t;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<X1, X2, X3, X4, X5>;
|
using L1 = mp_list<X1, X2, X3, X4, X5>;
|
||||||
|
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_clear;
|
using boost::mp11::mp_clear;
|
||||||
|
|
||||||
using L1 = mp_list<int, void(), float[]>;
|
using L1 = mp_list<int, void(), float[]>;
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_clear<L1>, mp_list<>>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_clear<L1>, mp_list<>>));
|
||||||
|
@@ -21,10 +21,10 @@ struct X3 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_contains;
|
using boost::mp11::mp_contains;
|
||||||
using boost::mp_true;
|
using boost::mp11::mp_true;
|
||||||
using boost::mp_false;
|
using boost::mp11::mp_false;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
@@ -19,8 +19,8 @@ struct X3 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_copy_if;
|
using boost::mp11::mp_copy_if;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
@@ -21,9 +21,9 @@ struct X3 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_count;
|
using boost::mp11::mp_count;
|
||||||
using boost::mp_size_t;
|
using boost::mp11::mp_size_t;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
@@ -19,9 +19,9 @@ struct X1 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_count_if;
|
using boost::mp11::mp_count_if;
|
||||||
using boost::mp_size_t;
|
using boost::mp11::mp_size_t;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
@@ -12,17 +12,21 @@
|
|||||||
#include <boost/core/lightweight_test_trait.hpp>
|
#include <boost/core/lightweight_test_trait.hpp>
|
||||||
#include <type_traits>
|
#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 T> struct has_type
|
||||||
{
|
{
|
||||||
template<class U> static boost::mp_true f( boost::mp_identity<typename U::type>* );
|
template<class U> static mp_true f( mp_identity<typename U::type>* );
|
||||||
template<class U> static boost::mp_false f( ... );
|
template<class U> static mp_false f( ... );
|
||||||
|
|
||||||
using type = decltype( f<T>(0) );
|
using type = decltype( f<T>(0) );
|
||||||
|
|
||||||
static const auto value = type::value;
|
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 = T*;
|
||||||
template<class... T> using add_pointer_impl = mp_defer<add_pointer, T...>;
|
template<class... T> using add_pointer_impl = mp_defer<add_pointer, T...>;
|
||||||
|
@@ -23,10 +23,10 @@ struct X5 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_drop;
|
using boost::mp11::mp_drop;
|
||||||
using boost::mp_drop_c;
|
using boost::mp11::mp_drop_c;
|
||||||
using boost::mp_size_t;
|
using boost::mp11::mp_size_t;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
@@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_empty;
|
using boost::mp11::mp_empty;
|
||||||
using boost::mp_true;
|
using boost::mp11::mp_true;
|
||||||
using boost::mp_false;
|
using boost::mp11::mp_false;
|
||||||
|
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_empty<L1>, mp_true>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_empty<L1>, mp_true>));
|
||||||
|
@@ -14,23 +14,23 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_eval_if_c;
|
using boost::mp11::mp_eval_if_c;
|
||||||
using boost::mp_identity;
|
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<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()>>));
|
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::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()>>));
|
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<-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()>>));
|
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<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()>>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_eval_if<mp_size_t<0>, char[], mp_identity, void()>, mp_identity<void()>>));
|
||||||
|
@@ -18,8 +18,8 @@ struct X1 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_fill;
|
using boost::mp11::mp_fill;
|
||||||
|
|
||||||
using L1 = mp_list<int, void(), float[]>;
|
using L1 = mp_list<int, void(), float[]>;
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_fill<L1, X1>, mp_list<X1, X1, X1>>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_fill<L1, X1>, mp_list<X1, X1, X1>>));
|
||||||
|
@@ -21,33 +21,42 @@ struct X3 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_find;
|
using boost::mp11::mp_find;
|
||||||
|
using boost::mp11::mp_size_t;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
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>;
|
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, void>, mp_size_t<6>>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L2, X1>, L2>));
|
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_list<X2, X2, X3, X3, X3>>));
|
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_list<X3, X3, X3>>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L2, X3>, mp_size_t<3>>));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
using L3 = std::tuple<>;
|
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>;
|
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, void>, mp_size_t<6>>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_find<L4, X1>, L4>));
|
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>, std::tuple<X2, X2, X3, X3, X3>>));
|
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>, std::tuple<X3, X3, X3>>));
|
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();
|
return boost::report_errors();
|
||||||
|
@@ -19,31 +19,40 @@ struct X1 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_find_if;
|
using boost::mp11::mp_find_if;
|
||||||
|
using boost::mp11::mp_size_t;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
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*>;
|
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_volatile>, mp_size_t<6>>));
|
||||||
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_const>, mp_size_t<1>>));
|
||||||
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_pointer>, mp_size_t<3>>));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = std::tuple<>;
|
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*>;
|
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_volatile>, mp_size_t<6>>));
|
||||||
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_const>, mp_size_t<1>>));
|
||||||
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_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();
|
return boost::report_errors();
|
||||||
|
@@ -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();
|
|
||||||
}
|
|
@@ -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();
|
|
||||||
}
|
|
@@ -22,8 +22,8 @@ template<class T1, class T2> struct F {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_fold;
|
using boost::mp11::mp_fold;
|
||||||
|
|
||||||
{
|
{
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_fold<mp_list<>, void, F>, void>));
|
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>>));
|
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>>));
|
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>>));
|
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>>));
|
||||||
|
@@ -15,9 +15,9 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_front;
|
using boost::mp11::mp_front;
|
||||||
using boost::mp_first;
|
using boost::mp11::mp_first;
|
||||||
|
|
||||||
using L1 = mp_list<void>;
|
using L1 = mp_list<void>;
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_front<L1>, void>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_front<L1>, void>));
|
||||||
|
@@ -15,14 +15,14 @@ struct X {};
|
|||||||
|
|
||||||
int main()
|
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 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<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<int const[]>::type, int const[]>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_identity<X>::type, X>));
|
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 const volatile>, void const volatile>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_identity_t<void()>, void()>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_identity_t<void()>, void()>));
|
||||||
|
@@ -14,22 +14,22 @@
|
|||||||
|
|
||||||
int main()
|
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<true, char[], void()>, char[]>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_if_c<false, char[], void()>, void()>));
|
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::true_type, char[], void()>, char[]>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_if<std::false_type, char[], void()>, void()>));
|
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<-7>, char[], void()>, char[]>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_if<mp_int<0>, char[], void()>, void()>));
|
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<14>, char[], void()>, char[]>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_if<mp_size_t<0>, char[], void()>, void()>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_if<mp_size_t<0>, char[], void()>, void()>));
|
||||||
|
@@ -17,7 +17,7 @@ struct X3 {};
|
|||||||
|
|
||||||
int main()
|
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<X1, mp_inherit<X1, X2, X3>>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_base_of<X2, 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
56
test/mp_invoke.cpp
Normal 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();
|
||||||
|
}
|
@@ -14,11 +14,11 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_iota;
|
using boost::mp11::mp_iota;
|
||||||
using boost::mp_iota_c;
|
using boost::mp11::mp_iota_c;
|
||||||
using boost::mp_int;
|
using boost::mp11::mp_int;
|
||||||
using boost::mp_size_t;
|
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<0>, mp_list<>>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota_c<1>, mp_list<mp_size_t<0>>>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_iota_c<1>, mp_list<mp_size_t<0>>>));
|
||||||
|
@@ -17,10 +17,10 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_map_contains;
|
using boost::mp11::mp_map_contains;
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_true;
|
using boost::mp11::mp_true;
|
||||||
using boost::mp_false;
|
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<mp_list<>, char>, mp_false>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_map_contains<std::tuple<>, int>, mp_false>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_map_contains<std::tuple<>, int>, mp_false>));
|
||||||
|
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_map_erase;
|
using boost::mp11::mp_map_erase;
|
||||||
using boost::mp_list;
|
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<mp_list<>, void>, mp_list<>>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_map_erase<std::tuple<>, int>, std::tuple<>>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_map_erase<std::tuple<>, int>, std::tuple<>>));
|
||||||
|
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_map_find;
|
using boost::mp11::mp_map_find;
|
||||||
using boost::mp_list;
|
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<mp_list<>, char>, void>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_map_find<std::tuple<>, int>, void>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_map_find<std::tuple<>, int>, void>));
|
||||||
|
@@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_map_insert;
|
using boost::mp11::mp_map_insert;
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_push_back;
|
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<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>>>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_map_insert<std::tuple<>, std::tuple<int>>, std::tuple<std::tuple<int>>>));
|
||||||
|
@@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_map_replace;
|
using boost::mp11::mp_map_replace;
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_push_back;
|
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<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>>>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_map_replace<std::tuple<>, std::tuple<int>>, std::tuple<std::tuple<int>>>));
|
||||||
|
@@ -15,14 +15,14 @@
|
|||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
using boost::mp_int;
|
using boost::mp11::mp_int;
|
||||||
|
|
||||||
template<class T, class U> using inc = mp_int<U::value + 1>;
|
template<class T, class U> using inc = mp_int<U::value + 1>;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_map_update;
|
using boost::mp11::mp_map_update;
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
|
|
||||||
using M1 = mp_list<>;
|
using M1 = mp_list<>;
|
||||||
|
|
||||||
|
@@ -19,10 +19,10 @@ struct X1 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_none_of;
|
using boost::mp11::mp_none_of;
|
||||||
using boost::mp_true;
|
using boost::mp11::mp_true;
|
||||||
using boost::mp_false;
|
using boost::mp11::mp_false;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
// Copyright 2015, 2016 Peter Dimov.
|
// Copyright 2015-2017 Peter Dimov.
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
//
|
//
|
||||||
@@ -14,34 +14,34 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_or;
|
using boost::mp11::mp_or;
|
||||||
using boost::mp_true;
|
using boost::mp11::mp_true;
|
||||||
using boost::mp_false;
|
using boost::mp11::mp_false;
|
||||||
using boost::mp_int;
|
using boost::mp11::mp_int;
|
||||||
using boost::mp_size_t;
|
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_false>));
|
||||||
|
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_true>, mp_true>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_true>, mp_true>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false>, mp_false>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false>, mp_false>));
|
||||||
|
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<-7>>, mp_true>));
|
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_false>));
|
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<7>>, mp_size_t<7>>));
|
||||||
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<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_true, void>, mp_true>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_true>, mp_true>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_true>, mp_true>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_false>, mp_false>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_false>, mp_false>));
|
||||||
|
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>>, mp_false>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>>, mp_int<0>>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<5>>, mp_true>));
|
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_true>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<-4>, void>, mp_int<-4>>));
|
||||||
|
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<7>, void>, mp_true>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<7>, void>, mp_size_t<7>>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<4>>, mp_true>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<4>>, mp_size_t<4>>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>>, mp_false>));
|
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_true, void, void>, mp_true>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_true, void>, mp_true>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_true, void>, mp_true>));
|
||||||
@@ -54,19 +54,19 @@ int main()
|
|||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_false, mp_false, mp_true>, mp_true>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_false, mp_false, mp_true>, mp_true>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_false, mp_false, mp_false>, mp_false>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_false, mp_false, mp_false, mp_false>, mp_false>));
|
||||||
|
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<1>, void, void, void>, mp_true>));
|
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_true>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<2>, void, void, void>, mp_int<2>>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<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<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_true>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>, mp_int<0>, mp_int<4>, void, void, void>, mp_int<4>>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_int<0>, mp_int<0>, mp_int<0>, mp_int<0>, mp_int<0>>, mp_false>));
|
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<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_true>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<2>, void, void, void>, mp_size_t<2>>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<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<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_true>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>, mp_size_t<0>, mp_size_t<4>, void, void, void>, mp_size_t<4>>));
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_size_t<0>, mp_size_t<0>, mp_size_t<0>, mp_size_t<0>>, mp_false>));
|
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>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_or<mp_size_t<0>, mp_int<0>, mp_false>, mp_false>));
|
||||||
|
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
|
@@ -19,8 +19,8 @@ struct X3 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_partition;
|
using boost::mp11::mp_partition;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
@@ -15,9 +15,9 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_pop_front;
|
using boost::mp11::mp_pop_front;
|
||||||
using boost::mp_rest;
|
using boost::mp11::mp_rest;
|
||||||
|
|
||||||
using L1 = mp_list<void>;
|
using L1 = mp_list<void>;
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pop_front<L1>, mp_list<>>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_pop_front<L1>, mp_list<>>));
|
||||||
|
@@ -27,8 +27,8 @@ template<class T1, class T2, class T3> struct F {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_product;
|
using boost::mp11::mp_product;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = std::tuple<X1, X2, X3>;
|
using L1 = std::tuple<X1, X2, X3>;
|
||||||
|
@@ -15,8 +15,8 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_push_back;
|
using boost::mp11::mp_push_back;
|
||||||
|
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_push_back<L1>, mp_list<>>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_push_back<L1>, mp_list<>>));
|
||||||
|
@@ -15,8 +15,8 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_push_front;
|
using boost::mp11::mp_push_front;
|
||||||
|
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_push_front<L1>, mp_list<>>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_push_front<L1>, mp_list<>>));
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
// Copyright 2015 Peter Dimov.
|
// Copyright 2015, 2017 Peter Dimov.
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
//
|
//
|
||||||
@@ -11,18 +11,76 @@
|
|||||||
#include <boost/core/lightweight_test_trait.hpp>
|
#include <boost/core/lightweight_test_trait.hpp>
|
||||||
#include <type_traits>
|
#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()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_identity_t;
|
using boost::mp11::mp_identity_t;
|
||||||
using boost::mp_quote;
|
using boost::mp11::mp_quote;
|
||||||
using boost::mp_unquote;
|
|
||||||
|
|
||||||
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_invoke<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, 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();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
@@ -19,8 +19,8 @@ struct X3 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_remove;
|
using boost::mp11::mp_remove;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
@@ -19,8 +19,8 @@ struct X3 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_remove_if;
|
using boost::mp11::mp_remove_if;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
@@ -18,8 +18,8 @@ template<class... T> using Y = X<T...>;
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_rename;
|
using boost::mp11::mp_rename;
|
||||||
|
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rename<L1, mp_list>, mp_list<>>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_rename<L1, mp_list>, mp_list<>>));
|
||||||
|
@@ -20,13 +20,13 @@ struct X2 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_repeat;
|
using boost::mp11::mp_repeat;
|
||||||
using boost::mp_repeat_c;
|
using boost::mp11::mp_repeat_c;
|
||||||
using boost::mp_true;
|
using boost::mp11::mp_true;
|
||||||
using boost::mp_false;
|
using boost::mp11::mp_false;
|
||||||
using boost::mp_int;
|
using boost::mp11::mp_int;
|
||||||
using boost::mp_size_t;
|
using boost::mp11::mp_size_t;
|
||||||
|
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
|
||||||
|
@@ -20,8 +20,8 @@ struct X3 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_replace;
|
using boost::mp11::mp_replace;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
@@ -18,8 +18,8 @@ struct X1 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_replace_if;
|
using boost::mp11::mp_replace_if;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
@@ -25,8 +25,8 @@ struct X9 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_reverse;
|
using boost::mp11::mp_reverse;
|
||||||
|
|
||||||
{
|
{
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_reverse<mp_list<>>, mp_list<>>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_reverse<mp_list<>>, mp_list<>>));
|
||||||
|
@@ -20,13 +20,16 @@ struct X4 {};
|
|||||||
|
|
||||||
template<class T1, class T2> struct F {};
|
template<class T1, class T2> struct F {};
|
||||||
|
|
||||||
template<class T, class L> using rev_push_back = boost::mp_push_back<L, T>;
|
using boost::mp11::mp_push_back;
|
||||||
template<class T, class L> using rev_push_front = boost::mp_push_front<L, T>;
|
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()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_reverse_fold;
|
using boost::mp11::mp_reverse_fold;
|
||||||
|
|
||||||
{
|
{
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_reverse_fold<mp_list<>, void, F>, void>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_reverse_fold<mp_list<>, void, F>, void>));
|
||||||
|
@@ -15,8 +15,8 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_second;
|
using boost::mp11::mp_second;
|
||||||
|
|
||||||
using L1 = mp_list<void, char[]>;
|
using L1 = mp_list<void, char[]>;
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_second<L1>, char[]>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_second<L1>, char[]>));
|
||||||
|
@@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_set_contains;
|
using boost::mp11::mp_set_contains;
|
||||||
using boost::mp_true;
|
using boost::mp11::mp_true;
|
||||||
using boost::mp_false;
|
using boost::mp11::mp_false;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
@@ -15,8 +15,8 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_set_push_back;
|
using boost::mp11::mp_set_push_back;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
@@ -15,8 +15,8 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_set_push_front;
|
using boost::mp11::mp_set_push_front;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
@@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_size;
|
using boost::mp11::mp_size;
|
||||||
using boost::mp_size_t;
|
using boost::mp11::mp_size_t;
|
||||||
|
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_size<L1>, mp_size_t<0>>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_size<L1>, mp_size_t<0>>));
|
||||||
|
@@ -14,14 +14,14 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <tuple>
|
#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))>;
|
template<class T, class U> using sizeof_less = mp_bool<(sizeof(T) < sizeof(U))>;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_sort;
|
using boost::mp11::mp_sort;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
@@ -23,10 +23,10 @@ struct X5 {};
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_take;
|
using boost::mp11::mp_take;
|
||||||
using boost::mp_take_c;
|
using boost::mp11::mp_take_c;
|
||||||
using boost::mp_size_t;
|
using boost::mp11::mp_size_t;
|
||||||
|
|
||||||
{
|
{
|
||||||
using L1 = mp_list<>;
|
using L1 = mp_list<>;
|
||||||
|
@@ -15,8 +15,8 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_third;
|
using boost::mp11::mp_third;
|
||||||
|
|
||||||
using L1 = mp_list<int[], void, float[]>;
|
using L1 = mp_list<int[], void, float[]>;
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_third<L1>, float[]>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_third<L1>, float[]>));
|
||||||
|
@@ -34,8 +34,8 @@ template<class T, class U> using is_same = typename std::is_same<T, U>::type;
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_transform;
|
using boost::mp11::mp_transform;
|
||||||
|
|
||||||
using L1 = mp_list<X1, X2, X3, X4>;
|
using L1 = mp_list<X1, X2, X3, X4>;
|
||||||
|
|
||||||
|
@@ -20,13 +20,15 @@ struct X2 {};
|
|||||||
struct X3 {};
|
struct X3 {};
|
||||||
struct X4 {};
|
struct X4 {};
|
||||||
|
|
||||||
|
using boost::mp11::mp_not;
|
||||||
|
|
||||||
template<class T> using add_pointer = T*;
|
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()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_transform_if;
|
using boost::mp11::mp_transform_if;
|
||||||
|
|
||||||
using L1 = mp_list<X1, X2&, X3 const, X4 const&>;
|
using L1 = mp_list<X1, X2&, X3 const, X4 const&>;
|
||||||
|
|
||||||
|
@@ -15,8 +15,8 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_list;
|
using boost::mp11::mp_list;
|
||||||
using boost::mp_unique;
|
using boost::mp11::mp_unique;
|
||||||
|
|
||||||
{
|
{
|
||||||
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique<mp_list<>>, mp_list<>>));
|
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unique<mp_list<>>, mp_list<>>));
|
||||||
|
@@ -27,8 +27,8 @@ template<class T> using add_extents = T[];
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using boost::mp_valid;
|
using boost::mp11::mp_valid;
|
||||||
using boost::mp_identity;
|
using boost::mp11::mp_identity;
|
||||||
|
|
||||||
BOOST_TEST_TRAIT_FALSE((mp_valid<mp_identity>));
|
BOOST_TEST_TRAIT_FALSE((mp_valid<mp_identity>));
|
||||||
BOOST_TEST_TRAIT_TRUE((mp_valid<mp_identity, void>));
|
BOOST_TEST_TRAIT_TRUE((mp_valid<mp_identity, void>));
|
||||||
|
Reference in New Issue
Block a user