-
Notifications
You must be signed in to change notification settings - Fork 94
Open
Description
Example could be found below or on godbolt. boost::mp11::mp_transform is not SFINAE friendly on transform error. It is SFINAE friendly on size mismatch though. It would be very helpful in constraints if it is SFINAE friendly.
template<template<typename...> typename F, typename... List>
concept has_boost_mp_transform = requires { typename boost::mp11::mp_transform<F, List...>; };
static_assert(!has_boost_mp_transform<std::remove_cvref_t, boost::mp11::mp_list<int&, double const>, std::tuple<short, int const&>>); // invalid transform. Does not compile.
static_assert(!has_boost_mp_transform<std::common_type_t, boost::mp11::mp_list<char*, float>, boost::mp11::mp_list<int, double>>); // invalid transform result. Does not compile.
static_assert(!has_boost_mp_transform<std::common_type_t, boost::mp11::mp_list<short, float>, boost::mp11::mp_list<int, double, char>>); // size mismatch. Compiles.
An example implementation for c++20 could be found below or on godbolt.
namespace no_adl {
template<template<typename...> typename F, typename List0, typename... List>
struct mp_transform_impl {};
template<template<typename...> typename F, template<typename...> typename TList0, typename... List>
struct mp_transform_impl<F, TList0<>, List...> {
using type = TList0<>;
};
template<template<typename...> typename F, template<typename...> typename TList0, typename T0, typename... T, typename... List> requires
requires { typename F<T0, boost::mp11::mp_front<List>...>; } &&
requires { typename mp_transform_impl<F, TList0<T...>, boost::mp11::mp_pop_front<List>...>::type; }
struct mp_transform_impl<F, TList0<T0, T...>, List...> {
using type = boost::mp11::mp_append<
TList0<F<T0, boost::mp11::mp_front<List>...>>,
typename mp_transform_impl<F, TList0<T...>, boost::mp11::mp_pop_front<List>...>::type
>;
};
template<template<typename...> typename F, typename... List>
requires boost::mp11::mp_same<boost::mp11::mp_size<List>...>::value && (0<sizeof...(List))
struct mp_transform: mp_transform_impl<F, List...> {};
}
template<template<typename...> typename F, typename... List>
using mp_transform = typename no_adl::mp_transform<F, List...>::type;
Metadata
Metadata
Assignees
Labels
No labels