2022-02-04 13:11:05 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "CoreTypes.h"
|
2022-04-08 03:44:36 +00:00
|
|
|
#include "Templates/Utility.h"
|
2022-03-26 11:31:45 +00:00
|
|
|
#include "TypeTraits/TypeTraits.h"
|
2022-02-04 13:11:05 +00:00
|
|
|
|
|
|
|
NAMESPACE_REDCRAFT_BEGIN
|
|
|
|
NAMESPACE_MODULE_BEGIN(Redcraft)
|
|
|
|
NAMESPACE_MODULE_BEGIN(Utility)
|
|
|
|
|
|
|
|
NAMESPACE_PRIVATE_BEGIN
|
|
|
|
|
|
|
|
struct InvokeFunction
|
|
|
|
{
|
2022-11-16 11:13:37 +00:00
|
|
|
template <typename F, typename... Ts>
|
|
|
|
static auto Invoke(F&& Object, Ts&&... Args)
|
|
|
|
-> decltype(Forward<F>(Object)(Forward<Ts>(Args)...))
|
2022-02-04 13:11:05 +00:00
|
|
|
{
|
2022-11-16 11:13:37 +00:00
|
|
|
return Forward<F>(Object)(Forward<Ts>(Args)...);
|
2022-02-04 13:11:05 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct InvokeMemberFunction
|
|
|
|
{
|
2022-11-16 11:13:37 +00:00
|
|
|
template <typename F, typename ObjectType, typename... Ts>
|
|
|
|
static auto Invoke(F&& Func, ObjectType&& Object, Ts&&... Args)
|
|
|
|
-> decltype((Forward<ObjectType>(Object)->*Func)(Forward<Ts>(Args)...))
|
2022-02-04 13:11:05 +00:00
|
|
|
{
|
2022-11-16 11:13:37 +00:00
|
|
|
return (Forward<ObjectType>(Object)->*Func)(Forward<Ts>(Args)...);
|
2022-02-04 13:11:05 +00:00
|
|
|
}
|
|
|
|
|
2022-11-16 11:13:37 +00:00
|
|
|
template <typename F, typename ObjectType, typename... Ts>
|
|
|
|
static auto Invoke(F&& Func, ObjectType&& Object, Ts&&... Args)
|
|
|
|
-> decltype((Forward<ObjectType>(Object).*Func)(Forward<Ts>(Args)...))
|
2022-02-04 13:11:05 +00:00
|
|
|
{
|
2022-11-16 11:13:37 +00:00
|
|
|
return (Forward<ObjectType>(Object).*Func)(Forward<Ts>(Args)...);
|
2022-02-04 13:11:05 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct InvokeMemberObject
|
|
|
|
{
|
|
|
|
template <typename F, typename ObjectType>
|
2022-04-08 03:44:36 +00:00
|
|
|
static auto Invoke(F&& Func, ObjectType&& Object)
|
|
|
|
-> decltype(Forward<ObjectType>(Object)->*Func)
|
2022-02-04 13:11:05 +00:00
|
|
|
{
|
2022-04-07 06:52:41 +00:00
|
|
|
return (Forward<ObjectType>(Object)->*Func);
|
2022-02-04 13:11:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename F, typename ObjectType>
|
2022-04-08 03:44:36 +00:00
|
|
|
static auto Invoke(F&& Func, ObjectType&& Object)
|
|
|
|
-> decltype(Forward<ObjectType>(Object).*Func)
|
2022-02-04 13:11:05 +00:00
|
|
|
{
|
2022-04-07 06:52:41 +00:00
|
|
|
return (Forward<ObjectType>(Object).*Func);
|
2022-02-04 13:11:05 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename F,
|
|
|
|
typename T,
|
2022-05-22 14:52:47 +00:00
|
|
|
typename Decayed = TDecay<F>,
|
2022-05-15 14:56:53 +00:00
|
|
|
bool IsMemberFunction = CMemberFunctionPointer<Decayed>,
|
|
|
|
bool IsMemberObject = CMemberObjectPointer<Decayed>>
|
2022-02-04 13:11:05 +00:00
|
|
|
struct InvokeMember;
|
|
|
|
|
|
|
|
template <typename F, typename T, typename Decayed>
|
|
|
|
struct InvokeMember<F, T, Decayed, true, false> : InvokeMemberFunction { };
|
|
|
|
|
|
|
|
template <typename F, typename T, typename Decayed>
|
|
|
|
struct InvokeMember<F, T, Decayed, false, true> : InvokeMemberObject { };
|
|
|
|
|
|
|
|
template <typename F, typename T, typename Decayed>
|
|
|
|
struct InvokeMember<F, T, Decayed, false, false> : InvokeFunction { };
|
|
|
|
|
2022-11-16 11:13:37 +00:00
|
|
|
template <typename F, typename... Ts>
|
2022-02-04 13:11:05 +00:00
|
|
|
struct InvokeImpl;
|
|
|
|
|
|
|
|
template <typename F>
|
|
|
|
struct InvokeImpl<F> : InvokeFunction { };
|
|
|
|
|
2022-11-16 11:13:37 +00:00
|
|
|
template <typename F, typename T, typename... Ts>
|
|
|
|
struct InvokeImpl<F, T, Ts...> : InvokeMember<F, T> { };
|
2022-02-04 13:11:05 +00:00
|
|
|
|
|
|
|
NAMESPACE_PRIVATE_END
|
|
|
|
|
2022-11-16 14:03:54 +00:00
|
|
|
template <typename F, typename... Ts> requires (CInvocable<F, Ts...>)
|
2022-11-16 11:13:37 +00:00
|
|
|
constexpr auto Invoke(F&& Func, Ts&&... Args)
|
|
|
|
-> decltype(NAMESPACE_PRIVATE::InvokeImpl<F, Ts...>::Invoke(Forward<F>(Func), Forward<Ts>(Args)...))
|
2022-02-04 13:11:05 +00:00
|
|
|
{
|
2022-11-16 11:13:37 +00:00
|
|
|
return NAMESPACE_PRIVATE::InvokeImpl<F, Ts...>::Invoke(Forward<F>(Func), Forward<Ts>(Args)...);
|
2022-02-04 13:11:05 +00:00
|
|
|
}
|
|
|
|
|
2022-11-16 14:03:54 +00:00
|
|
|
template <typename R, typename F, typename... Ts> requires (CInvocableResult<R, F, Ts...>)
|
2022-11-16 11:13:37 +00:00
|
|
|
constexpr R InvokeResult(F&& Func, Ts&&... Args)
|
2022-02-04 13:11:05 +00:00
|
|
|
{
|
2022-11-16 11:13:37 +00:00
|
|
|
if constexpr (CVoid<R>) Invoke(Forward<F>(Func), Forward<Ts>(Args)...);
|
|
|
|
else return Invoke(Forward<F>(Func), Forward<Ts>(Args)...);
|
2022-02-04 13:11:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NAMESPACE_MODULE_END(Utility)
|
|
|
|
NAMESPACE_MODULE_END(Redcraft)
|
|
|
|
NAMESPACE_REDCRAFT_END
|