From 64532c4792e5f0cb294dc9346004e44a21466d20 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 16 May 2023 02:37:59 +0300 Subject: [PATCH] Add support for (homogeneous) value lists to mp_append. Refs #53. --- include/boost/mp11/detail/mp_append.hpp | 50 +++++++++++++++- .../boost/mp11/detail/mp_is_value_list.hpp | 41 +++++++++++++ test/Jamfile | 1 + test/mp_append_3.cpp | 60 +++++++++++++++++++ 4 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 include/boost/mp11/detail/mp_is_value_list.hpp create mode 100644 test/mp_append_3.cpp diff --git a/include/boost/mp11/detail/mp_append.hpp b/include/boost/mp11/detail/mp_append.hpp index 937d15e..840a524 100644 --- a/include/boost/mp11/detail/mp_append.hpp +++ b/include/boost/mp11/detail/mp_append.hpp @@ -8,6 +8,8 @@ // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt +#include +#include #include #include #include @@ -153,6 +155,44 @@ template< using type = typename mp_append_impl::type; }; +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template struct append_value_impl +{ +}; + +template class L, auto... A> +struct append_value_impl> +{ + using type = L; +}; + +template class L1, auto... A1, template class L2, auto... A2> +struct append_value_impl, L2> +{ + using type = L1; +}; + +template class L1, auto... A1, template class L2, auto... A2, template class L3, auto... A3> +struct append_value_impl, L2, L3> +{ + using type = L1; +}; + +template class L1, auto... A1, template class L2, auto... A2, template class L3, auto... A3, template class L4, auto... A4> +struct append_value_impl, L2, L3, L4> +{ + using type = L1; +}; + +template class L1, auto... A1, template class L2, auto... A2, template class L3, auto... A3, template class L4, auto... A4, template class L5, auto... A5, class... Lr> +struct append_value_impl, L2, L3, L4, L5, Lr...> +{ + using type = typename append_value_impl, Lr...>::type; +}; + +#endif + #if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 ) template @@ -167,7 +207,15 @@ template struct mp_append_impl: mp_append_impl_cuda_workaround #else -template struct mp_append_impl: mp_if_c<(sizeof...(L) > 111), mp_quote, mp_if_c<(sizeof...(L) > 11), mp_quote, mp_quote > >::template fn +template struct mp_append_impl: + mp_cond< +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + mp_bool<(sizeof...(L) > 0 && sizeof...(L) == mp_count_if, mp_is_value_list>::value)>, mp_quote, +#endif + mp_bool<(sizeof...(L) > 111)>, mp_quote, + mp_bool<(sizeof...(L) > 11)>, mp_quote, + mp_true, mp_quote + >::template fn { }; diff --git a/include/boost/mp11/detail/mp_is_value_list.hpp b/include/boost/mp11/detail/mp_is_value_list.hpp new file mode 100644 index 0000000..8f94f03 --- /dev/null +++ b/include/boost/mp11/detail/mp_is_value_list.hpp @@ -0,0 +1,41 @@ +#ifndef BOOST_MP11_DETAIL_MP_IS_VALUE_LIST_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_IS_VALUE_LIST_HPP_INCLUDED + +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +namespace boost +{ +namespace mp11 +{ + +// mp_is_value_list +namespace detail +{ + +template struct mp_is_value_list_impl +{ + using type = mp_false; +}; + +#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +template class L, auto... A> struct mp_is_value_list_impl> +{ + using type = mp_true; +}; + +#endif + +} // namespace detail + +template using mp_is_value_list = typename detail::mp_is_value_list_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_IS_VALUE_LIST_HPP_INCLUDED diff --git a/test/Jamfile b/test/Jamfile index 62bb206..e6b8d2a 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -49,6 +49,7 @@ run mp_rename.cpp ; run mp_rename_2.cpp ; run mp_append.cpp ; run mp_append_2.cpp ; +run mp_append_3.cpp ; run mp_append_sf.cpp ; run mp_replace_front.cpp ; run mp_replace_front_2.cpp ; diff --git a/test/mp_append_3.cpp b/test/mp_append_3.cpp new file mode 100644 index 0000000..2f134e6 --- /dev/null +++ b/test/mp_append_3.cpp @@ -0,0 +1,60 @@ +// Copyright 2023 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +#if !defined(BOOST_MP11_HAS_TEMPLATE_AUTO) + +#pragma message("Test skipped because BOOST_MP11_HAS_TEMPLATE_AUTO is not defined") +int main() {} + +#else + +#include + +template struct L1 {}; +template struct L2 {}; + +int main() +{ + using boost::mp11::mp_list_v; + using boost::mp11::mp_append; + + // + + { + using L1 = mp_list_v; + using L2 = mp_list_v; + using L3 = mp_list_v; + using L4 = mp_list_v; + + BOOST_TEST_TRAIT_SAME(mp_append, mp_list_v); + BOOST_TEST_TRAIT_SAME(mp_append, mp_list_v); + BOOST_TEST_TRAIT_SAME(mp_append, mp_list_v); + BOOST_TEST_TRAIT_SAME(mp_append, mp_list_v); + } + + // + + BOOST_TEST_TRAIT_SAME(mp_append>, L1<>); + BOOST_TEST_TRAIT_SAME(mp_append, L2<1>>, L1<1>); + BOOST_TEST_TRAIT_SAME(mp_append, L2<1>, L1>, L1<1, true>); + BOOST_TEST_TRAIT_SAME(mp_append, L2<1>, L1, L2<2>>, L1<1, true, 2>); + BOOST_TEST_TRAIT_SAME(mp_append, L2<1>, L1, L2<2>, L1>, L1<1, true, 2, false>); + BOOST_TEST_TRAIT_SAME(mp_append, L2<1>, L1, L2<2>, L1, L2<3>>, L1<1, true, 2, false, 3>); + + // + + BOOST_TEST_TRAIT_SAME(mp_append>, L2<1>); + BOOST_TEST_TRAIT_SAME(mp_append, L2<2>>, L2<1, 2>); + BOOST_TEST_TRAIT_SAME(mp_append, L2<2>, L2<3>>, L2<1, 2, 3>); + BOOST_TEST_TRAIT_SAME(mp_append, L2<2>, L2<3>, L2<4>>, L2<1, 2, 3, 4>); + BOOST_TEST_TRAIT_SAME(mp_append, L2<2>, L2<3>, L2<4>, L2<5>>, L2<1, 2, 3, 4, 5>); + + // + + return boost::report_errors(); +} + +#endif