fix(range): fix range adapter closure behavior
This commit is contained in:
parent
aa8cd7ed33
commit
0a37460f24
@ -152,10 +152,12 @@ NODISCARD FORCEINLINE constexpr auto All(R&& InRange)
|
||||
/** Creates A view adapter that includes all elements of a range. */
|
||||
NODISCARD FORCEINLINE constexpr auto All()
|
||||
{
|
||||
return TAdaptorClosure([]<CViewableRange R> requires (requires { Range::All(DeclVal<R>()); }) (R&& Base)
|
||||
using FClosure = decltype([]<CViewableRange R> requires (requires { Range::All(DeclVal<R>()); }) (R&& Base)
|
||||
{
|
||||
return Range::All(Forward<R>(Base));
|
||||
});
|
||||
|
||||
return TAdaptorClosure<FClosure>();
|
||||
}
|
||||
|
||||
/** A view adapter that includes all elements of a range. */
|
||||
|
@ -88,7 +88,7 @@ NODISCARD FORCEINLINE constexpr auto To(R&& Range, Ts&&... Args)
|
||||
return Result;
|
||||
}
|
||||
|
||||
else static_assert(sizeof(C) == -1, "The container type is not constructible from a range");
|
||||
else static_assert(sizeof(R) == -1, "The container type is not constructible from a range");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -97,7 +97,7 @@ NODISCARD FORCEINLINE constexpr auto To(R&& Range, Ts&&... Args)
|
||||
return Range::To<C>(Range::All(Range) | Range::Transform([]<typename T>(T&& Element) { return Range::To<TRangeElement<C>>(Forward<T>(Element)); }), Forward<Args>(Args)...);
|
||||
}
|
||||
|
||||
else static_assert(sizeof(C) == -1, "The container type is not constructible from a range");
|
||||
else static_assert(sizeof(R) == -1, "The container type is not constructible from a range");
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,27 +115,31 @@ NODISCARD FORCEINLINE constexpr auto To(R&& Range, Ts&&... Args)
|
||||
return Range::To<decltype(C(DeclVal<TRangeIterator<R>>(), DeclVal<TRangeSentinel<R>>(), DeclVal<Args>()...))>(Forward<R>(Range), Forward<Ts>(Args)...);
|
||||
}
|
||||
|
||||
else static_assert(sizeof(C) == -1, "The container type is not constructible from a range");
|
||||
else static_assert(sizeof(R) == -1, "The container type is not constructible from a range");
|
||||
}
|
||||
|
||||
/** Constructs a non-view object from the elements of the range. */
|
||||
template <typename C, typename... Ts> requires (!CView<C>)
|
||||
NODISCARD FORCEINLINE constexpr auto To(Ts&&... Args)
|
||||
{
|
||||
return TAdaptorClosure([&Args...]<CInputRange R> requires (requires { Range::To<C>(DeclVal<R>(), DeclVal<Ts>()...); }) (R&& Range)
|
||||
using FClosure = decltype([]<CInputRange R, typename... Us> requires (requires { Range::To<C>(DeclVal<R>(), DeclVal<Us>()...); }) (R&& Range, Us&&... Args)
|
||||
{
|
||||
return Range::To<C>(Forward<R>(Range), Forward<Ts>(Args)...);
|
||||
return Range::To<C>(Forward<R>(Range), Forward<Us>(Args)...);
|
||||
});
|
||||
|
||||
return TAdaptorClosure<FClosure, TDecay<Ts>...>(Forward<Ts>(Args)...);
|
||||
}
|
||||
|
||||
/** Constructs a non-view object from the elements of the range. */
|
||||
template <template <typename...> typename C, typename... Ts>
|
||||
NODISCARD FORCEINLINE constexpr auto To(Ts&&... Args)
|
||||
{
|
||||
return TAdaptorClosure([&Args...]<CInputRange R> requires (requires { Range::To<C>(DeclVal<R>(), DeclVal<Ts>()...); }) (R&& Range)
|
||||
using FClosure = decltype([]<CInputRange R, typename... Us> requires (requires { Range::To<C>(DeclVal<R>(), DeclVal<Us>()...); }) (R&& Range, Us&&... Args)
|
||||
{
|
||||
return Range::To<C>(Forward<R>(Range), Forward<Ts>(Args)...);
|
||||
return Range::To<C>(Forward<R>(Range), Forward<Us>(Args)...);
|
||||
});
|
||||
|
||||
return TAdaptorClosure<FClosure, TDecay<Ts>...>(Forward<Ts>(Args)...);
|
||||
}
|
||||
|
||||
NAMESPACE_END(Range)
|
||||
|
@ -175,10 +175,12 @@ NODISCARD FORCEINLINE constexpr auto Filter(R&& Base, Pred&& Predicate)
|
||||
template <typename Pred>
|
||||
NODISCARD FORCEINLINE constexpr auto Filter(Pred&& Predicate)
|
||||
{
|
||||
return TAdaptorClosure([&Predicate]<CViewableRange R> requires (requires { Range::Filter(DeclVal<R>(), DeclVal<Pred>()); }) (R&& Base)
|
||||
using FClosure = decltype([]<CViewableRange R, typename T> requires (requires { Range::Filter(DeclVal<R>(), DeclVal<T>()); }) (R&& Base, T&& Predicate)
|
||||
{
|
||||
return Range::Filter(Forward<R>(Base), Forward<Pred>(Predicate));
|
||||
return Range::Filter(Forward<R>(Base), Forward<T>(Predicate));
|
||||
});
|
||||
|
||||
return TAdaptorClosure<FClosure, TDecay<Pred>>(Forward<Pred>(Predicate));
|
||||
}
|
||||
|
||||
NAMESPACE_END(Range)
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "Range/Utility.h"
|
||||
#include "Templates/Tuple.h"
|
||||
#include "Templates/Invoke.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
@ -23,50 +24,74 @@ template <CObject D> requires (CSameAs<D, TRemoveCV<D>>)
|
||||
class IAdaptorClosure { };
|
||||
|
||||
/** An adaptor closure helper that wraps a callable object. */
|
||||
template <CMoveConstructible F>
|
||||
class TAdaptorClosure : public IAdaptorClosure<TAdaptorClosure<F>>
|
||||
template <CDefaultConstructible F, CMoveConstructible... Ts> requires (CEmpty<F> && ... && CSameAs<TDecay<Ts>, Ts>)
|
||||
class TAdaptorClosure : public IAdaptorClosure<TAdaptorClosure<F, Ts...>>
|
||||
{
|
||||
public:
|
||||
|
||||
FORCEINLINE constexpr explicit TAdaptorClosure(F InClosure) : Closure(MoveTemp(InClosure)) { }
|
||||
template <typename... Us> requires (CConstructibleFrom<TTuple<Ts...>, Us...> && ... && CSameAs<TDecay<Us>, Ts>)
|
||||
FORCEINLINE constexpr explicit TAdaptorClosure(Us&&... InArgs) : Args(Forward<Us>(InArgs)...) { }
|
||||
|
||||
template <typename R> requires (CInvocable<F&, R>)
|
||||
template <typename R> requires (CInvocable<F, R, Ts&...>)
|
||||
NODISCARD FORCEINLINE constexpr auto operator()(R&& Range) &
|
||||
{
|
||||
return Invoke(Closure, Forward<R>(Range));
|
||||
return [this, &Range]<size_t... Indices>(TIndexSequence<Indices...>)
|
||||
{
|
||||
return Invoke(F(), Forward<R>(Range), Args.template GetValue<Indices>()...);
|
||||
}
|
||||
(TMakeIndexSequence<sizeof...(Ts)>());
|
||||
}
|
||||
|
||||
template <typename R> requires (CInvocable<const F&, R>)
|
||||
template <typename R> requires (CInvocable<F, R, const Ts&...>)
|
||||
NODISCARD FORCEINLINE constexpr auto operator()(R&& Range) const&
|
||||
{
|
||||
return Invoke(Closure, Forward<R>(Range));
|
||||
return [this, &Range]<size_t... Indices>(TIndexSequence<Indices...>)
|
||||
{
|
||||
return Invoke(F(), Forward<R>(Range), Args.template GetValue<Indices>()...);
|
||||
}
|
||||
(TMakeIndexSequence<sizeof...(Ts)>());
|
||||
}
|
||||
|
||||
template <typename R> requires (CInvocable<F&&, R>)
|
||||
template <typename R> requires (CInvocable<F, R, Ts&&...>)
|
||||
NODISCARD FORCEINLINE constexpr auto operator()(R&& Range) &&
|
||||
{
|
||||
return Invoke(MoveTemp(Closure), Forward<R>(Range));
|
||||
return [this, &Range]<size_t... Indices>(TIndexSequence<Indices...>)
|
||||
{
|
||||
return Invoke(F(), Forward<R>(Range), MoveTemp(Args).template GetValue<Indices>()...);
|
||||
}
|
||||
(TMakeIndexSequence<sizeof...(Ts)>());
|
||||
}
|
||||
|
||||
template <typename R> requires (CInvocable<const F&&, R>)
|
||||
template <typename R> requires (CInvocable<F, R, const Ts&&...>)
|
||||
NODISCARD FORCEINLINE constexpr auto operator()(R&& Range) const&&
|
||||
{
|
||||
return Invoke(MoveTemp(Closure), Forward<R>(Range));
|
||||
return [this, &Range]<size_t... Indices>(TIndexSequence<Indices...>)
|
||||
{
|
||||
return Invoke(F(), Forward<R>(Range), MoveTemp(Args).template GetValue<Indices>()...);
|
||||
}
|
||||
(TMakeIndexSequence<sizeof...(Ts)>());
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
NO_UNIQUE_ADDRESS F Closure;
|
||||
NO_UNIQUE_ADDRESS TTuple<Ts...> Args;
|
||||
|
||||
};
|
||||
|
||||
/** A pipe closure that wraps two adaptor closures. */
|
||||
template <CMoveConstructible T, CMoveConstructible U> requires (CDerivedFrom<T, IAdaptorClosure<T>> && CDerivedFrom<U, IAdaptorClosure<U>>)
|
||||
template <CMoveConstructible T, CMoveConstructible U>
|
||||
requires (CSameAs<TRemoveCVRef<T>, T> && CDerivedFrom<T, IAdaptorClosure<T>>
|
||||
&& CSameAs<TRemoveCVRef<U>, U> && CDerivedFrom<U, IAdaptorClosure<U>>)
|
||||
class TPipeClosure final : public IAdaptorClosure<TPipeClosure<T, U>>
|
||||
{
|
||||
public:
|
||||
|
||||
FORCEINLINE constexpr explicit TPipeClosure(T InLHS, U InRHS) : LHS(MoveTemp(InLHS)), RHS(MoveTemp(InRHS)) { }
|
||||
template <typename V, typename W>
|
||||
requires (CSameAs<TRemoveCVRef<V>, T> && CConstructibleFrom<T, V>
|
||||
&& CSameAs<TRemoveCVRef<W>, U> && CConstructibleFrom<U, W>)
|
||||
FORCEINLINE constexpr explicit TPipeClosure(V InLHS, W InRHS)
|
||||
: LHS(Forward<V>(InLHS)), RHS(Forward<W>(InRHS))
|
||||
{ }
|
||||
|
||||
template <typename R> requires (CInvocable<T&, R> && CInvocable<U&, TInvokeResult<T&, R>>)
|
||||
NODISCARD FORCEINLINE constexpr auto operator()(R&& Range) &
|
||||
@ -106,10 +131,12 @@ NODISCARD FORCEINLINE constexpr auto operator|(R&& Range, T&& Closure)
|
||||
}
|
||||
|
||||
/** Create a pipe closure that wraps two adaptor closures. */
|
||||
template <CMoveConstructible T, CMoveConstructible U> requires (CDerivedFrom<T, IAdaptorClosure<T>> && CDerivedFrom<U, IAdaptorClosure<U>>)
|
||||
NODISCARD FORCEINLINE constexpr auto operator|(T LHS, U RHS)
|
||||
template <CMoveConstructible T, CMoveConstructible U>
|
||||
requires (CDerivedFrom<TRemoveCVRef<T>, IAdaptorClosure<TRemoveCVRef<T>>>
|
||||
&& CDerivedFrom<TRemoveCVRef<U>, IAdaptorClosure<TRemoveCVRef<U>>>)
|
||||
NODISCARD FORCEINLINE constexpr auto operator|(T&& LHS, U&& RHS)
|
||||
{
|
||||
return TPipeClosure(MoveTemp(LHS), MoveTemp(RHS));
|
||||
return TPipeClosure<TRemoveCVRef<T>, TRemoveCVRef<U>>(Forward<T>(LHS), Forward<U>(RHS));
|
||||
}
|
||||
|
||||
NAMESPACE_END(Range)
|
||||
|
@ -222,10 +222,12 @@ NODISCARD FORCEINLINE constexpr auto Transform(R&& Base, F&& Func)
|
||||
template <typename F>
|
||||
NODISCARD FORCEINLINE constexpr auto Transform(F&& Func)
|
||||
{
|
||||
return TAdaptorClosure([&Func]<CViewableRange R> requires (requires { Range::Transform(DeclVal<R>(), DeclVal<F>()); }) (R&& Base)
|
||||
using FClosure = decltype([]<CViewableRange R, typename T> requires (requires { Range::Transform(DeclVal<R>(), DeclVal<T>()); }) (R&& Base, T&& Func)
|
||||
{
|
||||
return Range::Transform(Forward<R>(Base), Forward<F>(Func));
|
||||
return Range::Transform(Forward<R>(Base), Forward<T>(Func));
|
||||
});
|
||||
|
||||
return TAdaptorClosure<FClosure, TDecay<F>>(Forward<F>(Func));
|
||||
}
|
||||
|
||||
NAMESPACE_END(Range)
|
||||
|
Loading…
Reference in New Issue
Block a user