128 lines
4.6 KiB
C++
128 lines
4.6 KiB
C++
/***
|
|
Copyright (C) 2022-2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: auIsCallable.hpp
|
|
File: auTemplateMeta.hpp
|
|
Date: 2024-11-30
|
|
Date: 2022-11-17
|
|
Author: Reece
|
|
***/
|
|
#pragma once
|
|
|
|
#if !defined(AU_LANG_CPP_14_)
|
|
template<typename T, typename = void>
|
|
struct AuCallable : AuIsFunction<T> { };
|
|
|
|
template<typename T>
|
|
struct AuCallable<T, typename AuEnableIf<AuIsSame<decltype(void(&T::operator())), void>::value>::type> : AuTrueType
|
|
{
|
|
|
|
#elif defined(AU_LANG_CPP_20_)
|
|
|
|
template <class Func, class ...Params>
|
|
struct AuCallable : decltype(__audetail::IsCallable<Func, Params...>(0))
|
|
{
|
|
|
|
#else
|
|
|
|
template<typename T, typename U = void>
|
|
struct AuCallable
|
|
{
|
|
static bool const constexpr value = AuConditional_t<
|
|
AuIsClass<AuRemoveReference_t<T>>::value,
|
|
AuCallable<AuRemoveReference_t<T>, int>, std::false_type>::value;
|
|
};
|
|
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args...), U> : AuTrueType {};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(*)(Args...), U> : AuTrueType {};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(&)(Args...), U> : AuTrueType {};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args......), U> : AuTrueType {};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(*)(Args......), U> : AuTrueType {};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(&)(Args......), U> : AuTrueType {};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args...)const, U> : AuTrueType {};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args...)volatile, U> : AuTrueType {};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args...)const volatile, U> : AuTrueType {};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args......)const, U> : AuTrueType {};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args......)volatile, U> : AuTrueType{};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args......)const volatile, U> : AuTrueType {};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args...)&, U> : AuTrueType {};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args...)const&, U> : AuTrueType{};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args...)volatile&, U> : AuTrueType{};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args...)const volatile&, U> : AuTrueType{};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args......)&, U> : AuTrueType {};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args......)const&, U> : AuTrueType{};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args......)volatile&, U> : AuTrueType{};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args......)const volatile&, U> : AuTrueType{};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args...)&&, U> : AuTrueType{};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args...)const&&, U> : AuTrueType{};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args...)volatile&&, U> : AuTrueType{};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args...)const volatile&&, U> : AuTrueType{};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args......)&&, U> : AuTrueType{};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args......)const&&, U> : AuTrueType{};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args......)volatile&&, U> : AuTrueType{};
|
|
template<typename T, typename U, typename ...Args>
|
|
struct AuCallable<T(Args......)const volatile&&, U> : AuTrueType{};
|
|
|
|
template<typename T>
|
|
struct AuCallable<T, int>
|
|
{
|
|
private:
|
|
using YesType = char(&)[1];
|
|
using NoType = char(&)[2];
|
|
|
|
struct Fallback { void operator()(); };
|
|
|
|
struct Derived : T, Fallback {};
|
|
|
|
template<typename U, U>
|
|
struct Check;
|
|
|
|
template<typename>
|
|
static YesType Test(...);
|
|
|
|
template<typename C>
|
|
static NoType Test(Check<void (Fallback::*)(), &C::operator()>*);
|
|
|
|
public:
|
|
static bool const constexpr value = sizeof(Test<Derived>(0)) == sizeof(YesType);
|
|
#endif
|
|
};
|
|
|
|
#if defined(AU_LANG_CPP_14_)
|
|
template <typename F, class... Args>
|
|
AUROXTL_CONSTEXPR auto AuIsCallable_v = AuCallable<F, Args...>::value;
|
|
|
|
#define AuIsCallable_mv(F, ...) (AuIsCallable_v<F, __VA_ARGS__>)
|
|
|
|
#else
|
|
|
|
#define AuIsCallable_mv(F, ...) (AuCallable<F, __VA_ARGS__>::value)
|
|
|
|
#endif |