GuillaumeDua / CppShelf

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

[mp] starts_with #169

Open GuillaumeDua opened 9 months ago

GuillaumeDua commented 9 months ago

Benchmarked by #170


template <typename pack_1, typename pack_2>
struct starts_with : std::false_type{};
template <
    template <typename ...> typename pack,
    typename ... Ts, typename ... Us
>
requires (sizeof...(Ts) >= sizeof...(Us))
struct starts_with<pack<Ts...>, pack<Us...>> : std::is_same<
    take_n_t<sizeof...(Us), pack<Ts...>>,
    pack<Us...>
>{};
template <typename pack_1, typename pack_2>
constexpr auto starts_with_v = starts_with<pack_1, pack_2>::value;

vs.

template <typename P1, typename P2>
struct starts_with : std::false_type{};

template <
    typename pack_1,
    template <typename ...> typename pack_2,
    typename ... Ts
>
struct starts_with<pack_1, pack_2<Ts...>>
: decltype(overloaded{
        [](auto){ return std::false_type{}; },
        []<
            template <typename ...> typename p1,
            typename ... Us
        >(p1<Ts..., Us...>){ return std::true_type{}; }
    }(std::declval<pack_1>()))
{};
template <typename P1, typename P2>
constexpr auto starts_with_v = starts_with<P1, P2>::value;

vs.

template <typename P1, typename P2>
struct starts_with : std::false_type{};

template <
    typename pack_1,
    template <typename ...> typename pack_2,
    typename ... Ts
>
class starts_with<pack_1, pack_2<Ts...>>{
    template <typename T>
    static auto impl(T){ return std::false_type{}; }
    template <
        template <typename ...> typename p1,
        typename ... Us
    >
    static auto impl(p1<Ts..., Us...>){ return std::true_type{}; }

public:
    constexpr static auto value = decltype(impl(std::declval<pack_1>()))::value;
};
template <typename P1, typename P2>
constexpr auto starts_with_v = starts_with<P1, P2>::value;

template <typename P1, typename P2>
struct starts_with : std::false_type{};

template <
    typename pack_1,
    template <typename ...> typename pack_2,
    typename ... Ts
>
class starts_with<pack_1, pack_2<Ts...>>{
    template <typename T>
    static auto impl(T) -> std::false_type;
    template <
        template <typename ...> typename p1,
        typename ... Us
    >
    static auto impl(p1<Ts..., Us...>) -> std::true_type;

public:
    constexpr static auto value = decltype(impl(std::declval<pack_1>()))::value;
};
template <typename P1, typename P2>
constexpr auto starts_with_v = starts_with<P1, P2>::value;