diff --git a/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp b/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp index 28b1dd2..54083fe 100644 --- a/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp +++ b/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp @@ -438,9 +438,9 @@ void TestTypeTraits() always_check(!(CInvocableResult<int32, int32(int32), FTestStructA>)); always_check(!(CInvocableResult<FTestStructA, int32(int32), int32>)); - always_check((CSameAs<int32, TInvokeResult<int32()>::Type>)); - always_check((CSameAs<int32, TInvokeResult<int32(int32), int32>::Type>)); -// always_check((CSameAs<char(&)[2], TInvokeResult<char(&())[2]>::Type>)); + always_check((CSameAs<int32, TInvokeResult<int32()>>)); + always_check((CSameAs<int32, TInvokeResult<int32(int32), int32>>)); +// always_check((CSameAs<char(&)[2], TInvokeResult<char(&())[2]>>)); always_check((CInvocable <decltype([]( ) -> void { }) >)); always_check((CRegularInvocable <decltype([](int32 A ) -> int32 { return A; }), int32 >)); diff --git a/Redcraft.Utility/Source/Public/Templates/Tuple.h b/Redcraft.Utility/Source/Public/Templates/Tuple.h index e1252b7..42e13aa 100644 --- a/Redcraft.Utility/Source/Public/Templates/Tuple.h +++ b/Redcraft.Utility/Source/Public/Templates/Tuple.h @@ -356,14 +356,14 @@ public: template <typename F, typename... ArgTypes> requires CInvocable<F, Types..., ArgTypes...> constexpr auto ApplyBefore(F&& Func, ArgTypes&&... Args) volatile&& { return Helper::ApplyBefore(Forward<F>(Func), static_cast< volatile TTuple&&>(*this), Forward<ArgTypes>(Args)...); } template <typename F, typename... ArgTypes> requires CInvocable<F, Types..., ArgTypes...> constexpr auto ApplyBefore(F&& Func, ArgTypes&&... Args) const volatile&& { return Helper::ApplyBefore(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this), Forward<ArgTypes>(Args)...); } - template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, typename TInvokeResult<F, Types>::Type>)) constexpr auto Transform(F&& Func) & { return Helper::Transform(Forward<F>(Func), static_cast< TTuple& >(*this)); } - template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, typename TInvokeResult<F, Types>::Type>)) constexpr auto Transform(F&& Func) const & { return Helper::Transform(Forward<F>(Func), static_cast<const TTuple& >(*this)); } - template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, typename TInvokeResult<F, Types>::Type>)) constexpr auto Transform(F&& Func) volatile& { return Helper::Transform(Forward<F>(Func), static_cast< volatile TTuple& >(*this)); } - template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, typename TInvokeResult<F, Types>::Type>)) constexpr auto Transform(F&& Func) const volatile& { return Helper::Transform(Forward<F>(Func), static_cast<const volatile TTuple& >(*this)); } - template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, typename TInvokeResult<F, Types>::Type>)) constexpr auto Transform(F&& Func) && { return Helper::Transform(Forward<F>(Func), static_cast< TTuple&&>(*this)); } - template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, typename TInvokeResult<F, Types>::Type>)) constexpr auto Transform(F&& Func) const && { return Helper::Transform(Forward<F>(Func), static_cast<const TTuple&&>(*this)); } - template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, typename TInvokeResult<F, Types>::Type>)) constexpr auto Transform(F&& Func) volatile&& { return Helper::Transform(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); } - template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, typename TInvokeResult<F, Types>::Type>)) constexpr auto Transform(F&& Func) const volatile&& { return Helper::Transform(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); } + template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr auto Transform(F&& Func) & { return Helper::Transform(Forward<F>(Func), static_cast< TTuple& >(*this)); } + template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr auto Transform(F&& Func) const & { return Helper::Transform(Forward<F>(Func), static_cast<const TTuple& >(*this)); } + template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr auto Transform(F&& Func) volatile& { return Helper::Transform(Forward<F>(Func), static_cast< volatile TTuple& >(*this)); } + template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr auto Transform(F&& Func) const volatile& { return Helper::Transform(Forward<F>(Func), static_cast<const volatile TTuple& >(*this)); } + template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr auto Transform(F&& Func) && { return Helper::Transform(Forward<F>(Func), static_cast< TTuple&&>(*this)); } + template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr auto Transform(F&& Func) const && { return Helper::Transform(Forward<F>(Func), static_cast<const TTuple&&>(*this)); } + template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr auto Transform(F&& Func) volatile&& { return Helper::Transform(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); } + template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr auto Transform(F&& Func) const volatile&& { return Helper::Transform(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); } template <typename T> requires CConstructibleFrom<T, Types...> constexpr T Construct() & { return Helper::template Construct<T>(static_cast< TTuple& >(*this)); } template <typename T> requires CConstructibleFrom<T, Types...> constexpr T Construct() const & { return Helper::template Construct<T>(static_cast<const TTuple& >(*this)); } diff --git a/Redcraft.Utility/Source/Public/Templates/Variant.h b/Redcraft.Utility/Source/Public/Templates/Variant.h index 7e84454..07ae9f8 100644 --- a/Redcraft.Utility/Source/Public/Templates/Variant.h +++ b/Redcraft.Utility/Source/Public/Templates/Variant.h @@ -236,7 +236,7 @@ struct TVariant { checkf(IsValid(), TEXT("It is an error to call Visit() on an wrong TVariant. Please either check IsValid().")); - using ReturnType = typename TCommonType<typename TInvokeResult<F, Types>::Type...>::Type; + using ReturnType = typename TCommonType<TInvokeResult<F, Types>...>::Type; using FInvokeImpl = ReturnType(*)(F&&, void*); static constexpr FInvokeImpl InvokeImpl[] = { [](F&& Func, void* This) -> ReturnType { return InvokeResult<ReturnType>(Forward<F>(Func), *reinterpret_cast<Types*>(This)); }... }; @@ -249,7 +249,7 @@ struct TVariant { checkf(IsValid(), TEXT("It is an error to call Visit() on an wrong TVariant. Please either check IsValid().")); - using ReturnType = typename TCommonType<typename TInvokeResult<F, Types>::Type...>::Type; + using ReturnType = typename TCommonType<TInvokeResult<F, Types>...>::Type; using FInvokeImpl = ReturnType(*)(F&&, void*); static constexpr FInvokeImpl InvokeImpl[] = { [](F&& Func, void* This) -> ReturnType { return InvokeResult<ReturnType>(Forward<F>(Func), MoveTemp(*reinterpret_cast<Types*>(This))); }... }; @@ -262,7 +262,7 @@ struct TVariant { checkf(IsValid(), TEXT("It is an error to call Visit() on an wrong TVariant. Please either check IsValid().")); - using ReturnType = typename TCommonType<typename TInvokeResult<F, Types>::Type...>::Type; + using ReturnType = typename TCommonType<TInvokeResult<F, Types>...>::Type; using FInvokeImpl = ReturnType(*)(F&&, const void*); static constexpr FInvokeImpl InvokeImpl[] = { [](F&& Func, const void* This) -> ReturnType { return InvokeResult<ReturnType>(Forward<F>(Func), *reinterpret_cast<const Types*>(This)); }... }; @@ -275,7 +275,7 @@ struct TVariant { checkf(IsValid(), TEXT("It is an error to call Visit() on an wrong TVariant. Please either check IsValid().")); - using ReturnType = typename TCommonType<typename TInvokeResult<F, Types>::Type...>::Type; + using ReturnType = typename TCommonType<TInvokeResult<F, Types>...>::Type; using FInvokeImpl = ReturnType(*)(F&&, const void*); static constexpr FInvokeImpl InvokeImpl[] = { [](F&& Func, const void* This) -> ReturnType { return InvokeResult<ReturnType>(Forward<F>(Func), MoveTemp(*reinterpret_cast<const Types*>(This))); }... }; diff --git a/Redcraft.Utility/Source/Public/TypeTraits/Invocable.h b/Redcraft.Utility/Source/Public/TypeTraits/Invocable.h index dadf4ee..7f02460 100644 --- a/Redcraft.Utility/Source/Public/TypeTraits/Invocable.h +++ b/Redcraft.Utility/Source/Public/TypeTraits/Invocable.h @@ -12,13 +12,13 @@ NAMESPACE_MODULE_BEGIN(Utility) template <typename F, typename... Args> concept CInvocable = NAMESPACE_STD::is_invocable_v<F, Args...>; template <typename R, typename F, typename... Args> concept CInvocableResult = NAMESPACE_STD::is_invocable_r_v<R, F, Args...>; // FIXME: The result for char(&())[2] is wrong on MSVC -template <typename F, typename... Args> struct TInvokeResult { using Type = NAMESPACE_STD::invoke_result_t<F, Args...>; }; // FIXME: The result for char(&())[2] is wrong on MSVC +template <typename F, typename... Args> using TInvokeResult = NAMESPACE_STD::invoke_result_t<F, Args...>; // FIXME: The result for char(&())[2] is wrong on MSVC template <typename F, typename... Types> concept CRegularInvocable = CInvocable<F, Types...>; template <typename F, typename... Types> -concept CPredicate = CRegularInvocable<F, Types...> && CBooleanTestable<typename TInvokeResult<F, Types...>::Type>; +concept CPredicate = CRegularInvocable<F, Types...> && CBooleanTestable<TInvokeResult<F, Types...>>; template <typename R, typename T, typename U> concept CRelation =