zengine-old/engine/3rdparty/zlib/include/meta/meta.inl

98 lines
2.8 KiB
Plaintext
Raw Permalink Normal View History

2024-06-16 22:52:45 +08:00
#pragma once
#include <type_traits>
#include "meta.h"
namespace meta
{
template<typename T, template<typename ...> typename TMPLT>
struct is_template
: std::false_type
{
};
template<template<typename ...> typename TMPLT, typename...Args>
struct is_template<TMPLT<Args...>, TMPLT>
: std::true_type
{
};
template<typename T, T ... Indexes1, T ... Indexes2>
struct index_sequence_cat<std::index_sequence<Indexes1...>, std::index_sequence<Indexes2...>>
{
using type = std::index_sequence<Indexes1..., Indexes2...>;
};
template<>
struct index_sequence_rev<std::index_sequence<>>
{
using type = std::index_sequence<>;
};
template<typename T, T Last, T ... Indexes>
struct index_sequence_rev<std::index_sequence<Indexes..., Last>>
{
using type = index_sequence_cat_t<std::index_sequence<Last>, index_sequence_rev_t<std::index_sequence<Indexes...>>>;
};
template<typename T, typename = void>
struct is_iterable : std::false_type {};
template<typename T>
struct is_iterable<T, std::void_t<decltype(
std::begin(std::declval<T&>()) != std::end(std::declval<T&>()), // begin/end and operator !=
void(), // Handle evil operator ,
++std::declval<decltype(std::begin(std::declval<T&>()))&>(), // operator ++
void(*std::begin(std::declval<T&>())) // operator*
)>> : std::true_type {};
template<typename T, typename = void>
struct is_sequential_container : std::is_array<std::decay_t<T>> {};
template<typename T>
struct is_sequential_container<T, std::void_t<decltype(
std::declval<T&>().front()
)>> : is_iterable<T> {};
template<typename T, typename = void>
struct is_associative_container : std::false_type {};
template<typename T>
struct is_associative_container<T, std::void_t<decltype(
std::declval<T&>().insert(std::declval<typename std::decay_t<T>::value_type>())
)>> : is_iterable<T> {};
template<typename T>
struct is_container : std::disjunction<is_associative_container<T>, is_sequential_container<T>> {};
template<typename T, typename = void>
struct is_macro_enum : std::false_type {};
template<typename T>
struct is_macro_enum<T, std::void_t<decltype(
std::decay_t<T>::count,
std::decay_t<T>::names[0],
std::decay_t<T>::values[0]
)>> : std::is_enum<typename std::decay_t<T>::_enum> {};
template<typename T, typename VariantT>
struct is_variant_member;
template<typename T, typename... Ts>
struct is_variant_member<T, std::variant<Ts...>> : std::disjunction<std::is_same<T, Ts>...> {};
// true if is integral/floating point, or is constructible from and to string, or is macro enum
template<typename T>
struct is_basic_serializable : std::disjunction<
std::is_arithmetic<std::decay_t<T>>,
is_macro_enum<std::decay_t<T>>,
std::conjunction<std::is_constructible<string, T>, std::is_constructible<std::decay_t<T>, string>>> {};
}