From 4efda72a347f0795f69338ab5e70a7ef693cb73b Mon Sep 17 00:00:00 2001 From: Jonathan Poelen Date: Mon, 19 Jun 2023 22:51:22 +0200 Subject: [PATCH 01/13] optimize mp_transform_if (extract f from the struct to benefit from memoization) compiler | gcc-12 | clang-15 before | 0:00.13s - 60432K | 0:00.16s - 100956K after | 0:00.11s - 47300K | 0:00.16s - 100484K ```cpp using namespace boost::mp11; template using p = mp_bool; template using f = mp_size_t; template using test = mp_transform_if>; using r1 = mp_transform>; ``` --- include/boost/mp11/algorithm.hpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index be377f5a..6f4ae014 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -148,7 +148,7 @@ template class F, template class L1, class... T1, t namespace detail { -template class P, template class F, class... L> struct mp_transform_if_impl +template class P, template class F> struct mp_transform_if_impl_f { // the stupid quote-unquote dance avoids "pack expansion used as argument for non-pack parameter of alias template" @@ -165,8 +165,11 @@ template class P, template class F, class... L> str template using _f = mp_eval_if_q>, mp_first>, Qf, U...>; #endif +}; - using type = mp_transform<_f, L...>; +template class P, template class F, class... L> struct mp_transform_if_impl +{ + using type = mp_transform::template _f, L...>; }; } // namespace detail From b131e3f6890336b66853daa1136678bf97ec03b2 Mon Sep 17 00:00:00 2001 From: Jonathan Poelen Date: Mon, 19 Jun 2023 22:54:44 +0200 Subject: [PATCH 02/13] optimize mp_filter (extract f from the struct to benefit from memoization) compiler | gcc-12 | clang-15 before | 0:00.16s - 72460K | 0:00.16s - 102068K after | 0:00.14s - 61884K | 0:00.16s - 101828K ```cpp using namespace boost::mp11; template using p = mp_bool; template using test = mp_filter>; using r1 = mp_transform>; ``` --- include/boost/mp11/algorithm.hpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index 6f4ae014..b0054b8a 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -181,13 +181,16 @@ template using mp_transform_if_q = typename deta namespace detail { -template class P, class L1, class... L> struct mp_filter_impl +template class P> struct mp_filter_impl_f { using Qp = mp_quote

; template using _f = mp_if< mp_invoke_q, mp_list, mp_list<> >; +}; - using _t1 = mp_transform<_f, L1, L...>; +template class P, class L1, class... L> struct mp_filter_impl +{ + using _t1 = mp_transform::template _f, L1, L...>; using _t2 = mp_apply; using type = mp_assign; From bdfc8d1c1af2a6dd58a582313cb81270a86630ef Mon Sep 17 00:00:00 2001 From: Jonathan Poelen Date: Mon, 19 Jun 2023 23:07:13 +0200 Subject: [PATCH 03/13] optimize mp_drop (extract f from the struct to benefit from memoization) compiler | gcc-12 | clang-15 before | 0:00.48s - 192464K | 0:00.48s - 154480K after | 0:00.43s - 172472K | 0:00.46s - 150404K ```cpp template struct f { template using g = mp_drop; }; template> using test = mp_transform::template g, L>; using r1 = mp_transform>; ``` --- include/boost/mp11/algorithm.hpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index b0054b8a..1d9c128f 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -311,11 +311,14 @@ namespace detail template struct mp_drop_impl; -template class L, class... T, template class L2, class... U> struct mp_drop_impl, L2, mp_true> +template class L, class... U> struct mp_drop_impl_f { template static mp_identity> f( U*..., mp_identity*... ); +}; - using R = decltype( f( static_cast*>(0) ... ) ); +template class L, class... T, template class L2, class... U> struct mp_drop_impl, L2, mp_true> +{ + using R = decltype( mp_drop_impl_f::f( static_cast*>(0) ... ) ); using type = typename R::type; }; From 12a80bd61bade3ac90efb538e9192a5c29aab197 Mon Sep 17 00:00:00 2001 From: Jonathan Poelen Date: Mon, 19 Jun 2023 23:11:21 +0200 Subject: [PATCH 04/13] optimize mp_sort (extract f from the struct to benefit from memoization) compiler | gcc-12 | clang-15 before | 0:00.46s - 198848K | 0:00.49s - 132632K after | 0:00.42s - 183384K | 0:00.48s - 131748K ```cpp using namespace boost::mp11; template using test = mp_sort, mp_less>; using r1 = mp_transform>; ``` --- include/boost/mp11/algorithm.hpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index 1d9c128f..a746c95b 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -615,11 +615,14 @@ template class L, class T1, template class P> struc using type = L; }; -template class L, class T1, class... T, template class P> struct mp_sort_impl, P> +template class P> struct mp_sort_impl_f { - template using F = P; + template using f = P; +}; - using part = mp_partition, F>; +template class L, class T1, class... T, template class P> struct mp_sort_impl, P> +{ + using part = mp_partition, mp_sort_impl_f::template f>; using S1 = typename mp_sort_impl, P>::type; using S2 = typename mp_sort_impl, P>::type; From 33f6c727cad0777d77bffa6772cf1e9c3f70e192 Mon Sep 17 00:00:00 2001 From: Jonathan Poelen Date: Mon, 19 Jun 2023 23:33:12 +0200 Subject: [PATCH 05/13] optimize mp_replace_at (extract f from the struct to benefit from memoization) compiler | gcc-12 | clang-15 before | 0:00.34s - 134428K | 0:00.33s - 124720K after | 0:00.29s - 116920K | 0:00.32s - 122568K ```cpp using namespace boost::mp11; template using f = mp_replace_at, I, void>; template using test = mp_transform>; using r1 = mp_transform>; ``` --- include/boost/mp11/algorithm.hpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index a746c95b..5620120f 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -1047,14 +1047,22 @@ template using mp_any_of_q = mp_any_of; namespace detail { +template struct mp_replace_at_impl_p +{ + template using _p = std::is_same; +}; + +template struct mp_replace_at_impl_f +{ + template using _f = W; +}; + template struct mp_replace_at_impl { static_assert( I::value >= 0, "mp_replace_at: I must not be negative" ); - template using _p = std::is_same>; - template using _f = W; - using type = mp_transform_if<_p, _f, L, mp_iota > >; + using type = mp_transform_if>::template _p, mp_replace_at_impl_f::template _f, L, mp_iota > >; }; } // namespace detail From c479059e41aff595467071419b03ba565e13e455 Mon Sep 17 00:00:00 2001 From: Jonathan Poelen Date: Mon, 19 Jun 2023 23:33:29 +0200 Subject: [PATCH 06/13] optimize mp_power_set (extract f from the struct to benefit from memoization) compiler | gcc-12 | clang-15 before | 0:01.35s - 538732K | 0:00.65s - 203924K after | 0:01.02s - 396032K | 0:00.65s - 203080K ```cpp using namespace boost::mp11; template using test = mp_power_set>; using r1 = mp_transform>; ``` --- include/boost/mp11/algorithm.hpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index 5620120f..c5c4072a 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -1207,13 +1207,16 @@ template class L> struct mp_power_set_impl< L<> > #endif +template struct mp_power_set_impl_f +{ + template using _f = mp_push_front; +}; + template class L, class T1, class... T> struct mp_power_set_impl< L > { using S1 = mp_power_set< L >; - template using _f = mp_push_front; - - using S2 = mp_transform<_f, S1>; + using S2 = mp_transform::template _f, S1>; using type = mp_append< S1, S2 >; }; From 5c466a96ea85df4a6078cde47432b31502f8f46e Mon Sep 17 00:00:00 2001 From: Jonathan Poelen Date: Mon, 19 Jun 2023 23:42:04 +0200 Subject: [PATCH 07/13] optimize mp_map_find (extract f from the struct to benefit from memoization) compiler | gcc-12 | clang-15 before | 0:00.29s - 128600K | 0:00.25s - 120604K after | 0:00.22s - 99908K | 0:00.23s - 116084K ```cpp using namespace boost::mp11; template> struct f { template using g = mp_map_find; }; template> using test = mp_transform::template g, L>; using r1 = mp_transform>; ``` --- include/boost/mp11/detail/mp_map_find.hpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/include/boost/mp11/detail/mp_map_find.hpp b/include/boost/mp11/detail/mp_map_find.hpp index 2fb70d8e..c51964c2 100644 --- a/include/boost/mp11/detail/mp_map_find.hpp +++ b/include/boost/mp11/detail/mp_map_find.hpp @@ -67,14 +67,17 @@ template using mpmf_unwrap = typename mpmf_unwrap_impl::type; template struct mp_map_find_impl; -template class M, class... T, class K> struct mp_map_find_impl, K> +template struct mp_map_find_impl_f { - using U = mp_inherit...>; - template class L, class... U> static mp_identity> f( mp_identity>* ); static mp_identity f( ... ); +}; + +template class M, class... T, class K> struct mp_map_find_impl, K> +{ + using U = mp_inherit...>; - using type = mpmf_unwrap< decltype( f( static_cast(0) ) ) >; + using type = mpmf_unwrap< decltype( mp_map_find_impl_f::f( static_cast(0) ) ) >; }; } // namespace detail From 480189d36edc983520d9cdd67129e7770af6ea13 Mon Sep 17 00:00:00 2001 From: Jonathan Poelen Date: Mon, 19 Jun 2023 23:49:26 +0200 Subject: [PATCH 08/13] optimize mp_map_update (extract f from the struct to benefit from memoization) compiler | gcc-12 | clang-15 before | 0:00.73s - 270224K | 0:00.54s - 156112K after | 0:00.19s - 85004K | 0:00.29s - 119232K ```cpp using namespace boost::mp11; template> struct f { template using g = mp_map_update, mp_list>; }; template> using test = mp_transform::template g, L>; using r1 = mp_transform>; ``` --- include/boost/mp11/map.hpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/include/boost/mp11/map.hpp b/include/boost/mp11/map.hpp index b9581ac9..a60119d0 100644 --- a/include/boost/mp11/map.hpp +++ b/include/boost/mp11/map.hpp @@ -53,14 +53,20 @@ template using mp_map_replace = typename detail::mp_map_replac namespace detail { -template class F> struct mp_map_update_impl +template struct mp_map_update_impl_f { template using _f = std::is_same, mp_first>; +}; +template class F> struct mp_map_update_impl_f3 +{ // _f3> -> L> template using _f3 = mp_assign, mp_rename > >; +}; - using type = mp_if< mp_map_contains>, mp_transform_if<_f, _f3, M>, mp_push_back >; +template class F> struct mp_map_update_impl +{ + using type = mp_if< mp_map_contains>, mp_transform_if::template _f, mp_map_update_impl_f3::template _f3, M>, mp_push_back >; }; } // namespace detail From 29246d3e11d45c9dae4c26406451e9690f81b3b9 Mon Sep 17 00:00:00 2001 From: Jonathan Poelen Date: Mon, 19 Jun 2023 23:49:33 +0200 Subject: [PATCH 09/13] optimize mp_map_erase (extract f from the struct to benefit from memoization) compiler | gcc-12 | clang-15 before | 0:00.52s - 197128K | 0:00.44s - 140780K after | 0:00.47s - 183968K | 0:00.43s - 139336K ```cpp using namespace boost::mp11; template> struct f { template using g = mp_map_erase; }; template> using test = mp_transform::template g, L>; using r1 = mp_transform>; ``` --- include/boost/mp11/map.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/include/boost/mp11/map.hpp b/include/boost/mp11/map.hpp index a60119d0..79bb3d2b 100644 --- a/include/boost/mp11/map.hpp +++ b/include/boost/mp11/map.hpp @@ -78,10 +78,14 @@ template using mp_map_update_q = mp_map_update struct mp_map_erase_impl +template struct mp_map_erase_impl_f { template using _f = std::is_same, K>; - using type = mp_remove_if; +}; + +template struct mp_map_erase_impl +{ + using type = mp_remove_if::template _f>; }; } // namespace detail From de1ca6fa3e14359dd2850133cf9538d9a04374b2 Mon Sep 17 00:00:00 2001 From: Jonathan Poelen Date: Tue, 20 Jun 2023 01:42:00 +0200 Subject: [PATCH 10/13] optimize mp_map_replace compiler | gcc-12 | clang-15 before | 0:00.46s - 187160K | 0:00.38s - 129104K after | 0:00.21s - 80236K | 0:00.33s - 123644K ```cpp using namespace boost::mp11; template> struct f { template using g = mp_map_replace>; }; template> using test = mp_transform::template g, L>; using r1 = mp_transform>; ``` --- include/boost/mp11/map.hpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/boost/mp11/map.hpp b/include/boost/mp11/map.hpp index 79bb3d2b..f561698d 100644 --- a/include/boost/mp11/map.hpp +++ b/include/boost/mp11/map.hpp @@ -38,11 +38,19 @@ template class M, class... U, class T> struct mp_map_replace_ { using K = mp_first; - // mp_replace_if is inlined here using a struct _f because of msvc-14.0 +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) template struct _f { using type = mp_if< std::is_same, K>, T, V >; }; using type = mp_if< mp_map_contains, K>, M::type...>, M >; + +#else + + template using _f = mp_if< std::is_same, K>, T, V >; + + using type = mp_if< mp_map_contains, K>, M<_f...>, M >; + +#endif }; } // namespace detail From 09d7a0e73ba0860c6aacad0524680e0283c84e04 Mon Sep 17 00:00:00 2001 From: Jonathan Poelen Date: Fri, 23 Jun 2023 00:44:13 +0200 Subject: [PATCH 11/13] fix mp_map_update with msvc-12 --- include/boost/mp11/map.hpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/include/boost/mp11/map.hpp b/include/boost/mp11/map.hpp index f561698d..e7a08304 100644 --- a/include/boost/mp11/map.hpp +++ b/include/boost/mp11/map.hpp @@ -61,6 +61,8 @@ template using mp_map_replace = typename detail::mp_map_replac namespace detail { +#if ! BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) + template struct mp_map_update_impl_f { template using _f = std::is_same, mp_first>; @@ -72,9 +74,24 @@ template class F> struct mp_map_update_impl_f3 template using _f3 = mp_assign, mp_rename > >; }; +#endif + template class F> struct mp_map_update_impl { +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) + + template using _f = std::is_same, mp_first>; + + // _f3> -> L> + template using _f3 = mp_assign, mp_rename > >; + + using type = mp_if< mp_map_contains>, mp_transform_if<_f, _f3, M>, mp_push_back >; + +#else + using type = mp_if< mp_map_contains>, mp_transform_if::template _f, mp_map_update_impl_f3::template _f3, M>, mp_push_back >; + +#endif }; } // namespace detail From 45fbe8a07d53141f303693c625aee244d98f37d2 Mon Sep 17 00:00:00 2001 From: Jonathan Poelen Date: Fri, 23 Jun 2023 01:18:48 +0200 Subject: [PATCH 12/13] fix mp_replace_at with msvc-12 --- include/boost/mp11/algorithm.hpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index c5c4072a..87f8f645 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -1047,6 +1047,8 @@ template using mp_any_of_q = mp_any_of; namespace detail { +#if ! BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) + template struct mp_replace_at_impl_p { template using _p = std::is_same; @@ -1057,12 +1059,24 @@ template struct mp_replace_at_impl_f template using _f = W; }; +#endif + template struct mp_replace_at_impl { static_assert( I::value >= 0, "mp_replace_at: I must not be negative" ); +#if ! BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) + + template using _p = std::is_same>; + template using _f = W; + + using type = mp_transform_if<_p, _f, L, mp_iota > >; + +#else using type = mp_transform_if>::template _p, mp_replace_at_impl_f::template _f, L, mp_iota > >; + +#endif }; } // namespace detail From 7f478ea9ce73bde48e9cf45e70381b1beac1a0fb Mon Sep 17 00:00:00 2001 From: Jonathan Poelen Date: Wed, 5 Jul 2023 23:20:13 +0200 Subject: [PATCH 13/13] fix mp_replace_at with msvc-12 --- include/boost/mp11/algorithm.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index 87f8f645..e866d60a 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -1065,7 +1065,7 @@ template struct mp_replace_at_impl { static_assert( I::value >= 0, "mp_replace_at: I must not be negative" ); -#if ! BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) template using _p = std::is_same>; template using _f = W;