diff --git a/Redcraft.Utility/Source/Public/Miscellaneous/Range.h b/Redcraft.Utility/Source/Public/Miscellaneous/Range.h index 442c206..640919d 100644 --- a/Redcraft.Utility/Source/Public/Miscellaneous/Range.h +++ b/Redcraft.Utility/Source/Public/Miscellaneous/Range.h @@ -30,343 +30,6 @@ using TRangeRValueReferenceType = TRangeRValueReference; 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 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 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 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; - -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 IBasicViewInterface> -{ -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( 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_BEGIN(Range) - /** A view adapter that references the elements of some other range. */ template requires (CObject) class TRefView : public IBasicViewInterface> diff --git a/Redcraft.Utility/Source/Public/Range/Factory.h b/Redcraft.Utility/Source/Public/Range/Factory.h new file mode 100644 index 0000000..bb43074 --- /dev/null +++ b/Redcraft.Utility/Source/Public/Range/Factory.h @@ -0,0 +1,359 @@ +#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; + +public: + + 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 diff --git a/Redcraft.Utility/Source/Public/Range/Range.h b/Redcraft.Utility/Source/Public/Range/Range.h index d240bf0..781fd5b 100644 --- a/Redcraft.Utility/Source/Public/Range/Range.h +++ b/Redcraft.Utility/Source/Public/Range/Range.h @@ -3,3 +3,4 @@ #include "CoreTypes.h" #include "Range/Utility.h" #include "Range/View.h" +#include "Range/Factory.h" diff --git a/Redcraft.Utility/Source/Public/Range/View.h b/Redcraft.Utility/Source/Public/Range/View.h index c18f1cd..923902e 100644 --- a/Redcraft.Utility/Source/Public/Range/View.h +++ b/Redcraft.Utility/Source/Public/Range/View.h @@ -2,6 +2,7 @@ #include "CoreTypes.h" #include "Range/Utility.h" +#include "Templates/Utility.h" #include "TypeTraits/TypeTraits.h" NAMESPACE_REDCRAFT_BEGIN