From 6a37e9163967cd88c41c2a5ce2e4547e15107b4f Mon Sep 17 00:00:00 2001 From: Redstone1024 <2824517378@qq.com> Date: Tue, 17 Dec 2024 21:49:37 +0800 Subject: [PATCH] refactor(*): replace the old with the new iterator and range library --- .../Source/Public/Containers/Array.h | 83 ++++--- .../Source/Public/Containers/ArrayView.h | 40 ++-- .../Source/Public/Containers/Bitset.h | 32 ++- .../Source/Public/Containers/List.h | 46 ++-- .../Source/Public/Containers/StaticArray.h | 4 +- .../Source/Public/Containers/StaticBitset.h | 4 +- .../Public/Miscellaneous/ConstantIterator.h | 226 ------------------ .../Source/Public/Miscellaneous/Container.h | 77 ------ .../Source/Public/Miscellaneous/Iterator.h | 200 ---------------- .../Source/Public/Range/Conversion.h | 14 ++ .../Source/Public/Range/FilterView.h | 3 +- .../Source/Public/Range/Utility.h | 11 +- Redcraft.Utility/Source/Public/Range/View.h | 3 +- .../Source/Public/String/Conversion.h.inl | 10 +- .../Source/Public/String/String.h | 145 ++++++++--- .../Source/Public/String/StringView.h | 16 +- .../Source/Public/Templates/Meta.h | 4 +- .../Source/Public/Templates/Optional.h | 4 +- .../Source/Public/Templates/TypeHash.h | 14 ++ .../Source/Public/Templates/Utility.h | 13 +- .../Source/Public/Templates/Variant.h | 3 +- 21 files changed, 312 insertions(+), 640 deletions(-) delete mode 100644 Redcraft.Utility/Source/Public/Miscellaneous/ConstantIterator.h delete mode 100644 Redcraft.Utility/Source/Public/Miscellaneous/Container.h delete mode 100644 Redcraft.Utility/Source/Public/Miscellaneous/Iterator.h diff --git a/Redcraft.Utility/Source/Public/Containers/Array.h b/Redcraft.Utility/Source/Public/Containers/Array.h index 13306fe..e3fd863 100644 --- a/Redcraft.Utility/Source/Public/Containers/Array.h +++ b/Redcraft.Utility/Source/Public/Containers/Array.h @@ -1,16 +1,15 @@ #pragma once #include "CoreTypes.h" +#include "Range/Range.h" #include "Memory/Allocator.h" +#include "Iterator/Iterator.h" #include "Templates/Utility.h" #include "Templates/TypeHash.h" #include "TypeTraits/TypeTraits.h" #include "Miscellaneous/Compare.h" #include "Memory/MemoryOperator.h" -#include "Miscellaneous/Iterator.h" -#include "Miscellaneous/Container.h" #include "Miscellaneous/AssertionMacros.h" -#include "Miscellaneous/ConstantIterator.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) @@ -57,18 +56,24 @@ public: /** Constructs the container with 'Count' copies of elements with 'InValue'. */ TArray(size_t Count, const FElementType& InValue) requires (CCopyConstructible) - : TArray(MakeCountedConstantIterator(InValue, Count), DefaultSentinel) + : TArray(Range::Repeat(InValue, Count)) { } /** Constructs the container with the contents of the range ['First', 'Last'). */ - template S> requires (CConstructibleFrom> && CMovable) + template S> requires (CConstructibleFrom> && CMovable) TArray(I First, S Last) { if constexpr (CForwardIterator) { - if constexpr (CSizedSentinelFor) { checkf(First - Last <= 0, TEXT("Illegal range iterator. Please check First <= Last.")); } + size_t Count = 0; - const size_t Count = Iteration::Distance(First, Last); + if constexpr (CSizedSentinelFor) + { + checkf(First - Last <= 0, TEXT("Illegal range iterator. Please check First <= Last.")); + + Count = Last - First; + } + else for (I Iter = First; Iter != Last; ++Iter) ++Count; Impl.ArrayNum = Count; Impl.ArrayMax = Impl->CalculateSlackReserve(Num()); @@ -93,6 +98,10 @@ public: } } + /** Constructs the container with the contents of the range. */ + template requires (!CSameAs, TArray> && CConstructibleFrom> && CMovable) + FORCEINLINE explicit TArray(R&& Range) : TArray(Range::Begin(Range), Range::End(Range)) { } + /** Copy constructor. Constructs the container with the copy of the contents of 'InValue'. */ TArray(const TArray& InValue) requires (CCopyConstructible) { @@ -129,7 +138,7 @@ public: } /** Constructs the container with the contents of the initializer list. */ - FORCEINLINE TArray(initializer_list IL) requires (CCopyConstructible) : TArray(Iteration::Begin(IL), Iteration::End(IL)) { } + FORCEINLINE TArray(initializer_list IL) requires (CCopyConstructible) : TArray(Range::Begin(IL), Range::End(IL)) { } /** Destructs the array. The destructors of the elements are called and the used storage is deallocated. */ ~TArray() @@ -243,38 +252,38 @@ public: /** Replaces the contents with those identified by initializer list. */ TArray& operator=(initializer_list IL) requires (CCopyable) { - size_t NumToAllocate = GetNum(IL); + size_t NumToAllocate = Range::Num(IL); - NumToAllocate = NumToAllocate > Max() ? Impl->CalculateSlackGrow(GetNum(IL), Max()) : NumToAllocate; - NumToAllocate = NumToAllocate < Max() ? Impl->CalculateSlackShrink(GetNum(IL), Max()) : NumToAllocate; + NumToAllocate = NumToAllocate > Max() ? Impl->CalculateSlackGrow (Range::Num(IL), Max()) : NumToAllocate; + NumToAllocate = NumToAllocate < Max() ? Impl->CalculateSlackShrink(Range::Num(IL), Max()) : NumToAllocate; if (NumToAllocate != Max()) { Memory::Destruct(Impl.Pointer, Num()); Impl->Deallocate(Impl.Pointer); - Impl.ArrayNum = GetNum(IL); + Impl.ArrayNum = Range::Num(IL); Impl.ArrayMax = NumToAllocate; Impl.Pointer = Impl->Allocate(Max()); - Memory::CopyConstruct(Impl.Pointer, NAMESPACE_REDCRAFT::GetData(IL), Num()); + Memory::CopyConstruct(Impl.Pointer, Range::GetData(IL), Num()); return *this; } - if (GetNum(IL) <= Num()) + if (Range::Num(IL) <= Num()) { - Memory::CopyAssign(Impl.Pointer, NAMESPACE_REDCRAFT::GetData(IL), GetNum(IL)); - Memory::Destruct(Impl.Pointer + GetNum(IL), Num() - GetNum(IL)); + Memory::CopyAssign(Impl.Pointer, Range::GetData(IL), Range::Num(IL)); + Memory::Destruct(Impl.Pointer + Range::Num(IL), Num() - Range::Num(IL)); } - else if (GetNum(IL) <= Max()) + else if (Range::Num(IL) <= Max()) { - Memory::CopyAssign(Impl.Pointer, NAMESPACE_REDCRAFT::GetData(IL), Num()); - Memory::CopyConstruct(Impl.Pointer + Num(), NAMESPACE_REDCRAFT::GetData(IL) + Num(), GetNum(IL) - Num()); + Memory::CopyAssign(Impl.Pointer, Range::GetData(IL), Num()); + Memory::CopyConstruct(Impl.Pointer + Num(), Range::GetData(IL) + Num(), Range::Num(IL) - Num()); } else check_no_entry(); - Impl.ArrayNum = GetNum(IL); + Impl.ArrayNum = Range::Num(IL); return *this; } @@ -406,22 +415,29 @@ public: { checkf(IsValidIterator(Iter), TEXT("Read access violation. Please check IsValidIterator().")); - return Insert(Iter, MakeCountedConstantIterator(InValue, Count), DefaultSentinel); + return Insert(Iter, Range::Repeat(InValue, Count)); } /** Inserts elements from range ['First', 'Last') before 'Iter'. */ - template S> requires (CConstructibleFrom> - && CAssignableFrom> && CMovable) + template S> requires (CConstructibleFrom> + && CAssignableFrom> && CMovable) FIterator Insert(FConstIterator Iter, I First, S Last) { checkf(IsValidIterator(Iter), TEXT("Read access violation. Please check IsValidIterator().")); if constexpr (CForwardIterator) { - if constexpr (CSizedSentinelFor) { checkf(First - Last <= 0, TEXT("Illegal range iterator. Please check First <= Last.")); } - const size_t InsertIndex = Iter - Begin(); - const size_t Count = Iteration::Distance(First, Last); + + size_t Count = 0; + + if constexpr (CSizedSentinelFor) + { + checkf(First - Last <= 0, TEXT("Illegal range iterator. Please check First <= Last.")); + + Count = Last - First; + } + else for (I Jter = First; Jter != Last; ++Jter) ++Count; if (Count == 0) return FIterator(this, Impl.Pointer + InsertIndex); @@ -523,10 +539,18 @@ public: } } + /** Inserts elements from range before 'Iter'. */ + template requires (CConstructibleFrom> + && CAssignableFrom> && CMovable) + FORCEINLINE FIterator Insert(FConstIterator Iter, R&& Range) + { + return Insert(Iter, Range::Begin(Range), Range::End(Range)); + } + /** Inserts elements from initializer list before 'Iter' in the container. */ FORCEINLINE FIterator Insert(FConstIterator Iter, initializer_list IL) requires (CCopyable) { - return Insert(Iter, Iteration::Begin(IL), Iteration::End(IL)); + return Insert(Iter, Range::Begin(IL), Range::End(IL)); } /** Inserts a new element into the container directly before 'Iter'. */ @@ -1058,7 +1082,10 @@ private: }; template -TArray(I, S) -> TArray>; +TArray(I, S) -> TArray>; + +template +TArray(R) -> TArray>; template TArray(initializer_list) -> TArray; diff --git a/Redcraft.Utility/Source/Public/Containers/ArrayView.h b/Redcraft.Utility/Source/Public/Containers/ArrayView.h index 46b2688..43e8060 100644 --- a/Redcraft.Utility/Source/Public/Containers/ArrayView.h +++ b/Redcraft.Utility/Source/Public/Containers/ArrayView.h @@ -1,16 +1,16 @@ #pragma once #include "CoreTypes.h" +#include "Range/Range.h" #include "Memory/Address.h" #include "Memory/Allocator.h" #include "Containers/Array.h" +#include "Iterator/Iterator.h" #include "Templates/Utility.h" #include "Templates/TypeHash.h" #include "Containers/StaticArray.h" #include "TypeTraits/TypeTraits.h" #include "Miscellaneous/Compare.h" -#include "Miscellaneous/Iterator.h" -#include "Miscellaneous/Container.h" #include "Miscellaneous/AssertionMacros.h" NAMESPACE_REDCRAFT_BEGIN @@ -29,7 +29,7 @@ class TArrayView { public: - using FElementType = T; + using FElementType = TRemoveCV; using FReference = T&; @@ -53,7 +53,7 @@ public: } /** Constructs an array view that is a view over the range ['InFirst', 'InFirst' + 'Count'). */ - template requires (CConvertibleTo(*)[], FElementType(*)[]>) + template requires (CConvertibleTo, T> && CSameAs>, TRemoveCVRef>) FORCEINLINE constexpr explicit (Extent != DynamicExtent) TArrayView(I InFirst, size_t InCount) { checkf(Extent == DynamicExtent || Extent == InCount, TEXT("Illegal range count. Please check InCount.")); @@ -67,7 +67,7 @@ public: } /** Constructs an array view that is a view over the range ['InFirst', 'InLast'). */ - template S> requires (CConvertibleTo(*)[], FElementType(*)[]>) + template S> requires (CConvertibleTo, T> && CSameAs>, TRemoveCVRef>) FORCEINLINE constexpr explicit (Extent != DynamicExtent) TArrayView(I InFirst, S InLast) { checkf(Extent == DynamicExtent || Extent == InLast - InFirst, TEXT("Illegal range iterator. Please check InLast - InFirst.")); @@ -156,36 +156,36 @@ public: /** Obtains an array view that is a view over the first 'Count' elements of this array view. */ template requires (Extent == DynamicExtent || Extent >= Count) - NODISCARD FORCEINLINE constexpr TArrayView First() const + NODISCARD FORCEINLINE constexpr TArrayView First() const { checkf(Count <= Num(), TEXT("Illegal subview range. Please check Count.")); - return TArrayView(Begin(), Count); + return TArrayView(Begin(), Count); } /** Obtains an array view that is a view over the first 'Count' elements of this array view. */ - NODISCARD FORCEINLINE constexpr TArrayView First(size_t Count) const + NODISCARD FORCEINLINE constexpr TArrayView First(size_t Count) const { checkf(Count <= Num(), TEXT("Illegal subview range. Please check Count.")); - return TArrayView(Begin(), Count); + return TArrayView(Begin(), Count); } /** Obtains an array view that is a view over the last 'Count' elements of this array view. */ template requires (Extent == DynamicExtent || Extent >= Count) - NODISCARD FORCEINLINE constexpr TArrayView Last() const + NODISCARD FORCEINLINE constexpr TArrayView Last() const { checkf(Count <= Num(), TEXT("Illegal subview range. Please check Count.")); - return TArrayView(End() - Count, Count); + return TArrayView(End() - Count, Count); } /** Obtains an array view that is a view over the last 'Count' elements of this array view. */ - NODISCARD FORCEINLINE constexpr TArrayView Last(size_t Count) const + NODISCARD FORCEINLINE constexpr TArrayView Last(size_t Count) const { checkf(Count <= Num(), TEXT("Illegal subview range. Please check Count.")); - return TArrayView(End() - Count, Count); + return TArrayView(End() - Count, Count); } /** Obtains an array view that is a view over the 'Count' elements of this array view starting at 'Offset'. */ @@ -198,11 +198,11 @@ public: if constexpr (Count != DynamicExtent) { - return TArrayView(Begin() + Offset, Count); + return TArrayView(Begin() + Offset, Count); } else { - return TArrayView(Begin() + Offset, Num() - Offset); + return TArrayView(Begin() + Offset, Num() - Offset); } } @@ -213,11 +213,11 @@ public: if (Count != DynamicExtent) { - return TArrayView(Begin() + Offset, Count); + return TArrayView(Begin() + Offset, Count); } else { - return TArrayView(Begin() + Offset, Num() - Offset); + return TArrayView(Begin() + Offset, Num() - Offset); } } @@ -245,7 +245,7 @@ public: } /** @return The pointer to the underlying element storage. */ - NODISCARD FORCEINLINE constexpr FElementType* GetData() const { return Impl.Pointer; } + NODISCARD FORCEINLINE constexpr T* GetData() const { return Impl.Pointer; } /** @return The iterator to the first or end element. */ NODISCARD FORCEINLINE constexpr FIterator Begin() const { return FIterator(this, Impl.Pointer); } @@ -291,7 +291,7 @@ public: private: - struct FImplWithoutNum { FElementType* Pointer; }; + struct FImplWithoutNum { T* Pointer; }; struct FImplWithNum : FImplWithoutNum { size_t ArrayNum; }; @@ -367,7 +367,7 @@ public: }; template -TArrayView(I, S) -> TArrayView>>; +TArrayView(I, S) -> TArrayView>>; template TArrayView(T(&)[N]) -> TArrayView; diff --git a/Redcraft.Utility/Source/Public/Containers/Bitset.h b/Redcraft.Utility/Source/Public/Containers/Bitset.h index 26dd9a0..c9b6ba0 100644 --- a/Redcraft.Utility/Source/Public/Containers/Bitset.h +++ b/Redcraft.Utility/Source/Public/Containers/Bitset.h @@ -1,16 +1,16 @@ #pragma once #include "CoreTypes.h" +#include "Range/Range.h" #include "Memory/Memory.h" #include "Memory/Allocator.h" +#include "Iterator/Iterator.h" #include "Templates/Utility.h" #include "Templates/TypeHash.h" #include "Templates/Noncopyable.h" #include "TypeTraits/TypeTraits.h" #include "Miscellaneous/Compare.h" #include "Memory/MemoryOperator.h" -#include "Miscellaneous/Iterator.h" -#include "Miscellaneous/Container.h" #include "Miscellaneous/AssertionMacros.h" NAMESPACE_REDCRAFT_BEGIN @@ -101,16 +101,22 @@ public: } /** Constructs the bitset with the bits of the range ['First', 'Last'). */ - template S> requires (CConstructibleFrom>) + template S> requires (CConstructibleFrom>) TBitset(I First, S Last) { if constexpr (CForwardIterator) { - if constexpr (CSizedSentinelFor) { checkf(First - Last <= 0, TEXT("Illegal range iterator. Please check First <= Last.")); } + size_t Count = 0; - const size_t InCount = Iteration::Distance(First, Last); + if constexpr (CSizedSentinelFor) + { + checkf(First - Last <= 0, TEXT("Illegal range iterator. Please check First <= Last.")); - new (this) TBitset(InCount); + Count = Last - First; + } + else for (I Iter = First; Iter != Last; ++Iter) ++Count; + + new (this) TBitset(Count); for (FReference Ref: *this) Ref = *First++; } @@ -126,6 +132,10 @@ public: } } + /** Constructs the bitset with the bits of the range. */ + template requires (!CSameAs, TBitset> && CConstructibleFrom>) + FORCEINLINE explicit TBitset(R&& Range) : TBitset(Range::Begin(Range), Range::End(Range)) { } + /** Copy constructor. Constructs the bitset with the copy of the bits of 'InValue'. */ FORCEINLINE TBitset(const TBitset& InValue) { @@ -160,7 +170,7 @@ public: } /** Constructs the bitset with the bits of the initializer list. */ - FORCEINLINE TBitset(initializer_list IL) : TBitset(Iteration::Begin(IL), Iteration::End(IL)) { } + FORCEINLINE TBitset(initializer_list IL) : TBitset(Range::Begin(IL), Range::End(IL)) { } /** Destructs the bitset. The storage is deallocated. */ ~TBitset() @@ -228,9 +238,9 @@ public: /** Replaces the bits with those identified by initializer list. */ TBitset& operator=(initializer_list IL) { - auto First = Iteration::Begin(IL); + auto First = Range::Begin(IL); - const size_t BlocksCount = (GetNum(IL) + BlockWidth - 1) / BlockWidth; + const size_t BlocksCount = (Range::Num(IL) + BlockWidth - 1) / BlockWidth; size_t NumToAllocate = BlocksCount; @@ -241,7 +251,7 @@ public: { Impl->Deallocate(Impl.Pointer); - Impl.BitsetNum = GetNum(IL); + Impl.BitsetNum = Range::Num(IL); Impl.BlocksMax = NumToAllocate; Impl.Pointer = Impl->Allocate(MaxBlocks()); @@ -250,7 +260,7 @@ public: return *this; } - Impl.BitsetNum = GetNum(IL); + Impl.BitsetNum = Range::Num(IL); for (FReference Ref : *this) Ref = *First++; diff --git a/Redcraft.Utility/Source/Public/Containers/List.h b/Redcraft.Utility/Source/Public/Containers/List.h index 785ff56..221cd1d 100644 --- a/Redcraft.Utility/Source/Public/Containers/List.h +++ b/Redcraft.Utility/Source/Public/Containers/List.h @@ -1,16 +1,15 @@ #pragma once #include "CoreTypes.h" +#include "Range/Range.h" #include "Memory/Allocator.h" +#include "Iterator/Iterator.h" #include "Templates/Utility.h" #include "Templates/TypeHash.h" #include "TypeTraits/TypeTraits.h" #include "Miscellaneous/Compare.h" #include "Memory/MemoryOperator.h" -#include "Miscellaneous/Iterator.h" -#include "Miscellaneous/Container.h" #include "Miscellaneous/AssertionMacros.h" -#include "Miscellaneous/ConstantIterator.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) @@ -76,11 +75,11 @@ public: /** Constructs the container with 'Count' copies of elements with 'InValue'. */ TList(size_t Count, const FElementType& InValue) requires (CCopyable) - : TList(MakeCountedConstantIterator(InValue, Count), DefaultSentinel) + : TList(Range::Repeat(InValue, Count)) { } /** Constructs the container with the contents of the range ['First', 'Last'). */ - template S> requires (CConstructibleFrom>) + template S> requires (CConstructibleFrom>) TList(I First, S Last) : TList() { FNode* EndNode = Impl.HeadNode->PrevNode; @@ -101,6 +100,10 @@ public: Impl.HeadNode->PrevNode = EndNode; } + /** Constructs the container with the contents of the range. */ + template requires (!CSameAs, TList> && CConstructibleFrom>) + FORCEINLINE explicit TList(R&& Range) : TList(Range::Begin(Range), Range::End(Range)) { } + /** Copy constructor. Constructs the container with the copy of the contents of 'InValue'. */ FORCEINLINE TList(const TList& InValue) requires (CCopyConstructible) : TList(InValue.Begin(), InValue.End()) { } @@ -108,7 +111,7 @@ public: FORCEINLINE TList(TList&& InValue) : TList() { Swap(*this, InValue); } /** Constructs the container with the contents of the initializer list. */ - FORCEINLINE TList(initializer_list IL) requires (CCopyConstructible) : TList(Iteration::Begin(IL), Iteration::End(IL)) { } + FORCEINLINE TList(initializer_list IL) requires (CCopyConstructible) : TList(Range::Begin(IL), Range::End(IL)) { } /** Destructs the list. The destructors of the elements are called and the used storage is deallocated. */ ~TList() @@ -168,10 +171,10 @@ public: /** Replaces the contents with those identified by initializer list. */ TList& operator=(initializer_list IL) requires (CCopyable) { - FIterator ThisIter = Begin(); - const FElementType* OtherIter = Iteration::Begin(IL); + FIterator ThisIter = Begin(); + const FElementType* OtherIter = Range::Begin(IL); - while (ThisIter != End() && OtherIter != Iteration::End(IL)) + while (ThisIter != End() && OtherIter != Range::End(IL)) { *ThisIter = *OtherIter; @@ -181,18 +184,18 @@ public: if (ThisIter == End()) { - while (OtherIter != Iteration::End(IL)) + while (OtherIter != Range::End(IL)) { EmplaceBack(*OtherIter); ++OtherIter; } } - else if (OtherIter == Iteration::End(IL)) + else if (OtherIter == Range::End(IL)) { Erase(ThisIter, End()); } - Impl.ListNum = GetNum(IL); + Impl.ListNum = Range::Num(IL); return *this; } @@ -244,11 +247,11 @@ public: /** Inserts 'Count' copies of the 'InValue' before 'Iter' in the container. */ FIterator Insert(FConstIterator Iter, size_t Count, const FElementType& InValue) requires (CCopyConstructible) { - return Insert(Iter, MakeCountedConstantIterator(InValue, Count), DefaultSentinel); + return Insert(Iter, Range::Repeat(InValue, Count)); } /** Inserts elements from range ['First', 'Last') before 'Iter'. */ - template S> requires (CConstructibleFrom>) + template S> requires (CConstructibleFrom>) FIterator Insert(FConstIterator Iter, I First, S Last) { if (First == Last) return FIterator(Iter.Pointer); @@ -282,8 +285,12 @@ public: return FIterator(FirstNode); } + /** Inserts elements from range ['First', 'Last') before 'Iter'. */ + template requires (CConstructibleFrom>) + FORCEINLINE FIterator Insert(FConstIterator Iter, R&& Range) { return Insert(Iter, Range::Begin(Range), Range::End(Range)); } + /** Inserts elements from initializer list before 'Iter' in the container. */ - FORCEINLINE FIterator Insert(FConstIterator Iter, initializer_list IL) requires (CCopyConstructible) { return Insert(Iter, Iteration::Begin(IL), Iteration::End(IL)); } + FORCEINLINE FIterator Insert(FConstIterator Iter, initializer_list IL) requires (CCopyConstructible) { return Insert(Iter, Range::Begin(IL), Range::End(IL)); } /** Inserts a new element into the container directly before 'Iter'. */ template requires (CConstructibleFrom) @@ -381,7 +388,7 @@ public: { FIterator First = End(); - Iteration::Advance(First, Count - Impl.ListNum); + for (size_t Index = 0; Index != Impl.ListNum - Count; ++Index) --First; Erase(First, End()); @@ -417,7 +424,7 @@ public: { FIterator First = End(); - Iteration::Advance(First, Count - Impl.ListNum); + for (size_t Index = 0; Index != Impl.ListNum - Count; ++Index) --First; Erase(First, End()); @@ -598,7 +605,10 @@ private: }; template -TList(I, S) -> TList>; +TList(I, S) -> TList>; + +template +TList(R) -> TList>; template TList(initializer_list) -> TList; diff --git a/Redcraft.Utility/Source/Public/Containers/StaticArray.h b/Redcraft.Utility/Source/Public/Containers/StaticArray.h index 1fd36ce..f3e2301 100644 --- a/Redcraft.Utility/Source/Public/Containers/StaticArray.h +++ b/Redcraft.Utility/Source/Public/Containers/StaticArray.h @@ -1,13 +1,13 @@ #pragma once #include "CoreTypes.h" +#include "Range/Range.h" #include "Templates/Meta.h" +#include "Iterator/Iterator.h" #include "Templates/Utility.h" #include "Templates/TypeHash.h" #include "TypeTraits/TypeTraits.h" #include "Miscellaneous/Compare.h" -#include "Miscellaneous/Iterator.h" -#include "Miscellaneous/Container.h" #include "Miscellaneous/AssertionMacros.h" NAMESPACE_REDCRAFT_BEGIN diff --git a/Redcraft.Utility/Source/Public/Containers/StaticBitset.h b/Redcraft.Utility/Source/Public/Containers/StaticBitset.h index 884bee2..8e720c4 100644 --- a/Redcraft.Utility/Source/Public/Containers/StaticBitset.h +++ b/Redcraft.Utility/Source/Public/Containers/StaticBitset.h @@ -1,14 +1,14 @@ #pragma once #include "CoreTypes.h" +#include "Range/Range.h" +#include "Iterator/Iterator.h" #include "Templates/Utility.h" #include "Templates/TypeHash.h" #include "Templates/Noncopyable.h" #include "TypeTraits/TypeTraits.h" #include "Miscellaneous/Compare.h" #include "Memory/MemoryOperator.h" -#include "Miscellaneous/Iterator.h" -#include "Miscellaneous/Container.h" #include "Miscellaneous/AssertionMacros.h" NAMESPACE_REDCRAFT_BEGIN diff --git a/Redcraft.Utility/Source/Public/Miscellaneous/ConstantIterator.h b/Redcraft.Utility/Source/Public/Miscellaneous/ConstantIterator.h deleted file mode 100644 index a950971..0000000 --- a/Redcraft.Utility/Source/Public/Miscellaneous/ConstantIterator.h +++ /dev/null @@ -1,226 +0,0 @@ -#pragma once - -#include "CoreTypes.h" -#include "Memory/Address.h" -#include "Templates/Utility.h" -#include "Miscellaneous/Iterator.h" -#include "Miscellaneous/Compare.h" -#include "TypeTraits/TypeTraits.h" - -NAMESPACE_REDCRAFT_BEGIN -NAMESPACE_MODULE_BEGIN(Redcraft) -NAMESPACE_MODULE_BEGIN(Utility) - -/** An iterator that always points to the same value. */ -template requires (CDestructible || CLValueReference) -class TConstantIterator final -{ -public: - - using FElementType = TRemoveCV; - - FORCEINLINE constexpr TConstantIterator() = default; - - FORCEINLINE constexpr ~TConstantIterator() = default; - - template requires (!CSameAs> && CConstructibleFrom) - FORCEINLINE constexpr explicit TConstantIterator(U&& InValue) : Value(Forward(InValue)) { } - - template requires (CConstructibleFrom) - FORCEINLINE constexpr explicit (!CConvertibleTo) TConstantIterator(const TConstantIterator& InValue) : Value(InValue.Value) { } - - template requires (CConstructibleFrom) - FORCEINLINE constexpr explicit (!CConvertibleTo) TConstantIterator(TConstantIterator&& InValue) : Value(MoveTemp(InValue.Value)) { } - - FORCEINLINE constexpr TConstantIterator(const TConstantIterator&) requires (CCopyConstructible) = default; - - FORCEINLINE constexpr TConstantIterator(TConstantIterator&&) requires (CMoveConstructible) = default; - - template requires (CConvertibleTo && CAssignableFrom) - FORCEINLINE constexpr TConstantIterator& operator=(const TConstantIterator& InValue) { Value = InValue.Value; return *this; } - - template requires (CConvertibleTo && CAssignableFrom) - FORCEINLINE constexpr TConstantIterator& operator=(TConstantIterator&& InValue) { Value = MoveTemp(InValue.Value); return *this; } - - FORCEINLINE constexpr TConstantIterator& operator=(const TConstantIterator&) requires (CCopyAssignable) = default; - - FORCEINLINE constexpr TConstantIterator& operator=(TConstantIterator&&) requires (CMoveAssignable) = default; - - NODISCARD FORCEINLINE constexpr const T& operator*() const { return Value; } - NODISCARD FORCEINLINE constexpr const T* operator->() const { return AddressOf(Value); } - - FORCEINLINE constexpr TConstantIterator& operator++() { return *this; } - - FORCEINLINE constexpr void operator++(int) { } - -private: - - T Value; - - template requires (CDestructible || CLValueReference) - friend class TConstantIterator; - -}; - -static_assert(CInputIterator>); - -/** An iterator that always points to the same value. */ -template -class TConstantIterator final -{ -public: - - using FElementType = TRemoveCV; - - FORCEINLINE constexpr TConstantIterator() = default; - - FORCEINLINE constexpr TConstantIterator(const TConstantIterator&) = default; - FORCEINLINE constexpr TConstantIterator(TConstantIterator&&) = default; - FORCEINLINE constexpr TConstantIterator& operator=(const TConstantIterator&) = default; - FORCEINLINE constexpr TConstantIterator& operator=(TConstantIterator&&) = default; - - FORCEINLINE constexpr ~TConstantIterator() = default; - - FORCEINLINE constexpr explicit TConstantIterator(const T& InValue) : Ptr(AddressOf(InValue)) { } - - FORCEINLINE constexpr explicit TConstantIterator(const T&& InValue) = delete; - - template requires (CConvertibleTo) - FORCEINLINE constexpr TConstantIterator(const TConstantIterator& InValue) : Ptr(InValue.Ptr) { } - - template requires (CConvertibleTo) - FORCEINLINE constexpr TConstantIterator& operator=(const TConstantIterator& InValue) { Ptr = InValue.Ptr; return *this; } - - NODISCARD FORCEINLINE constexpr const T& operator*() const { return *Ptr; } - NODISCARD FORCEINLINE constexpr const T* operator->() const { return Ptr; } - - FORCEINLINE constexpr TConstantIterator& operator++() { return *this; } - - FORCEINLINE constexpr void operator++(int) { } - -private: - - const T* Ptr; - - template requires (CDestructible || CLValueReference) - friend class TConstantIterator; - -}; - -static_assert(CInputIterator>); - -/** An iterator adapter specialization that tracks the distance of a constant iterator to the end of the range. */ -template requires (CDestructible || CLValueReference) -class TCountedIterator> final -{ -public: - - using FIteratorType = TConstantIterator; - - using FElementType = typename TConstantIterator::FElementType; - -# if DO_CHECK - FORCEINLINE constexpr TCountedIterator() requires (CDefaultConstructible) : Length(1), MaxLength(0) { } -# else - FORCEINLINE constexpr TCountedIterator() requires (CDefaultConstructible) = default; -# endif - - FORCEINLINE constexpr TCountedIterator(const TCountedIterator&) = default; - FORCEINLINE constexpr TCountedIterator(TCountedIterator&&) = default; - FORCEINLINE constexpr TCountedIterator& operator=(const TCountedIterator&) = default; - FORCEINLINE constexpr TCountedIterator& operator=(TCountedIterator&&) = default; - - FORCEINLINE constexpr ~TCountedIterator() = default; - - template requires (!CSameAs> && CConstructibleFrom) - 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.Current), Length(InValue.Num()) { check_code({ MaxLength = InValue.MaxLength; }); } - - template requires (!CSameAs && CConstructibleFrom) - 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.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).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; } - - template J> - NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TCountedIterator& LHS, const TCountedIterator& RHS) { return LHS.Length <=> RHS.Length; } - - NODISCARD FORCEINLINE constexpr bool operator==(FDefaultSentinel) const& { return Length == static_cast(0); } - - NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(FDefaultSentinel) const& { return static_cast(0) <=> Length; } - - NODISCARD FORCEINLINE constexpr const TRemoveReference& operator*() const { CheckThis(true ); return *Current; } - NODISCARD FORCEINLINE constexpr const TRemoveReference* operator->() const { CheckThis(false); return ToAddress(Current); } - - NODISCARD FORCEINLINE constexpr const TRemoveReference& operator[](ptrdiff) const { return *this; } - - FORCEINLINE constexpr TCountedIterator& operator++() { --Length; CheckThis(); return *this; } - FORCEINLINE constexpr TCountedIterator& operator--() { ++Length; CheckThis(); return *this; } - - FORCEINLINE constexpr TCountedIterator operator++(int) { TCountedIterator Temp = *this; --Length; CheckThis(); return Temp; } - FORCEINLINE constexpr TCountedIterator operator--(int) { TCountedIterator Temp = *this; ++Length; CheckThis(); return Temp; } - - FORCEINLINE constexpr TCountedIterator& operator+=(ptrdiff Offset) { Length -= Offset; CheckThis(); return *this; } - FORCEINLINE constexpr TCountedIterator& operator-=(ptrdiff Offset) { Length += Offset; CheckThis(); return *this; } - - NODISCARD friend FORCEINLINE constexpr TCountedIterator operator+(TCountedIterator Iter, ptrdiff Offset) { TCountedIterator Temp = Iter; Temp += Offset; return Temp; } - NODISCARD friend FORCEINLINE constexpr TCountedIterator operator+(ptrdiff Offset, TCountedIterator Iter) { TCountedIterator Temp = Iter; Temp += Offset; return Temp; } - - NODISCARD FORCEINLINE constexpr TCountedIterator operator-(ptrdiff Offset) const { TCountedIterator Temp = *this; Temp -= Offset; return Temp; } - - template J> - NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TCountedIterator& LHS, const TCountedIterator& RHS) { LHS.CheckThis(); RHS.CheckThis(); return LHS.Length - RHS.Length; } - - 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 FIteratorType& GetBase() const& { CheckThis(); return Current; } - NODISCARD FORCEINLINE constexpr FIteratorType GetBase() && { CheckThis(); return MoveTemp(Current); } - NODISCARD FORCEINLINE constexpr ptrdiff Num() const { CheckThis(); return Length; } - -private: - - FIteratorType Current; - ptrdiff Length; - -# if DO_CHECK - ptrdiff MaxLength; -# endif - - FORCEINLINE void CheckThis(bool bExceptEnd = false) const - { - checkf(static_cast(0) <= Length && Length <= MaxLength, TEXT("Read access violation. Please check Num().")); - checkf(!(bExceptEnd && Length == static_cast(0)), TEXT("Read access violation. Please check Num().")); - } - - template - friend class TCountedIterator; - -}; - -static_assert(CRandomAccessIterator>>); -static_assert(CSizedSentinelFor>>); - -template requires (CDestructible || CLValueReference) -NODISCARD FORCEINLINE constexpr auto MakeConstantIterator(T&& Value) -{ - return TConstantIterator(Forward(Value)); -} - -template requires (CDestructible || CLValueReference) -NODISCARD FORCEINLINE constexpr auto MakeCountedConstantIterator(T&& Value, ptrdiff N) -{ - return TCountedIterator>(MakeConstantIterator(Forward(Value)), N); -} - -NAMESPACE_MODULE_END(Utility) -NAMESPACE_MODULE_END(Redcraft) -NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/Miscellaneous/Container.h b/Redcraft.Utility/Source/Public/Miscellaneous/Container.h deleted file mode 100644 index 6730c8e..0000000 --- a/Redcraft.Utility/Source/Public/Miscellaneous/Container.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once - -#include "CoreTypes.h" -#include "Templates/TypeHash.h" -#include "TypeTraits/Swappable.h" - -NAMESPACE_REDCRAFT_BEGIN -NAMESPACE_MODULE_BEGIN(Redcraft) -NAMESPACE_MODULE_BEGIN(Utility) - -/** @return The pointer to the container element storage. */ -template requires (requires(T&& Container) { { Container.GetData() } -> CPointer; }) -FORCEINLINE constexpr auto GetData(T&& Container) -{ - return Container.GetData(); -} - -/** Overloads the GetData algorithm for arrays. */ -template FORCEINLINE constexpr T* GetData( T(& Container)[N]) { return Container; } -template FORCEINLINE constexpr T* GetData( T(&& Container)[N]) { return Container; } -template FORCEINLINE constexpr const T* GetData(const T(& Container)[N]) { return Container; } -template FORCEINLINE constexpr const T* GetData(const T(&& Container)[N]) { return Container; } - -/** Overloads the GetData algorithm for initializer_list. */ -template -FORCEINLINE constexpr const T* GetData(initializer_list Container) -{ - return Container.begin(); -} - -/** @return The number of elements in the container. */ -template requires (requires(T&& Container) { { Container.Num() } -> CConvertibleTo; }) -FORCEINLINE constexpr auto GetNum(T&& Container) -{ - return Container.Num(); -} - -/** Overloads the GetNum algorithm for arrays. */ -template FORCEINLINE constexpr size_t GetNum( T(& )[N]) { return N; } -template FORCEINLINE constexpr size_t GetNum( T(&&)[N]) { return N; } -template FORCEINLINE constexpr size_t GetNum(const T(& )[N]) { return N; } -template FORCEINLINE constexpr size_t GetNum(const T(&&)[N]) { return N; } - -/** Overloads the GetNum algorithm for initializer_list. */ -template -FORCEINLINE constexpr size_t GetNum(initializer_list Container) -{ - return Container.size(); -} - -/** Overloads the Swap algorithm for arrays. */ -template requires (CSwappable>) -FORCEINLINE constexpr void Swap(T(&A)[N], T(&B)[N]) -{ - for (size_t Index = 0; Index < N; ++Index) - { - Swap(A[Index], B[Index]); - } -} - -/** Overloads the GetTypeHash algorithm for arrays. */ -template requires (CHashable>) -FORCEINLINE constexpr size_t GetTypeHash(T(&A)[N]) -{ - size_t Result = 3516520171; - - for (size_t Index = 0; Index < N; ++Index) - { - Result = HashCombine(Result, GetTypeHash(A[Index])); - } - - return Result; -} - -NAMESPACE_MODULE_END(Utility) -NAMESPACE_MODULE_END(Redcraft) -NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/Miscellaneous/Iterator.h b/Redcraft.Utility/Source/Public/Miscellaneous/Iterator.h deleted file mode 100644 index 6245297..0000000 --- a/Redcraft.Utility/Source/Public/Miscellaneous/Iterator.h +++ /dev/null @@ -1,200 +0,0 @@ -#pragma once - -#include "CoreTypes.h" -#include "Iterator/Iterator.h" -#include "TypeTraits/TypeTraits.h" -#include "Miscellaneous/AssertionMacros.h" - -NAMESPACE_REDCRAFT_BEGIN -NAMESPACE_MODULE_BEGIN(Redcraft) -NAMESPACE_MODULE_BEGIN(Utility) - -template -using TIteratorElementType = TIteratorElement; - -template -using TIteratorPointerType = TIteratorPointer; - -template -using TIteratorReferenceType = TIteratorReference; - -template requires (requires(I& Iter) { { MoveTemp(*Iter) } -> CReferenceable; }) -using TIteratorRValueReferenceType = TIteratorRValueReference; - -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) - -template > I> -FORCEINLINE void IndirectlyCopy(I&& Iter, J&& Jter) -{ - *Iter = *Jter; -} - -template > I> -FORCEINLINE void IndirectlyMove(I&& Iter, J&& Jter) -{ - *Iter = MoveTemp(*Jter); -} - -template requires (CSwappable, TIteratorReferenceType>) -FORCEINLINE void IndirectlySwap(I&& Iter, J&& Jter) -{ - Swap(*Iter, *Jter); -} - -template -concept CIndirectlyCopyable = requires(const I Iter, const J Jter) { IndirectlyCopy(Iter, Jter); }; - -template -concept CIndirectlyMovable = requires(const I Iter, const J Jter) { IndirectlyMove(Iter, Jter); }; - -template -concept CIndirectlySwappable = CIndirectlyReadable && CIndirectlyReadable - && requires(const I Iter, const J Jter) - { - IndirectlySwap(Iter, Iter); - IndirectlySwap(Jter, Jter); - IndirectlySwap(Iter, Jter); - IndirectlySwap(Jter, Iter); - }; - -NAMESPACE_BEGIN(Iteration) - -/** @return The iterator to the beginning of a container. */ -template requires (requires(T&& Container) { { Container.Begin() } -> CForwardIterator; }) -FORCEINLINE constexpr auto Begin(T&& Container) -{ - return Container.Begin(); -} - -/** Overloads the Begin algorithm for arrays. */ -template FORCEINLINE constexpr T* Begin( T(& Container)[N]) { return Container; } -template FORCEINLINE constexpr T* Begin( T(&& Container)[N]) { return Container; } -template FORCEINLINE constexpr const T* Begin(const T(& Container)[N]) { return Container; } -template FORCEINLINE constexpr const T* Begin(const T(&& Container)[N]) { return Container; } - -/** Overloads the Begin algorithm for initializer_list. */ -template -FORCEINLINE constexpr auto Begin(initializer_list Container) -{ - return Container.begin(); -} - -/** @return The iterator to the end of a container. */ -template requires (requires(T&& Container) { { Container.End() } -> CForwardIterator; }) -FORCEINLINE constexpr auto End(T&& Container) -{ - return Container.End(); -} - -/** Overloads the End algorithm for arrays. */ -template FORCEINLINE constexpr T* End( T(& Container)[N]) { return Container + N; } -template FORCEINLINE constexpr T* End( T(&& Container)[N]) { return Container + N; } -template FORCEINLINE constexpr const T* End(const T(& Container)[N]) { return Container + N; } -template FORCEINLINE constexpr const T* End(const T(&& Container)[N]) { return Container + N; } - -/** Overloads the End algorithm for initializer_list. */ -template -FORCEINLINE constexpr auto End(initializer_list Container) -{ - return Container.end(); -} - -/** @return The reverse iterator to the beginning of a container. */ -template requires (requires(T&& Container) { { Container.RBegin() } -> CForwardIterator; }) -FORCEINLINE constexpr auto RBegin(T&& Container) -{ - return Container.RBegin(); -} - -/** Overloads the RBegin algorithm for arrays. */ -template FORCEINLINE constexpr auto RBegin( T(& Container)[N]) { return TReverseIterator(End(Container)); } -template FORCEINLINE constexpr auto RBegin( T(&& Container)[N]) { return TReverseIterator(End(Container)); } -template FORCEINLINE constexpr auto RBegin(const T(& Container)[N]) { return TReverseIterator(End(Container)); } -template FORCEINLINE constexpr auto RBegin(const T(&& Container)[N]) { return TReverseIterator(End(Container)); } - -/** Overloads the RBegin algorithm for initializer_list. */ -template -FORCEINLINE constexpr auto RBegin(initializer_list Container) -{ - return TReverseIterator(Container.end()); -} - -/** @return The reverse iterator to the end of a container. */ -template requires (requires(T&& Container) { { Container.REnd() } -> CForwardIterator; }) -FORCEINLINE constexpr auto REnd(T&& Container) -{ - return Container.REnd(); -} - -/** Overloads the REnd algorithm for arrays. */ -template FORCEINLINE constexpr auto REnd( T(& Container)[N]) { return TReverseIterator(Begin(Container)); } -template FORCEINLINE constexpr auto REnd( T(&& Container)[N]) { return TReverseIterator(Begin(Container)); } -template FORCEINLINE constexpr auto REnd(const T(& Container)[N]) { return TReverseIterator(Begin(Container)); } -template FORCEINLINE constexpr auto REnd(const T(&& Container)[N]) { return TReverseIterator(Begin(Container)); } - -/** Overloads the REnd algorithm for initializer_list. */ -template -FORCEINLINE constexpr auto REnd(initializer_list Container) -{ - return TReverseIterator(Container.begin()); -} - -NAMESPACE_END(Iteration) - -NAMESPACE_MODULE_END(Utility) -NAMESPACE_MODULE_END(Redcraft) -NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/Range/Conversion.h b/Redcraft.Utility/Source/Public/Range/Conversion.h index 0fbd350..a2c301e 100644 --- a/Redcraft.Utility/Source/Public/Range/Conversion.h +++ b/Redcraft.Utility/Source/Public/Range/Conversion.h @@ -12,6 +12,20 @@ NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) +// NOTE: In the STL, use std::from_range_t as a disambiguation tag that resolves ambiguity +// introduced by the list-initialization. For example, for the following code: +// +// R RangeOfInts = /* ... */; +// static_assert(CRange and CSameAs, int>); +// +// TArray Arr(RangeOfInts); +// TArray Brr{RangeOfInts}; +// +// If R is TArray than decltype(Arr) is TArray and decltype(Brr) is TArray, +// otherwise, decltype(Arr) is TArray and decltype(Brr) is TArray. +// +// But Redcraft can't use the std::from_range_t tag because list-initialization is discouraged. + /** A concept specifies a container that can reserve size. */ template concept CReservableContainer = CSizedRange diff --git a/Redcraft.Utility/Source/Public/Range/FilterView.h b/Redcraft.Utility/Source/Public/Range/FilterView.h index fa88adb..1b74544 100644 --- a/Redcraft.Utility/Source/Public/Range/FilterView.h +++ b/Redcraft.Utility/Source/Public/Range/FilterView.h @@ -7,6 +7,7 @@ #include "Range/AllView.h" #include "Memory/Address.h" #include "Templates/Invoke.h" +#include "Iterator/Iterator.h" #include "Templates/Utility.h" #include "TypeTraits/TypeTraits.h" @@ -79,7 +80,7 @@ private: public: - using FElementType = TIteratorElementType>; + using FElementType = TIteratorElement>; FORCEINLINE constexpr FIteratorImpl() requires (CDefaultConstructible>) { } // Use '{ }' instead of '= default;' to avoid MSVC bug. diff --git a/Redcraft.Utility/Source/Public/Range/Utility.h b/Redcraft.Utility/Source/Public/Range/Utility.h index b272130..1e8783e 100644 --- a/Redcraft.Utility/Source/Public/Range/Utility.h +++ b/Redcraft.Utility/Source/Public/Range/Utility.h @@ -37,7 +37,7 @@ NODISCARD FORCEINLINE constexpr auto Begin(T&& Container) /** Overloads the Begin algorithm for initializer_list. */ template -NODISCARD FORCEINLINE constexpr auto Begin(initializer_list& Container) +NODISCARD FORCEINLINE constexpr const T* Begin(initializer_list& Container) { return Container.begin(); } @@ -67,7 +67,7 @@ NODISCARD FORCEINLINE constexpr auto End(T&& Container) /** Overloads the End algorithm for initializer_list. */ template -NODISCARD FORCEINLINE constexpr auto End(initializer_list& Container) +NODISCARD FORCEINLINE constexpr const T* End(initializer_list& Container) { return Container.end(); } @@ -180,6 +180,13 @@ NODISCARD FORCEINLINE constexpr size_t Num(T&& Container) return Range::End(Forward(Container)) - Range::Begin(Forward(Container)); } +/** Overloads the Num algorithm for initializer_list. */ +template +NODISCARD FORCEINLINE constexpr size_t Num(initializer_list& Container) +{ + return Container.size(); +} + /** @return true if the container is empty, false otherwise. */ template requires (requires(T&& Container) { { Container.IsEmpty() } -> CBooleanTestable; }) NODISCARD FORCEINLINE constexpr bool IsEmpty(T&& Container) diff --git a/Redcraft.Utility/Source/Public/Range/View.h b/Redcraft.Utility/Source/Public/Range/View.h index 22b9ed5..e923149 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 "Iterator/Iterator.h" #include "Templates/Utility.h" #include "TypeTraits/TypeTraits.h" @@ -100,7 +101,7 @@ class TRangeView : public IBasicViewInterface> { public: - using FElementType = TIteratorElementType; + using FElementType = TIteratorElement; FORCEINLINE constexpr TRangeView() requires (CDefaultConstructible) = default; diff --git a/Redcraft.Utility/Source/Public/String/Conversion.h.inl b/Redcraft.Utility/Source/Public/String/Conversion.h.inl index 9a20026..9330852 100644 --- a/Redcraft.Utility/Source/Public/String/Conversion.h.inl +++ b/Redcraft.Utility/Source/Public/String/Conversion.h.inl @@ -900,7 +900,7 @@ struct TStringObjectFormatter } // Format the container value by format string. - else if constexpr (requires { Iteration::Begin(Object); Iteration::End(Object); }) + else if constexpr (requires { Range::Begin(Object); Range::End(Object); }) { auto FillAndAlign = ParseFillAndAlign(); @@ -951,7 +951,7 @@ struct TStringObjectFormatter return false; } - if (Iteration::Begin(Object) == Iteration::End(Object)) + if (Range::Begin(Object) == Range::End(Object)) { Result += Begin; Result += End; @@ -966,7 +966,7 @@ struct TStringObjectFormatter struct { TStringView Fmt; } ElementParam = { Subfmt }; // It is assumed that if the first element is successfully formatted, all elements will succeed. - bool bIsSuccessful = TStringObjectFormatter::Do(Buffer, *Iteration::Begin(Object), ElementParam); + bool bIsSuccessful = TStringObjectFormatter::Do(Buffer, *Range::Begin(Object), ElementParam); if (!bIsSuccessful) { @@ -977,9 +977,9 @@ struct TStringObjectFormatter Result += Begin; Result += Buffer; - auto Sentinel = Iteration::End(Object); + auto Sentinel = Range::End(Object); - for (auto Iter = ++Iteration::Begin(Object); Iter != Sentinel; ++Iter) + for (auto Iter = ++Range::Begin(Object); Iter != Sentinel; ++Iter) { Result += Separator; diff --git a/Redcraft.Utility/Source/Public/String/String.h b/Redcraft.Utility/Source/Public/String/String.h index 2feff1a..67ecef6 100644 --- a/Redcraft.Utility/Source/Public/String/String.h +++ b/Redcraft.Utility/Source/Public/String/String.h @@ -1,15 +1,15 @@ #pragma once #include "CoreTypes.h" +#include "Range/Range.h" #include "String/Char.h" #include "Containers/Array.h" #include "String/StringView.h" +#include "Iterator/Iterator.h" #include "Templates/Utility.h" #include "Templates/Optional.h" #include "TypeTraits/TypeTraits.h" #include "Templates/Noncopyable.h" -#include "Miscellaneous/Iterator.h" -#include "Miscellaneous/Container.h" #include "Miscellaneous/AssertionMacros.h" NAMESPACE_REDCRAFT_BEGIN @@ -80,9 +80,14 @@ public: FORCEINLINE TString(TStringView View) : TString(View.Begin(), View.End()) { } /** Constructs the string with the contents of the range ['First', 'Last'). */ - template S> requires (CConstructibleFrom>) + template S> requires (CConstructibleFrom>) FORCEINLINE TString(I First, S Last) : FSuper(MoveTemp(First), MoveTemp(Last)) { } + /** Constructs the string with the contents of the range. */ + template requires (!CSameAs, TString> + && !CSameAs, TStringView> && CConstructibleFrom>) + FORCEINLINE explicit TString(R&& Range) : TString(Range::Begin(Range), Range::End(Range)) { } + /** Copy constructor. Constructs the string with the copy of the contents of 'InValue'. */ FORCEINLINE TString(const TString&) = default; @@ -90,7 +95,7 @@ public: FORCEINLINE TString(TString&&) = default; /** Constructs the string with the contents of the initializer list. */ - FORCEINLINE TString(initializer_list IL) : TString(Iteration::Begin(IL), Iteration::End(IL)) { } + FORCEINLINE TString(initializer_list IL) : TString(Range::Begin(IL), Range::End(IL)) { } /** Copy assignment operator. Replaces the contents with a copy of the contents of 'InValue'. */ FORCEINLINE TString& operator=(const TString&) = default; @@ -167,7 +172,7 @@ public: } /** Inserts characters from the range ['First', 'Last') before 'Index' in the string. */ - template S> requires (CConstructibleFrom>) + template S> requires (CConstructibleFrom>) FORCEINLINE FIterator Insert(size_t Index, I First, S Last) { checkf(Index <= this->Num(), TEXT("Illegal index. Please check Index <= Num().")); @@ -176,7 +181,7 @@ public: } /** Inserts characters from the range ['First', 'Last') before 'Iter'. */ - template S> requires (CConstructibleFrom>) + template S> requires (CConstructibleFrom>) FORCEINLINE FIterator Insert(FConstIterator Iter, I First, S Last) { checkf(this->IsValidIterator(Iter), TEXT("Read access violation. Please check IsValidIterator().")); @@ -237,20 +242,33 @@ public: void StableErase(...) = delete; /** Appends 'Count' copies of the 'InValue' to the end of the string. */ - TString& Append(size_t Count, FElementType InChar) { return Append(MakeCountedConstantIterator(InChar, Count), DefaultSentinel); } + TString& Append(size_t Count, FElementType InChar) { return Append(Range::Repeat(InChar, Count)); } - /** Appends the contents of the 'View' to the end of the string. */ - FORCEINLINE TString& Append(TStringView View) { return Append(View.Begin(), View.End()); } + /** Appends the contents of the range ['InPtr', 'InPtr' + 'Count') to the end of the string. */ + FORCEINLINE TString& Append(const FElementType* InPtr, size_t Count) { return Append(TStringView(InPtr, Count)); } + + FORCEINLINE TString& Append(nullptr_t, size_t) = delete; + + /** Constructs a string with the contents of the range ['InPtr', '\0'). */ + FORCEINLINE TString& Append(const FElementType* InPtr) { return Append(TStringView(InPtr)); } + + FORCEINLINE TString& Append(nullptr_t) = delete; /** Appends the contents of the range ['First', 'Last') to the end of the string. */ - template S> requires (CConstructibleFrom>) + template S> requires (CConstructibleFrom>) TString& Append(I First, S Last) { if constexpr (CForwardIterator) { - if constexpr (CSizedSentinelFor) { checkf(First <= Last, TEXT("Illegal range iterator. Please check First <= Last.")); } + size_t Count = 0; - const size_t Count = Iteration::Distance(First, Last); + if constexpr (CSizedSentinelFor) + { + checkf(First - Last <= 0, TEXT("Illegal range iterator. Please check First <= Last.")); + + Count = Last - First; + } + else for (I Iter = First; Iter != Last; ++Iter) ++Count; const size_t CurrentNum = this->Num(); @@ -269,14 +287,24 @@ public: return *this; } + /** Appends the contents of the range to the end of the string. */ + template requires (CConstructibleFrom>) + FORCEINLINE TString& Append(R&& Range) { return Append(Range::Begin(Range), Range::End(Range)); } + /** Appends the contents of the initializer list to the end of the string. */ - FORCEINLINE TString& Append(initializer_list IL) { return Append(Iteration::Begin(IL), Iteration::End(IL)); } + FORCEINLINE TString& Append(initializer_list IL) { return Append(Range::Begin(IL), Range::End(IL)); } /** Appends the given character value to the end of the string. */ FORCEINLINE TString& operator+=(FElementType InChar) { return Append(1, InChar); } - /** Appends the contents of the 'View' to the end of the string. */ - FORCEINLINE TString& operator+=(TStringView View) { return Append(View); } + /** Appends the contents of the range ['InPtr', '\0') to the end of the string. */ + FORCEINLINE TString& operator+=(const FElementType* InPtr) { return Append(InPtr); } + + FORCEINLINE TString& operator+=(nullptr_t) = delete; + + /** Appends the contents of the range to the end of the string. */ + template requires (CConstructibleFrom>) + FORCEINLINE TString& operator+=(R&& Range) { return Append(Range); } /** Appends the contents of the range ['First', 'Last') to the end of the string. */ FORCEINLINE TString& operator+=(initializer_list IL) { return Append(IL); } @@ -435,27 +463,49 @@ public: { checkf(this->IsValidIterator(First) && this->IsValidIterator(Last) && First <= Last, TEXT("Read access violation. Please check IsValidIterator().")); - return Replace(First, Last, MakeCountedConstantIterator(InChar, Count), DefaultSentinel); + return Replace(First, Last, Range::Repeat(InChar, Count)); } - /** Replace the substring [Index, Index + CountToReplace) with the contents of the 'View'. */ - FORCEINLINE TString& Replace(size_t Index, size_t CountToReplace, TStringView View) + /** Replace the substring [Index, Index + CountToReplace) with the contents of the ['InPtr', 'InPtr' + 'Count'). */ + FORCEINLINE TString& Replace(size_t Index, size_t CountToReplace, const FElementType* InPtr, size_t Count) { checkf(Index <= this->Num() && Index + CountToReplace <= this->Num(), TEXT("Illegal substring range. Please check Index and CountToReplace.")); - return Replace(this->Begin() + Index, this->Begin() + Index + CountToReplace, View); + return Replace(this->Begin() + Index, this->Begin() + Index + CountToReplace, InPtr, InPtr + Count); } - /** Replace the substring ['First', 'Last') with the contents of the 'View'. */ - FORCEINLINE TString& Replace(FConstIterator First, FConstIterator Last, TStringView View) + FORCEINLINE TString& Replace(size_t, size_t, nullptr_t, size_t) = delete; + + /** Replace the substring ['First', 'Last') with the contents of the ['InPtr', 'InPtr' + 'Count'). */ + FORCEINLINE TString& Replace(FConstIterator First, FConstIterator Last, const FElementType* InPtr, size_t Count) { checkf(this->IsValidIterator(First) && this->IsValidIterator(Last) && First <= Last, TEXT("Read access violation. Please check IsValidIterator().")); - return Replace(First, Last, View.Begin(), View.End()); + return Replace(First, Last, TStringView(InPtr, Count)); + } + + FORCEINLINE TString& Replace(FConstIterator, FConstIterator, nullptr_t, size_t) = delete; + + /** Replace the substring [Index, Index + CountToReplace) with the contents of the ['InPtr', '\0'). */ + FORCEINLINE TString& Replace(size_t Index, size_t CountToReplace, const FElementType* InPtr) + { + checkf(Index <= this->Num() && Index + CountToReplace <= this->Num(), TEXT("Illegal substring range. Please check Index and CountToReplace.")); + + return Replace(this->Begin() + Index, this->Begin() + Index + CountToReplace, InPtr); + } + + FORCEINLINE TString& Replace(size_t, size_t, nullptr_t) = delete; + + /** Replace the substring ['First', 'Last') with the contents of the ['InPtr', '\0'). */ + FORCEINLINE TString& Replace(FConstIterator First, FConstIterator Last, const FElementType* InPtr) + { + checkf(this->IsValidIterator(First) && this->IsValidIterator(Last) && First <= Last, TEXT("Read access violation. Please check IsValidIterator().")); + + return Replace(First, Last, TStringView(InPtr)); } /** Replace the substring [Index, Index + CountToReplace) with the contents of the range ['First', 'Last'). */ - template S> requires (CConstructibleFrom>) + template S> requires (CConstructibleFrom>) FORCEINLINE TString& Replace(size_t Index, size_t CountToReplace, I InString, S Sentinel) { checkf(Index <= this->Num() && Index + CountToReplace <= this->Num(), TEXT("Illegal substring range. Please check Index and CountToReplace.")); @@ -464,19 +514,27 @@ public: } /** Replace the substring ['First', 'Last') with the contents of the range ['InString', 'Sentinel'). */ - template S> requires (CConstructibleFrom>) + template S> requires (CConstructibleFrom>) TString& Replace(FConstIterator First, FConstIterator Last, I InString, S Sentinel) { checkf(this->IsValidIterator(First) && this->IsValidIterator(Last) && First <= Last, TEXT("Read access violation. Please check IsValidIterator().")); if constexpr (CForwardIterator) { - if constexpr (CSizedSentinelFor) { checkf(First - Last <= 0, TEXT("Illegal range iterator. Please check First <= Last.")); } + checkf(First - Last <= 0, TEXT("Illegal range iterator. Please check First <= Last.")); const size_t InsertIndex = First - this->Begin(); + const size_t RemoveCount = Last - First; - const size_t RemoveCount = Iteration::Distance(First, Last); - const size_t InsertCount = Iteration::Distance(InString, Sentinel); + size_t InsertCount = 0; + + if constexpr (CSizedSentinelFor) + { + checkf(InString - Sentinel <= 0, TEXT("Illegal range iterator. Please check InString <= Sentinel.")); + + InsertCount = Sentinel - InString; + } + else for (I Iter = InString; Iter != Sentinel; ++Iter) ++InsertCount; const size_t NumToReset = this->Num() - RemoveCount + InsertCount; @@ -519,6 +577,24 @@ public: return *this; } + /** Replace the substring [Index, Index + CountToReplace) with the contents of the range. */ + template requires (CConstructibleFrom>) + FORCEINLINE TString& Replace(size_t Index, size_t CountToReplace, R&& Range) + { + checkf(Index <= this->Num() && Index + CountToReplace <= this->Num(), TEXT("Illegal substring range. Please check Index and CountToReplace.")); + + return Replace(this->Begin() + Index, this->Begin() + Index + CountToReplace, Forward(Range)); + } + + /** Replace the substring ['First', 'Last') with the contents of the range. */ + template requires (CConstructibleFrom>) + FORCEINLINE TString& Replace(FConstIterator First, FConstIterator Last, R&& Range) + { + checkf(this->IsValidIterator(First) && this->IsValidIterator(Last) && First <= Last, TEXT("Read access violation. Please check IsValidIterator().")); + + return Replace(First, Last, Range::Begin(Range), Range::End(Range)); + } + /** Replace the substring [Index, Index + CountToReplace) with the contents of the initializer list. */ FORCEINLINE TString& Replace(size_t Index, size_t CountToReplace, initializer_list IL) { @@ -532,7 +608,7 @@ public: { checkf(this->IsValidIterator(First) && this->IsValidIterator(Last) && First <= Last, TEXT("Read access violation. Please check IsValidIterator().")); - return Replace(First, Last, Iteration::Begin(IL), Iteration::End(IL)); + return Replace(First, Last, Range::Begin(IL), Range::End(IL)); } /** Obtains a string that is a view over the 'Count' characters of this string view starting at 'Offset'. */ @@ -540,7 +616,7 @@ public: { checkf(Offset <= this->Num() && Offset + Count <= this->Num(), TEXT("Illegal substring range. Please check Offset and Count.")); - return TStringView(*this).Substr(Offset, Count); + return TString(TStringView(*this).Substr(Offset, Count)); } /** Copies the characters of this string to the destination buffer without null-termination. */ @@ -725,7 +801,7 @@ public: do { - const auto Result = Facet.in(State, BeginFrom, EndFrom, NextFrom, Iteration::Begin(Buffer), Iteration::End(Buffer), NextTo); + const auto Result = Facet.in(State, BeginFrom, EndFrom, NextFrom, Range::Begin(Buffer), Range::End(Buffer), NextTo); if (BeginFrom == NextFrom) return false; @@ -773,7 +849,7 @@ public: do { - const auto Result = Facet.out(State, BeginFrom, EndFrom, NextFrom, Iteration::Begin(Buffer), Iteration::End(Buffer), NextTo); + const auto Result = Facet.out(State, BeginFrom, EndFrom, NextFrom, Range::Begin(Buffer), Range::End(Buffer), NextTo); if (BeginFrom == NextFrom) return false; @@ -1360,8 +1436,11 @@ TString(const T*) -> TString; template TString(TStringView) -> TString; -template -TString(I, S) -> TString>; +template +TString(I, S) -> TString>; + +template +TString(R) -> TString>; template TString(initializer_list) -> TString; diff --git a/Redcraft.Utility/Source/Public/String/StringView.h b/Redcraft.Utility/Source/Public/String/StringView.h index b899757..8252896 100644 --- a/Redcraft.Utility/Source/Public/String/StringView.h +++ b/Redcraft.Utility/Source/Public/String/StringView.h @@ -1,17 +1,16 @@ #pragma once #include "CoreTypes.h" +#include "Range/Range.h" #include "String/Char.h" #include "Memory/Allocator.h" +#include "Iterator/Iterator.h" #include "Templates/Utility.h" #include "Templates/TypeHash.h" #include "Containers/ArrayView.h" #include "TypeTraits/TypeTraits.h" #include "Memory/MemoryOperator.h" -#include "Miscellaneous/Iterator.h" -#include "Miscellaneous/Container.h" #include "Miscellaneous/AssertionMacros.h" -#include "Miscellaneous/ConstantIterator.h" #include #include @@ -86,7 +85,7 @@ private: public: - using FElementType = T; + using FElementType = TRemoveCV; using FReference = typename FSuper::FReference; @@ -99,11 +98,11 @@ public: FORCEINLINE constexpr TStringView() = default; /** Constructs a string view that is a view over the range ['InFirst', 'InFirst' + 'Count'). */ - template requires (CConvertibleTo(*)[], const FElementType(*)[]>) + template requires (CConvertibleTo, T> && CSameAs>, TRemoveCVRef>) FORCEINLINE constexpr TStringView(I InFirst, size_t InCount) : FSuper(InFirst, InCount) { } /** Constructs a string view that is a view over the range ['InFirst', 'InLast'). */ - template S> requires (CConvertibleTo(*)[], const FElementType(*)[]>) + template S> requires (CConvertibleTo, T> && CSameAs>, TRemoveCVRef>) FORCEINLINE constexpr TStringView(I InFirst, S InLast) : FSuper(InFirst, InLast) { } /** Constructs a string view that is a view over the string 'InString'. */ @@ -663,8 +662,11 @@ public: }; +template +TStringView(I) -> TStringView>; + template -TStringView(I, S) -> TStringView>; +TStringView(I, S) -> TStringView>; template TStringView(TString) -> TStringView; diff --git a/Redcraft.Utility/Source/Public/Templates/Meta.h b/Redcraft.Utility/Source/Public/Templates/Meta.h index 01a6986..2d3a352 100644 --- a/Redcraft.Utility/Source/Public/Templates/Meta.h +++ b/Redcraft.Utility/Source/Public/Templates/Meta.h @@ -3,7 +3,6 @@ #include "CoreTypes.h" #include "Templates/Utility.h" #include "TypeTraits/TypeTraits.h" -#include "Miscellaneous/Container.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) @@ -13,8 +12,7 @@ template struct TIntegerSequence { using FValueType = T; - FORCEINLINE static constexpr size_t Num() { return sizeof...(Ints); } - FORCEINLINE static constexpr const T* GetData() { return NAMESPACE_REDCRAFT::GetData({ Ints... }); } + FORCEINLINE static constexpr size_t Num() { return sizeof...(Ints); } }; NAMESPACE_PRIVATE_BEGIN diff --git a/Redcraft.Utility/Source/Public/Templates/Optional.h b/Redcraft.Utility/Source/Public/Templates/Optional.h index 23d60ae..28e71dc 100644 --- a/Redcraft.Utility/Source/Public/Templates/Optional.h +++ b/Redcraft.Utility/Source/Public/Templates/Optional.h @@ -56,8 +56,8 @@ public: FORCEINLINE constexpr TOptional(FInvalid) : TOptional() { } /** Constructs an object with initial content an object, direct-initialized from Forward(InValue). */ - template requires (CConstructibleFrom) - && (!CSameAs, FInPlace>) && (!CSameAs>) + template requires (CConstructibleFrom + && !CSameAs, FInPlace> && !CSameAs>) FORCEINLINE constexpr explicit (!CConvertibleTo) TOptional(U&& InValue) : TOptional(InPlace, Forward(InValue)) { } diff --git a/Redcraft.Utility/Source/Public/Templates/TypeHash.h b/Redcraft.Utility/Source/Public/Templates/TypeHash.h index 0e72e32..10ccdfc 100644 --- a/Redcraft.Utility/Source/Public/Templates/TypeHash.h +++ b/Redcraft.Utility/Source/Public/Templates/TypeHash.h @@ -94,6 +94,20 @@ FORCEINLINE constexpr size_t GetTypeHash(const T& A) return GetTypeHash(A.hash_code()); } +/** Overloads the GetTypeHash algorithm for arrays. */ +template requires (requires(const T& A) { { GetTypeHash(A) } -> CSameAs; }) +FORCEINLINE constexpr size_t GetTypeHash(T(&A)[N]) +{ + size_t Result = 3516520171; + + for (size_t Index = 0; Index < N; ++Index) + { + Result = HashCombine(Result, GetTypeHash(A[Index])); + } + + return Result; +} + template concept CHashable = requires(const T& A) { { GetTypeHash(A) } -> CSameAs; }; diff --git a/Redcraft.Utility/Source/Public/Templates/Utility.h b/Redcraft.Utility/Source/Public/Templates/Utility.h index dd78dec..bed4fe9 100644 --- a/Redcraft.Utility/Source/Public/Templates/Utility.h +++ b/Redcraft.Utility/Source/Public/Templates/Utility.h @@ -1,7 +1,7 @@ #pragma once #include "CoreTypes.h" -#include "TypeTraits/CompositeType.h" +#include "TypeTraits/Common.h" #include "TypeTraits/Miscellaneous.h" #include "TypeTraits/SupportedOperations.h" @@ -73,6 +73,17 @@ FORCEINLINE constexpr void Swap(T& A, T& B) B = MoveTemp(Temp); } +/** Overloads the Swap algorithm for arrays. */ +template requires (CCommonReference + && requires(T& A, U& B) { Swap(A, A); Swap(B, B); Swap(A, B); Swap(B, A); }) +FORCEINLINE constexpr void Swap(T(&A)[N], U(&B)[N]) +{ + for (size_t Index = 0; Index < N; ++Index) + { + Swap(A[Index], B[Index]); + } +} + /** Replaces the value of 'A' with 'B' and returns the old value of 'A'. */ template requires (CMoveConstructible && CAssignableFrom) FORCEINLINE constexpr T Exchange(T& A, U&& B) diff --git a/Redcraft.Utility/Source/Public/Templates/Variant.h b/Redcraft.Utility/Source/Public/Templates/Variant.h index 108c6dd..6497513 100644 --- a/Redcraft.Utility/Source/Public/Templates/Variant.h +++ b/Redcraft.Utility/Source/Public/Templates/Variant.h @@ -1,6 +1,7 @@ #pragma once #include "CoreTypes.h" +#include "Range/Utility.h" #include "Templates/Meta.h" #include "Templates/Invoke.h" #include "Templates/Utility.h" @@ -478,7 +479,7 @@ struct TVariantVisitImpl for (size_t Index = 0; Index < sizeof...(VariantTypes); ++Index) { Result *= VariantNums[Index]; - Result += GetData(Indices)[Index]; + Result += Range::Begin(Indices)[Index]; } return Result;