<commit_before>#pragma once

#include <tuple>

namespace kgr {
namespace detail {

template <typename T>
struct function_traits
	: function_traits<decltype(&T::operator())>
{};

template <typename Type, typename R, typename... Args>
struct function_traits<R(Type::*)(Args...) const> {
	using return_type = R;
	using argument_types = std::tuple<Args...>;
	template<int n> using argument_type = typename std::tuple_element<n, argument_types>::type;
};

template <typename Type, typename R, typename... Args>
struct function_traits<R(Type::*)(Args...)> {
	using return_type = R;
	using argument_types = std::tuple<Args...>;
	template<int n> using argument_type = typename std::tuple_element<n, argument_types>::type;
};

template <typename R, typename... Args>
struct function_traits<R(*)(Args...)> {
	using return_type = R;
	using argument_types = std::tuple<Args...>;
	template<int n> using argument_type = typename std::tuple_element<n, argument_types>::type;
};

template <typename... F>
using function_arguments_t = typename function_traits<F...>::argument_types;

template <typename... F>
using function_result_t = typename function_traits<F...>::return_type;

template <int n, typename... F>
using function_argument_t = typename function_traits<F...>::template argument_type<n>;<commit_msg>no need for variadic template<commit_after>#pragma once

#include <tuple>

namespace kgr {
namespace detail {

template <typename T>
struct function_traits
	: function_traits<decltype(&T::operator())>
{};

template <typename Type, typename R, typename... Args>
struct function_traits<R(Type::*)(Args...) const> {
	using return_type = R;
	using argument_types = std::tuple<Args...>;
	template<int n> using argument_type = typename std::tuple_element<n, argument_types>::type;
};

template <typename Type, typename R, typename... Args>
struct function_traits<R(Type::*)(Args...)> {
	using return_type = R;
	using argument_types = std::tuple<Args...>;
	template<int n> using argument_type = typename std::tuple_element<n, argument_types>::type;
};

template <typename R, typename... Args>
struct function_traits<R(*)(Args...)> {
	using return_type = R;
	using argument_types = std::tuple<Args...>;
	template<int n> using argument_type = typename std::tuple_element<n, argument_types>::type;
};

template <typename F>
using function_arguments_t = typename function_traits<F>::argument_types;

template <typename F>
using function_result_t = typename function_traits<F>::return_type;

template <int n, typename F>
using function_argument_t = typename function_traits<F>::template argument_type<n>;
{'fraction_non_alphanumeric': 0.14617169373549885, 'fraction_numerical': 0.0, 'mean_word_length': 6.126721763085399, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 53, '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': '6804151', 'n_tokens_mistral': 821, 'n_tokens_neox': 781, 'n_words': 209}