[+] AuIsArray_v, AuDecay_t, AuIsFunction_v

This commit is contained in:
Reece Wilson 2022-03-28 14:32:35 +01:00
parent 681581486e
commit 7e7c241f4d
2 changed files with 224 additions and 0 deletions

View File

@ -0,0 +1,172 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: auMetaIsFunction.hpp
Date: 2022-3-28
Author: Reece
Copy/pasted: https://en.cppreference.com/w/cpp/types/AuIsFunction
***/
#pragma once
// primary
template <class>
struct AuIsFunction : AuFalseType { };
// specialization for regular functions
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...)> : AuTrueType {};
// specialization for variadic functions such as std::printf
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......)> : AuTrueType {};
// specialization for function types that have cv-qualifiers
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) const> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) volatile> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) const volatile> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) const> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) volatile> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) const volatile> : AuTrueType {};
// specialization for function types that have ref-qualifiers
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) &> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) const &> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) volatile &> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) const volatile &> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) &> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) const &> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) volatile &> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) const volatile &> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) &&> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) const &&> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) volatile &&> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) const volatile &&> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) &&> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) const &&> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) volatile &&> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) const volatile &&> : AuTrueType {};
// specializations for noexcept versions of all the above (C++17 and later)
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) const noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) volatile noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) const volatile noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) const noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) volatile noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) const volatile noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) & noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) const & noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) volatile & noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) const volatile & noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) & noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) const & noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) volatile & noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) const volatile & noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) && noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) const && noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) volatile && noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args...) const volatile && noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) && noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) const && noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) volatile && noexcept> : AuTrueType {};
template <class Ret, class... Args>
struct AuIsFunction<Ret(Args......) const volatile && noexcept> : AuTrueType {};
template <class T>
inline constexpr bool AuIsFunction_v = AuIsFunction<T>::value;

View File

@ -28,6 +28,8 @@ struct AuBoolType
using AuFalseType = AuBoolType<false>;
using AuTrueType = AuBoolType<true>;
#include "auMetaIsFunction.hpp"
template <class T>
using AuToValueType_t = typename T::value_type;
@ -244,6 +246,39 @@ struct AuAddConst
template <class T>
using AuAddConst_t = typename AuAddConst<T>::type;
template <class T>
using AuAddRemoveCV_t = AuRemoveConst_t<AuRemoveReference_t<T>>;
template <class T>
struct AuRemoveExtent
{
using type = T;
};
template <class T>
struct AuRemoveExtent<T[]>
{
using type = T;
};
template <class T, AuUInt Len>
struct AuRemoveExtent<T[Len]>
{
using type = T;
};
template <class T>
using AuRemoveExtent_t = typename AuRemoveExtent<T>::type;
template <class>
constexpr inline bool AuIsArray_v = false;
template <class T, size_t Len>
inline constexpr bool AuIsArray_v<T[Len]> = true;
template <class T>
inline constexpr bool AuIsArray_v<T[]> = true;
template <bool Test, class T = void>
using AuEnableIf_t = typename AuEnableIf<Test, T>::type;
@ -276,6 +311,23 @@ struct AuConditional<false, T, T2>
template <bool Test, class T, class T2>
using AuConditional_t = typename AuConditional<Test, T, T2>::type;
template <class T>
struct AuDecay
{
using type = AuConditional_t<
AuIsArray_v<T>,
AuAddPointer_t<AuRemoveExtent_t<T>>,
AuConditional_t<
AuIsFunction_v<T>,
AuAddPointer_t<T>,
AuAddRemoveCV_t<T>
>
>;
};
template <class T>
using AuDecay_t = typename AuDecay<T>::type;
template <template <class...> class Base, typename Derived>
struct AuIsBaseOfTemplateImpl
{