#pragma once #include "CoreTypes.h" #include "Templates/Utility.h" #include "TypeTraits/TypeTraits.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) -> decltype(Forward(Object)(Forward(Args)...)) { return Forward(Object)(Forward(Args)...); } }; struct InvokeMemberFunction { template static auto Invoke(F&& Func, ObjectType&& Object, Types&&... Args) -> decltype((Forward(Object)->*Func)(Forward(Args)...)) { return (Forward(Object)->*Func)(Forward(Args)...); } template static auto Invoke(F&& Func, ObjectType&& Object, Types&&... Args) -> decltype((Forward(Object).*Func)(Forward(Args)...)) { return (Forward(Object).*Func)(Forward(Args)...); } }; struct InvokeMemberObject { template static auto Invoke(F&& Func, ObjectType&& Object) -> decltype(Forward(Object)->*Func) { return (Forward(Object)->*Func); } template static auto Invoke(F&& Func, ObjectType&& Object) -> decltype(Forward(Object).*Func) { return (Forward(Object).*Func); } }; template , bool IsMemberFunction = CMemberFunctionPointer, bool IsMemberObject = CMemberObjectPointer> 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 CInvocable constexpr auto Invoke(F&& Func, Types&&... Args) -> decltype(NAMESPACE_PRIVATE::InvokeImpl::Invoke(Forward(Func), Forward(Args)...)) { return NAMESPACE_PRIVATE::InvokeImpl::Invoke(Forward(Func), Forward(Args)...); } template requires CInvocableResult constexpr R InvokeResult(F&& Func, Types&&... Args) { if constexpr (CVoid) Invoke(Forward(Func), Forward(Args)...); else return Invoke(Forward(Func), Forward(Args)...); } NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END