#pragma once #include "CoreTypes.h" #include "TypeTraits/Miscellaneous.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) NAMESPACE_PRIVATE_BEGIN struct InvokeFunction { template static auto Invoke(F&& Object, Types&&... Args) { return Object(Forward(Args)...); } }; struct InvokeMemberFunction { template static auto Invoke(F&& Func, ObjectType&& Object, Types&&... Args) -> decltype((Object->*Func)(Forward(Args)...)) { return (Object->*Func)(Forward(Args)...); } template static auto Invoke(F&& Func, ObjectType&& Object, Types&&... Args) -> decltype((Object.*Func)(Forward(Args)...)) { return (Object.*Func)(Forward(Args)...); } }; struct InvokeMemberObject { template static auto Invoke(F&& Func, ObjectType&& Object) -> decltype(Object->*Func) { return (Object->*Func); } template static auto Invoke(F&& Func, ObjectType&& Object) -> decltype(Object.*Func) { return (Object.*Func); } }; template ::Type, bool IsMemberFunction = TIsMemberFunctionPointer::Value, bool IsMemberObject = TIsMemberObjectPointer::Value> struct InvokeMember; template struct InvokeMember : InvokeMemberFunction { }; template struct InvokeMember : InvokeMemberObject { }; template struct InvokeMember : InvokeFunction { }; template struct InvokeImpl; template struct InvokeImpl : InvokeFunction { }; template struct InvokeImpl : InvokeMember { }; NAMESPACE_PRIVATE_END template requires TIsInvocable::Value constexpr auto Invoke(F&& Func, Types&&... Args) { return NAMESPACE_PRIVATE::InvokeImpl::Invoke(Forward(Func), Forward(Args)...); } template requires TIsInvocableResult::Value constexpr R InvokeResult(F&& Func, Types&&... Args) { if constexpr (TIsVoid::Value) Invoke(Forward(Func), Forward(Args)...); else return Invoke(Forward(Func), Forward(Args)...); } NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END