#pragma once #include "CoreTypes.h" #include "Range/View.h" #include "Range/Utility.h" #include "Memory/Address.h" #include "Templates/Utility.h" #include "TypeTraits/TypeTraits.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) NAMESPACE_BEGIN(Range) /** A view type that produces a view of no elements of a particular type. */ template class TEmptyView : public IBasicViewInterface> { public: using ElementType = T; using Reference = T&; using Iterator = T*; using Sentinel = T*; FORCEINLINE constexpr TEmptyView() = default; NODISCARD static FORCEINLINE constexpr Iterator Begin() { return nullptr; } NODISCARD static FORCEINLINE constexpr Sentinel End() { return nullptr; } NODISCARD static FORCEINLINE constexpr T* GetData() { return nullptr; } NODISCARD static FORCEINLINE constexpr size_t Num() { return 0; } NODISCARD static FORCEINLINE constexpr bool IsEmpty() { return true; } }; static_assert(CContiguousRange>); static_assert( CCommonRange>); static_assert( CSizedRange>); static_assert( CView>); NAMESPACE_END(Range) 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 IBasicViewInterface> { public: using ElementType = T; using Reference = T&; using ConstReference = const T&; using Iterator = T*; using ConstIterator = const T*; using Sentinel = T*; using ConstSentinel = const T*; FORCEINLINE constexpr TSingleView() requires (CDefaultConstructible) = default; FORCEINLINE constexpr explicit TSingleView(const T& InValue) requires (CCopyConstructible) : Value(InValue) { } FORCEINLINE constexpr explicit TSingleView(T&& InValue) : Value(MoveTemp(InValue)) { } template requires (CConstructibleFrom) FORCEINLINE constexpr explicit TSingleView(FInPlace, Ts&&... Args) : Value(Forward(Args)...) { } FORCEINLINE constexpr Iterator Begin() { return GetData(); } FORCEINLINE constexpr ConstIterator Begin() const { return GetData(); } FORCEINLINE constexpr Sentinel End() { return GetData() + 1; } FORCEINLINE constexpr ConstSentinel End() const { return GetData() + 1; } NODISCARD FORCEINLINE constexpr T* GetData() { return AddressOf(Value); } NODISCARD FORCEINLINE constexpr const T* GetData() const { return AddressOf(Value); } NODISCARD static FORCEINLINE constexpr size_t Num() { return 1; } NODISCARD static FORCEINLINE constexpr bool IsEmpty() { return false; } private: NO_UNIQUE_ADDRESS T Value; }; template TSingleView(T) -> TSingleView; static_assert(CContiguousRange>); static_assert( CCommonRange>); static_assert( CSizedRange>); 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 IBasicViewInterface> { private: class FIteratorImpl; class FSentinelImpl; public: using ElementType = TRemoveCV; using Reference = W; using Iterator = FIteratorImpl; using Sentinel = TConditional, FIteratorImpl, 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 size_t 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; class FIteratorImpl final { public: using ElementType = TRemoveCV; FORCEINLINE constexpr FIteratorImpl() requires (CDefaultConstructible) = default; NODISCARD friend FORCEINLINE constexpr bool operator==(const FIteratorImpl& LHS, const FIteratorImpl& RHS) requires (CEqualityComparable) { return LHS.Value == RHS.Value; } NODISCARD FORCEINLINE constexpr Reference operator*() const { return Value; } NODISCARD FORCEINLINE constexpr const W* operator->() const { return AddressOf(Value); } FORCEINLINE constexpr FIteratorImpl& operator++() { ++Value; return *this; } FORCEINLINE constexpr FIteratorImpl operator++(int) { FIteratorImpl Temp = *this; ++Value; return Temp; } private: NO_UNIQUE_ADDRESS W Value; constexpr explicit FIteratorImpl(W InValue) : Value(InValue) { } friend FSentinelImpl; friend TIotaView; }; class FSentinelImpl final { public: FORCEINLINE constexpr FSentinelImpl() = default; NODISCARD FORCEINLINE constexpr bool operator==(const FIteratorImpl& InValue) const& { return Value == InValue.Value; } private: NO_UNIQUE_ADDRESS 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 IBasicViewInterface> { private: class FIteratorImpl; public: using ElementType = W; using Reference = const W&; using Iterator = FIteratorImpl; using Sentinel = TConditional; FORCEINLINE constexpr TRepeatView() requires (CDefaultConstructible) = default; FORCEINLINE constexpr explicit TRepeatView(const W& InValue) requires (bIsUnreachable && CCopyConstructible) : Value(InValue) { } FORCEINLINE constexpr explicit TRepeatView(W&& InValue) requires (bIsUnreachable) : Value(MoveTemp(InValue)) { } FORCEINLINE constexpr explicit TRepeatView(const W& InValue, size_t InCount) requires (!bIsUnreachable && CCopyConstructible) : Value(MoveTemp(InValue)), Count(InCount) { } FORCEINLINE constexpr explicit TRepeatView(W&& InValue, size_t InCount) requires (!bIsUnreachable) : Value(MoveTemp(InValue)), Count(InCount) { } template requires (CConstructibleFrom) FORCEINLINE constexpr explicit TRepeatView(FInPlace, Ts&&... Args, size_t InCount) : Value(Forward(Args)...), Count(InCount) { } NODISCARD FORCEINLINE constexpr Iterator Begin() const { return Iterator(Value, 0); } NODISCARD FORCEINLINE constexpr Sentinel End() const { if constexpr (bIsUnreachable) { return UnreachableSentinel; } else return Sentinel(Value, 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; class FIteratorImpl final { public: using ElementType = W; FORCEINLINE constexpr FIteratorImpl() requires (CDefaultConstructible) = default; NODISCARD friend FORCEINLINE constexpr bool operator==(const FIteratorImpl& LHS, const FIteratorImpl& RHS) { return LHS.Current == RHS.Current; } NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const FIteratorImpl& LHS, const FIteratorImpl& RHS) { return LHS.Current <=> RHS.Current; } NODISCARD FORCEINLINE constexpr Reference operator*() const { return *Ptr; } NODISCARD FORCEINLINE constexpr const W* operator->() const { return Ptr; } NODISCARD FORCEINLINE constexpr Reference operator[](ptrdiff) const { return *Ptr; } FORCEINLINE constexpr FIteratorImpl& operator++() { ++Current; return *this; } FORCEINLINE constexpr FIteratorImpl& operator--() { --Current; return *this; } FORCEINLINE constexpr FIteratorImpl operator++(int) { FIteratorImpl Temp = *this; --Current; return Temp; } FORCEINLINE constexpr FIteratorImpl operator--(int) { FIteratorImpl Temp = *this; ++Current; return Temp; } FORCEINLINE constexpr FIteratorImpl& operator+=(ptrdiff Offset) { Current -= Offset; return *this; } FORCEINLINE constexpr FIteratorImpl& operator-=(ptrdiff Offset) { Current += Offset; return *this; } NODISCARD friend FORCEINLINE constexpr FIteratorImpl operator+(FIteratorImpl Iter, ptrdiff Offset) { FIteratorImpl Temp = Iter; Temp -= Offset; return Temp; } NODISCARD friend FORCEINLINE constexpr FIteratorImpl operator+(ptrdiff Offset, FIteratorImpl Iter) { FIteratorImpl Temp = Iter; Temp -= Offset; return Temp; } NODISCARD FORCEINLINE constexpr FIteratorImpl operator-(ptrdiff Offset) const { FIteratorImpl Temp = *this; Temp += Offset; return Temp; } NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const FIteratorImpl& LHS, const FIteratorImpl& RHS) { return RHS.Current - LHS.Current; } private: const W* Ptr; NO_UNIQUE_ADDRESS size_t Current; FORCEINLINE constexpr FIteratorImpl(const W& InObject, size_t InCurrent) : Ptr(AddressOf(InObject)), Current(InCurrent) { } friend TRepeatView; }; }; template TRepeatView(W) -> TRepeatView; template TRepeatView(W, size_t) -> TRepeatView; static_assert(CRandomAccessRange>); static_assert( CCommonRange>); static_assert( CSizedRange>); 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) NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END