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(); +}