GuillaumeDua / CppShelf

Collection of powerfuls - C++ Single-Header Libraries Files
https://guillaumedua.github.io/CppShelf/
MIT License
9 stars 1 forks source link

[mp] type_traits compositions #160

Open GuillaumeDua opened 8 months ago

GuillaumeDua commented 8 months ago

Motivation

template <typename T>
using not_same_as_int = typename compose<
    std::negation,
    bind_front<std::is_same, int>::type
>::template type<T>;

// bind_front
template <template <typename ...> typename pack, typename ... bounded_args>
struct bind_front {
    template <typename ... Ts>
    using type = pack<bounded_args..., Ts...>;
};

// compose (TODO: remove recursivity ¯\_(ツ)_/¯)
template <template <typename...> typename ... traits>
struct compose;
template <template <typename...> typename traits>
struct compose<traits> {
    template <typename ... Ts>
    using type = typename traits<Ts...>::type;
};
template <
    template <typename...> typename trait,
    template <typename...> typename ... rest
>
struct compose<trait, rest...> {
    template <typename ... Ts>
    using type = trait<typename compose<rest...>::template type<Ts...>>;
};

template <typename T>
using not_same_as_int = typename compose<
    std::negation,
    std::negation,
    std::negation,
    bind_front<std::is_same, int>::type
>::template type<T>;

static_assert(not_same_as_int<char>::value);
static_assert(std::is_same_v<
    not_same_as_int<char>,
    std::negation<std::negation<std::negation<std::integral_constant<bool, false> > > >
>);

static auto _ = []() -> bool {
    std::cout << csl::typeinfo::type_name_v<not_same_as_int<char>> << '\n';
    return {};
}();

Tests:

using only_ints = csl::mp::filters_t<
    csl::mp::bind_back<std::is_same, int>::type,
    pack<char, int, bool, int>
>;
static_assert(std::same_as<only_ints, pack<int, int>>);

using not_ints = csl::mp::filters_t<
    csl::mp::compose<
        std::negation,
        csl::mp::bind_back<std::is_same, int>::type
    >::type,
    pack<char, int, bool, int>
>;
static_assert(std::same_as<not_ints, pack<char, bool>>);