From d9f05d4241e435d5b3b7f339824a452d57dd3581 Mon Sep 17 00:00:00 2001 From: Redstone1024 <2824517378@qq.com> Date: Mon, 9 Dec 2024 19:20:10 +0800 Subject: [PATCH] feat(miscellaneous): add basic range factories --- .../Source/Public/Miscellaneous/Range.h | 257 +++++++++++++++++- 1 file changed, 251 insertions(+), 6 deletions(-) diff --git a/Redcraft.Utility/Source/Public/Miscellaneous/Range.h b/Redcraft.Utility/Source/Public/Miscellaneous/Range.h index 19dbcbd..6a16e11 100644 --- a/Redcraft.Utility/Source/Public/Miscellaneous/Range.h +++ b/Redcraft.Utility/Source/Public/Miscellaneous/Range.h @@ -342,6 +342,7 @@ concept CViewableRange = CRange NAMESPACE_BEGIN(Range) +/** A view type that produces a view of no elements of a particular type. */ template class TEmptyView : public TViewInterface> { @@ -352,8 +353,6 @@ public: using Iterator = T*; using Sentinel = T*; - using ReverseIterator = TReverseIterator; - FORCEINLINE constexpr TEmptyView() = default; NODISCARD static FORCEINLINE constexpr Iterator Begin() { return nullptr; } @@ -370,11 +369,12 @@ static_assert( CView>); NAMESPACE_END(Range) -template +template constexpr bool bEnableBorrowedRange> = true; NAMESPACE_BEGIN(Range) +/** A view type that contains exactly one element of a specified value. */ template requires (CMoveConstructible) class TSingleView : public TViewInterface> { @@ -391,9 +391,6 @@ public: using Sentinel = T*; using ConstSentinel = const T*; - using ReverseIterator = TReverseIterator< Iterator>; - using ConstReverseIterator = TReverseIterator; - FORCEINLINE constexpr TSingleView() requires (CDefaultConstructible) = default; FORCEINLINE constexpr explicit TSingleView(const T& InValue) requires (CCopyConstructible) : Value(InValue) { } @@ -427,6 +424,254 @@ static_assert(CContiguousRange>); static_assert( CCommonRange>); static_assert( CView>); +/** A view type that generates a sequence of elements by repeatedly incrementing an initial value. Can be either bounded or unbounded. */ +template S = FUnreachableSentinel> requires (CSemiregular && CCopyable) +class TIotaView : public TViewInterface> +{ +private: + + class FSentinelImpl; + +public: + + using ElementType = W; + + using Reference = const W&; + + class Iterator; + + using Sentinel = TConditional, Iterator, FSentinelImpl>; + + FORCEINLINE constexpr TIotaView() requires (CDefaultConstructible) = default; + + FORCEINLINE constexpr explicit TIotaView(W InValue) requires (CDefaultConstructible) : First(InValue), Last() { } + + FORCEINLINE constexpr explicit TIotaView(TIdentity InValue, TIdentity InLast) : First(InValue), Last(InLast) { } + + FORCEINLINE constexpr explicit TIotaView(Iterator InFirst, Sentinel InLast) : First(InFirst.Value), Last(InLast.Value) { } + + FORCEINLINE constexpr explicit TIotaView(Iterator InFirst, FUnreachableSentinel) requires (CSameAs) : First(InFirst.Value) { } + + NODISCARD FORCEINLINE constexpr Iterator Begin() const { return Iterator(First); } + + NODISCARD FORCEINLINE constexpr Sentinel End() const { return Sentinel(Last); } + + NODISCARD FORCEINLINE constexpr auto Num() const requires ((CIntegral && CIntegral) || CSizedSentinelFor) { return Last - First; } + + NODISCARD FORCEINLINE constexpr bool IsEmpty() const { return First == Last; } + +private: + + NO_UNIQUE_ADDRESS W First; + NO_UNIQUE_ADDRESS S Last; + +public: + + class Iterator final + { + public: + + using ElementType = TRemoveCV; + + FORCEINLINE constexpr Iterator() requires (CDefaultConstructible) = default; + + NODISCARD friend FORCEINLINE constexpr bool operator==(const Iterator& LHS, const Iterator& RHS) requires (CEqualityComparable) { return LHS.Value == RHS.Value; } + + NODISCARD FORCEINLINE constexpr W operator*() const { return Value; } + NODISCARD FORCEINLINE constexpr const W* operator->() const { return AddressOf(Value); } + + FORCEINLINE constexpr Iterator& operator++() { ++Value; return *this; } + + FORCEINLINE constexpr Iterator operator++(int) { Iterator Temp = *this; ++Value; return Temp; } + + private: + + W Value; + + constexpr explicit Iterator(W InValue) : Value(InValue) { } + + friend FSentinelImpl; + + friend TIotaView; + }; + +private: + + class FSentinelImpl final + { + public: + + FORCEINLINE constexpr FSentinelImpl() = default; + + NODISCARD FORCEINLINE constexpr bool operator==(const Iterator& InValue) const& { return Value == InValue.Value; } + + private: + + S Value; + + FORCEINLINE constexpr FSentinelImpl(S InValue) : Value(InValue) { } + + friend TIotaView; + }; + +}; + +template +TIotaView(T, U) -> TIotaView; + +static_assert(CForwardRange>); +static_assert( CView>); + +NAMESPACE_END(Range) + +template +constexpr bool bEnableBorrowedRange> = true; + +NAMESPACE_BEGIN(Range) + +/** A view type that generates a sequence of elements by repeatedly producing the same value. Can be either bounded or unbounded. */ +template requires (CMoveConstructible && CSameAs>) +class TRepeatView : public TViewInterface> +{ +public: + + using ElementType = W; + + using Reference = const W&; + + class Iterator; + + using Sentinel = TConditional; + + FORCEINLINE constexpr TRepeatView() requires CDefaultConstructible = default; + + FORCEINLINE constexpr explicit TRepeatView(W InValue) requires (bIsUnreachable) : Value(MoveTemp(InValue)) { } + + FORCEINLINE constexpr explicit TRepeatView(W InValue, size_t InCount) requires (!bIsUnreachable) : Value(MoveTemp(InValue)), Count(InCount) { } + + NODISCARD FORCEINLINE constexpr Iterator Begin() const { return Iterator(*this, 0); } + + NODISCARD FORCEINLINE constexpr Sentinel End() const + { + if constexpr (bIsUnreachable) + { + return UnreachableSentinel; + } + + else return Sentinel(*this, Count); + } + + NODISCARD FORCEINLINE constexpr size_t Num() const requires (!bIsUnreachable) { return Count; } + +private: + + using FSizeType = TConditional; + + NO_UNIQUE_ADDRESS W Value; + + NO_UNIQUE_ADDRESS FSizeType Count; + +public: + + class Iterator final + { + public: + + using ElementType = W; + + FORCEINLINE constexpr Iterator() requires (CDefaultConstructible) = default; + + NODISCARD friend FORCEINLINE constexpr bool operator==(const Iterator& LHS, const Iterator& RHS) { return LHS.Current == RHS.Current; } + + NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const Iterator& LHS, const Iterator& RHS) { return LHS.Current <=> RHS.Current; } + + NODISCARD FORCEINLINE constexpr const W& operator*() const { return Owner->Value; } + NODISCARD FORCEINLINE constexpr const W* operator->() const { return AddressOf(Owner->Value); } + + NODISCARD FORCEINLINE constexpr const W& operator[](ptrdiff Index) const { return *(*this + Index); } + + FORCEINLINE constexpr Iterator& operator++() { ++Current; return *this; } + FORCEINLINE constexpr Iterator& operator--() { --Current; return *this; } + + FORCEINLINE constexpr Iterator operator++(int) { Iterator Temp = *this; --Current; return Temp; } + FORCEINLINE constexpr Iterator operator--(int) { Iterator Temp = *this; ++Current; return Temp; } + + FORCEINLINE constexpr Iterator& operator+=(ptrdiff Offset) { Current -= Offset; return *this; } + FORCEINLINE constexpr Iterator& operator-=(ptrdiff Offset) { Current += Offset; return *this; } + + NODISCARD friend FORCEINLINE constexpr Iterator operator+(Iterator Iter, ptrdiff Offset) { Iterator Temp = Iter; Temp -= Offset; return Temp; } + NODISCARD friend FORCEINLINE constexpr Iterator operator+(ptrdiff Offset, Iterator Iter) { Iterator Temp = Iter; Temp -= Offset; return Temp; } + + NODISCARD FORCEINLINE constexpr Iterator operator-(ptrdiff Offset) const { Iterator Temp = *this; Temp += Offset; return Temp; } + + NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const Iterator& LHS, const Iterator& RHS) { return RHS.Current - LHS.Current; } + + private: + + const TRepeatView* Owner; + + NO_UNIQUE_ADDRESS size_t Current; + + FORCEINLINE constexpr Iterator(const TRepeatView& InOwner, size_t InCurrent) : Owner(&InOwner), Current(InCurrent) { } + + friend TRepeatView; + }; + +}; + +template +TRepeatView(W) -> TRepeatView; + +template +TRepeatView(W, size_t) -> TRepeatView; + +static_assert(CRandomAccessRange>); +static_assert( CCommonRange>); +static_assert( CView>); + +NAMESPACE_END(Range) + +NAMESPACE_BEGIN(Range) + +/** A view of no elements of a particular type. */ +template +inline constexpr TEmptyView Empty; + +/** Creates a view that contains exactly one element of a specified value. */ +template requires (CObject> && CMoveConstructible>) +NODISCARD FORCEINLINE constexpr TSingleView> Single(T&& Value) +{ + return TSingleView>(Forward(Value)); +} + +/** Creates a view that generates a sequence of elements by repeatedly incrementing an initial value. */ +template requires (CWeaklyIncrementable> && CCopyable>) +NODISCARD FORCEINLINE constexpr TIotaView> Iota(W&& Value) +{ + return TIotaView>(Forward(Value)); +} + +/** Creates a view that generates a sequence of elements by repeatedly incrementing an initial value. */ +template requires (CWeaklyIncrementable> && CWeaklyEqualityComparable && CCopyable> && CSemiregular>) +NODISCARD FORCEINLINE constexpr TIotaView, TDecay> Iota(W&& Value, S&& Last) +{ + return TIotaView, TDecay>(Forward(Value), Forward(Last)); +} + +/** Creates a view that generates a sequence of elements by repeatedly producing the same value. */ +template requires (CObject> && CMoveConstructible>) +NODISCARD FORCEINLINE constexpr TRepeatView> Repeat(W&& Value) +{ + return TRepeatView>(Forward(Value)); +} + +/** Creates a view that generates a sequence of elements by repeatedly producing the same value. */ +template requires (CObject> && CMoveConstructible>) +NODISCARD FORCEINLINE constexpr TRepeatView, false> Repeat(W&& Value, size_t Count) +{ + return TRepeatView, false>(Forward(Value), Count); +} + NAMESPACE_END(Range) template requires (CRange>)