/*** 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 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 inline constexpr bool AuIsLValueReference_v = false; template inline constexpr bool AuIsLValueReference_v = true; template inline constexpr bool AuIsRValueReference_v = false; template inline constexpr bool AuIsRValueReference_v = true; 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 struct AuAddPointer { using type = AuRemoveReference_t *; }; template using AuAddPointer_t = typename AuAddPointer::type; template struct AuAddLReference { using type = AuRemovePointer_t &; }; template using AuAddLReference_t = typename AuAddLReference::type; template struct AuAddRReference { using type = AuRemovePointer_t &&; }; template using AuAddRReference_t = typename AuAddRReference::type; template inline AuAddRReference_t AuDeclVal(); template using AuEnableIf_t = typename AuEnableIf::type; template struct AuIsConstructible { template static constexpr AuTrueType Test(decltype(T(AuDeclVal()...))); template static constexpr AuFalseType Test(...); using type = decltype(Test(0)); }; template using AuIsConstructible_t = typename 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