1
0
forked from boostorg/mp11

Merge branch 'develop'

This commit is contained in:
Peter Dimov
2017-05-26 00:05:16 +03:00
8 changed files with 266 additions and 10 deletions

View File

@@ -107,6 +107,7 @@
<dt><span class="section"><a href="mp11.html#mp11.reference.algorithm.mp_transform_f_l"><code class="computeroutput"><span class="identifier">mp_transform</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">,</span> <span class="identifier">L</span><span class="special">...&gt;</span></code></a></span></dt>
<dt><span class="section"><a href="mp11.html#mp11.reference.algorithm.mp_transform_q_q_l"><code class="computeroutput"><span class="identifier">mp_transform_q</span><span class="special">&lt;</span><span class="identifier">Q</span><span class="special">,</span> <span class="identifier">L</span><span class="special">...&gt;</span></code></a></span></dt>
<dt><span class="section"><a href="mp11.html#mp11.reference.algorithm.mp_transform_if_p_f_l"><code class="computeroutput"><span class="identifier">mp_transform_if</span><span class="special">&lt;</span><span class="identifier">P</span><span class="special">,</span> <span class="identifier">F</span><span class="special">,</span> <span class="identifier">L</span><span class="special">...&gt;</span></code></a></span></dt>
<dt><span class="section"><a href="mp11.html#mp11.reference.algorithm.mp_transform_if_q_qp_qf_l"><code class="computeroutput"><span class="identifier">mp_transform_if_q</span><span class="special">&lt;</span><span class="identifier">Qp</span><span class="special">,</span> <span class="identifier">Qf</span><span class="special">,</span> <span class="identifier">L</span><span class="special">...&gt;</span></code></a></span></dt>
<dt><span class="section"><a href="mp11.html#mp11.reference.algorithm.mp_fill_l_v"><code class="computeroutput"><span class="identifier">mp_fill</span><span class="special">&lt;</span><span class="identifier">L</span><span class="special">,</span> <span class="identifier">V</span><span class="special">&gt;</span></code></a></span></dt>
<dt><span class="section"><a href="mp11.html#mp11.reference.algorithm.mp_count_l_v"><code class="computeroutput"><span class="identifier">mp_count</span><span class="special">&lt;</span><span class="identifier">L</span><span class="special">,</span> <span class="identifier">V</span><span class="special">&gt;</span></code></a></span></dt>
<dt><span class="section"><a href="mp11.html#mp11.reference.algorithm.mp_count_if_l_p"><code class="computeroutput"><span class="identifier">mp_count_if</span><span class="special">&lt;</span><span class="identifier">L</span><span class="special">,</span> <span class="identifier">P</span><span class="special">&gt;</span></code></a></span></dt>
@@ -861,7 +862,7 @@
<span class="keyword">template</span><span class="special">&lt;</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">V</span><span class="special">&gt;</span> <span class="keyword">auto</span> <span class="identifier">rvisit</span><span class="special">(</span> <span class="identifier">F</span><span class="special">&amp;&amp;</span> <span class="identifier">f</span><span class="special">,</span> <span class="identifier">V</span><span class="special">&amp;&amp;...</span> <span class="identifier">v</span> <span class="special">)</span>
<span class="special">{</span>
<span class="keyword">using</span> <span class="identifier">R</span> <span class="special">=</span> <span class="identifier">mp_unique</span><span class="special">&lt;</span><span class="identifier">mp_product</span><span class="special">&lt;</span><span class="identifier">Qret</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;::</span><span class="keyword">template</span> <span class="identifier">fn</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">remove_reference_t</span><span class="special">&lt;</span><span class="identifier">V</span><span class="special">&gt;...&gt;&gt;;</span>
<span class="keyword">using</span> <span class="identifier">R</span> <span class="special">=</span> <span class="identifier">mp_unique</span><span class="special">&lt;</span><span class="identifier">mp_product_q</span><span class="special">&lt;</span><span class="identifier">Qret</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">remove_reference_t</span><span class="special">&lt;</span><span class="identifier">V</span><span class="special">&gt;...&gt;&gt;;</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">visit</span><span class="special">(</span> <span class="special">[&amp;](</span> <span class="keyword">auto</span><span class="special">&amp;&amp;...</span> <span class="identifier">x</span> <span class="special">){</span> <span class="keyword">return</span> <span class="identifier">R</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">)(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">x</span><span class="special">)&gt;(</span><span class="identifier">x</span><span class="special">)...</span> <span class="special">)</span> <span class="special">);</span> <span class="special">},</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">V</span><span class="special">&gt;(</span> <span class="identifier">v</span> <span class="special">)...</span> <span class="special">);</span>
<span class="special">}</span>
@@ -1526,6 +1527,17 @@
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="mp11.reference.algorithm.mp_transform_if_q_qp_qf_l"></a><a class="link" href="mp11.html#mp11.reference.algorithm.mp_transform_if_q_qp_qf_l" title="mp_transform_if_q&lt;Qp, Qf, L...&gt;"><code class="computeroutput"><span class="identifier">mp_transform_if_q</span><span class="special">&lt;</span><span class="identifier">Qp</span><span class="special">,</span> <span class="identifier">Qf</span><span class="special">,</span> <span class="identifier">L</span><span class="special">...&gt;</span></code></a>
</h4></div></div></div>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Qp</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Qf</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">L</span><span class="special">&gt;</span> <span class="keyword">using</span> <span class="identifier">mp_transform_if_q</span> <span class="special">=</span> <span class="identifier">mp_transform_if</span><span class="special">&lt;</span><span class="identifier">Qp</span><span class="special">::</span><span class="keyword">template</span> <span class="identifier">fn</span><span class="special">,</span> <span class="identifier">Qf</span><span class="special">::</span><span class="keyword">template</span> <span class="identifier">fn</span><span class="special">,</span> <span class="identifier">L</span><span class="special">...&gt;;</span>
</pre>
<p>
As <code class="computeroutput"><span class="identifier">mp_transform_if</span></code>, but
takes a quoted metafunction.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="mp11.reference.algorithm.mp_fill_l_v"></a><a class="link" href="mp11.html#mp11.reference.algorithm.mp_fill_l_v" title="mp_fill&lt;L, V&gt;"><code class="computeroutput"><span class="identifier">mp_fill</span><span class="special">&lt;</span><span class="identifier">L</span><span class="special">,</span> <span class="identifier">V</span><span class="special">&gt;</span></code></a>
</h4></div></div></div>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">L</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">&gt;</span> <span class="keyword">using</span> <span class="identifier">mp_fill</span> <span class="special">=</span> <span class="comment">/*...*/</span><span class="special">;</span>
@@ -1555,7 +1567,7 @@
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">L</span><span class="special">,</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">P</span><span class="special">&gt;</span> <span class="keyword">using</span> <span class="identifier">mp_count_if</span> <span class="special">=</span> <span class="comment">/*...*/</span><span class="special">;</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">mp_count_f</span><span class="special">&lt;</span><span class="identifier">L</span><span class="special">,</span> <span class="identifier">P</span><span class="special">&gt;</span></code> returns <code class="computeroutput"><span class="identifier">mp_size_t</span><span class="special">&lt;</span><span class="identifier">N</span><span class="special">&gt;</span></code>, where <code class="computeroutput"><span class="identifier">N</span></code>
<code class="computeroutput"><span class="identifier">mp_count_if</span><span class="special">&lt;</span><span class="identifier">L</span><span class="special">,</span> <span class="identifier">P</span><span class="special">&gt;</span></code> returns <code class="computeroutput"><span class="identifier">mp_size_t</span><span class="special">&lt;</span><span class="identifier">N</span><span class="special">&gt;</span></code>, where <code class="computeroutput"><span class="identifier">N</span></code>
is the number of elements <code class="computeroutput"><span class="identifier">T</span></code>
of <code class="computeroutput"><span class="identifier">L</span></code> for which <code class="computeroutput"><span class="identifier">mp_to_bool</span><span class="special">&lt;</span><span class="identifier">P</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;</span></code>
is <code class="computeroutput"><span class="identifier">mp_true</span></code>.
@@ -2482,7 +2494,7 @@
each element of <code class="computeroutput"><span class="identifier">tp</span></code> by evaluating
the expression <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="identifier">J</span><span class="special">&gt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">Tp</span><span class="special">&gt;(</span><span class="identifier">tp</span><span class="special">)))</span></code>
for <code class="computeroutput"><span class="identifier">J</span></code> in 0..<code class="computeroutput"><span class="identifier">N</span><span class="special">-</span><span class="number">1</span></code>,
where <code class="computeroutput"><span class="identifier">N</span></code> is <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple_size</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">remove_reference_t</span><span class="special">&lt;</span><span class="identifier">Tp</span><span class="special">&gt;&gt;::</span><span class="identifier">value</span></code>.
where <code class="computeroutput"><span class="identifier">N</span></code> is <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple_size</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">remove_reference</span><span class="special">&lt;</span><span class="identifier">Tp</span><span class="special">&gt;::</span><span class="identifier">type</span><span class="special">&gt;::</span><span class="identifier">value</span></code>.
</p>
<p>
Returns <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">)</span></code>.
@@ -2492,7 +2504,7 @@
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: May 24, 2017 at 02:43:53 GMT</small></p></td>
<td align="left"><p><small>Last revised: May 25, 2017 at 18:31:25 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>

View File

@@ -39,6 +39,12 @@ As `mp_transform`, but takes a quoted metafunction.
`F<T1, T2, ..., Tn>`, and returns the result, where `Ti` are the corresponding elements of `Li`.
[endsect]
[section `mp_transform_if_q<Qp, Qf, L...>`]
template<class Qp, class Qf, class... L> using mp_transform_if_q = mp_transform_if<Qp::template fn, Qf::template fn, L...>;
As `mp_transform_if`, but takes a quoted metafunction.
[endsect]
[section `mp_fill<L, V>`]
template<class L, class V> using mp_fill = /*...*/;
@@ -54,7 +60,7 @@ As `mp_transform`, but takes a quoted metafunction.
[section `mp_count_if<L, P>`]
template<class L, template<class...> class P> using mp_count_if = /*...*/;
`mp_count_f<L, P>` returns `mp_size_t<N>`, where `N` is the number of elements `T` of `L` for which `mp_to_bool<P<T>>` is `mp_true`.
`mp_count_if<L, P>` returns `mp_size_t<N>`, where `N` is the number of elements `T` of `L` for which `mp_to_bool<P<T>>` is `mp_true`.
[endsect]
[section `mp_contains<L, V>`]

View File

@@ -403,7 +403,7 @@ and we're done:
template<class F, class... V> auto rvisit( F&& f, V&&... v )
{
using R = mp_unique<mp_product<Qret<F>::template fn, std::remove_reference_t<V>...>>;
using R = mp_unique<mp_product_q<Qret<F>, 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 )... );
}

View File

@@ -12,7 +12,7 @@
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`.
expression `f(std::get<J>(std::forward<Tp>(tp)))` for `J` in 0..`N-1`, where `N` is `std::tuple_size<typename std::remove_reference<Tp>::type>::value`.
Returns `std::forward<F>(f)`.
[endsect]

View File

@@ -66,17 +66,47 @@ template<template<class...> class F, class... L> struct mp_transform_impl
template<template<class...> class F, template<class...> class L, class... T> struct mp_transform_impl<F, L<T...>>
{
#if BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
template<class... U> struct f { using type = F<U...>; };
using type = L<typename f<T>::type...>;
#else
using type = L<F<T>...>;
#endif
};
template<template<class...> class F, template<class...> class L1, class... T1, template<class...> class L2, class... T2> struct mp_transform_impl<F, L1<T1...>, L2<T2...>>
{
#if BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
template<class... U> struct f { using type = F<U...>; };
using type = L1<typename f<T1, T2>::type...>;
#else
using type = L1<F<T1,T2>...>;
#endif
};
template<template<class...> class F, template<class...> class L1, class... T1, template<class...> class L2, class... T2, template<class...> class L3, class... T3> struct mp_transform_impl<F, L1<T1...>, L2<T2...>, L3<T3...>>
{
#if BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
template<class... U> struct f { using type = F<U...>; };
using type = L1<typename f<T1, T2, T3>::type...>;
#else
using type = L1<F<T1,T2,T3>...>;
#endif
};
#if BOOST_WORKAROUND( BOOST_MSVC, == 1900 ) || BOOST_WORKAROUND( BOOST_GCC, < 40800 )
@@ -125,14 +155,18 @@ namespace detail
template<template<class...> class P, template<class...> class F, class... L> struct mp_transform_if_impl
{
// the stupid quote-unquote dance avoids "pack expansion used as argument for non-pack parameter of alias template"
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
template<class... U> struct _f_ { using type = mp_eval_if<mp_not<mp_invoke<mp_quote<P>, U...>>, mp_first<mp_list<U...>>, mp_quote<F>::template fn, U...>; };
using Qp = mp_quote<P>;
using Qf = mp_quote<F>;
#if BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
template<class... U> struct _f_ { using type = mp_eval_if_q<mp_not<mp_invoke<Qp, U...>>, mp_first<mp_list<U...>>, Qf, U...>; };
template<class... U> using _f = typename _f_<U...>::type;
#else
template<class... U> using _f = mp_eval_if<mp_not<mp_invoke<mp_quote<P>, U...>>, mp_first<mp_list<U...>>, mp_quote<F>::template fn, U...>;
template<class... U> using _f = mp_eval_if_q<mp_not<mp_invoke<Qp, U...>>, mp_first<mp_list<U...>>, Qf, U...>;
#endif
@@ -142,6 +176,7 @@ template<template<class...> class P, template<class...> class F, class... L> str
} // namespace detail
template<template<class...> class P, template<class...> class F, class... L> using mp_transform_if = typename detail::mp_transform_if_impl<P, F, L...>::type;
template<class Qp, class Qf, class... L> using mp_transform_if_q = typename detail::mp_transform_if_impl<Qp::template fn, Qf::template fn, L...>::type;
// mp_fill<L, V>
namespace detail

View File

@@ -35,8 +35,10 @@ run mp_apply_q.cpp : : : $(REQ) ;
run mp_assign.cpp : : : $(REQ) ;
run mp_clear.cpp : : : $(REQ) ;
run mp_transform.cpp : : : $(REQ) ;
run mp_transform_q.cpp : : : $(REQ) ;
run mp_transform_sf.cpp : : : $(REQ) ;
run mp_transform_if.cpp : : : $(REQ) ;
run mp_transform_if_q.cpp : : : $(REQ) ;
run mp_fill.cpp : : : $(REQ) ;
run mp_count.cpp : : : $(REQ) ;
run mp_count_if.cpp : : : $(REQ) ;

View File

@@ -0,0 +1,87 @@
// 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/algorithm.hpp>
#include <boost/mp11/list.hpp>
#include <boost/mp11/integral.hpp>
#include <boost/mp11/utility.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <type_traits>
#include <tuple>
#include <utility>
struct X1 {};
struct X2 {};
struct X3 {};
struct X4 {};
using boost::mp11::mp_not;
using boost::mp11::mp_quote;
template<class T> using add_pointer = T*;
using Q_add_pointer = mp_quote<add_pointer>;
template<class T, class...> using is_not_ref = mp_not<std::is_reference<T>>;
using Q_is_not_ref = mp_quote<is_not_ref>;
template<class T1, class T2> using second = T2;
using Q_second = mp_quote<second>;
template<class T1, class T2, class T3> using third = T3;
using Q_third = mp_quote<third>;
template<class T1, class T2, class T3, class T4> using fourth = T4;
using Q_fourth = mp_quote<fourth>;
template<class T1, class T2, class T3, class T4, class T5> using fifth = T5;
using Q_fifth = mp_quote<fifth>;
int main()
{
using boost::mp11::mp_list;
using boost::mp11::mp_transform_if_q;
using boost::mp11::mp_size_t;
using boost::mp11::mp_size;
using boost::mp11::mp_fill;
using boost::mp11::mp_iota;
using L1 = mp_list<X1, X2&, X3 const, X4 const&>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_if_q<Q_is_not_ref, Q_add_pointer, L1>, mp_list<X1*, X2&, X3 const*, X4 const&>>));
using L2 = std::tuple<X1, X2&, X3 const, X4 const&>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_if_q<Q_is_not_ref, Q_add_pointer, L2>, std::tuple<X1*, X2&, X3 const*, X4 const&>>));
using L3 = std::pair<X1 const, X2&>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_if_q<Q_is_not_ref, Q_add_pointer, L3>, std::pair<X1 const*, X2&>>));
//
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_if_q<Q_is_not_ref, Q_second, L1, mp_fill<L1, void>>, mp_list<void, X2&, void, X4 const&>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_if_q<Q_is_not_ref, Q_second, L2, mp_fill<L2, void>>, std::tuple<void, X2&, void, X4 const&>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_if_q<Q_is_not_ref, Q_second, L3, mp_fill<L3, void>>, std::pair<void, X2&>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_if_q<Q_is_not_ref, Q_third, L1, L1, mp_iota<mp_size<L1>>>, mp_list<mp_size_t<0>, X2&, mp_size_t<2>, X4 const&>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_if_q<Q_is_not_ref, Q_third, L2, L2, mp_iota<mp_size<L2>>>, std::tuple<mp_size_t<0>, X2&, mp_size_t<2>, X4 const&>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_if_q<Q_is_not_ref, Q_third, L3, L3, mp_iota<mp_size<L3>>>, std::pair<mp_size_t<0>, X2&>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_if_q<Q_is_not_ref, Q_fourth, L1, L1, L1, mp_iota<mp_size<L1>>>, mp_list<mp_size_t<0>, X2&, mp_size_t<2>, X4 const&>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_if_q<Q_is_not_ref, Q_fourth, L2, L2, L2, mp_iota<mp_size<L2>>>, std::tuple<mp_size_t<0>, X2&, mp_size_t<2>, X4 const&>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_if_q<Q_is_not_ref, Q_fourth, L3, L3, L3, mp_iota<mp_size<L3>>>, std::pair<mp_size_t<0>, X2&>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_if_q<Q_is_not_ref, Q_fifth, L1, L1, L1, L1, mp_iota<mp_size<L1>>>, mp_list<mp_size_t<0>, X2&, mp_size_t<2>, X4 const&>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_if_q<Q_is_not_ref, Q_fifth, L2, L2, L2, L2, mp_iota<mp_size<L2>>>, std::tuple<mp_size_t<0>, X2&, mp_size_t<2>, X4 const&>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_if_q<Q_is_not_ref, Q_fifth, L3, L3, L3, L3, mp_iota<mp_size<L3>>>, std::pair<mp_size_t<0>, X2&>>));
//
return boost::report_errors();
}

114
test/mp_transform_q.cpp Normal file
View File

@@ -0,0 +1,114 @@
// 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/utility.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <type_traits>
#include <tuple>
#include <utility>
struct X1 {};
struct X2 {};
struct X3 {};
struct X4 {};
struct Y1 {};
struct Y2 {};
struct Y3 {};
struct Y4 {};
struct Z1 {};
struct Z2 {};
struct Z3 {};
struct Z4 {};
struct U1 {};
struct U2 {};
struct V1 {};
struct V2 {};
struct W1 {};
struct W2 {};
using boost::mp11::mp_quote;
using boost::mp11::mp_list;
template<class T> using add_pointer = typename std::add_pointer<T>::type;
using Q_add_pointer = mp_quote<add_pointer>;
template<class T, class U> using is_same = typename std::is_same<T, U>::type;
using Q_is_same = mp_quote<is_same>;
using Q_mp_list = mp_quote<mp_list>;
using Q_std_tuple = mp_quote<std::tuple>;
using Q_std_pair = mp_quote<std::pair>;
int main()
{
using boost::mp11::mp_transform_q;
using L1 = mp_list<X1, X2, X3, X4>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_mp_list, L1>, mp_list<mp_list<X1>, mp_list<X2>, mp_list<X3>, mp_list<X4>>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_std_tuple, L1>, mp_list<std::tuple<X1>, std::tuple<X2>, std::tuple<X3>, std::tuple<X4>>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_add_pointer, L1>, mp_list<X1*, X2*, X3*, X4*>>));
using L2 = std::tuple<Y1, Y2, Y3, Y4>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_mp_list, L1, L2>, mp_list<mp_list<X1, Y1>, mp_list<X2, Y2>, mp_list<X3, Y3>, mp_list<X4, Y4>>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_std_tuple, L1, L2>, mp_list<std::tuple<X1, Y1>, std::tuple<X2, Y2>, std::tuple<X3, Y3>, std::tuple<X4, Y4>>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_std_pair, L1, L2>, mp_list<std::pair<X1, Y1>, std::pair<X2, Y2>, std::pair<X3, Y3>, std::pair<X4, Y4>>>));
using L3 = mp_list<Z1, Z2, Z3, Z4>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_mp_list, L1, L2, L3>, mp_list<mp_list<X1, Y1, Z1>, mp_list<X2, Y2, Z2>, mp_list<X3, Y3, Z3>, mp_list<X4, Y4, Z4>>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_std_tuple, L1, L2, L3>, mp_list<std::tuple<X1, Y1, Z1>, std::tuple<X2, Y2, Z2>, std::tuple<X3, Y3, Z3>, std::tuple<X4, Y4, Z4>>>));
//
using L4 = std::tuple<X1, Y2, X3, Y4>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_is_same, L1, L1>, mp_list<std::true_type, std::true_type, std::true_type, std::true_type>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_is_same, L1, L2>, mp_list<std::false_type, std::false_type, std::false_type, std::false_type>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_is_same, L1, L4>, mp_list<std::true_type, std::false_type, std::true_type, std::false_type>>));
//
using L5 = std::pair<X1, X2>;
using L6 = std::pair<Y1, Y2>;
using L7 = std::pair<X1, Y2>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_mp_list, L5>, std::pair<mp_list<X1>, mp_list<X2>>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_mp_list, L5, L6>, std::pair<mp_list<X1, Y1>, mp_list<X2, Y2>>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_mp_list, L5, L6, L7>, std::pair<mp_list<X1, Y1, X1>, mp_list<X2, Y2, Y2>>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_add_pointer, L5>, std::pair<X1*, X2*>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_is_same, L5, L5>, std::pair<std::true_type, std::true_type>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_is_same, L5, L6>, std::pair<std::false_type, std::false_type>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_is_same, L5, L7>, std::pair<std::true_type, std::false_type>>));
//
using L8 = std::pair<Z1, Z2>;
using L9 = std::pair<U1, U2>;
using L10 = std::pair<V1, V2>;
using L11 = std::pair<W1, W2>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_std_tuple, L5, L6, L8, L9>, std::pair<std::tuple<X1, Y1, Z1, U1>, std::tuple<X2, Y2, Z2, U2>>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_std_tuple, L5, L6, L8, L9, L10>, std::pair<std::tuple<X1, Y1, Z1, U1, V1>, std::tuple<X2, Y2, Z2, U2, V2>>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform_q<Q_std_tuple, L5, L6, L8, L9, L10, L11>, std::pair<std::tuple<X1, Y1, Z1, U1, V1, W1>, std::tuple<X2, Y2, Z2, U2, V2, W2>>>));
//
return boost::report_errors();
}