From 89dc5b715e223b4b575012e65715b63b9a1ef393 Mon Sep 17 00:00:00 2001 From: Redstone1024 <2824517378@qq.com> Date: Sun, 8 Dec 2024 20:38:33 +0800 Subject: [PATCH] fix(miscellaneous): fix iterator for only movable base object --- .../Public/Miscellaneous/ConstantIterator.h | 14 +- .../Source/Public/Miscellaneous/Iterator.h | 202 +++++++++--------- 2 files changed, 109 insertions(+), 107 deletions(-) diff --git a/Redcraft.Utility/Source/Public/Miscellaneous/ConstantIterator.h b/Redcraft.Utility/Source/Public/Miscellaneous/ConstantIterator.h index 4d6bed3..66c35d4 100644 --- a/Redcraft.Utility/Source/Public/Miscellaneous/ConstantIterator.h +++ b/Redcraft.Utility/Source/Public/Miscellaneous/ConstantIterator.h @@ -136,16 +136,16 @@ public: FORCEINLINE constexpr explicit TCountedIterator(U&& InValue, ptrdiff N) : Current(Forward(InValue)), Length(N) { check_code({ MaxLength = N; }); } template requires (!CSameAs && CConstructibleFrom) - FORCEINLINE constexpr explicit (!CConvertibleTo) TCountedIterator(const TCountedIterator& InValue) : Current(InValue.GetBase()), Length(InValue.Num()) { check_code({ MaxLength = InValue.MaxLength; }); } + FORCEINLINE constexpr explicit (!CConvertibleTo) TCountedIterator(const TCountedIterator& InValue) : Current(InValue.Current), Length(InValue.Num()) { check_code({ MaxLength = InValue.MaxLength; }); } template requires (!CSameAs && CConstructibleFrom) - FORCEINLINE constexpr explicit (!CConvertibleTo) TCountedIterator(TCountedIterator&& InValue) : Current(MoveTemp(InValue).GetBase()), Length(InValue.Num()) { check_code({ MaxLength = InValue.MaxLength; }); } + FORCEINLINE constexpr explicit (!CConvertibleTo) TCountedIterator(TCountedIterator&& InValue) : Current(MoveTemp(InValue).Current), Length(InValue.Num()) { check_code({ MaxLength = InValue.MaxLength; }); } template requires (!CSameAs && CConvertibleTo && CAssignableFrom) - FORCEINLINE constexpr TCountedIterator& operator=(const TCountedIterator& InValue) { Current = InValue.GetBase(); Length = InValue.Num(); check_code({ MaxLength = InValue.MaxLength; }); return *this; } + FORCEINLINE constexpr TCountedIterator& operator=(const TCountedIterator& InValue) { Current = InValue.Current; Length = InValue.Num(); check_code({ MaxLength = InValue.MaxLength; }); return *this; } template requires (!CSameAs && CConvertibleTo && CAssignableFrom) - FORCEINLINE constexpr TCountedIterator& operator=(TCountedIterator&& InValue) { Current = MoveTemp(InValue).GetBase(); Length = InValue.Num(); check_code({ MaxLength = InValue.MaxLength; }); return *this; } + FORCEINLINE constexpr TCountedIterator& operator=(TCountedIterator&& InValue) { Current = MoveTemp(InValue).Current; Length = InValue.Num(); check_code({ MaxLength = InValue.MaxLength; }); return *this; } template J> NODISCARD friend FORCEINLINE constexpr bool operator==(const TCountedIterator& LHS, const TCountedIterator& RHS) { return LHS.Length == RHS.Length; } @@ -182,9 +182,9 @@ public: NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TCountedIterator& LHS, FDefaultSentinel) { LHS.CheckThis(); return -LHS.Num(); } NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(FDefaultSentinel, const TCountedIterator& RHS) { RHS.CheckThis(); return RHS.Num(); } - NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { CheckThis(); return Current; } - NODISCARD FORCEINLINE constexpr IteratorType GetBase() && { CheckThis(); return Current; } - NODISCARD FORCEINLINE constexpr ptrdiff Num() const { CheckThis(); return Length; } + NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { CheckThis(); return Current; } + NODISCARD FORCEINLINE constexpr IteratorType GetBase() && { CheckThis(); return MoveTemp(Current); } + NODISCARD FORCEINLINE constexpr ptrdiff Num() const { CheckThis(); return Length; } private: diff --git a/Redcraft.Utility/Source/Public/Miscellaneous/Iterator.h b/Redcraft.Utility/Source/Public/Miscellaneous/Iterator.h index 43f2ea0..f43c5a7 100644 --- a/Redcraft.Utility/Source/Public/Miscellaneous/Iterator.h +++ b/Redcraft.Utility/Source/Public/Miscellaneous/Iterator.h @@ -17,13 +17,11 @@ NAMESPACE_PRIVATE_BEGIN template using WithReference = T&; -template struct TIteratorElementType { using Type = typename I::ElementType; }; +template struct TIteratorElementType { using Type = typename I::ElementType; }; +template struct TIteratorElementType { using Type = TRemoveCV; }; -template struct TIteratorElementType { using Type = TRemoveCV; }; - -template struct TIteratorPointerType { using Type = void; }; - -template struct TIteratorPointerType { using Type = T*; }; +template struct TIteratorPointerType { using Type = void; }; +template struct TIteratorPointerType { using Type = T*; }; template requires (requires(I& Iter) { { Iter.operator->() } -> CPointer; }) struct TIteratorPointerType { using Type = decltype(DeclVal().operator->()); }; @@ -138,6 +136,62 @@ concept CContiguousIterator = CRandomAccessIterator && CLValueReference); +NAMESPACE_BEGIN(Iteration) + +/** Increments given iterator 'Iter' by 'N' elements. */ +template +FORCEINLINE constexpr void Advance(I& Iter, ptrdiff N) +{ + if constexpr (CRandomAccessIterator) + { + Iter += N; + } + else if constexpr (CBidirectionalIterator) + { + for (; N > 0; --N) ++Iter; + for (; N < 0; ++N) --Iter; + } + else + { + checkf(N >= 0, TEXT("The iterator must satisfy the CBidirectionalIterator in order to be decremented.")); + for (; N > 0; --N) ++Iter; + } +} + +/** @return The number of hops from 'First' to 'Last'. */ +template S> +FORCEINLINE constexpr ptrdiff Distance(I First, S Last) +{ + if constexpr (CSizedSentinelFor) + { + return Last - First; + } + else + { + ptrdiff Result = 0; + for (; First != Last; ++First) ++Result; + return Result; + } +} + +/** @return The 'N'-th successor of iterator 'Iter'. */ +template +FORCEINLINE constexpr I Next(I Iter, TMakeUnsigned N = 1) +{ + Iteration::Advance(Iter, N); + return Iter; +} + +/** @return The 'N'-th predecessor of iterator 'Iter'. */ +template +FORCEINLINE constexpr I Prev(I Iter, TMakeUnsigned N = 1) +{ + Iteration::Advance(Iter, -N); + return Iter; +} + +NAMESPACE_END(Iteration) + /** A iterator adaptor for reverse-order traversal. */ template class TReverseIterator final @@ -161,27 +215,27 @@ public: FORCEINLINE constexpr explicit TReverseIterator(T&& InValue) : Current(Forward(InValue)) { } template requires (!CSameAs && CConstructibleFrom) - FORCEINLINE constexpr explicit (!CConvertibleTo) TReverseIterator(const TReverseIterator& InValue) : Current(InValue.GetBase()) { } + FORCEINLINE constexpr explicit (!CConvertibleTo) TReverseIterator(const TReverseIterator& InValue) : Current(InValue.Current) { } template requires (!CSameAs && CConstructibleFrom) - FORCEINLINE constexpr explicit (!CConvertibleTo) TReverseIterator(TReverseIterator&& InValue) : Current(MoveTemp(InValue).GetBase()) { } + FORCEINLINE constexpr explicit (!CConvertibleTo) TReverseIterator(TReverseIterator&& InValue) : Current(MoveTemp(InValue).Current) { } template requires (!CSameAs && CConvertibleTo && CAssignableFrom) - FORCEINLINE constexpr TReverseIterator& operator=(const TReverseIterator& InValue) { Current = InValue.GetBase(); return *this; } + FORCEINLINE constexpr TReverseIterator& operator=(const TReverseIterator& InValue) { Current = InValue.Current; return *this; } template requires (!CSameAs && CConvertibleTo && CAssignableFrom) - FORCEINLINE constexpr TReverseIterator& operator=(TReverseIterator&& InValue) { Current = MoveTemp(InValue).GetBase(); return *this; } + FORCEINLINE constexpr TReverseIterator& operator=(TReverseIterator&& InValue) { Current = MoveTemp(InValue).Current; return *this; } template requires (CSentinelFor) - NODISCARD friend FORCEINLINE constexpr bool operator==(const TReverseIterator& LHS, const TReverseIterator& RHS) { return LHS.GetBase() == RHS.GetBase(); } + NODISCARD friend FORCEINLINE constexpr bool operator==(const TReverseIterator& LHS, const TReverseIterator& RHS) { return LHS.Current == RHS.Current; } template requires (CSizedSentinelFor) - NODISCARD friend FORCEINLINE constexpr TCompareThreeWayResult operator<=>(const TReverseIterator& LHS, const TReverseIterator& RHS) { return RHS.GetBase() <=> LHS.GetBase(); } + NODISCARD friend FORCEINLINE constexpr TCompareThreeWayResult operator<=>(const TReverseIterator& LHS, const TReverseIterator& RHS) { return RHS.Current <=> LHS.Current; } - NODISCARD FORCEINLINE constexpr TIteratorReferenceType operator*() const { IteratorType Temp = GetBase(); return *--Temp; } - NODISCARD FORCEINLINE constexpr TIteratorPointerType operator->() const { IteratorType Temp = GetBase(); return ToAddress(--Temp); } + NODISCARD FORCEINLINE constexpr TIteratorReferenceType operator*() const { IteratorType Temp = Current; return *--Temp; } + NODISCARD FORCEINLINE constexpr TIteratorPointerType operator->() const { IteratorType Temp = Current; return ToAddress(--Temp); } - NODISCARD FORCEINLINE constexpr TIteratorReferenceType operator[](ptrdiff Index) const requires (CRandomAccessIterator) { return GetBase()[-Index - 1]; } + NODISCARD FORCEINLINE constexpr TIteratorReferenceType operator[](ptrdiff Index) const requires (CRandomAccessIterator) { return Current[-Index - 1]; } FORCEINLINE constexpr TReverseIterator& operator++() { --Current; return *this; } FORCEINLINE constexpr TReverseIterator& operator--() { ++Current; return *this; } @@ -197,10 +251,10 @@ public: NODISCARD FORCEINLINE constexpr TReverseIterator operator-(ptrdiff Offset) const requires (CRandomAccessIterator) { TReverseIterator Temp = *this; Temp += Offset; return Temp; } - NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TReverseIterator& LHS, const TReverseIterator& RHS) { return RHS.GetBase() - LHS.GetBase(); } + NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TReverseIterator& LHS, const TReverseIterator& RHS) { return RHS.Current - LHS.Current; } - NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { return Current; } - NODISCARD FORCEINLINE constexpr IteratorType GetBase() && { return Current; } + NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { return Current; } + NODISCARD FORCEINLINE constexpr IteratorType GetBase() && { return MoveTemp(Current); } private: @@ -236,27 +290,27 @@ public: FORCEINLINE constexpr explicit TMoveIterator(T&& InValue) : Current(Forward(InValue)) { } template requires (!CSameAs && CConstructibleFrom) - FORCEINLINE constexpr explicit (!CConvertibleTo) TMoveIterator(const TMoveIterator& InValue) : Current(InValue.GetBase()) { } + FORCEINLINE constexpr explicit (!CConvertibleTo) TMoveIterator(const TMoveIterator& InValue) : Current(InValue.Current) { } template requires (!CSameAs && CConstructibleFrom) - FORCEINLINE constexpr explicit (!CConvertibleTo) TMoveIterator(TMoveIterator&& InValue) : Current(MoveTemp(InValue).GetBase()) { } + FORCEINLINE constexpr explicit (!CConvertibleTo) TMoveIterator(TMoveIterator&& InValue) : Current(MoveTemp(InValue).Current) { } template requires (!CSameAs && CConvertibleTo && CAssignableFrom) - FORCEINLINE constexpr TMoveIterator& operator=(const TMoveIterator& InValue) { Current = InValue.GetBase(); return *this; } + FORCEINLINE constexpr TMoveIterator& operator=(const TMoveIterator& InValue) { Current = InValue.Current; return *this; } template requires (!CSameAs && CConvertibleTo && CAssignableFrom) - FORCEINLINE constexpr TMoveIterator& operator=(TMoveIterator&& InValue) { Current = MoveTemp(InValue).GetBase(); return *this; } + FORCEINLINE constexpr TMoveIterator& operator=(TMoveIterator&& InValue) { Current = MoveTemp(InValue).Current; return *this; } template requires (CSentinelFor) - NODISCARD friend FORCEINLINE constexpr bool operator==(const TMoveIterator& LHS, const TMoveIterator& RHS) { return LHS.GetBase() == RHS.GetBase(); } + NODISCARD friend FORCEINLINE constexpr bool operator==(const TMoveIterator& LHS, const TMoveIterator& RHS) { return LHS.Current == RHS.Current; } template requires (CSizedSentinelFor) - NODISCARD friend FORCEINLINE constexpr TCompareThreeWayResult operator<=>(const TMoveIterator& LHS, const TMoveIterator& RHS) { return LHS.GetBase() <=> RHS.GetBase(); } + NODISCARD friend FORCEINLINE constexpr TCompareThreeWayResult operator<=>(const TMoveIterator& LHS, const TMoveIterator& RHS) { return LHS.Current <=> RHS.Current; } - NODISCARD FORCEINLINE constexpr TIteratorRValueReferenceType operator*() const { return MoveTemp(*GetBase()); } + NODISCARD FORCEINLINE constexpr TIteratorRValueReferenceType operator*() const { return MoveTemp(*Current); } NODISCARD FORCEINLINE constexpr TIteratorPointerType operator->() const = delete; - NODISCARD FORCEINLINE constexpr TIteratorRValueReferenceType operator[](ptrdiff Index) const requires (CRandomAccessIterator) { return MoveTemp(GetBase()[Index]); } + NODISCARD FORCEINLINE constexpr TIteratorRValueReferenceType operator[](ptrdiff Index) const requires (CRandomAccessIterator) { return MoveTemp(Current[Index]); } FORCEINLINE constexpr TMoveIterator& operator++() { ++Current; return *this; } FORCEINLINE constexpr TMoveIterator& operator--() requires (CBidirectionalIterator) { --Current; return *this; } @@ -273,10 +327,10 @@ public: NODISCARD FORCEINLINE constexpr TMoveIterator operator-(ptrdiff Offset) const requires (CRandomAccessIterator) { TMoveIterator Temp = *this; Temp -= Offset; return Temp; } - NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TMoveIterator& LHS, const TMoveIterator& RHS) { return LHS.GetBase() - RHS.GetBase(); } + NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TMoveIterator& LHS, const TMoveIterator& RHS) { return LHS.Current - RHS.Current; } - NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { return Current; } - NODISCARD FORCEINLINE constexpr IteratorType GetBase() && { return Current; } + NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { return Current; } + NODISCARD FORCEINLINE constexpr IteratorType GetBase() && { return MoveTemp(Current); } private: @@ -304,38 +358,38 @@ public: FORCEINLINE constexpr ~TMoveSentinel() = default; template requires (!CSameAs> && CConstructibleFrom) - FORCEINLINE constexpr explicit TMoveSentinel(T&& InValue) : Last(Forward(InValue)) { } + FORCEINLINE constexpr explicit TMoveSentinel(T&& InValue) : Current(Forward(InValue)) { } template requires (!CSameAs && CConstructibleFrom) - FORCEINLINE constexpr explicit (!CConvertibleTo) TMoveSentinel(const TMoveSentinel& InValue) : Last(InValue.GetBase()) { } + FORCEINLINE constexpr explicit (!CConvertibleTo) TMoveSentinel(const TMoveSentinel& InValue) : Current(InValue.Current) { } template requires (!CSameAs && CConstructibleFrom) - FORCEINLINE constexpr explicit (!CConvertibleTo) TMoveSentinel(TMoveSentinel&& InValue) : Last(MoveTemp(InValue).GetBase()) { } + FORCEINLINE constexpr explicit (!CConvertibleTo) TMoveSentinel(TMoveSentinel&& InValue) : Current(MoveTemp(InValue).Current) { } template requires (!CSameAs && CConvertibleTo && CAssignableFrom) - FORCEINLINE constexpr TMoveSentinel& operator=(const TMoveSentinel& InValue) { Last = InValue.GetBase(); return *this; } + FORCEINLINE constexpr TMoveSentinel& operator=(const TMoveSentinel& InValue) { Current = InValue.Current; return *this; } template requires (!CSameAs && CConvertibleTo && CAssignableFrom) - FORCEINLINE constexpr TMoveSentinel& operator=(TMoveSentinel&& InValue) { Last = MoveTemp(InValue).GetBase(); return *this; } + FORCEINLINE constexpr TMoveSentinel& operator=(TMoveSentinel&& InValue) { Current = MoveTemp(InValue).Current; return *this; } template requires (CSentinelFor) - NODISCARD FORCEINLINE constexpr bool operator==(const TMoveIterator& InValue) const& { return GetBase() == InValue.GetBase(); } + NODISCARD FORCEINLINE constexpr bool operator==(const TMoveIterator& InValue) const& { return Current == InValue.Current; } template requires (CSizedSentinelFor) - NODISCARD FORCEINLINE constexpr TCompareThreeWayResult operator<=>(const TMoveIterator& InValue) const& { return GetBase() <=> InValue.GetBase(); } + NODISCARD FORCEINLINE constexpr TCompareThreeWayResult operator<=>(const TMoveIterator& InValue) const& { return Current <=> InValue.Current; } template requires (CSizedSentinelFor) - NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TMoveSentinel& Sentinel, const TMoveIterator& Iter) { return Sentinel.GetBase() - Iter.GetBase(); } + NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TMoveSentinel& Sentinel, const TMoveIterator& Iter) { return Sentinel.Current - Iter.Current; } template requires (CSizedSentinelFor) - NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TMoveIterator& Iter, const TMoveSentinel& Sentinel) { return Iter.GetBase() - Sentinel.GetBase(); } + NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TMoveIterator& Iter, const TMoveSentinel& Sentinel) { return Iter.Current - Sentinel.Current; } - NODISCARD FORCEINLINE constexpr const SentinelType& GetBase() const& { return Last; } - NODISCARD FORCEINLINE constexpr SentinelType GetBase() && { return Last; } + NODISCARD FORCEINLINE constexpr const SentinelType& GetBase() const& { return Current; } + NODISCARD FORCEINLINE constexpr SentinelType GetBase() && { return MoveTemp(Current); } private: - SentinelType Last; + SentinelType Current; }; @@ -382,16 +436,16 @@ public: FORCEINLINE constexpr explicit TCountedIterator(T&& InValue, ptrdiff N) : Current(Forward(InValue)), Length(N) { check_code({ MaxLength = N; }); } template requires (!CSameAs && CConstructibleFrom) - FORCEINLINE constexpr explicit (!CConvertibleTo) TCountedIterator(const TCountedIterator& InValue) : Current(InValue.GetBase()), Length(InValue.Num()) { check_code({ MaxLength = InValue.MaxLength; }); } + FORCEINLINE constexpr explicit (!CConvertibleTo) TCountedIterator(const TCountedIterator& InValue) : Current(InValue.Current), Length(InValue.Num()) { check_code({ MaxLength = InValue.MaxLength; }); } template requires (!CSameAs && CConstructibleFrom) - FORCEINLINE constexpr explicit (!CConvertibleTo) TCountedIterator(TCountedIterator&& InValue) : Current(MoveTemp(InValue).GetBase()), Length(InValue.Num()) { check_code({ MaxLength = InValue.MaxLength; }); } + FORCEINLINE constexpr explicit (!CConvertibleTo) TCountedIterator(TCountedIterator&& InValue) : Current(MoveTemp(InValue).Current), Length(InValue.Num()) { check_code({ MaxLength = InValue.MaxLength; }); } template requires (!CSameAs && CConvertibleTo && CAssignableFrom) - FORCEINLINE constexpr TCountedIterator& operator=(const TCountedIterator& InValue) { Current = InValue.GetBase(); Length = InValue.Num(); check_code({ MaxLength = InValue.MaxLength; }); return *this; } + FORCEINLINE constexpr TCountedIterator& operator=(const TCountedIterator& InValue) { Current = InValue.Current; Length = InValue.Num(); check_code({ MaxLength = InValue.MaxLength; }); return *this; } template requires (!CSameAs && CConvertibleTo && CAssignableFrom) - FORCEINLINE constexpr TCountedIterator& operator=(TCountedIterator&& InValue) { Current = MoveTemp(InValue).GetBase(); Length = InValue.Num(); check_code({ MaxLength = InValue.MaxLength; }); return *this; } + FORCEINLINE constexpr TCountedIterator& operator=(TCountedIterator&& InValue) { Current = MoveTemp(InValue).Current; Length = InValue.Num(); check_code({ MaxLength = InValue.MaxLength; }); return *this; } template J> NODISCARD friend FORCEINLINE constexpr bool operator==(const TCountedIterator& LHS, const TCountedIterator& RHS) { return LHS.Length == RHS.Length; } @@ -432,9 +486,9 @@ public: NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TCountedIterator& LHS, FDefaultSentinel) { LHS.CheckThis(); return -LHS.Num(); } NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(FDefaultSentinel, const TCountedIterator& RHS) { RHS.CheckThis(); return RHS.Num(); } - NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { CheckThis(); return Current; } - NODISCARD FORCEINLINE constexpr IteratorType GetBase() && { CheckThis(); return Current; } - NODISCARD FORCEINLINE constexpr ptrdiff Num() const { CheckThis(); return Length; } + NODISCARD FORCEINLINE constexpr const IteratorType& GetBase() const& { CheckThis(); return Current; } + NODISCARD FORCEINLINE constexpr IteratorType GetBase() && { CheckThis(); return MoveTemp(Current); } + NODISCARD FORCEINLINE constexpr ptrdiff Num() const { CheckThis(); return Length; } private: @@ -625,58 +679,6 @@ NODISCARD FORCEINLINE constexpr auto MakeInserter(C& Container, const typename C NAMESPACE_BEGIN(Iteration) -/** Increments given iterator 'Iter' by 'N' elements. */ -template -FORCEINLINE constexpr void Advance(I& Iter, ptrdiff N) -{ - if constexpr (CRandomAccessIterator) - { - Iter += N; - } - else if constexpr (CBidirectionalIterator) - { - for (; N > 0; --N) ++Iter; - for (; N < 0; ++N) --Iter; - } - else - { - checkf(N >= 0, TEXT("The iterator must satisfy the CBidirectionalIterator in order to be decremented.")); - for (; N > 0; --N) ++Iter; - } -} - -/** @return The number of hops from 'First' to 'Last'. */ -template S> -FORCEINLINE constexpr ptrdiff Distance(I First, S Last) -{ - if constexpr (CSizedSentinelFor) - { - return Last - First; - } - else - { - ptrdiff Result = 0; - for (; First != Last; ++First) ++Result; - return Result; - } -} - -/** @return The 'N'-th successor of iterator 'Iter'. */ -template -FORCEINLINE constexpr I Next(I Iter, TMakeUnsigned N = 1) -{ - Advance(Iter, N); - return Iter; -} - -/** @return The 'N'-th predecessor of iterator 'Iter'. */ -template -FORCEINLINE constexpr I Prev(I Iter, TMakeUnsigned N = 1) -{ - Advance(Iter, -N); - return Iter; -} - /** @return The iterator to the beginning of a container. */ template requires (requires(T&& Container) { { Container.Begin() } -> CForwardIterator; }) FORCEINLINE constexpr auto Begin(T&& Container)