215 lines
4.2 KiB
C++
215 lines
4.2 KiB
C++
|
/***
|
||
|
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||
|
|
||
|
File: auTemplateMeta.hpp
|
||
|
Date: 2022-2-1
|
||
|
Author: Reece
|
||
|
***/
|
||
|
#pragma once
|
||
|
|
||
|
template<bool v>
|
||
|
struct AuBoolType
|
||
|
{
|
||
|
static constexpr bool value = v;
|
||
|
using value_type = bool;
|
||
|
using type = AuBoolType;
|
||
|
|
||
|
constexpr operator value_type() const noexcept
|
||
|
{
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
constexpr value_type operator()() const noexcept
|
||
|
{
|
||
|
return value;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
using AuFalseType = AuBoolType<false>;
|
||
|
using AuTrueType = AuBoolType<true>;
|
||
|
|
||
|
template<class T>
|
||
|
using AuToValueType_t = typename T::value_type;
|
||
|
|
||
|
template<class T>
|
||
|
using AuToElementType_t = typename T::yelement_type;
|
||
|
|
||
|
template<class T, class U>
|
||
|
struct AuIsSame : AuFalseType
|
||
|
{};
|
||
|
|
||
|
template<class T>
|
||
|
struct AuIsSame<T, T> : AuTrueType
|
||
|
{};
|
||
|
|
||
|
template<class T, class U>
|
||
|
inline constexpr bool AuIsSame_v = AuIsSame<T, U>::value;
|
||
|
|
||
|
namespace _audetail
|
||
|
{
|
||
|
template<class T>
|
||
|
AuBoolType<!std::is_union<T>::value> IsClass(int T:: *);
|
||
|
|
||
|
template<class>
|
||
|
AuFalseType IsClass(...);
|
||
|
|
||
|
template<typename B>
|
||
|
AuTrueType TestIsPtrConvertible(const volatile B *);
|
||
|
template<typename>
|
||
|
AuFalseType TestIsPtrConvertible(const volatile void *);
|
||
|
|
||
|
template<typename, typename>
|
||
|
auto TestIsBaseOf(...)->AuTrueType;
|
||
|
|
||
|
template<typename B, typename D>
|
||
|
auto TestIsBaseOf(int) -> decltype(TestIsPtrConvertible<B>(static_cast<D *>(nullptr)));
|
||
|
}
|
||
|
|
||
|
template<class T>
|
||
|
struct AuIsClass : decltype(_audetail::IsClass<T>(nullptr))
|
||
|
{};
|
||
|
|
||
|
template<class T>
|
||
|
inline constexpr bool AuIsClass_v = AuIsClass<T>::value;
|
||
|
|
||
|
template<typename Base, typename Derived>
|
||
|
struct AuIsBaseOf :
|
||
|
AuBoolType<
|
||
|
AuIsClass_v<Base> &&
|
||
|
AuIsClass_v<Derived> &&
|
||
|
decltype(_audetail::TestIsBaseOf<Base, Derived>(0))::value
|
||
|
>
|
||
|
{};
|
||
|
|
||
|
template<typename Base, typename Derived>
|
||
|
inline constexpr bool AuIsBaseOf_v = AuIsBaseOf<Base, Derived>::value;
|
||
|
|
||
|
template<class>
|
||
|
inline constexpr bool AuIsPointer_v = false;
|
||
|
|
||
|
template<class T>
|
||
|
inline constexpr bool AuIsPointer_v<T *> = true;
|
||
|
|
||
|
template<class T>
|
||
|
inline constexpr bool AuIsPointer_v<T *const> = true;
|
||
|
|
||
|
template<class T>
|
||
|
inline constexpr bool AuIsPointer_v<T *volatile> = true;
|
||
|
|
||
|
template<class T>
|
||
|
inline constexpr bool AuIsPointer_v<T *const volatile> = true;
|
||
|
|
||
|
template<class T>
|
||
|
struct AuRemovePointer
|
||
|
{
|
||
|
typedef T type;
|
||
|
};
|
||
|
|
||
|
template<class T>
|
||
|
struct AuRemovePointer<T *>
|
||
|
{
|
||
|
typedef T type;
|
||
|
};
|
||
|
|
||
|
template<class T>
|
||
|
struct AuRemovePointer<T *const>
|
||
|
{
|
||
|
typedef T type;
|
||
|
};
|
||
|
|
||
|
template<class T>
|
||
|
struct AuRemovePointer<T *volatile>
|
||
|
{
|
||
|
typedef T type;
|
||
|
};
|
||
|
|
||
|
template<class T>
|
||
|
struct AuRemovePointer<T *const volatile>
|
||
|
{
|
||
|
typedef T type;
|
||
|
};
|
||
|
|
||
|
template<class T>
|
||
|
using AuRemovePointer_t = typename AuRemovePointer<T>::type;
|
||
|
|
||
|
template<class T>
|
||
|
using AuIsVoid = AuIsSame<void, T>;
|
||
|
|
||
|
template<class T>
|
||
|
inline constexpr bool AuIsVoid_v = AuIsVoid<T>::value;
|
||
|
|
||
|
template<class T>
|
||
|
struct AuRemoveReference
|
||
|
{
|
||
|
using type = T;
|
||
|
};
|
||
|
|
||
|
template<class T>
|
||
|
struct AuRemoveReference<T &>
|
||
|
{
|
||
|
using type = T;
|
||
|
};
|
||
|
|
||
|
template<class T>
|
||
|
struct AuRemoveReference<T &&>
|
||
|
{
|
||
|
using type = T;
|
||
|
};
|
||
|
|
||
|
template<class T>
|
||
|
using AuRemoveReference_t = typename AuRemoveReference<T>::type;
|
||
|
|
||
|
template<class T>
|
||
|
struct AuRemoveConst
|
||
|
{
|
||
|
typedef T type;
|
||
|
};
|
||
|
|
||
|
template<class T>
|
||
|
struct AuRemoveConst<const T>
|
||
|
{
|
||
|
typedef T type;
|
||
|
};
|
||
|
|
||
|
template<class T>
|
||
|
using AuRemoveConst_t = typename AuRemoveConst<T>::type;
|
||
|
|
||
|
template<bool Test, class T = void>
|
||
|
struct AuEnableIf
|
||
|
{};
|
||
|
|
||
|
template<class T>
|
||
|
struct AuEnableIf<true, T>
|
||
|
{
|
||
|
using type = T;
|
||
|
};
|
||
|
|
||
|
template<bool Test, class T = void>
|
||
|
using AuEnableIf_t = typename AuEnableIf<Test, T>::type;
|
||
|
|
||
|
template<bool Test, class T, class T2>
|
||
|
struct AuConditional
|
||
|
{
|
||
|
using type = T;
|
||
|
};
|
||
|
|
||
|
template<class T, class T2>
|
||
|
struct AuConditional<false, T, T2>
|
||
|
{
|
||
|
using type = T2;
|
||
|
};
|
||
|
|
||
|
template<bool Test, class T, class T2>
|
||
|
using AuConditional_t = typename AuConditional<Test, T, T2>::type;
|
||
|
|
||
|
template<template<typename...> class base, typename derived>
|
||
|
struct is_base_of_template_impl_au
|
||
|
{
|
||
|
template<typename... Ts>
|
||
|
static constexpr AuTrueType test(const base<Ts...> *);
|
||
|
static constexpr AuFalseType test(...);
|
||
|
using type = decltype(test(std::declval<derived *>()));
|
||
|
};
|
||
|
|
||
|
template<template <typename...> class base, typename derived>
|
||
|
using AuIsBaseOfTemplate = typename is_base_of_template_impl_au<base, derived>::type;
|