1
0
forked from boostorg/mp11

Add arguments to mp_quote, allowing partial application

This commit is contained in:
Peter Dimov
2017-03-15 18:09:30 +02:00
parent 63a4fafe16
commit 8d9e6f50dd
4 changed files with 87 additions and 26 deletions

View File

@@ -76,7 +76,7 @@
<span class="identifier">U</span><span class="special">...&gt;</span></code></a></span></dt> <span class="identifier">U</span><span class="special">...&gt;</span></code></a></span></dt>
<dt><span class="section"><a href="mp11.html#mp11.reference.utility.mp_valid_f_t"><code class="computeroutput"><span class="identifier">mp_valid</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">,</span> <span class="identifier">T</span><span class="special">...&gt;</span></code></a></span></dt> <dt><span class="section"><a href="mp11.html#mp11.reference.utility.mp_valid_f_t"><code class="computeroutput"><span class="identifier">mp_valid</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">,</span> <span class="identifier">T</span><span class="special">...&gt;</span></code></a></span></dt>
<dt><span class="section"><a href="mp11.html#mp11.reference.utility.mp_defer_f_t"><code class="computeroutput"><span class="identifier">mp_defer</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">,</span> <span class="identifier">T</span><span class="special">...&gt;</span></code></a></span></dt> <dt><span class="section"><a href="mp11.html#mp11.reference.utility.mp_defer_f_t"><code class="computeroutput"><span class="identifier">mp_defer</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">,</span> <span class="identifier">T</span><span class="special">...&gt;</span></code></a></span></dt>
<dt><span class="section"><a href="mp11.html#mp11.reference.utility.mp_quote_f"><code class="computeroutput"><span class="identifier">mp_quote</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;</span></code></a></span></dt> <dt><span class="section"><a href="mp11.html#mp11.reference.utility.mp_quote_f_t"><code class="computeroutput"><span class="identifier">mp_quote</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">,</span> <span class="identifier">T</span><span class="special">...&gt;</span></code></a></span></dt>
<dt><span class="section"><a href="mp11.html#mp11.reference.utility.mp_unquote_q_t"><code class="computeroutput"><span class="identifier">mp_unquote</span><span class="special">&lt;</span><span class="identifier">Q</span><span class="special">,</span> <span class="identifier">T</span><span class="special">...&gt;</span></code></a></span></dt> <dt><span class="section"><a href="mp11.html#mp11.reference.utility.mp_unquote_q_t"><code class="computeroutput"><span class="identifier">mp_unquote</span><span class="special">&lt;</span><span class="identifier">Q</span><span class="special">,</span> <span class="identifier">T</span><span class="special">...&gt;</span></code></a></span></dt>
</dl></dd> </dl></dd>
<dt><span class="section"><a href="mp11.html#mp11.reference.algorithm">Algorithms, <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">mp11</span><span class="special">/</span><span class="identifier">algorithm</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code></a></span></dt> <dt><span class="section"><a href="mp11.html#mp11.reference.algorithm">Algorithms, <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">mp11</span><span class="special">/</span><span class="identifier">algorithm</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code></a></span></dt>
@@ -490,18 +490,20 @@
</div> </div>
<div class="section"> <div class="section">
<div class="titlepage"><div><div><h4 class="title"> <div class="titlepage"><div><div><h4 class="title">
<a name="mp11.reference.utility.mp_quote_f"></a><a class="link" href="mp11.html#mp11.reference.utility.mp_quote_f" title="mp_quote&lt;F&gt;"><code class="computeroutput"><span class="identifier">mp_quote</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;</span></code></a> <a name="mp11.reference.utility.mp_quote_f_t"></a><a class="link" href="mp11.html#mp11.reference.utility.mp_quote_f_t" title="mp_quote&lt;F, T...&gt;"><code class="computeroutput"><span class="identifier">mp_quote</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">,</span> <span class="identifier">T</span><span class="special">...&gt;</span></code></a>
</h4></div></div></div> </h4></div></div></div>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span><span class="special">...&gt;</span> <span class="keyword">class</span> <span class="identifier">F</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">mp_quote</span> <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span><span class="special">...&gt;</span> <span class="keyword">class</span> <span class="identifier">F</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">struct</span> <span class="identifier">mp_quote</span>
<span class="special">{</span> <span class="special">{</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">using</span> <span class="identifier">apply</span> <span class="special">=</span> <span class="identifier">F</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">...&gt;;</span> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">using</span> <span class="identifier">apply</span> <span class="special">=</span> <span class="identifier">F</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">...,</span> <span class="identifier">U</span><span class="special">...&gt;;</span>
<span class="special">};</span> <span class="special">};</span>
</pre> </pre>
<p> <p>
<code class="computeroutput"><span class="identifier">mp_quote</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;</span></code> <code class="computeroutput"><span class="identifier">mp_quote</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">,</span> <span class="identifier">T</span><span class="special">...&gt;</span></code> transforms the template <code class="computeroutput"><span class="identifier">F</span></code> into a type. In the common case <code class="computeroutput"><span class="identifier">mp_quote</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;</span></code>,
transforms the template <code class="computeroutput"><span class="identifier">F</span></code> the nested template <code class="computeroutput"><span class="identifier">apply</span></code>
into a type. The nested template <code class="computeroutput"><span class="identifier">apply</span></code> of the result is an alias for <code class="computeroutput"><span class="identifier">F</span></code>;
of the result is an alias for <code class="computeroutput"><span class="identifier">F</span></code>. otherwise, <code class="computeroutput"><span class="identifier">apply</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">...&gt;</span></code>
is an alias for <code class="computeroutput"><span class="identifier">F</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">...,</span> <span class="identifier">U</span><span class="special">...&gt;</span></code>,
allowing partial application.
</p> </p>
</div> </div>
<div class="section"> <div class="section">
@@ -511,9 +513,9 @@
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Q</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">using</span> <span class="identifier">mp_unquote</span> <span class="special">=</span> <span class="keyword">typename</span> <span class="identifier">Q</span><span class="special">::</span><span class="keyword">template</span> <span class="identifier">apply</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">...&gt;;</span> <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Q</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">using</span> <span class="identifier">mp_unquote</span> <span class="special">=</span> <span class="keyword">typename</span> <span class="identifier">Q</span><span class="special">::</span><span class="keyword">template</span> <span class="identifier">apply</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">...&gt;;</span>
</pre> </pre>
<p> <p>
<code class="computeroutput"><span class="identifier">mp_unquote</span><span class="special">&lt;</span><span class="identifier">Q</span><span class="special">,</span> <span class="identifier">T</span><span class="special">...&gt;</span></code>, where <code class="computeroutput"><span class="identifier">Q</span></code> <code class="computeroutput"><span class="identifier">mp_unquote</span><span class="special">&lt;</span><span class="identifier">Q</span><span class="special">,</span> <span class="identifier">T</span><span class="special">...&gt;</span></code> evaluates the nested template <code class="computeroutput"><span class="identifier">apply</span></code> of a quoted metafunction. <code class="computeroutput"><span class="identifier">mp_unquote</span><span class="special">&lt;</span><span class="identifier">mp_quote</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;,</span> <span class="identifier">T</span><span class="special">...&gt;</span></code>
is <code class="computeroutput"><span class="identifier">mp_quote</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;</span></code>,
is an alias for <code class="computeroutput"><span class="identifier">F</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</span></code>. is an alias for <code class="computeroutput"><span class="identifier">F</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">...&gt;</span></code>.
<code class="computeroutput"><span class="identifier">mp_unquote</span><span class="special">&lt;</span><span class="identifier">mp_quote</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">,</span> <span class="identifier">T</span><span class="special">...&gt;,</span> <span class="identifier">U</span><span class="special">...&gt;</span></code> is an alias for <code class="computeroutput"><span class="identifier">F</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">...,</span> <span class="identifier">U</span><span class="special">...&gt;</span></code>.
</p> </p>
</div> </div>
</div> </div>
@@ -914,7 +916,7 @@
</div> </div>
</div> </div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: March 14, 2017 at 20:19:38 GMT</small></p></td> <td align="left"><p><small>Last revised: March 15, 2017 at 16:06:15 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td> <td align="right"><div class="copyright-footer"></div></td>
</tr></table> </tr></table>
<hr> <hr>

View File

@@ -61,19 +61,20 @@ When `mp_valid<F, T...>` is `mp_true`, `mp_defer<F, T...>` is a struct with a ne
`mp_defer<F, T...>` is an empty struct. `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 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.
[endsect] [endsect]
[section `mp_unquote<Q, T...>`] [section `mp_unquote<Q, T...>`]
template<class Q, class... T> using mp_unquote = typename Q::template apply<T...>; template<class Q, class... T> using mp_unquote = typename Q::template apply<T...>;
`mp_unquote<Q, T...>`, where `Q` is `mp_quote<F>`, is an alias for `F<T...>`. `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...>`.
[endsect] [endsect]
[endsect] [endsect]

View File

@@ -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.
// //
@@ -102,9 +102,9 @@ 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 apply = F<T..., U...>;
}; };
// mp_unquote // mp_unquote
@@ -116,9 +116,9 @@ template<class Q, class... T> struct mp_unquote_impl
using type = typename Q::template apply<T...>; using type = typename Q::template apply<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_unquote_impl<mp_quote<F, T...>, U...>
{ {
using type = F<T...>; using type = F<T..., U...>;
}; };
} // namespace detail } // namespace detail

View File

@@ -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::mp_unquote;
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_unquote<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::mp_identity_t;
using boost::mp_quote; using boost::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_unquote<Q, void>, void>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unquote<Q, int[]>, int[]>)); BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unquote<Q, int[]>, int[]>));
}
{
using Q = mp_quote<std::is_same, void>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unquote<Q, void>, std::is_same<void, void>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_unquote<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_unquote<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 apply, 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 apply, 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();
} }