/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: auTemplateMeta.hpp Date: 2022-2-1 Author: Reece Note: most of this code assumes C++17 or greater ***/ #pragma once template struct AuBoolType { static AUROXTL_CONSTEXPR bool value = v; using value_type = bool; using type = AuBoolType; AUROXTL_CONSTEXPR operator value_type() const noexcept { return value; } AUROXTL_CONSTEXPR value_type operator()() const noexcept { return value; } }; using AuFalseType = AuBoolType; using AuTrueType = AuBoolType; #include "auTemplateMetaIsFunction.hpp" template using AuToValueType_t = typename T::value_type; template using AuToElementType_t = typename T::element_type; template using AuToIterator_t = typename T::iterator; template static AuToIterator_t AuToIterator(const T &a); // intended use case: `decltype(AuToIterator(myHashMap)) itr;` template static AuToElementType_t AuToElementType(const T &a); template static AuToValueType_t AuToValueType(const T &a); template struct AuIsSame : AuFalseType {}; template struct AuIsSame : AuTrueType {}; template inline AUROXTL_CONSTEXPR bool AuIsSame_v = AuIsSame::value; template inline AUROXTL_CONSTEXPR bool AuIsConst_v = false; template inline AUROXTL_CONSTEXPR bool AuIsConst_v = true; 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))); // yoinked: https://stackoverflow.com/a/40867906 template static auto IsCallable(int) -> decltype((void)AuDeclVal()(AuDeclVal()...), AuTrueType {}); template static AuFalseType IsCallable(...); } template struct AuIsClass : decltype(_audetail::IsClass(nullptr)) {}; template inline AUROXTL_CONSTEXPR bool AuIsClass_v = AuIsClass::value; template struct AuIsBaseOf : AuBoolType< AuIsClass_v && AuIsClass_v && decltype(_audetail::TestIsBaseOf(0))::value > {}; template inline AUROXTL_CONSTEXPR bool AuIsBaseOf_v = AuIsBaseOf::value; template inline AUROXTL_CONSTEXPR bool AuIsPointer_v = false; template inline AUROXTL_CONSTEXPR bool AuIsPointer_v = true; template inline AUROXTL_CONSTEXPR bool AuIsPointer_v = true; template inline AUROXTL_CONSTEXPR bool AuIsPointer_v = true; template inline AUROXTL_CONSTEXPR bool AuIsPointer_v = true; template inline AUROXTL_CONSTEXPR bool AuIsReference_v = false; template inline AUROXTL_CONSTEXPR bool AuIsReference_v = true; template inline AUROXTL_CONSTEXPR bool AuIsReference_v = true; template inline AUROXTL_CONSTEXPR bool AuIsLValueReference_v = false; template inline AUROXTL_CONSTEXPR bool AuIsLValueReference_v = true; template inline AUROXTL_CONSTEXPR bool AuIsRValueReference_v = false; template inline AUROXTL_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 AUROXTL_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 AuRemoveVolatile { typedef T type; }; template struct AuRemoveVolatile { typedef T type; }; template using AuRemoveVolatile_t = typename AuRemoveVolatile::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 = AuRemoveReference_t &; }; template using AuAddLReference_t = typename AuAddLReference::type; template struct AuAddRReference { using type = AuRemoveReference_t &&; }; template using AuAddRReference_t = typename AuAddRReference::type; template T &&AuDeclVal(); template struct AuAddConst { using type = const T; }; template using AuAddConst_t = typename AuAddConst::type; template using AuRemoveCV_t = AuRemoveConst_t>; template struct AuRemoveExtent { using type = T; }; template struct AuRemoveExtent { using type = T; }; template struct AuRemoveExtent { using type = T; }; template using AuRemoveExtent_t = typename AuRemoveExtent::type; template using AuVoid_t = void; template AUROXTL_CONSTEXPR inline bool AuIsArray_v = false; template inline AUROXTL_CONSTEXPR bool AuIsArray_v = true; template inline AUROXTL_CONSTEXPR bool AuIsArray_v = true; template using AuEnableIf_t = typename AuEnableIf::type; #if !defined(AURORA_COMPILER_CLANG) && !defined(AURORA_COMPILER_MSVC) template struct AuIsConstructible { template static AUROXTL_CONSTEXPR AuTrueType Test(decltype(::new C(AuDeclVal()...))); template static AUROXTL_CONSTEXPR AuFalseType Test(...); using type = decltype(Test(0)); }; template using AuIsConstructible_t = typename AuIsConstructible::type; #else template struct AuIsConstructible : AuBoolType<__is_constructible(T, Args...)> { }; template using AuIsConstructible_t = typename AuIsConstructible::type; #endif template inline AUROXTL_CONSTEXPR bool AuIsConstructible_v = AuIsConstructible::type::value; template struct AuConditional { using type = T; }; template struct AuConditional { using type = T2; }; template using AuConditional_t = typename AuConditional::type; template using AuDecay_t = AuConditional_t< AuIsArray_v, AuAddPointer_t>, AuConditional_t< AuIsFunction_v, AuAddPointer_t, AuRemoveCV_t > >; template struct AuDecay { using type = AuDecay_t; }; template