<commit_before>#ifndef VAST_UTIL_META_H
#define VAST_UTIL_META_H

#include <memory>
#include <type_traits>
#include <caf/detail/type_list.hpp>

namespace vast {
namespace util {

/// Computes the maximum over a variadic list of types according to a given
/// higher-order metafunction.
template <template <typename> class F, typename Head>
constexpr decltype(F<Head>::value) max()
{
  return F<Head>::value;
}

template <
  template <typename> class F, typename Head, typename Next, typename... Tail
>
constexpr decltype(F<Head>::value) max()
{
  return max<F, Head>() > max<F, Next, Tail...>()
    ? max<F, Head>()
    : max<F, Next, Tail...>();
}

namespace detail {

struct can_call
{
  template <typename F, typename... A>
  static auto test(int)
    -> decltype(std::declval<F>()(std::declval<A>()...), std::true_type());

  template <typename, typename...>
  static auto test(...) -> std::false_type;
};

} // namespace detail

template <typename F, typename... A>
struct callable : decltype(detail::can_call::test<F, A...>(0)) {};

template <typename F, typename... A>
struct callable <F(A...)> : callable<F, A...> {};

template <typename... A, typename F>
constexpr callable<F, A...> is_callable_with(F&&)
{
  return callable<F(A...)>{};
}

// Integral bool
template <bool B, typename...>
using bool_t = typename std::integral_constant<bool, B>::type;

// Negation
template <typename T>
using not_t = bool_t<! T::value>;

// Same as above, but takes a value as boolean expression.
template <typename If, typename Then, typename Else>
using if_then_else = std::conditional_t<If::value, Then, Else>;

// Disjunction.
template <typename...>
struct any : bool_t<false> {};

template <typename Head, typename... Tail>
struct any<Head, Tail...> : if_then_else<Head, bool_t<true>, any<Tail...>> { };

// Conjunction
template <typename...>
struct all : bool_t<true> { };

template <typename Head, typename... Tail>
struct all<Head, Tail...> : if_then_else<Head, all<Tail...>, bool_t<false>> { };

// SFINAE helpers
namespace detail { enum class enabler { }; }

template <bool B, typename T = void>
using disable_if = std::enable_if<! B, T>;

template <bool B, typename T = void>
using disable_if_t = typename disable_if<B, T>::type;

template <typename A, typename B>
using is_same_or_derived = std::is_base_of<A, std::remove_reference_t<B>>;

/// @see http://bit.ly/uref-copy.
template <typename A, typename B>
using disable_if_same_or_derived = disable_if<is_same_or_derived<A, B>::value>;

template <typename A, typename B>
using disable_if_same_or_derived_t =
  typename disable_if_same_or_derived<A, B>::type;

template <typename... Ts>
using disable_if_all = disable_if_t<all<Ts...>::value, detail::enabler>;

template <typename T, typename U, typename R = T>
using enable_if_same = std::enable_if_t<std::is_same<T, U>::value, R>;

template <typename T, typename U, typename R = T>
using disable_if_same = disable_if_t<std::is_same<T, U>::value, R>;

template <typename T>
using unqualified = std::remove_cv_t<std::remove_reference_t<T>>;

//
// Various meta functions mostly used to sfinae out certain types.
//<commit_msg>Add meta function to deduce forwarding references.<commit_after>#ifndef VAST_UTIL_META_H
#define VAST_UTIL_META_H

#include <memory>
#include <type_traits>
#include <caf/detail/type_list.hpp>

namespace vast {
namespace util {

/// Computes the maximum over a variadic list of types according to a given
/// higher-order metafunction.
template <template <typename> class F, typename Head>
constexpr decltype(F<Head>::value) max()
{
  return F<Head>::value;
}

template <
  template <typename> class F, typename Head, typename Next, typename... Tail
>
constexpr decltype(F<Head>::value) max()
{
  return max<F, Head>() > max<F, Next, Tail...>()
    ? max<F, Head>()
    : max<F, Next, Tail...>();
}

namespace detail {

struct can_call
{
  template <typename F, typename... A>
  static auto test(int)
    -> decltype(std::declval<F>()(std::declval<A>()...), std::true_type());

  template <typename, typename...>
  static auto test(...) -> std::false_type;
};

} // namespace detail

template <typename F, typename... A>
struct callable : decltype(detail::can_call::test<F, A...>(0)) {};

template <typename F, typename... A>
struct callable <F(A...)> : callable<F, A...> {};

template <typename... A, typename F>
constexpr callable<F, A...> is_callable_with(F&&)
{
  return callable<F(A...)>{};
}

// Integral bool
template <bool B, typename...>
using bool_t = typename std::integral_constant<bool, B>::type;

// Negation
template <typename T>
using not_t = bool_t<! T::value>;

// Same as above, but takes a value as boolean expression.
template <typename If, typename Then, typename Else>
using if_then_else = std::conditional_t<If::value, Then, Else>;

// Disjunction.
template <typename...>
struct any : bool_t<false> {};

template <typename Head, typename... Tail>
struct any<Head, Tail...> : if_then_else<Head, bool_t<true>, any<Tail...>> { };

// Conjunction
template <typename...>
struct all : bool_t<true> { };

template <typename Head, typename... Tail>
struct all<Head, Tail...> : if_then_else<Head, all<Tail...>, bool_t<false>> { };

// SFINAE helpers
namespace detail { enum class enabler { }; }

template <bool B, typename T = void>
using disable_if = std::enable_if<! B, T>;

template <bool B, typename T = void>
using disable_if_t = typename disable_if<B, T>::type;

template <typename A, typename B>
using is_same_or_derived = std::is_base_of<A, std::remove_reference_t<B>>;

/// @see http://bit.ly/uref-copy.
template <typename A, typename B>
using disable_if_same_or_derived = disable_if<is_same_or_derived<A, B>::value>;

template <typename A, typename B>
using disable_if_same_or_derived_t =
  typename disable_if_same_or_derived<A, B>::type;

template <typename... Ts>
using disable_if_all = disable_if_t<all<Ts...>::value, detail::enabler>;

template <typename T, typename U, typename R = T>
using enable_if_same = std::enable_if_t<std::is_same<T, U>::value, R>;

template <typename T, typename U, typename R = T>
using disable_if_same = disable_if_t<std::is_same<T, U>::value, R>;

template <typename T>
using unqualified = std::remove_cv_t<std::remove_reference_t<T>>;

template <typename T, typename U = std::decay_t<T>>
using deduce = std::conditional_t<
  std::is_rvalue_reference<T>::value,
  std::add_rvalue_reference_t<std::decay_t<U>>,
  std::conditional_t<
    std::is_lvalue_reference<T>::value
      && std::is_const<std::remove_reference_t<T>>::value,
    std::add_lvalue_reference_t<std::add_const_t<std::decay_t<U>>>,
    std::conditional_t<
      std::is_lvalue_reference<T>::value
        && ! std::is_const<std::remove_reference_t<T>>::value,
      std::add_lvalue_reference_t<std::decay_t<U>>,
      std::false_type
    >
  >
>;

//
// Various meta functions mostly used to sfinae out certain types.
//
{'fraction_non_alphanumeric': 0.16322374163514694, 'fraction_numerical': 0.0002909514111143439, 'mean_word_length': 4.762782900251467, 'pattern_counts': {'":': 0, '<': 162, '<?xml version=': 0, '>': 168, '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': '6303885', 'n_tokens_mistral': 2459, 'n_tokens_neox': 2363, 'n_words': 630}