#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 FInvokeFunction { template <typename F, typename... Ts> static auto Invoke(F&& Object, Ts&&... Args) -> decltype(Forward<F>(Object)(Forward<Ts>(Args)...)) { return Forward<F>(Object)(Forward<Ts>(Args)...); } }; struct FInvokeMemberFunction { template <typename F, typename ObjectType, typename... Ts> static auto Invoke(F&& Func, ObjectType&& Object, Ts&&... Args) -> decltype((Forward<ObjectType>(Object)->*Func)(Forward<Ts>(Args)...)) { return (Forward<ObjectType>(Object)->*Func)(Forward<Ts>(Args)...); } template <typename F, typename ObjectType, typename... Ts> static auto Invoke(F&& Func, ObjectType&& Object, Ts&&... Args) -> decltype((Forward<ObjectType>(Object).*Func)(Forward<Ts>(Args)...)) { return (Forward<ObjectType>(Object).*Func)(Forward<Ts>(Args)...); } }; struct FInvokeMemberObject { template <typename F, typename ObjectType> static auto Invoke(F&& Func, ObjectType&& Object) -> decltype(Forward<ObjectType>(Object)->*Func) { return (Forward<ObjectType>(Object)->*Func); } template <typename F, typename ObjectType> static auto Invoke(F&& Func, ObjectType&& Object) -> decltype(Forward<ObjectType>(Object).*Func) { return (Forward<ObjectType>(Object).*Func); } }; template <typename F, typename T, typename Decayed = TDecay<F>, bool IsMemberFunction = CMemberFunctionPointer<Decayed>, bool IsMemberObject = CMemberObjectPointer<Decayed>> struct FInvokeMember; template <typename F, typename T, typename Decayed> struct FInvokeMember<F, T, Decayed, true, false> : FInvokeMemberFunction { }; template <typename F, typename T, typename Decayed> struct FInvokeMember<F, T, Decayed, false, true> : FInvokeMemberObject { }; template <typename F, typename T, typename Decayed> struct FInvokeMember<F, T, Decayed, false, false> : FInvokeFunction { }; template <typename F, typename... Ts> struct FInvokeImpl; template <typename F> struct FInvokeImpl<F> : FInvokeFunction { }; template <typename F, typename T, typename... Ts> struct FInvokeImpl<F, T, Ts...> : FInvokeMember<F, T> { }; NAMESPACE_PRIVATE_END /** Invoke the Callable object f with the parameters args. */ template <typename F, typename... Ts> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr auto Invoke(F&& Func, Ts&&... Args) -> decltype(NAMESPACE_PRIVATE::FInvokeImpl<F, Ts...>::Invoke(Forward<F>(Func), Forward<Ts>(Args)...)) { return NAMESPACE_PRIVATE::FInvokeImpl<F, Ts...>::Invoke(Forward<F>(Func), Forward<Ts>(Args)...); } /** Invoke the Callable object f with the parameters args. */ template <typename R, typename F, typename... Ts> requires (CInvocableResult<R, F, Ts...>) NODISCARD FORCEINLINE constexpr R InvokeResult(F&& Func, Ts&&... Args) { if constexpr (CVoid<R>) Invoke(Forward<F>(Func), Forward<Ts>(Args)...); else return Invoke(Forward<F>(Func), Forward<Ts>(Args)...); } NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END