diff --git a/doc/mp11/utility.adoc b/doc/mp11/utility.adoc index d5bb622..7a9777a 100644 --- a/doc/mp11/utility.adoc +++ b/doc/mp11/utility.adoc @@ -295,7 +295,7 @@ As `mp_not_fn`, but takes a quoted metafunction. `mp_compose` is a quoted metafunction that applies `F1`, `F2`, ..., `Fn` to its argument, in sequence. That is, -`mp_compose::fn` is `Fn<...F2>...>`. +`mp_compose::fn` is `Fn<...F2>...>`. ## mp_compose_q diff --git a/include/boost/mp11/detail/mp_front.hpp b/include/boost/mp11/detail/mp_front.hpp new file mode 100644 index 0000000..2183f15 --- /dev/null +++ b/include/boost/mp11/detail/mp_front.hpp @@ -0,0 +1,42 @@ +#ifndef BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED + +// Copyright 2015-2021 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 + +namespace boost +{ +namespace mp11 +{ + +// mp_front +namespace detail +{ + +template struct mp_front_impl +{ +// An error "no type named 'type'" here means that the argument to mp_front +// is either not a list, or is an empty list +}; + +template class L, class T1, class... T> struct mp_front_impl> +{ + using type = T1; +}; + +} // namespace detail + +template using mp_front = typename detail::mp_front_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED diff --git a/include/boost/mp11/detail/mp_rename.hpp b/include/boost/mp11/detail/mp_rename.hpp new file mode 100644 index 0000000..d05f6f7 --- /dev/null +++ b/include/boost/mp11/detail/mp_rename.hpp @@ -0,0 +1,43 @@ +#ifndef BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED + +// Copyright 2015-2021 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 + +namespace boost +{ +namespace mp11 +{ + +// mp_rename +namespace detail +{ + +template class B> struct mp_rename_impl +{ +// An error "no type named 'type'" here means that the first argument to mp_rename is not a list +}; + +template class A, class... T, template class B> struct mp_rename_impl, B> +{ + using type = B; +}; + +} // namespace detail + +template class B> using mp_rename = typename detail::mp_rename_impl::type; + +template class F, class L> using mp_apply = typename detail::mp_rename_impl::type; + +template using mp_apply_q = typename detail::mp_rename_impl::type; + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED diff --git a/include/boost/mp11/list.hpp b/include/boost/mp11/list.hpp index e0d3e29..6572a62 100644 --- a/include/boost/mp11/list.hpp +++ b/include/boost/mp11/list.hpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include @@ -66,23 +68,7 @@ template using mp_assign = typename detail::mp_assign_impl using mp_clear = mp_assign>; // mp_front -namespace detail -{ - -template struct mp_front_impl -{ -// An error "no type named 'type'" here means that the argument to mp_front -// is either not a list, or is an empty list -}; - -template class L, class T1, class... T> struct mp_front_impl> -{ - using type = T1; -}; - -} // namespace detail - -template using mp_front = typename detail::mp_front_impl::type; +// in detail/mp_front.hpp // mp_pop_front namespace detail @@ -184,26 +170,9 @@ template class L, class... U, class... T> struct mp_push_back template using mp_push_back = typename detail::mp_push_back_impl::type; // mp_rename -namespace detail -{ - -template class B> struct mp_rename_impl -{ -// An error "no type named 'type'" here means that the first argument to mp_rename is not a list -}; - -template class A, class... T, template class B> struct mp_rename_impl, B> -{ - using type = B; -}; - -} // namespace detail - -template class B> using mp_rename = typename detail::mp_rename_impl::type; - -template class F, class L> using mp_apply = typename detail::mp_rename_impl::type; - -template using mp_apply_q = typename detail::mp_rename_impl::type; +// mp_apply +// mp_apply_q +// in detail/mp_rename.hpp // mp_replace_front namespace detail diff --git a/include/boost/mp11/utility.hpp b/include/boost/mp11/utility.hpp index 533009a..b3fa7a9 100644 --- a/include/boost/mp11/utility.hpp +++ b/include/boost/mp11/utility.hpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include namespace boost @@ -233,7 +235,7 @@ template using mp_not_fn_q = mp_not_fn; namespace detail { -template using mp_reverse_invoke_q = mp_invoke_q; +template using mp_compose_helper = mp_list< mp_apply_q >; } // namespace detail @@ -241,14 +243,14 @@ template using mp_reverse_invoke_q = mp_invoke_q; template class... F> struct mp_compose { - template using fn = mp_fold...>, T, detail::mp_reverse_invoke_q>; + template using fn = mp_front< mp_fold...>, mp_list, detail::mp_compose_helper> >; }; #endif template struct mp_compose_q { - template using fn = mp_fold, T, detail::mp_reverse_invoke_q>; + template using fn = mp_front< mp_fold, mp_list, detail::mp_compose_helper> >; }; } // namespace mp11 diff --git a/test/mp_compose.cpp b/test/mp_compose.cpp index 46184a6..57a86ed 100644 --- a/test/mp_compose.cpp +++ b/test/mp_compose.cpp @@ -4,6 +4,7 @@ // https://www.boost.org/LICENSE_1_0.txt +#include #include #include @@ -15,6 +16,8 @@ template using G1 = F1; template using G2 = F2; template using G3 = F3; +template struct H {}; + int main() { using namespace boost::mp11; @@ -32,6 +35,10 @@ int main() BOOST_TEST_TRAIT_TRUE((std::is_same::fn, F3>>>)); BOOST_TEST_TRAIT_TRUE((std::is_same::fn, F3>>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, H>)); + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, F1>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, G1>>>)); + #endif using QF1 = mp_quote; @@ -42,6 +49,8 @@ int main() using QG2 = mp_quote; using QG3 = mp_quote; + using QH = mp_quote; + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, void>)); BOOST_TEST_TRAIT_TRUE((std::is_same::fn, F1>)); @@ -53,6 +62,10 @@ int main() BOOST_TEST_TRAIT_TRUE((std::is_same::fn, F3>>>)); BOOST_TEST_TRAIT_TRUE((std::is_same::fn, F3>>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, H>)); + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, F1>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same::fn, G1>>>)); + // return boost::report_errors();