#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, Ts&&... Args) -> decltype(Forward(Object)(Forward(Args)...)) { return Forward(Object)(Forward(Args)...); } }; struct InvokeMemberFunction { template static auto Invoke(F&& Func, ObjectType&& Object, Ts&&... Args) -> decltype((Forward(Object)->*Func)(Forward(Args)...)) { return (Forward(Object)->*Func)(Forward(Args)...); } template static auto Invoke(F&& Func, ObjectType&& Object, Ts&&... 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 /** Invoke the Callable object f with the parameters args. */ template requires (CInvocable) FORCEINLINE constexpr auto Invoke(F&& Func, Ts&&... Args) -> decltype(NAMESPACE_PRIVATE::InvokeImpl::Invoke(Forward(Func), Forward(Args)...)) { return NAMESPACE_PRIVATE::InvokeImpl::Invoke(Forward(Func), Forward(Args)...); } /** Invoke the Callable object f with the parameters args. */ template requires (CInvocableResult) NODISCARD FORCEINLINE constexpr R InvokeResult(F&& Func, Ts&&... 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