AuROXTL/Include/auROXTL/auTemplateMetaIsFunction.hpp

181 lines
5.7 KiB
C++

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: auTemplateMetaIsFunction.hpp
Date: 2022-3-28
Author: Reece
Copy/pasted: https://en.cppreference.com/w/cpp/types/AuIsFunction
***/
#pragma once
#if defined(AURORA_COMPILER_CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wambiguous-ellipsis"
#endif
// 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;
#if defined(AURORA_COMPILER_CLANG)
#pragma clang diagnostic pop
#endif