Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b21ff00
optimize mp_transform_if (extract f from the struct to benefit from m…
jonathanpoelen Jun 19, 2023
94162fb
optimize mp_filter (extract f from the struct to benefit from memoiza…
jonathanpoelen Jun 19, 2023
225f679
optimize mp_drop (extract f from the struct to benefit from memoization)
jonathanpoelen Jun 19, 2023
88314f6
optimize mp_sort (extract f from the struct to benefit from memoization)
jonathanpoelen Jun 19, 2023
a76ce80
optimize mp_replace_at (extract f from the struct to benefit from mem…
jonathanpoelen Jun 19, 2023
f6768fe
optimize mp_power_set (extract f from the struct to benefit from memo…
jonathanpoelen Jun 19, 2023
7fe4395
optimize mp_map_find (extract f from the struct to benefit from memoi…
jonathanpoelen Jun 19, 2023
de54a2b
optimize mp_map_update (extract f from the struct to benefit from mem…
jonathanpoelen Jun 19, 2023
a1ba7c2
optimize mp_map_erase (extract f from the struct to benefit from memo…
jonathanpoelen Jun 19, 2023
e8e9705
optimize mp_map_replace
jonathanpoelen Jun 19, 2023
49747e7
fix mp_map_update with msvc-12
jonathanpoelen Jun 22, 2023
2c96255
fix mp_replace_at with msvc-12
jonathanpoelen Jun 22, 2023
18415c7
fix mp_replace_at with msvc-12
jonathanpoelen Jul 5, 2023
a018e3a
replace ::template f with quoted metafunctions and _q variants
jonathanpoelen Nov 3, 2025
51c1366
inlining mp_transform_if_impl and mp_map_erase_impl
jonathanpoelen Nov 8, 2025
fd96b45
optimize mp_nth_element
jonathanpoelen Nov 8, 2025
6e1bf5f
optimize mp_map_find_impl gcc workaround
jonathanpoelen Nov 8, 2025
f61cb65
disable mp_map_find_impl gcc workaround with >=14.4 and >=15.2
jonathanpoelen Nov 8, 2025
6d4088f
optimize mp_transform with 5 lists or more
jonathanpoelen Nov 8, 2025
61b9d6e
optimize mp_fill
jonathanpoelen Nov 9, 2025
ffeb694
optimize mp_replace_if
jonathanpoelen Nov 9, 2025
be1393e
optimize mp_replace
jonathanpoelen Nov 9, 2025
8d807a8
optimize mp_remove
jonathanpoelen Nov 9, 2025
99b8ff6
optimize mp_sliding_fold
jonathanpoelen Nov 9, 2025
72365c2
optimize mp_copy_if
jonathanpoelen Nov 9, 2025
2cded73
optimize mp_remove_if
jonathanpoelen Nov 9, 2025
d70897f
optimize mp_map_replace
jonathanpoelen Nov 9, 2025
4e9f1a1
optimize integer_sequence with gcc
jonathanpoelen Nov 9, 2025
4b54d24
optimize integer_sequence when no builtin is available
jonathanpoelen Nov 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 67 additions & 36 deletions include/boost/mp11/algorithm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,13 @@ template<class Q, class... L> using mp_transform_q = mp_transform<Q::template fn
namespace detail
{

template<class V, class T> using mp_transform_push_back = mp_transform<mp_push_back, V, T>;

template<template<class...> class F, template<class...> class L1, class... T1, template<class...> class L2, class... T2, template<class...> class L3, class... T3, template<class...> class L4, class... T4, class... L> struct mp_transform_impl<F, L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>, L...>
{
using A1 = L1<mp_list<T1, T2, T3, T4>...>;

template<class V, class T> using _f = mp_transform<mp_push_back, V, T>;

using A2 = mp_fold<mp_list<L...>, A1, _f>;
using A2 = mp_fold<mp_list<L...>, A1, mp_transform_push_back>;

template<class T> using _g = mp_apply<F, T>;

Expand All @@ -172,7 +172,7 @@ template<template<class...> class F, template<class...> class L1, class... T1, t
namespace detail
{

template<template<class...> class P, template<class...> class F, class... L> struct mp_transform_if_impl
template<template<class...> class P, template<class...> class F> struct mp_transform_if_impl
{
// the stupid quote-unquote dance avoids "pack expansion used as argument for non-pack parameter of alias template"

Expand All @@ -181,34 +181,35 @@ template<template<class...> class P, template<class...> class F, class... L> str

#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )

template<class... U> struct _f_ { using type = mp_eval_if_q<mp_not<mp_invoke_q<Qp, U...>>, mp_first<mp_list<U...>>, Qf, U...>; };
template<class... U> using _f = typename _f_<U...>::type;
template<class... U> struct _f { using type = mp_eval_if_q<mp_not<mp_invoke_q<Qp, U...>>, mp_first<mp_list<U...>>, Qf, U...>; };
template<class... U> using fn = typename _f<U...>::type;

#else

template<class... U> using _f = mp_eval_if_q<mp_not<mp_invoke_q<Qp, U...>>, mp_first<mp_list<U...>>, Qf, U...>;
template<class... U> using fn = mp_eval_if_q<mp_not<mp_invoke_q<Qp, U...>>, mp_first<mp_list<U...>>, Qf, U...>;

#endif

using type = mp_transform<_f, L...>;
};

} // 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;
template<template<class...> class P, template<class...> class F, class... L> using mp_transform_if = mp_transform_q<detail::mp_transform_if_impl<P, F>, L...>;
template<class Qp, class Qf, class... L> using mp_transform_if_q = mp_transform_q<detail::mp_transform_if_impl<Qp::template fn, Qf::template fn>, L...>;

// mp_filter<P, L...>
namespace detail
{

template<template<class...> class P, class L1, class... L> struct mp_filter_impl
template<template<class...> class P> struct mp_filter_impl_f
{
using Qp = mp_quote<P>;

template<class T1, class... T> using _f = mp_if< mp_invoke_q<Qp, T1, T...>, mp_list<T1>, mp_list<> >;
template<class T1, class... T> using fn = mp_if<mp_invoke_q<Qp, T1, T...>, mp_list<T1>, mp_list<> >;
};

using _t1 = mp_transform<_f, L1, L...>;
template<template<class...> class P, class L1, class... L> struct mp_filter_impl
{
using _t1 = mp_transform_q<mp_filter_impl_f<P>, L1, L...>;
using _t2 = mp_apply<mp_append, _t1>;

using type = mp_assign<L1, _t2>;
Expand All @@ -228,6 +229,8 @@ template<class L, class V> struct mp_fill_impl
// An error "no type named 'type'" here means that the L argument of mp_fill is not a list
};

template<class T, class> using mp_fill_first_item = T;

template<template<class...> class L, class... T, class V> struct mp_fill_impl<L<T...>, V>
{
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1900 )
Expand All @@ -237,8 +240,7 @@ template<template<class...> class L, class... T, class V> struct mp_fill_impl<L<

#else

template<class...> using _f = V;
using type = L<_f<T>...>;
using type = L<mp_fill_first_item<V, T>...>;

#endif
};
Expand Down Expand Up @@ -329,11 +331,14 @@ namespace detail

template<class L, class L2, class En> struct mp_drop_impl;

template<template<class...> class L, class... T, template<class...> class L2, class... U> struct mp_drop_impl<L<T...>, L2<U...>, mp_true>
template<template<class...> class L, class... U> struct mp_drop_impl_f
{
template<class... W> static mp_identity<L<W...>> f( U*..., mp_identity<W>*... );
};

using R = decltype( f( static_cast<mp_identity<T>*>(0) ... ) );
template<template<class...> class L, class... T, template<class...> class L2, class... U> struct mp_drop_impl<L<T...>, L2<U...>, mp_true>
{
using R = decltype( mp_drop_impl_f<L, U...>::f( static_cast<mp_identity<T>*>(0) ... ) );

using type = typename R::type;
};
Expand Down Expand Up @@ -524,8 +529,7 @@ template<template<class...> class L, class... T, class V, class W> struct mp_rep
template<class A> struct _f { using type = mp_if<std::is_same<A, V>, W, A>; };
using type = L<typename _f<T>::type...>;
#else
template<class A> using _f = mp_if<std::is_same<A, V>, W, A>;
using type = L<_f<T>...>;
using type = L<mp_if<std::is_same<T, V>, W, T>...>;
#endif
};

Expand All @@ -545,8 +549,7 @@ template<template<class...> class L, class... T, template<class...> class P, cla
template<class U> struct _f { using type = mp_if<P<U>, W, U>; };
using type = L<typename _f<T>::type...>;
#else
template<class U> using _f = mp_if<P<U>, W, U>;
using type = L<_f<T>...>;
using type = L<mp_if<P<T>, W, T>...>;
#endif
};

Expand All @@ -570,8 +573,7 @@ template<template<class...> class L, class... T, class V> struct mp_remove_impl<
template<class U> struct _f { using type = mp_if<std::is_same<U, V>, mp_list<>, mp_list<U>>; };
using type = mp_append<L<>, typename _f<T>::type...>;
#else
template<class U> using _f = mp_if<std::is_same<U, V>, mp_list<>, mp_list<U>>;
using type = mp_append<L<>, _f<T>...>;
using type = mp_append<L<>, mp_if<std::is_same<T, V>, mp_list<>, mp_list<T>>...>;
#endif
};

Expand Down Expand Up @@ -639,11 +641,14 @@ template<template<class...> class L, class T1, template<class...> class P> struc
using type = L<T1>;
};

template<template<class...> class L, class T1, class... T, template<class...> class P> struct mp_sort_impl<L<T1, T...>, P>
template<class T1, template<class...> class P> struct mp_sort_impl_f
{
template<class U> using F = P<U, T1>;
template<class U> using fn = P<U, T1>;
};

using part = mp_partition<L<T...>, F>;
template<template<class...> class L, class T1, class... T, template<class...> class P> struct mp_sort_impl<L<T1, T...>, P>
{
using part = mp_partition_q<L<T...>, mp_sort_impl_f<T1, P>>;

using S1 = typename mp_sort_impl<mp_first<part>, P>::type;
using S2 = typename mp_sort_impl<mp_second<part>, P>::type;
Expand Down Expand Up @@ -672,9 +677,7 @@ template<template<class...> class L, class T1, class... T, std::size_t I, templa
{
static_assert( I < 1 + sizeof...(T), "mp_nth_element index out of range" );

template<class U> using F = P<U, T1>;

using part = mp_partition<L<T...>, F>;
using part = mp_partition_q<L<T...>, mp_sort_impl_f<T1, P>>;

using L1 = mp_first<part>;
static std::size_t const N1 = mp_size<L1>::value;
Expand Down Expand Up @@ -1030,14 +1033,36 @@ template<class L, class Q> using mp_any_of_q = mp_any_of<L, Q::template fn>;
namespace detail
{

#if ! BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )

template<class I> struct mp_replace_at_impl_p
{
template<class T1, class T2> using fn = std::is_same<T2, I>;
};

template<class W> struct mp_replace_at_impl_f
{
template<class T1, class T2> using fn = W;
};

#endif

template<class L, class I, class W> struct mp_replace_at_impl
{
static_assert( I::value >= 0, "mp_replace_at<L, I, W>: I must not be negative" );

#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )

template<class T1, class T2> using _p = std::is_same<T2, mp_size_t<I::value>>;
template<class T1, class T2> using _f = W;

using type = mp_transform_if<_p, _f, L, mp_iota<mp_size<L> > >;

#else

using type = mp_transform_if_q<mp_replace_at_impl_p<mp_size_t<I::value>>, mp_replace_at_impl_f<W>, L, mp_iota<mp_size<L> > >;

#endif
};

} // namespace detail
Expand Down Expand Up @@ -1182,13 +1207,16 @@ template<template<class...> class L> struct mp_power_set_impl< L<> >

#endif

template<class T1> struct mp_power_set_impl_f
{
template<class L2> using fn = mp_push_front<L2, T1>;
};

template<template<class...> class L, class T1, class... T> struct mp_power_set_impl< L<T1, T...> >
{
using S1 = mp_power_set< L<T...> >;

template<class L2> using _f = mp_push_front<L2, T1>;

using S2 = mp_transform<_f, S1>;
using S2 = mp_transform_q<mp_power_set_impl_f<T1>, S1>;

using type = mp_append< S1, S2 >;
};
Expand Down Expand Up @@ -1260,15 +1288,18 @@ template<class L, template<class...> class F> using mp_pairwise_fold = mp_pairwi
namespace detail
{

template<class L, std::size_t M> struct mp_sliding_fold_impl_f
{
template<class I> using fn = mp_slice_c<L, I::value, I::value + M>;
};

template<class C, class L, class Q, class S> struct mp_sliding_fold_impl;

template<class L, class N, class Q> struct mp_sliding_fold_impl<mp_true, L, N, Q>
{
static const std::size_t M = mp_size<L>::value - N::value + 1;

template<class I> using F = mp_slice_c<L, I::value, I::value + M>;

using J = mp_transform<F, mp_iota<N>>;
using J = mp_transform_q<mp_sliding_fold_impl_f<L, M>, mp_iota<N>>;

using type = mp_apply<mp_transform_q, mp_push_front<J, Q>>;
};
Expand Down
3 changes: 1 addition & 2 deletions include/boost/mp11/detail/mp_copy_if.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ template<template<class...> class L, class... T, template<class...> class P> str
template<class U> struct _f { using type = mp_if<P<U>, mp_list<U>, mp_list<>>; };
using type = mp_append<L<>, typename _f<T>::type...>;
#else
template<class U> using _f = mp_if<P<U>, mp_list<U>, mp_list<>>;
using type = mp_append<L<>, _f<T>...>;
using type = mp_append<L<>, mp_if<P<T>, mp_list<T>, mp_list<>>...>;
#endif
};

Expand Down
26 changes: 17 additions & 9 deletions include/boost/mp11/detail/mp_map_find.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
#include <boost/mp11/utility.hpp>
#include <boost/mp11/detail/config.hpp>

#if BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, >= 140000 )
#if (BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, >= 140000 ) && BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 140400 )) \
|| (BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, >= 150000 ) && BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 150200 ))

#include <boost/mp11/detail/mp_list.hpp>
#include <boost/mp11/detail/mp_append.hpp>
Expand All @@ -34,20 +35,24 @@ namespace boost
namespace mp11
{

#if BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, >= 140000 )
#if (BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, >= 140000 ) && BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 140400 )) \
|| (BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, >= 150000 ) && BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 150200 ))

// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120161

namespace detail
{

template<class K, class T> struct mp_map_find_impl_k
{
using type = mp_if<std::is_same<mp_front<T>, K>, mp_list<T>, mp_list<>>;
};

template<class M, class K> struct mp_map_find_impl;

template<template<class...> class M, class... T, class K> struct mp_map_find_impl<M<T...>, K>
{
template<class U> using _f = mp_if<std::is_same<mp_front<U>, K>, mp_list<U>, mp_list<>>;

using _l = mp_append<_f<T>..., mp_list<void>>;
using _l = mp_append<typename mp_map_find_impl_k<K, T>::type..., mp_list<void>>;

using type = mp_front<_l>;
};
Expand Down Expand Up @@ -99,14 +104,17 @@ template<class T> using mpmf_unwrap = typename mpmf_unwrap_impl<T>::type;

template<class M, class K> struct mp_map_find_impl;

template<template<class...> class M, class... T, class K> struct mp_map_find_impl<M<T...>, K>
template<class K> struct mp_map_find_impl_f
{
using U = mp_inherit<mpmf_wrap<T>...>;

template<template<class...> class L, class... U> static mp_identity<L<K, U...>> f( mp_identity<L<K, U...>>* );
static mp_identity<void> f( ... );
};

template<template<class...> class M, class... T, class K> struct mp_map_find_impl<M<T...>, K>
{
using U = mp_inherit<mpmf_wrap<T>...>;

using type = mpmf_unwrap< decltype( f( static_cast<U*>(0) ) ) >;
using type = mpmf_unwrap< decltype( mp_map_find_impl_f<K>::f( static_cast<U*>(0) ) ) >;
};

} // namespace detail
Expand Down
3 changes: 1 addition & 2 deletions include/boost/mp11/detail/mp_remove_if.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ template<template<class...> class L, class... T, template<class...> class P> str
template<class U> struct _f { using type = mp_if<P<U>, mp_list<>, mp_list<U>>; };
using type = mp_append<L<>, typename _f<T>::type...>;
#else
template<class U> using _f = mp_if<P<U>, mp_list<>, mp_list<U>>;
using type = mp_append<L<>, _f<T>...>;
using type = mp_append<L<>, mp_if<P<T>, mp_list<>, mp_list<T>>...>;
#endif
};

Expand Down
Loading
Loading