From 4521eff93cd02b3883727c7e5104274bab3ddb87 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 8 May 2017 18:59:19 +0300 Subject: [PATCH 1/7] Cast the result of f() to void (avoid op,) --- include/boost/tuple_for_each.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/tuple_for_each.hpp b/include/boost/tuple_for_each.hpp index 35d2b7a..2d2d135 100644 --- a/include/boost/tuple_for_each.hpp +++ b/include/boost/tuple_for_each.hpp @@ -17,7 +17,7 @@ namespace detail template BOOST_CONSTEXPR F tuple_for_each_impl( Tp && tp, boost::integer_sequence, F && f ) { using A = int[sizeof...(J)]; - return (void)A{ (f(std::get(std::forward(tp))), 0)... }, std::forward(f); + return (void)A{ ((void)f(std::get(std::forward(tp))), 0)... }, std::forward(f); } } // namespace detail From 939a3b949d9b85091fd0955e2e5fef82d7d221ae Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 9 May 2017 20:53:00 +0300 Subject: [PATCH 2/7] Add mp_bind_q, mp_bind_front(_q), mp_bind_back(_q), mp_transform_q --- include/boost/mp11/algorithm.hpp | 1 + include/boost/mp11/bind.hpp | 41 +++++++++++++++++++++ include/boost/mp11/utility.hpp | 7 +++- test/Jamfile.v2 | 3 ++ test/mp_bind_back.cpp | 63 ++++++++++++++++++++++++++++++++ test/mp_bind_front.cpp | 63 ++++++++++++++++++++++++++++++++ test/mp_bind_q.cpp | 62 +++++++++++++++++++++++++++++++ 7 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 test/mp_bind_back.cpp create mode 100644 test/mp_bind_front.cpp create mode 100644 test/mp_bind_q.cpp diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index 503f5cd..ba7eedf 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -80,6 +80,7 @@ template class F, template class L1, class... T1, t } // namespace detail template class F, class... L> using mp_transform = typename detail::mp_transform_impl::type; +template using mp_transform_q = mp_transform; namespace detail { diff --git a/include/boost/mp11/bind.hpp b/include/boost/mp11/bind.hpp index f7febf5..794b19b 100644 --- a/include/boost/mp11/bind.hpp +++ b/include/boost/mp11/bind.hpp @@ -16,6 +16,7 @@ namespace boost namespace mp11 { +// mp_arg template struct mp_arg { template using fn = mp_at_c, I>; @@ -31,6 +32,7 @@ using _7 = mp_arg<6>; using _8 = mp_arg<7>; using _9 = mp_arg<8>; +// mp_bind template class F, class... T> struct mp_bind; namespace detail @@ -58,6 +60,45 @@ template class F, class... T> struct mp_bind template using fn = F::type...>; }; +template using mp_bind_q = mp_bind; + +// mp_bind_front +template class F, class... T> struct mp_bind_front +{ +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 && BOOST_MSVC >= 1900 ) +#else +private: +#endif + + template struct _fn { using type = F; }; + +public: + + // the indirection through _fn works around the language inability + // to expand U... into a fixed parameter list of an alias template + + template using fn = typename _fn::type; +}; + +template using mp_bind_front_q = mp_bind_front; + +// mp_bind_back +template class F, class... T> struct mp_bind_back +{ +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 && BOOST_MSVC >= 1900 ) +#else +private: +#endif + + template struct _fn { using type = F; }; + +public: + + template using fn = typename _fn::type; +}; + +template using mp_bind_back_q = mp_bind_back; + } // namespace mp11 } // namespace boost diff --git a/include/boost/mp11/utility.hpp b/include/boost/mp11/utility.hpp index 78b5a9a..c077996 100644 --- a/include/boost/mp11/utility.hpp +++ b/include/boost/mp11/utility.hpp @@ -9,6 +9,8 @@ // http://www.boost.org/LICENSE_1_0.txt #include +#include +#include namespace boost { @@ -106,14 +108,17 @@ template class F, class... T> using mp_defer = mp_if class F, class... T> struct mp_quote { +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 && BOOST_MSVC >= 1900 ) +#else private: +#endif template struct _fn { using type = F; }; public: // the indirection through _fn works around the language inability - // to expand T.. to expand into a fixed parameter list of an alias template + // to expand T... into a fixed parameter list of an alias template template using fn = typename _fn::type; }; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 3bfaec6..7fa0101 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -106,3 +106,6 @@ run mp_map_update.cpp : : : $(REQ) ; # bind run mp_bind.cpp : : : $(REQ) ; +run mp_bind_q.cpp : : : $(REQ) ; +run mp_bind_front.cpp : : : $(REQ) ; +run mp_bind_back.cpp : : : $(REQ) ; diff --git a/test/mp_bind_back.cpp b/test/mp_bind_back.cpp new file mode 100644 index 0000000..f497a13 --- /dev/null +++ b/test/mp_bind_back.cpp @@ -0,0 +1,63 @@ + +// 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 + + +#include +#include +#include +#include +#include + +template struct L {}; +template struct P {}; + +template using is_base_of_t = typename std::is_base_of::type; + +struct B1 {}; +struct B2 {}; +struct D: B1, B2 {}; +struct NB {}; + +int main() +{ + using namespace boost::mp11; + + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, L>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, char[1], char[2]>::fn, L>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, P>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, char[1]>::fn, P>)); + + // + + using L1 = L; + + { + using L2 = mp_transform::fn, L1>; + BOOST_TEST_TRAIT_TRUE((std::is_same>)); + } + + { + using L2 = mp_transform_q, L1>; + BOOST_TEST_TRAIT_TRUE((std::is_same>)); + } + + { + using L2 = mp_transform, D>::fn, L1>; + BOOST_TEST_TRAIT_TRUE((std::is_same>)); + } + + { + using L2 = mp_transform_q, D>, L1>; + BOOST_TEST_TRAIT_TRUE((std::is_same>)); + } + + // + + return boost::report_errors(); +} diff --git a/test/mp_bind_front.cpp b/test/mp_bind_front.cpp new file mode 100644 index 0000000..bce077f --- /dev/null +++ b/test/mp_bind_front.cpp @@ -0,0 +1,63 @@ + +// 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 + + +#include +#include +#include +#include +#include + +template struct L {}; +template struct P {}; + +template using is_base_of_t = typename std::is_base_of::type; + +struct B {}; +struct D1: B {}; +struct D2: B {}; +struct ND {}; + +int main() +{ + using namespace boost::mp11; + + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, L>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, char[1], char[2]>::fn, L>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, P>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, char[1]>::fn, P>)); + + // + + using L1 = L; + + { + using L2 = mp_transform::fn, L1>; + BOOST_TEST_TRAIT_TRUE((std::is_same>)); + } + + { + using L2 = mp_transform_q, L1>; + BOOST_TEST_TRAIT_TRUE((std::is_same>)); + } + + { + using L2 = mp_transform, B>::fn, L1>; + BOOST_TEST_TRAIT_TRUE((std::is_same>)); + } + + { + using L2 = mp_transform_q, B>, L1>; + BOOST_TEST_TRAIT_TRUE((std::is_same>)); + } + + // + + return boost::report_errors(); +} diff --git a/test/mp_bind_q.cpp b/test/mp_bind_q.cpp new file mode 100644 index 0000000..0fa495c --- /dev/null +++ b/test/mp_bind_q.cpp @@ -0,0 +1,62 @@ + +// 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 + + +#include +#include +#include +#include + +struct X1 {}; +struct X2 {}; +struct X3 {}; +struct X4 {}; +struct X5 {}; +struct X6 {}; +struct X7 {}; +struct X8 {}; +struct X9 {}; + +template using add_pointer = typename std::add_pointer::type; + +int main() +{ + using namespace boost::mp11; + + using Q_addp = mp_quote; + + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X1*>)); + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X1*>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X2*>)); + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X2*>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X3*>)); + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X3*>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X4*>)); + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X4*>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X5*>)); + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X5*>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X6*>)); + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X6*>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X7*>)); + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X7*>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X8*>)); + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X8*>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X9*>)); + + // + + return boost::report_errors(); +} From 5eec097378c388d4a115b96b2372711fbbc5160a Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 10 May 2017 00:39:18 +0300 Subject: [PATCH 3/7] Update documentation --- doc/html/mp11.html | 62 +++++++++++++++++++++++++++++++++++++++++- doc/mp11/algorithm.qbk | 6 ++++ doc/mp11/bind.qbk | 24 ++++++++++++++++ 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/doc/html/mp11.html b/doc/html/mp11.html index 4a64ff4..2a1b025 100644 --- a/doc/html/mp11.html +++ b/doc/html/mp11.html @@ -98,6 +98,7 @@
mp_assign<L1, L2>
mp_clear<L>
mp_transform<F, L...>
+
mp_transform_q<Q, L...>
mp_transform_if<P, F, L...>
mp_fill<L, V>
mp_count<L, V>
@@ -164,6 +165,10 @@ ..., _9
mp_bind<F, T...>
+
mp_bind_front<F, T...>
+
mp_bind_front_q<Q, T...>
+
mp_bind_back<F, T...>
+
mp_bind_back_q<Q, T...>
Integer Sequences, <boost/integer_sequence.hpp>
@@ -987,6 +992,17 @@
+
template<class Q, class... L> using mp_transform_q = mp_transform<Q::template fn, L...>;
+
+

+ As mp_transform, but takes + a quoted metafunction. +

+
+
+
template<template<class...> class P, template<class...> class F, class L...> using mp_transform_if = /*...*/;
@@ -1680,6 +1696,50 @@
           is F<int, void, G<float>>.
         

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

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

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

+ As mp_bind_front, but takes + a quoted metafunction. +

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

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

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

+ As mp_bind_back, but takes + a quoted metafunction. +

+

@@ -1780,7 +1840,7 @@

- +

Last revised: April 01, 2017 at 16:43:16 GMT

Last revised: May 09, 2017 at 21:23:56 GMT


diff --git a/doc/mp11/algorithm.qbk b/doc/mp11/algorithm.qbk index e4a3991..14ccad0 100644 --- a/doc/mp11/algorithm.qbk +++ b/doc/mp11/algorithm.qbk @@ -26,6 +26,12 @@ `mp_transform, L2, ..., Ln>` applies `F` to each successive tuple of elements and returns `L1...>`. [endsect] +[section `mp_transform_q`] + template using mp_transform_q = mp_transform; + +As `mp_transform`, but takes a quoted metafunction. +[endsect] + [section `mp_transform_if`] template class P, template class F, class L...> using mp_transform_if = /*...*/; diff --git a/doc/mp11/bind.qbk b/doc/mp11/bind.qbk index 0278122..424eaf5 100644 --- a/doc/mp11/bind.qbk +++ b/doc/mp11/bind.qbk @@ -38,4 +38,28 @@ of `U...` and the `mp_bind` expressions replaced with their corresponding evalua For example, `mp_bind>::fn` is `F>`. [endsect] +[section `mp_bind_front`] + template class F, class... T> struct mp_bind_front; + +`mp_bind_front` binds the leftmost arguments of `F` to `T...`. Its nested template `fn` returns `F`. +[endsect] + +[section `mp_bind_front_q`] + template using mp_bind_front_q = mp_bind_front; + +As `mp_bind_front`, but takes a quoted metafunction. +[endsect] + +[section `mp_bind_back`] + template class F, class... T> struct mp_bind_back; + +`mp_bind_back` binds the rightmost arguments of `F` to `T...`. Its nested template `fn` returns `F`. +[endsect] + +[section `mp_bind_back_q`] + template using mp_bind_back_q = mp_bind_back; + +As `mp_bind_back`, but takes a quoted metafunction. +[endsect] + [endsect] From 4500b673f2e81d2e039dd3669998e39c2f76a565 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 10 May 2017 23:23:56 +0300 Subject: [PATCH 4/7] Update documentation --- doc/html/mp11.html | 18 ++++++++++++++++-- doc/mp11/bind.qbk | 6 ++++++ doc/mp11/definitions.qbk | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/doc/html/mp11.html b/doc/html/mp11.html index 2a1b025..fd46376 100644 --- a/doc/html/mp11.html +++ b/doc/html/mp11.html @@ -165,6 +165,8 @@ ..., _9
mp_bind<F, T...>
+
mp_bind_q<Q, + T...>
mp_bind_front<F, T...>
mp_bind_front_q<Q, T...>
mp_bind_back<F, T...>
@@ -249,7 +251,7 @@

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

struct Q1 { template<class...> using fn = void; };
 struct Q2 { template<class T> using fn = T*; };
@@ -1698,6 +1700,18 @@
 
+
template<class Q, class... T> using mp_bind_q = mp_bind<Q::template fn, T...>;
+
+

+ As mp_bind, but takes a + quoted metafunction. +

+
+
+
template<template<class...> class F, class... T> struct mp_bind_front;
@@ -1840,7 +1854,7 @@
 
- +

Last revised: May 09, 2017 at 21:23:56 GMT

Last revised: May 10, 2017 at 20:23:11 GMT


diff --git a/doc/mp11/bind.qbk b/doc/mp11/bind.qbk index 424eaf5..5cc48c3 100644 --- a/doc/mp11/bind.qbk +++ b/doc/mp11/bind.qbk @@ -38,6 +38,12 @@ of `U...` and the `mp_bind` expressions replaced with their corresponding evalua For example, `mp_bind>::fn` is `F>`. [endsect] +[section `mp_bind_q`] + template using mp_bind_q = mp_bind; + +As `mp_bind`, but takes a quoted metafunction. +[endsect] + [section `mp_bind_front`] template class F, class... T> struct mp_bind_front; diff --git a/doc/mp11/definitions.qbk b/doc/mp11/definitions.qbk index 23586d7..ce7def2 100644 --- a/doc/mp11/definitions.qbk +++ b/doc/mp11/definitions.qbk @@ -18,7 +18,7 @@ A /metafunction/ is a class template or a template alias whose parameters are al template using F2 = T*; template using F3 = std::integral_constant; -A /quoted metafunction/ is a class with a public metafunction called `fn`, for example +A /quoted metafunction/ is a class with a public metafunction member called `fn`, for example struct Q1 { template using fn = void; }; struct Q2 { template using fn = T*; }; From 543a0f755e19a667d2a75bc736de5d7fcf8e62e0 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 12 May 2017 19:21:27 +0300 Subject: [PATCH 5/7] Add mp_apply_q --- doc/html/mp11.html | 18 +++++- doc/mp11/list.qbk | 8 ++- include/boost/mp11/list.hpp | 2 + test/Jamfile.v2 | 1 + test/mp_apply_q.cpp | 113 ++++++++++++++++++++++++++++++++++++ 5 files changed, 139 insertions(+), 3 deletions(-) create mode 100644 test/mp_apply_q.cpp diff --git a/doc/html/mp11.html b/doc/html/mp11.html index fd46376..1c96c26 100644 --- a/doc/html/mp11.html +++ b/doc/html/mp11.html @@ -70,6 +70,8 @@ Y>
mp_apply<F, L>
+
mp_apply_q<Q, + L>
mp_append<L...>
mp_replace_front<L, T>
mp_replace_first<L, T>
@@ -734,7 +736,7 @@
template<template<class...> class F, class L> using mp_apply = mp_rename<L, F>;
 

- mp_apply<F, L> applies the metafunction F to the contents of the list L, that is, mp_rename<F, L<T...>> + mp_apply<F, L> applies the metafunction F to the contents of the list L, that is, mp_apply<F, L<T...>> is an alias for F<T...>. (mp_apply is the same as mp_rename with the arguments @@ -743,6 +745,18 @@

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

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

+
+
+
template<class... L> using mp_append = /*...*/;
@@ -1854,7 +1868,7 @@
 
- +

Last revised: May 10, 2017 at 20:23:11 GMT

Last revised: May 12, 2017 at 16:19:34 GMT


diff --git a/doc/mp11/list.qbk b/doc/mp11/list.qbk index 4c4dcd0..67cdfc8 100644 --- a/doc/mp11/list.qbk +++ b/doc/mp11/list.qbk @@ -88,10 +88,16 @@ is an alias for `L`. [section `mp_apply`] template class F, class L> using mp_apply = mp_rename; -`mp_apply` applies the metafunction `F` to the contents of the list `L`, that is, `mp_rename>` is an alias for `F`. +`mp_apply` applies the metafunction `F` to the contents of the list `L`, that is, `mp_apply>` is an alias for `F`. (`mp_apply` is the same as `mp_rename` with the arguments reversed.) [endsect] +[section `mp_apply_q`] + template using mp_apply_q = mp_apply; + +Same as `mp_apply`, but takes a quoted metafunction. +[endsect] + [section `mp_append`] template using mp_append = /*...*/; diff --git a/include/boost/mp11/list.hpp b/include/boost/mp11/list.hpp index ef205b7..5795d0a 100644 --- a/include/boost/mp11/list.hpp +++ b/include/boost/mp11/list.hpp @@ -150,6 +150,8 @@ template class B> using mp_rename = typename detail: template class F, class L> using mp_apply = typename detail::mp_rename_impl::type; +template using mp_apply_q = typename detail::mp_rename_impl::type; + // mp_replace_front namespace detail { diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 7fa0101..c627c6b 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -29,6 +29,7 @@ run mp_append_2.cpp : : : $(REQ) ; run mp_replace_front.cpp : : : $(REQ) ; run mp_replace_second.cpp : : : $(REQ) ; run mp_replace_third.cpp : : : $(REQ) ; +run mp_apply_q.cpp : : : $(REQ) ; # algorithm run mp_assign.cpp : : : $(REQ) ; diff --git a/test/mp_apply_q.cpp b/test/mp_apply_q.cpp new file mode 100644 index 0000000..d2a47c0 --- /dev/null +++ b/test/mp_apply_q.cpp @@ -0,0 +1,113 @@ + +// 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 +#include +#include +#include +#include +#include + +template struct X {}; +template using Y = X; + +struct Q +{ + template using fn = X; +}; + +int main() +{ + using boost::mp11::mp_list; + using boost::mp11::mp_quote; + using boost::mp11::mp_apply_q; + + using L1 = mp_list<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>, std::tuple<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>, X<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>, Y<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X<>>)); + + using L2 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L2>, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L2>, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L2>, X>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L2>, Y>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X>)); + + using L3 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L3>, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L3>, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L3>, X>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L3>, Y>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L3>, std::pair>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X>)); + + using L4 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L4>, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L4>, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L4>, X>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L4>, Y>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X>)); + + // + + using L5 = std::tuple<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L5>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L5>, std::tuple<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L5>, X<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L5>, Y<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X<>>)); + + using L6 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L6>, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L6>, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L6>, X>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L6>, Y>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X>)); + + using L7 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L7>, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L7>, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L7>, X>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L7>, Y>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L7>, std::pair>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X>)); + + using L8 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L8>, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L8>, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L8>, X>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L8>, Y>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X>)); + + // + + using L9 = std::pair; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L9>, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L9>, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L9>, X>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L9>, Y>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L9>, std::pair>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X>)); + + // + + return boost::report_errors(); +} From 9fbf51bbcb6144b84915731bb6b0fd3b1e475719 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 12 May 2017 19:43:03 +0300 Subject: [PATCH 6/7] Remove bind_front functionality from mp_quote --- doc/html/mp11.html | 24 ++++++++++---------- doc/mp11/utility.qbk | 11 +++++----- include/boost/mp11/utility.hpp | 11 +++------- test/mp_quote.cpp | 40 ++++++++++------------------------ 4 files changed, 30 insertions(+), 56 deletions(-) diff --git a/doc/html/mp11.html b/doc/html/mp11.html index 1c96c26..17487f5 100644 --- a/doc/html/mp11.html +++ b/doc/html/mp11.html @@ -92,7 +92,7 @@ U...>
mp_valid<F, T...>
mp_defer<F, T...>
-
mp_quote<F, T...>
+
mp_quote<F>
mp_invoke<Q, T...>
Algorithms, <boost/mp11/algorithm.hpp>
@@ -934,20 +934,19 @@
-
template<template<class...> class F, class... T> struct mp_quote
+
template<template<class...> class F> struct mp_quote
 {
-    template<class... U> using fn = F<T..., U...>;
+    template<class... T> using fn = F<T...>;
 };
 

- mp_quote<F, T...> transforms the template F into a type. In the common case mp_quote<F>, - the nested template fn - of the result is an alias for F; - otherwise, fn<U...> - is an alias for F<T..., U...>, - allowing partial application. + mp_quote<F> + transforms the template F + into a type with a nested template fn + such that fn<T...> + returns F<T...>.

@@ -958,8 +957,7 @@

mp_invoke<Q, T...> evaluates the nested template fn 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...>. + returns F<T...>.

@@ -1868,7 +1866,7 @@ - +

Last revised: May 12, 2017 at 16:19:34 GMT

Last revised: May 12, 2017 at 16:42:29 GMT


diff --git a/doc/mp11/utility.qbk b/doc/mp11/utility.qbk index ae51f85..0052d34 100644 --- a/doc/mp11/utility.qbk +++ b/doc/mp11/utility.qbk @@ -61,20 +61,19 @@ When `mp_valid` is `mp_true`, `mp_defer` is a struct with a ne `mp_defer` is an empty struct. [endsect] -[section `mp_quote`] - template class F, class... T> struct mp_quote +[section `mp_quote`] + template class F> struct mp_quote { - template using fn = F; + template using fn = F; }; -`mp_quote` transforms the template `F` into a type. In the common case `mp_quote`, the nested template `fn` of the result is an alias for `F`; -otherwise, `fn` is an alias for `F`, allowing partial application. +`mp_quote` transforms the template `F` into a type with a nested template `fn` such that `fn` returns `F`. [endsect] [section `mp_invoke`] template using mp_invoke = typename Q::template fn; -`mp_invoke` evaluates the nested template `fn` of a quoted metafunction. `mp_invoke, T...>` is an alias for `F`. `mp_invoke, U...>` is an alias for `F`. +`mp_invoke` evaluates the nested template `fn` of a quoted metafunction. `mp_invoke, T...>` returns `F`. [endsect] [endsect] diff --git a/include/boost/mp11/utility.hpp b/include/boost/mp11/utility.hpp index c077996..e220b5f 100644 --- a/include/boost/mp11/utility.hpp +++ b/include/boost/mp11/utility.hpp @@ -106,21 +106,21 @@ struct mp_no_type template class F, class... T> using mp_defer = mp_if, detail::mp_defer_impl, detail::mp_no_type>; // mp_quote -template class F, class... T> struct mp_quote +template class F> struct mp_quote { #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 && BOOST_MSVC >= 1900 ) #else private: #endif - template struct _fn { using type = F; }; + template struct _fn { using type = F; }; public: // the indirection through _fn works around the language inability // to expand T... into a fixed parameter list of an alias template - template using fn = typename _fn::type; + template using fn = typename _fn::type; }; // mp_unquote @@ -132,11 +132,6 @@ template struct mp_invoke_impl using type = typename Q::template fn; }; -template class F, class... T, class... U> struct mp_invoke_impl, U...> -{ - using type = F; -}; - } // namespace detail template using mp_invoke = typename detail::mp_invoke_impl::type; diff --git a/test/mp_quote.cpp b/test/mp_quote.cpp index 29bb317..9d2ca6a 100644 --- a/test/mp_quote.cpp +++ b/test/mp_quote.cpp @@ -19,12 +19,9 @@ template class F, class... T> using Y = X...>; template using Z = X...>; -struct B {}; -struct D1: B {}; -struct D2: B {}; -struct ND {}; +template struct P {}; -template using is_base_of_t = typename std::is_base_of::type; +template using first = T; int main() { @@ -38,19 +35,6 @@ int main() BOOST_TEST_TRAIT_TRUE((std::is_same, int[]>)); } - { - using Q = mp_quote; - - BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>)); - BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>)); - } - - { - using Q = mp_quote; - - BOOST_TEST_TRAIT_TRUE((std::is_same, X>)); - } - { using Q = mp_quote; @@ -68,19 +52,17 @@ int main() } { - using Q = mp_quote; + using Q = mp_quote

; -#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 ) -#else - using R1 = Y; - BOOST_TEST_TRAIT_TRUE((std::is_same>)); -#endif + BOOST_TEST_TRAIT_TRUE((std::is_same, P>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, P>)); + } -#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 && BOOST_MSVC >= 1900 ) -#else - using R2 = Z; - BOOST_TEST_TRAIT_TRUE((std::is_same>)); -#endif + { + using Q = mp_quote; + + BOOST_TEST_TRAIT_TRUE((std::is_same, void>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, char[]>)); } return boost::report_errors(); From 509ce8f95e0d299c29a85904b41e93dca4a1a78d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 12 May 2017 19:49:05 +0300 Subject: [PATCH 7/7] Add endsect ids, enable quickbook strict mode --- doc/Jamfile.v2 | 2 +- doc/html/mp11.html | 2 +- doc/mp11/algorithm.qbk | 2 +- doc/mp11/bind.qbk | 2 +- doc/mp11/definitions.qbk | 4 ++-- doc/mp11/examples.qbk | 4 ++-- doc/mp11/function.qbk | 2 +- doc/mp11/integer_sequence.qbk | 2 +- doc/mp11/integral.qbk | 2 +- doc/mp11/list.qbk | 2 +- doc/mp11/map.qbk | 2 +- doc/mp11/overview.qbk | 4 ++-- doc/mp11/set.qbk | 2 +- doc/mp11/tuple_for_each.qbk | 2 +- doc/mp11/utility.qbk | 2 +- 15 files changed, 18 insertions(+), 18 deletions(-) diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 35d5468..f8d1a5d 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -10,7 +10,7 @@ project doc/mp11 ; import boostbook ; import quickbook ; -xml mp11_ : mp11.qbk ; +xml mp11_ : mp11.qbk : on ; boostbook standalone_mp11 : mp11_ diff --git a/doc/html/mp11.html b/doc/html/mp11.html index 17487f5..cd95a45 100644 --- a/doc/html/mp11.html +++ b/doc/html/mp11.html @@ -1866,7 +1866,7 @@ - +

Last revised: May 12, 2017 at 16:42:29 GMT

Last revised: May 12, 2017 at 16:48:16 GMT


diff --git a/doc/mp11/algorithm.qbk b/doc/mp11/algorithm.qbk index 14ccad0..b325077 100644 --- a/doc/mp11/algorithm.qbk +++ b/doc/mp11/algorithm.qbk @@ -244,4 +244,4 @@ for the elements of `L` and `mp_false` for the elements of `L`. Re `mp_any_of` 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:algorithm] diff --git a/doc/mp11/bind.qbk b/doc/mp11/bind.qbk index 5cc48c3..f254929 100644 --- a/doc/mp11/bind.qbk +++ b/doc/mp11/bind.qbk @@ -68,4 +68,4 @@ As `mp_bind_front`, but takes a quoted metafunction. As `mp_bind_back`, but takes a quoted metafunction. [endsect] -[endsect] +[endsect:bind] diff --git a/doc/mp11/definitions.qbk b/doc/mp11/definitions.qbk index ce7def2..3955fbf 100644 --- a/doc/mp11/definitions.qbk +++ b/doc/mp11/definitions.qbk @@ -6,7 +6,7 @@ / http://www.boost.org/LICENSE_1_0.txt) /] -[section Definitions] +[section:definitions Definitions] A /list/ is a '''—''' usually but not necessarily variadic '''—''' template class whose parameters are all types, for example `mp_list`, `mp_list<>`, `std::tuple`, `std::pair`, `std::shared_ptr`. @@ -36,4 +36,4 @@ A /map/ is a list of lists, the inner lists having at least one element (the key using M1 = std::tuple, std::pair, std::pair>; using M2 = mp_list, mp_list, mp_list>; -[endsect] +[endsect:definitions] diff --git a/doc/mp11/examples.qbk b/doc/mp11/examples.qbk index 2644118..041c589 100644 --- a/doc/mp11/examples.qbk +++ b/doc/mp11/examples.qbk @@ -6,7 +6,7 @@ / http://www.boost.org/LICENSE_1_0.txt) /] -[section Examples] +[section:examples Examples] [section Generating Test Cases] @@ -173,4 +173,4 @@ and we're done: [endsect] -[endsect] +[endsect:examples] diff --git a/doc/mp11/function.qbk b/doc/mp11/function.qbk index 01948c2..b0ef1ae 100644 --- a/doc/mp11/function.qbk +++ b/doc/mp11/function.qbk @@ -37,4 +37,4 @@ If no such type exists, the last one is returned. `mp_or<>` is `mp_false`. Simil `mp_or`, but does not perform short-circuit evaluation. [endsect] -[endsect] +[endsect:function] diff --git a/doc/mp11/integer_sequence.qbk b/doc/mp11/integer_sequence.qbk index e33df75..f0604b6 100644 --- a/doc/mp11/integer_sequence.qbk +++ b/doc/mp11/integer_sequence.qbk @@ -42,4 +42,4 @@ The contents of this header are defined in namespace `boost`. `index_sequence_for` is `make_index_sequence`. Same as C++14's `std::index_sequence_for`. [endsect] -[endsect] +[endsect:integer_sequence] diff --git a/doc/mp11/integral.qbk b/doc/mp11/integral.qbk index 77c45c8..dbe757f 100644 --- a/doc/mp11/integral.qbk +++ b/doc/mp11/integral.qbk @@ -38,4 +38,4 @@ For an Mp11 integral constant type `T`, `T::value` is an integral constant in th template using mp_size_t = std::integral_constant; [endsect] -[endsect] +[endsect:integral] diff --git a/doc/mp11/list.qbk b/doc/mp11/list.qbk index 67cdfc8..ccddc86 100644 --- a/doc/mp11/list.qbk +++ b/doc/mp11/list.qbk @@ -132,4 +132,4 @@ is an alias for `L`. is an alias for `L`. [endsect] -[endsect] +[endsect:list] diff --git a/doc/mp11/map.qbk b/doc/mp11/map.qbk index d76338b..fad9dfd 100644 --- a/doc/mp11/map.qbk +++ b/doc/mp11/map.qbk @@ -48,4 +48,4 @@ replaces the existing element `L` with `L>`. If the map `M` contains an element with a key `K`, removes it. [endsect] -[endsect] +[endsect:map] diff --git a/doc/mp11/overview.qbk b/doc/mp11/overview.qbk index 79502b4..0686565 100644 --- a/doc/mp11/overview.qbk +++ b/doc/mp11/overview.qbk @@ -6,7 +6,7 @@ / http://www.boost.org/LICENSE_1_0.txt) /] -[section Overview] +[section:overview Overview] Mp11 is a C++11 metaprogramming library based on template aliases and variadic templates. It implements the approach outlined in the article @@ -31,4 +31,4 @@ gives us `std::tuple`, but we can also apply `mp_list` to the same and get `std::tuple, mp_list>`. -[endsect] +[endsect:overview] diff --git a/doc/mp11/set.qbk b/doc/mp11/set.qbk index a646823..3964d60 100644 --- a/doc/mp11/set.qbk +++ b/doc/mp11/set.qbk @@ -28,4 +28,4 @@ For each `T1` in `T...`, `mp_set_push_back` appends `T1` to the end of `mp_set_push_front` inserts at the front of `S` those elements of `T...` for which `S` does not already contain the same type. [endsect] -[endsect] +[endsect:set] diff --git a/doc/mp11/tuple_for_each.qbk b/doc/mp11/tuple_for_each.qbk index bfdf767..2b06fcd 100644 --- a/doc/mp11/tuple_for_each.qbk +++ b/doc/mp11/tuple_for_each.qbk @@ -19,4 +19,4 @@ expression `f(std::get(std::forward(tp)))` for `J` in 0..`N-1`, where `N` Returns `std::forward(f)`. [endsect] -[endsect] +[endsect:tuple_for_each] diff --git a/doc/mp11/utility.qbk b/doc/mp11/utility.qbk index 0052d34..1786265 100644 --- a/doc/mp11/utility.qbk +++ b/doc/mp11/utility.qbk @@ -76,4 +76,4 @@ When `mp_valid` is `mp_true`, `mp_defer` is a struct with a ne `mp_invoke` evaluates the nested template `fn` of a quoted metafunction. `mp_invoke, T...>` returns `F`. [endsect] -[endsect] +[endsect:utility]