/*** 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 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; using AuTrueType = AuBoolType; template using AuToValueType_t = typename T::value_type; template using AuToElementType_t = typename T::element_type; template struct AuIsSame : AuFalseType {}; template struct AuIsSame : AuTrueType {}; template inline constexpr bool AuIsSame_v = AuIsSame::value; namespace _audetail { template AuBoolType::value> IsClass(int T:: *); template AuFalseType IsClass(...); template AuTrueType TestIsPtrConvertible(const volatile B *); template AuFalseType TestIsPtrConvertible(const volatile void *); template auto TestIsBaseOf(...)->AuTrueType; template auto TestIsBaseOf(int) -> decltype(TestIsPtrConvertible(static_cast(nullptr))); } template struct AuIsClass : decltype(_audetail::IsClass(nullptr)) {}; template inline constexpr bool AuIsClass_v = AuIsClass::value; template struct AuIsBaseOf : AuBoolType< AuIsClass_v && AuIsClass_v && decltype(_audetail::TestIsBaseOf(0))::value > {}; template inline constexpr bool AuIsBaseOf_v = AuIsBaseOf::value; template inline constexpr bool AuIsPointer_v = false; template inline constexpr bool AuIsPointer_v = true; template inline constexpr bool AuIsPointer_v = true; template inline constexpr bool AuIsPointer_v = true; template inline constexpr bool AuIsPointer_v = true; template inline constexpr bool AuIsReference_v = false; template inline constexpr bool AuIsReference_v = true; template inline constexpr bool AuIsReference_v = true; template struct AuIsLValueReference : AuFalseType {}; template struct AuIsLValueReference : AuTrueType {}; template inline constexpr bool AuIsLValueReference_v = AuIsLValueReference::value; template struct AuIsRValueReference : AuFalseType {}; template struct AuIsRValueReference : AuTrueType {}; template inline constexpr bool AuIsRValueReference_v = AuIsRValueReference::value; template struct AuRemovePointer { typedef T type; }; template struct AuRemovePointer { typedef T type; }; template struct AuRemovePointer { typedef T type; }; template struct AuRemovePointer { typedef T type; }; template struct AuRemovePointer { typedef T type; }; template using AuRemovePointer_t = typename AuRemovePointer::type; template using AuIsVoid = AuIsSame; template inline constexpr bool AuIsVoid_v = AuIsVoid::value; template struct AuRemoveReference { using type = T; }; template struct AuRemoveReference { using type = T; }; template struct AuRemoveReference { using type = T; }; template using AuRemoveReference_t = typename AuRemoveReference::type; template struct AuRemoveConst { typedef T type; }; template struct AuRemoveConst { typedef T type; }; template using AuRemoveConst_t = typename AuRemoveConst::type; template struct AuEnableIf {}; template struct AuEnableIf { using type = T; }; template using AuEnableIf_t = typename AuEnableIf::type; template struct AuIsConstructible { template static constexpr AuTrueType Test(decltype(T(std::declval()...))); template static constexpr AuFalseType Test(...); using type = decltype(Test(0)); }; template inline constexpr bool AuIsConstructible_t = AuIsConstructible::type; template inline constexpr bool AuIsConstructible_v = AuIsConstructible_t::value; template struct AuConditional { using type = T; }; template struct AuConditional { using type = T2; }; template using AuConditional_t = typename AuConditional::type; template class Base, typename Derived> struct AuIsBaseOfTemplateImpl { template static constexpr AuTrueType Test(const Base *); static constexpr AuFalseType Test(...); using type = decltype(Test(std::declval *>())); }; template