diff --git a/doc/html/mp11.html b/doc/html/mp11.html index cfd8531..0304c01 100644 --- a/doc/html/mp11.html +++ b/doc/html/mp11.html @@ -76,7 +76,7 @@ U...>
mp_valid<F, T...>
mp_defer<F, T...>
-
mp_quote<F>
+
mp_quote<F, T...>
mp_unquote<Q, T...>
Algorithms, <boost/mp11/algorithm.hpp>
@@ -490,18 +490,20 @@

-mp_quote<F> +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 apply = 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 apply + of the result is an alias for F; + otherwise, apply<U...> + is an alias for F<T..., U...>, + allowing partial application.

@@ -511,9 +513,9 @@
template<class Q, class... T> using mp_unquote = typename Q::template apply<T...>;
 

- mp_unquote<Q, T...>, where Q - is mp_quote<F>, + mp_unquote<Q, T...> evaluates the nested template apply of a quoted metafunction. mp_unquote<mp_quote<F>, T...> is an alias for F<T...>. + mp_unquote<mp_quote<F, T...>, U...> is an alias for F<T..., U...>.

@@ -914,7 +916,7 @@ - +

Last revised: March 14, 2017 at 20:19:38 GMT

Last revised: March 15, 2017 at 16:06:15 GMT


diff --git a/doc/mp11/utility.qbk b/doc/mp11/utility.qbk index 51c39d3..b0b4a4b 100644 --- a/doc/mp11/utility.qbk +++ b/doc/mp11/utility.qbk @@ -61,19 +61,20 @@ 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> struct mp_quote +[section `mp_quote`] + template class F, class... T> struct mp_quote { - template using apply = F; + template using apply = F; }; -`mp_quote` transforms the template `F` into a type. The nested template `apply` of the result is an alias for `F`. +`mp_quote` transforms the template `F` into a type. In the common case `mp_quote`, the nested template `apply` of the result is an alias for `F`; +otherwise, `apply` is an alias for `F`, allowing partial application. [endsect] [section `mp_unquote`] template using mp_unquote = typename Q::template apply; -`mp_unquote`, where `Q` is `mp_quote`, is an alias for `F`. +`mp_unquote` evaluates the nested template `apply` of a quoted metafunction. `mp_unquote, T...>` is an alias for `F`. `mp_unquote, U...>` is an alias for `F`. [endsect] [endsect] diff --git a/include/boost/mp11/utility.hpp b/include/boost/mp11/utility.hpp index a438a33..220155f 100644 --- a/include/boost/mp11/utility.hpp +++ b/include/boost/mp11/utility.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_MP11_UTILITY_HPP_INCLUDED #define BOOST_MP11_UTILITY_HPP_INCLUDED -// Copyright 2015 Peter Dimov. +// Copyright 2015, 2017 Peter Dimov. // // Distributed under the Boost Software License, Version 1.0. // @@ -102,9 +102,9 @@ 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> struct mp_quote +template class F, class... T> struct mp_quote { - template using apply = F; + template using apply = F; }; // mp_unquote @@ -116,9 +116,9 @@ template struct mp_unquote_impl using type = typename Q::template apply; }; -template class F, class... T> struct mp_unquote_impl, T...> +template class F, class... T, class... U> struct mp_unquote_impl, U...> { - using type = F; + using type = F; }; } // namespace detail diff --git a/test/mp_quote.cpp b/test/mp_quote.cpp index 74a8193..39ab385 100644 --- a/test/mp_quote.cpp +++ b/test/mp_quote.cpp @@ -11,18 +11,76 @@ #include #include -struct X {}; +using boost::mp_unquote; + +template struct X {}; + +template class F, class... T> using Y = X...>; + +template using Z = X...>; + +struct B {}; +struct D1: B {}; +struct D2: B {}; +struct ND {}; + +template using is_base_of_t = typename std::is_base_of::type; int main() { using boost::mp_identity_t; using boost::mp_quote; - using boost::mp_unquote; - using Q = mp_quote; + { + using Q = mp_quote; - BOOST_TEST_TRAIT_TRUE((std::is_same, void>)); - BOOST_TEST_TRAIT_TRUE((std::is_same, int[]>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, void>)); + 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; + + // using R1 = Y; + // BOOST_TEST_TRAIT_TRUE((std::is_same>)); + // + // 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; + BOOST_TEST_TRAIT_TRUE((std::is_same>)); +#endif + } + + { + 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 + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 && BOOST_MSVC >= 1900 ) +#else + using R2 = Z; + BOOST_TEST_TRAIT_TRUE((std::is_same>)); +#endif + } return boost::report_errors(); }