<commit_before>#pragma once

#include <gcl/mp/type_traits.hpp>
#include <tuple>
#include <array>
#include <algorithm>

namespace gcl::mp::type_traits
{
    template <template <typename ...> class T, typename ... Ts>
    class pack_arguments_as {
        template <template <typename...> class PackType, typename... PackArgs>
        constexpr static auto impl(PackType<PackArgs...>)
        {
            return T<PackArgs...>{};
        }
        template <typename... PackArgs>
        constexpr static auto impl(PackArgs...)
        {
            return T<PackArgs...>{};
        }
      public:
        using type = decltype(impl(std::declval<Ts>()...));
    };
    template <template <typename ...> class T, typename ... Ts>
    using pack_arguments_as_t = typename pack_arguments_as<T, Ts...>::type;

    template <typename T, typename U>
    struct concatenate;
    template <template <typename...> typename T, typename ... Ts, typename ... Us>
    struct concatenate<T<Ts...>, T<Us...>>
    {
        using type = T<Ts..., Us...>;
    };
    template <typename T, typename U>
    using concatenate_t = typename concatenate<T,U>::type;

    template <std::size_t N, typename... Ts>
    using type_at = typename std::tuple_element<N, std::tuple<Ts...>>;
    template <std::size_t N, typename... Ts>
    using type_at_t = typename type_at<N, Ts...>::type;

    template <typename to_find, typename pack_type>
    class index_of {
        template <auto distance_algorithm, template <typename...> class PackType, typename... PackArgs>
        consteval static auto impl(PackType<PackArgs...>)
        {
            constexpr auto index =
                []<typename TupleType, std::size_t... I>(TupleType, std::index_sequence<I...>) consteval
            {
                constexpr std::array<bool, sizeof...(I)> matches = {
                    std::is_same_v<to_find, std::tuple_element_t<I, TupleType>>...};
                static_assert(std::size(matches) == sizeof...(I));
                using matches_iterator_type = decltype(std::cbegin(matches));
                return distance_algorithm(matches);
            }
            (std::tuple<PackArgs...>{}, std::make_index_sequence<sizeof...(PackArgs)>{});<commit_msg>[mp::pack_traits] : arguments_index_sequence_t<commit_after>#pragma once

#include <gcl/mp/type_traits.hpp>
#include <tuple>
#include <array>
#include <algorithm>

namespace gcl::mp::type_traits
{
    template <template <typename ...> class T, typename ... Ts>
    class pack_arguments_as {
        template <template <typename...> class PackType, typename... PackArgs>
        constexpr static auto impl(PackType<PackArgs...>)
        {
            return T<PackArgs...>{};
        }
        template <typename... PackArgs>
        constexpr static auto impl(PackArgs...)
        {
            return T<PackArgs...>{};
        }
      public:
        using type = decltype(impl(std::declval<Ts>()...));
    };
    template <template <typename ...> class T, typename ... Ts>
    using pack_arguments_as_t = typename pack_arguments_as<T, Ts...>::type;
    template <template <typename ...> class T, typename ... Ts>
    using arguments_index_sequence_t = decltype(std::make_index_sequence<std::tuple_size_v<pack_arguments_as_t<std::tuple, Ts...>>>{});

    template <typename T, typename U>
    struct concatenate;
    template <template <typename...> typename T, typename ... Ts, typename ... Us>
    struct concatenate<T<Ts...>, T<Us...>>
    {
        using type = T<Ts..., Us...>;
    };
    template <typename T, typename U>
    using concatenate_t = typename concatenate<T,U>::type;

    template <std::size_t N, typename... Ts>
    using type_at = typename std::tuple_element<N, std::tuple<Ts...>>;
    template <std::size_t N, typename... Ts>
    using type_at_t = typename type_at<N, Ts...>::type;

    template <template <typename...> class T, typename... Ts>
    struct trait_as_mask {

        constexpr static auto value = []<typename... PackArgs>(std::tuple<PackArgs...>) consteval
        {
            using TupleType = std::tuple<PackArgs...>;
            return []<std::size_t... I>(std::index_sequence<I...>) consteval
            {
                return std::array<bool, sizeof...(I)>{T<std::tuple_element_t<I, TupleType>>::value...};
            }
            (std::make_index_sequence<sizeof...(PackArgs)>{});
        }
        (arguments_as_t<std::tuple, Ts...>{});
    };
    template <template <typename...> class T, typename... Ts>
    constexpr static auto trait_as_mask_v = trait_as_mask<T, Ts...>::value;

    template <typename to_find, typename pack_type>
    class index_of {
        template <auto distance_algorithm, template <typename...> class PackType, typename... PackArgs>
        consteval static auto impl(PackType<PackArgs...>)
        {
            constexpr auto index =
                []<typename TupleType, std::size_t... I>(TupleType, std::index_sequence<I...>) consteval
            {
                constexpr std::array<bool, sizeof...(I)> matches = {
                    std::is_same_v<to_find, std::tuple_element_t<I, TupleType>>...};
                static_assert(std::size(matches) == sizeof...(I));
                using matches_iterator_type = decltype(std::cbegin(matches));
                return distance_algorithm(matches);
            }
            (std::tuple<PackArgs...>{}, std::make_index_sequence<sizeof...(PackArgs)>{});
{'fraction_non_alphanumeric': 0.15826408125577102, 'fraction_numerical': 0.0, 'mean_word_length': 2.4629156010230178, 'pattern_counts': {'":': 0, '<': 105, '<?xml version=': 0, '>': 105, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5502083', 'n_tokens_mistral': 1645, 'n_tokens_neox': 1568, 'n_words': 366}