Skip to content

Improve compilation speed by taking advantage of memoization #79

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
61 changes: 49 additions & 12 deletions include/boost/mp11/algorithm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,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_f
{
// the stupid quote-unquote dance avoids "pack expansion used as argument for non-pack parameter of alias template"

Expand All @@ -165,8 +165,11 @@ template<template<class...> class P, template<class...> class F, class... L> str
template<class... U> using _f = 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...>;
template<template<class...> class P, template<class...> class F, class... L> struct mp_transform_if_impl
{
using type = mp_transform<mp_transform_if_impl_f<P, F>::template _f, L...>;
};

} // namespace detail
Expand All @@ -178,13 +181,16 @@ template<class Qp, class Qf, class... L> using mp_transform_if_q = typename deta
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<> >;
};

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

using type = mp_assign<L1, _t2>;
Expand Down Expand Up @@ -305,11 +311,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 @@ -606,11 +615,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 f = 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<L<T...>, mp_sort_impl_f<T1, P>::template f>;

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 @@ -1035,14 +1047,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 _p = std::is_same<T2, I>;
};

template<class W> struct mp_replace_at_impl_f
{
template<class T1, class T2> using _f = 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<mp_replace_at_impl_p<mp_size_t<I::value>>::template _p, mp_replace_at_impl_f<W>::template _f, L, mp_iota<mp_size<L> > >;

#endif
};

} // namespace detail
Expand Down Expand Up @@ -1187,13 +1221,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 _f = 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<mp_power_set_impl_f<T1>::template _f, S1>;

using type = mp_append< S1, S2 >;
};
Expand Down
11 changes: 7 additions & 4 deletions include/boost/mp11/detail/mp_map_find.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,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
41 changes: 38 additions & 3 deletions include/boost/mp11/map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,19 @@ template<template<class...> class M, class... U, class T> struct mp_map_replace_
{
using K = mp_first<T>;

// mp_replace_if is inlined here using a struct _f because of msvc-14.0
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )

template<class V> struct _f { using type = mp_if< std::is_same<mp_first<V>, K>, T, V >; };

using type = mp_if< mp_map_contains<M<U...>, K>, M<typename _f<U>::type...>, M<U..., T> >;

#else

template<class V> using _f = mp_if< std::is_same<mp_first<V>, K>, T, V >;

using type = mp_if< mp_map_contains<M<U...>, K>, M<_f<U>...>, M<U..., T> >;

#endif
};

} // namespace detail
Expand All @@ -53,14 +61,37 @@ template<class M, class T> using mp_map_replace = typename detail::mp_map_replac
namespace detail
{

#if ! BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )

template<class T> struct mp_map_update_impl_f
{
template<class U> using _f = std::is_same<mp_first<T>, mp_first<U>>;
};

template<template<class...> class F> struct mp_map_update_impl_f3
{
// _f3<L<X, Y...>> -> L<X, F<X, Y...>>
template<class L> using _f3 = mp_assign<L, mp_list<mp_first<L>, mp_rename<L, F> > >;
};

#endif

template<class M, class T, template<class...> class F> struct mp_map_update_impl
{
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )

template<class U> using _f = std::is_same<mp_first<T>, mp_first<U>>;

// _f3<L<X, Y...>> -> L<X, F<X, Y...>>
template<class L> using _f3 = mp_assign<L, mp_list<mp_first<L>, mp_rename<L, F> > >;

using type = mp_if< mp_map_contains<M, mp_first<T>>, mp_transform_if<_f, _f3, M>, mp_push_back<M, T> >;

#else

using type = mp_if< mp_map_contains<M, mp_first<T>>, mp_transform_if<mp_map_update_impl_f<T>::template _f, mp_map_update_impl_f3<F>::template _f3, M>, mp_push_back<M, T> >;

#endif
};

} // namespace detail
Expand All @@ -72,10 +103,14 @@ template<class M, class T, class Q> using mp_map_update_q = mp_map_update<M, T,
namespace detail
{

template<class M, class K> struct mp_map_erase_impl
template<class K> struct mp_map_erase_impl_f
{
template<class T> using _f = std::is_same<mp_first<T>, K>;
using type = mp_remove_if<M, _f>;
};

template<class M, class K> struct mp_map_erase_impl
{
using type = mp_remove_if<M, mp_map_erase_impl_f<K>::template _f>;
};

} // namespace detail
Expand Down