Compare commits
4 Commits
4845520225
...
f54386d102
Author | SHA1 | Date | |
---|---|---|---|
f54386d102 | |||
6a37e91639 | |||
0a37460f24 | |||
aa8cd7ed33 |
@ -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<FElementType>)
|
||||
: TArray(MakeCountedConstantIterator(InValue, Count), DefaultSentinel)
|
||||
: TArray(Range::Repeat(InValue, Count))
|
||||
{ }
|
||||
|
||||
/** Constructs the container with the contents of the range ['First', 'Last'). */
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReferenceType<I>> && CMovable<FElementType>)
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReference<I>> && CMovable<FElementType>)
|
||||
TArray(I First, S Last)
|
||||
{
|
||||
if constexpr (CForwardIterator<I>)
|
||||
{
|
||||
if constexpr (CSizedSentinelFor<S, I>) { 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<S, I>)
|
||||
{
|
||||
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 <CInputRange R> requires (!CSameAs<TRemoveCVRef<R>, TArray> && CConstructibleFrom<FElementType, TRangeReference<R>> && CMovable<FElementType>)
|
||||
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<FElementType>)
|
||||
{
|
||||
@ -129,7 +138,7 @@ public:
|
||||
}
|
||||
|
||||
/** Constructs the container with the contents of the initializer list. */
|
||||
FORCEINLINE TArray(initializer_list<FElementType> IL) requires (CCopyConstructible<FElementType>) : TArray(Iteration::Begin(IL), Iteration::End(IL)) { }
|
||||
FORCEINLINE TArray(initializer_list<FElementType> IL) requires (CCopyConstructible<FElementType>) : 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<FElementType> IL) requires (CCopyable<FElementType>)
|
||||
{
|
||||
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<FElementType>(Impl.Pointer, NAMESPACE_REDCRAFT::GetData(IL), Num());
|
||||
Memory::CopyConstruct<FElementType>(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<FElementType>(Impl.Pointer + Num(), NAMESPACE_REDCRAFT::GetData(IL) + Num(), GetNum(IL) - Num());
|
||||
Memory::CopyAssign(Impl.Pointer, Range::GetData(IL), Num());
|
||||
Memory::CopyConstruct<FElementType>(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 <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReferenceType<I>>
|
||||
&& CAssignableFrom<FElementType&, TIteratorReferenceType<I>> && CMovable<FElementType>)
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReference<I>>
|
||||
&& CAssignableFrom<FElementType&, TIteratorReference<I>> && CMovable<FElementType>)
|
||||
FIterator Insert(FConstIterator Iter, I First, S Last)
|
||||
{
|
||||
checkf(IsValidIterator(Iter), TEXT("Read access violation. Please check IsValidIterator()."));
|
||||
|
||||
if constexpr (CForwardIterator<I>)
|
||||
{
|
||||
if constexpr (CSizedSentinelFor<S, I>) { 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<S, I>)
|
||||
{
|
||||
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 <CInputRange R> requires (CConstructibleFrom<FElementType, TRangeReference<R>>
|
||||
&& CAssignableFrom<FElementType&, TRangeReference<R>> && CMovable<FElementType>)
|
||||
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<FElementType> IL) requires (CCopyable<FElementType>)
|
||||
{
|
||||
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 <typename I, typename S>
|
||||
TArray(I, S) -> TArray<TIteratorElementType<I>>;
|
||||
TArray(I, S) -> TArray<TIteratorElement<I>>;
|
||||
|
||||
template <typename R>
|
||||
TArray(R) -> TArray<TRangeElement<R>>;
|
||||
|
||||
template <typename T>
|
||||
TArray(initializer_list<T>) -> TArray<T>;
|
||||
|
@ -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<T>;
|
||||
|
||||
using FReference = T&;
|
||||
|
||||
@ -53,7 +53,7 @@ public:
|
||||
}
|
||||
|
||||
/** Constructs an array view that is a view over the range ['InFirst', 'InFirst' + 'Count'). */
|
||||
template <CContiguousIterator I> requires (CConvertibleTo<TIteratorElementType<I>(*)[], FElementType(*)[]>)
|
||||
template <CContiguousIterator I> requires (CConvertibleTo<TIteratorReference<I>, T> && CSameAs<TRemoveCVRef<TIteratorReference<I>>, TRemoveCVRef<T>>)
|
||||
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 <CContiguousIterator I, CSizedSentinelFor<I> S> requires (CConvertibleTo<TIteratorElementType<I>(*)[], FElementType(*)[]>)
|
||||
template <CContiguousIterator I, CSizedSentinelFor<I> S> requires (CConvertibleTo<TIteratorReference<I>, T> && CSameAs<TRemoveCVRef<TIteratorReference<I>>, TRemoveCVRef<T>>)
|
||||
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 <size_t Count> requires (Extent == DynamicExtent || Extent >= Count)
|
||||
NODISCARD FORCEINLINE constexpr TArrayView<FElementType, Count> First() const
|
||||
NODISCARD FORCEINLINE constexpr TArrayView<T, Count> First() const
|
||||
{
|
||||
checkf(Count <= Num(), TEXT("Illegal subview range. Please check Count."));
|
||||
|
||||
return TArrayView<FElementType, Count>(Begin(), Count);
|
||||
return TArrayView<T, Count>(Begin(), Count);
|
||||
}
|
||||
|
||||
/** Obtains an array view that is a view over the first 'Count' elements of this array view. */
|
||||
NODISCARD FORCEINLINE constexpr TArrayView<FElementType, DynamicExtent> First(size_t Count) const
|
||||
NODISCARD FORCEINLINE constexpr TArrayView<T, DynamicExtent> First(size_t Count) const
|
||||
{
|
||||
checkf(Count <= Num(), TEXT("Illegal subview range. Please check Count."));
|
||||
|
||||
return TArrayView<FElementType, DynamicExtent>(Begin(), Count);
|
||||
return TArrayView<T, DynamicExtent>(Begin(), Count);
|
||||
}
|
||||
|
||||
/** Obtains an array view that is a view over the last 'Count' elements of this array view. */
|
||||
template <size_t Count> requires (Extent == DynamicExtent || Extent >= Count)
|
||||
NODISCARD FORCEINLINE constexpr TArrayView<FElementType, Count> Last() const
|
||||
NODISCARD FORCEINLINE constexpr TArrayView<T, Count> Last() const
|
||||
{
|
||||
checkf(Count <= Num(), TEXT("Illegal subview range. Please check Count."));
|
||||
|
||||
return TArrayView<FElementType, Count>(End() - Count, Count);
|
||||
return TArrayView<T, Count>(End() - Count, Count);
|
||||
}
|
||||
|
||||
/** Obtains an array view that is a view over the last 'Count' elements of this array view. */
|
||||
NODISCARD FORCEINLINE constexpr TArrayView<FElementType, DynamicExtent> Last(size_t Count) const
|
||||
NODISCARD FORCEINLINE constexpr TArrayView<T, DynamicExtent> Last(size_t Count) const
|
||||
{
|
||||
checkf(Count <= Num(), TEXT("Illegal subview range. Please check Count."));
|
||||
|
||||
return TArrayView<FElementType, DynamicExtent>(End() - Count, Count);
|
||||
return TArrayView<T, DynamicExtent>(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<FElementType, SubviewExtent>(Begin() + Offset, Count);
|
||||
return TArrayView<T, SubviewExtent>(Begin() + Offset, Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
return TArrayView<FElementType, SubviewExtent>(Begin() + Offset, Num() - Offset);
|
||||
return TArrayView<T, SubviewExtent>(Begin() + Offset, Num() - Offset);
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,11 +213,11 @@ public:
|
||||
|
||||
if (Count != DynamicExtent)
|
||||
{
|
||||
return TArrayView<FElementType, DynamicExtent>(Begin() + Offset, Count);
|
||||
return TArrayView<T, DynamicExtent>(Begin() + Offset, Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
return TArrayView<FElementType, DynamicExtent>(Begin() + Offset, Num() - Offset);
|
||||
return TArrayView<T, DynamicExtent>(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 <typename I, typename S>
|
||||
TArrayView(I, S) -> TArrayView<TRemoveReference<TIteratorReferenceType<I>>>;
|
||||
TArrayView(I, S) -> TArrayView<TRemoveReference<TIteratorReference<I>>>;
|
||||
|
||||
template <typename T, size_t N>
|
||||
TArrayView(T(&)[N]) -> TArrayView<T, N>;
|
||||
|
@ -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 <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<bool, TIteratorReferenceType<I>>)
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<bool, TIteratorReference<I>>)
|
||||
TBitset(I First, S Last)
|
||||
{
|
||||
if constexpr (CForwardIterator<I>)
|
||||
{
|
||||
if constexpr (CSizedSentinelFor<S, I>) { 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<S, I>)
|
||||
{
|
||||
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 <CInputRange R> requires (!CSameAs<TRemoveCVRef<R>, TBitset> && CConstructibleFrom<bool, TRangeReference<R>>)
|
||||
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<bool> IL) : TBitset(Iteration::Begin(IL), Iteration::End(IL)) { }
|
||||
FORCEINLINE TBitset(initializer_list<bool> 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<bool> 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++;
|
||||
|
||||
|
@ -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<FElementType>)
|
||||
: TList(MakeCountedConstantIterator(InValue, Count), DefaultSentinel)
|
||||
: TList(Range::Repeat(InValue, Count))
|
||||
{ }
|
||||
|
||||
/** Constructs the container with the contents of the range ['First', 'Last'). */
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReferenceType<I>>)
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReference<I>>)
|
||||
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 <CInputRange R> requires (!CSameAs<TRemoveCVRef<R>, TList> && CConstructibleFrom<FElementType, TRangeReference<R>>)
|
||||
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<FElementType>) : 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<FElementType> IL) requires (CCopyConstructible<FElementType>) : TList(Iteration::Begin(IL), Iteration::End(IL)) { }
|
||||
FORCEINLINE TList(initializer_list<FElementType> IL) requires (CCopyConstructible<FElementType>) : 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<FElementType> IL) requires (CCopyable<FElementType>)
|
||||
{
|
||||
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<FElementType>)
|
||||
{
|
||||
return Insert(Iter, MakeCountedConstantIterator(InValue, Count), DefaultSentinel);
|
||||
return Insert(Iter, Range::Repeat(InValue, Count));
|
||||
}
|
||||
|
||||
/** Inserts elements from range ['First', 'Last') before 'Iter'. */
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReferenceType<I>>)
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReference<I>>)
|
||||
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 <CInputRange R> requires (CConstructibleFrom<FElementType, TRangeReference<R>>)
|
||||
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<FElementType> IL) requires (CCopyConstructible<FElementType>) { return Insert(Iter, Iteration::Begin(IL), Iteration::End(IL)); }
|
||||
FORCEINLINE FIterator Insert(FConstIterator Iter, initializer_list<FElementType> IL) requires (CCopyConstructible<FElementType>) { return Insert(Iter, Range::Begin(IL), Range::End(IL)); }
|
||||
|
||||
/** Inserts a new element into the container directly before 'Iter'. */
|
||||
template <typename... Ts> requires (CConstructibleFrom<FElementType, Ts...>)
|
||||
@ -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 <typename I, typename S>
|
||||
TList(I, S) -> TList<TIteratorElementType<I>>;
|
||||
TList(I, S) -> TList<TIteratorElement<I>>;
|
||||
|
||||
template <typename R>
|
||||
TList(R) -> TList<TRangeElement<R>>;
|
||||
|
||||
template <typename T>
|
||||
TList(initializer_list<T>) -> TList<T>;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 <typename T> requires (CDestructible<T> || CLValueReference<T>)
|
||||
class TConstantIterator final
|
||||
{
|
||||
public:
|
||||
|
||||
using FElementType = TRemoveCV<T>;
|
||||
|
||||
FORCEINLINE constexpr TConstantIterator() = default;
|
||||
|
||||
FORCEINLINE constexpr ~TConstantIterator() = default;
|
||||
|
||||
template <typename U = T> requires (!CSameAs<TConstantIterator, TRemoveCVRef<U>> && CConstructibleFrom<T, U&&>)
|
||||
FORCEINLINE constexpr explicit TConstantIterator(U&& InValue) : Value(Forward<U>(InValue)) { }
|
||||
|
||||
template <typename U> requires (CConstructibleFrom<T, const U&>)
|
||||
FORCEINLINE constexpr explicit (!CConvertibleTo<const U&, T>) TConstantIterator(const TConstantIterator<U>& InValue) : Value(InValue.Value) { }
|
||||
|
||||
template <typename U> requires (CConstructibleFrom<T, U&&>)
|
||||
FORCEINLINE constexpr explicit (!CConvertibleTo<U&&, T>) TConstantIterator(TConstantIterator<U>&& InValue) : Value(MoveTemp(InValue.Value)) { }
|
||||
|
||||
FORCEINLINE constexpr TConstantIterator(const TConstantIterator&) requires (CCopyConstructible<T>) = default;
|
||||
|
||||
FORCEINLINE constexpr TConstantIterator(TConstantIterator&&) requires (CMoveConstructible<T>) = default;
|
||||
|
||||
template <typename U> requires (CConvertibleTo<const U&, T> && CAssignableFrom<T&, const U&>)
|
||||
FORCEINLINE constexpr TConstantIterator& operator=(const TConstantIterator<U>& InValue) { Value = InValue.Value; return *this; }
|
||||
|
||||
template <typename U> requires (CConvertibleTo<U&&, T> && CAssignableFrom<T&, U&&>)
|
||||
FORCEINLINE constexpr TConstantIterator& operator=(TConstantIterator<U>&& InValue) { Value = MoveTemp(InValue.Value); return *this; }
|
||||
|
||||
FORCEINLINE constexpr TConstantIterator& operator=(const TConstantIterator&) requires (CCopyAssignable<T>) = default;
|
||||
|
||||
FORCEINLINE constexpr TConstantIterator& operator=(TConstantIterator&&) requires (CMoveAssignable<T>) = 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 <typename U> requires (CDestructible<U> || CLValueReference<U>)
|
||||
friend class TConstantIterator;
|
||||
|
||||
};
|
||||
|
||||
static_assert(CInputIterator<TConstantIterator<int>>);
|
||||
|
||||
/** An iterator that always points to the same value. */
|
||||
template <typename T>
|
||||
class TConstantIterator<T&> final
|
||||
{
|
||||
public:
|
||||
|
||||
using FElementType = TRemoveCV<T>;
|
||||
|
||||
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 <typename U> requires (CConvertibleTo<U*, T*>)
|
||||
FORCEINLINE constexpr TConstantIterator(const TConstantIterator<U>& InValue) : Ptr(InValue.Ptr) { }
|
||||
|
||||
template <typename U> requires (CConvertibleTo<U*, T*>)
|
||||
FORCEINLINE constexpr TConstantIterator& operator=(const TConstantIterator<U>& 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 <typename U> requires (CDestructible<U> || CLValueReference<U>)
|
||||
friend class TConstantIterator;
|
||||
|
||||
};
|
||||
|
||||
static_assert(CInputIterator<TConstantIterator<int&>>);
|
||||
|
||||
/** An iterator adapter specialization that tracks the distance of a constant iterator to the end of the range. */
|
||||
template <typename T> requires (CDestructible<T> || CLValueReference<T>)
|
||||
class TCountedIterator<TConstantIterator<T>> final
|
||||
{
|
||||
public:
|
||||
|
||||
using FIteratorType = TConstantIterator<T>;
|
||||
|
||||
using FElementType = typename TConstantIterator<T>::FElementType;
|
||||
|
||||
# if DO_CHECK
|
||||
FORCEINLINE constexpr TCountedIterator() requires (CDefaultConstructible<FIteratorType>) : Length(1), MaxLength(0) { }
|
||||
# else
|
||||
FORCEINLINE constexpr TCountedIterator() requires (CDefaultConstructible<FIteratorType>) = 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 <typename U = FIteratorType> requires (!CSameAs<TCountedIterator, TRemoveCVRef<U>> && CConstructibleFrom<FIteratorType, U>)
|
||||
FORCEINLINE constexpr explicit TCountedIterator(U&& InValue, ptrdiff N) : Current(Forward<U>(InValue)), Length(N) { check_code({ MaxLength = N; }); }
|
||||
|
||||
template <CInputOrOutputIterator J> requires (!CSameAs<FIteratorType, J> && CConstructibleFrom<FIteratorType, const J&>)
|
||||
FORCEINLINE constexpr explicit (!CConvertibleTo<const J&, FIteratorType>) TCountedIterator(const TCountedIterator<J>& InValue) : Current(InValue.Current), Length(InValue.Num()) { check_code({ MaxLength = InValue.MaxLength; }); }
|
||||
|
||||
template <CInputOrOutputIterator J> requires (!CSameAs<FIteratorType, J> && CConstructibleFrom<FIteratorType, J>)
|
||||
FORCEINLINE constexpr explicit (!CConvertibleTo<J&&, FIteratorType>) TCountedIterator(TCountedIterator<J>&& InValue) : Current(MoveTemp(InValue).Current), Length(InValue.Num()) { check_code({ MaxLength = InValue.MaxLength; }); }
|
||||
|
||||
template <CInputOrOutputIterator J> requires (!CSameAs<FIteratorType, J> && CConvertibleTo<const J&, FIteratorType> && CAssignableFrom<FIteratorType&, const J&>)
|
||||
FORCEINLINE constexpr TCountedIterator& operator=(const TCountedIterator<J>& InValue) { Current = InValue.Current; Length = InValue.Num(); check_code({ MaxLength = InValue.MaxLength; }); return *this; }
|
||||
|
||||
template <CInputOrOutputIterator J> requires (!CSameAs<FIteratorType, J> && CConvertibleTo<J&&, FIteratorType> && CAssignableFrom<FIteratorType&, J&&>)
|
||||
FORCEINLINE constexpr TCountedIterator& operator=(TCountedIterator<J>&& InValue) { Current = MoveTemp(InValue).Current; Length = InValue.Num(); check_code({ MaxLength = InValue.MaxLength; }); return *this; }
|
||||
|
||||
template <CCommonType<FIteratorType> J>
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const TCountedIterator& LHS, const TCountedIterator<J>& RHS) { return LHS.Length == RHS.Length; }
|
||||
|
||||
template <CCommonType<FIteratorType> J>
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TCountedIterator& LHS, const TCountedIterator<J>& RHS) { return LHS.Length <=> RHS.Length; }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr bool operator==(FDefaultSentinel) const& { return Length == static_cast<ptrdiff>(0); }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(FDefaultSentinel) const& { return static_cast<ptrdiff>(0) <=> Length; }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr const TRemoveReference<T>& operator*() const { CheckThis(true ); return *Current; }
|
||||
NODISCARD FORCEINLINE constexpr const TRemoveReference<T>* operator->() const { CheckThis(false); return ToAddress(Current); }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr const TRemoveReference<T>& 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 <CCommonType<FIteratorType> J>
|
||||
NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const TCountedIterator& LHS, const TCountedIterator<J>& 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<ptrdiff>(0) <= Length && Length <= MaxLength, TEXT("Read access violation. Please check Num()."));
|
||||
checkf(!(bExceptEnd && Length == static_cast<ptrdiff>(0)), TEXT("Read access violation. Please check Num()."));
|
||||
}
|
||||
|
||||
template <CInputOrOutputIterator J>
|
||||
friend class TCountedIterator;
|
||||
|
||||
};
|
||||
|
||||
static_assert(CRandomAccessIterator<TCountedIterator<TConstantIterator<int>>>);
|
||||
static_assert(CSizedSentinelFor<FDefaultSentinel, TCountedIterator<TConstantIterator<int>>>);
|
||||
|
||||
template <typename T> requires (CDestructible<T> || CLValueReference<T>)
|
||||
NODISCARD FORCEINLINE constexpr auto MakeConstantIterator(T&& Value)
|
||||
{
|
||||
return TConstantIterator<T>(Forward<T>(Value));
|
||||
}
|
||||
|
||||
template <typename T> requires (CDestructible<T> || CLValueReference<T>)
|
||||
NODISCARD FORCEINLINE constexpr auto MakeCountedConstantIterator(T&& Value, ptrdiff N)
|
||||
{
|
||||
return TCountedIterator<TConstantIterator<T>>(MakeConstantIterator(Forward<T>(Value)), N);
|
||||
}
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
@ -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 <typename T> requires (requires(T&& Container) { { Container.GetData() } -> CPointer; })
|
||||
FORCEINLINE constexpr auto GetData(T&& Container)
|
||||
{
|
||||
return Container.GetData();
|
||||
}
|
||||
|
||||
/** Overloads the GetData algorithm for arrays. */
|
||||
template <typename T, size_t N> FORCEINLINE constexpr T* GetData( T(& Container)[N]) { return Container; }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr T* GetData( T(&& Container)[N]) { return Container; }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr const T* GetData(const T(& Container)[N]) { return Container; }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr const T* GetData(const T(&& Container)[N]) { return Container; }
|
||||
|
||||
/** Overloads the GetData algorithm for initializer_list. */
|
||||
template <typename T>
|
||||
FORCEINLINE constexpr const T* GetData(initializer_list<T> Container)
|
||||
{
|
||||
return Container.begin();
|
||||
}
|
||||
|
||||
/** @return The number of elements in the container. */
|
||||
template <typename T> requires (requires(T&& Container) { { Container.Num() } -> CConvertibleTo<size_t>; })
|
||||
FORCEINLINE constexpr auto GetNum(T&& Container)
|
||||
{
|
||||
return Container.Num();
|
||||
}
|
||||
|
||||
/** Overloads the GetNum algorithm for arrays. */
|
||||
template <typename T, size_t N> FORCEINLINE constexpr size_t GetNum( T(& )[N]) { return N; }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr size_t GetNum( T(&&)[N]) { return N; }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr size_t GetNum(const T(& )[N]) { return N; }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr size_t GetNum(const T(&&)[N]) { return N; }
|
||||
|
||||
/** Overloads the GetNum algorithm for initializer_list. */
|
||||
template <typename T>
|
||||
FORCEINLINE constexpr size_t GetNum(initializer_list<T> Container)
|
||||
{
|
||||
return Container.size();
|
||||
}
|
||||
|
||||
/** Overloads the Swap algorithm for arrays. */
|
||||
template <typename T, size_t N> requires (CSwappable<TRemoveAllExtents<T>>)
|
||||
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 <typename T, size_t N> requires (CHashable<TRemoveAllExtents<T>>)
|
||||
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
|
@ -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 <typename I>
|
||||
using TIteratorElementType = TIteratorElement<I>;
|
||||
|
||||
template <typename I>
|
||||
using TIteratorPointerType = TIteratorPointer<I>;
|
||||
|
||||
template <CReferenceable I>
|
||||
using TIteratorReferenceType = TIteratorReference<I>;
|
||||
|
||||
template <CReferenceable I> requires (requires(I& Iter) { { MoveTemp(*Iter) } -> CReferenceable; })
|
||||
using TIteratorRValueReferenceType = TIteratorRValueReference<I>;
|
||||
|
||||
NAMESPACE_BEGIN(Iteration)
|
||||
|
||||
/** Increments given iterator 'Iter' by 'N' elements. */
|
||||
template <CInputIterator I>
|
||||
FORCEINLINE constexpr void Advance(I& Iter, ptrdiff N)
|
||||
{
|
||||
if constexpr (CRandomAccessIterator<I>)
|
||||
{
|
||||
Iter += N;
|
||||
}
|
||||
else if constexpr (CBidirectionalIterator<I>)
|
||||
{
|
||||
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 <CInputIterator I, CSentinelFor<I> S>
|
||||
FORCEINLINE constexpr ptrdiff Distance(I First, S Last)
|
||||
{
|
||||
if constexpr (CSizedSentinelFor<S, I>)
|
||||
{
|
||||
return Last - First;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptrdiff Result = 0;
|
||||
for (; First != Last; ++First) ++Result;
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
|
||||
/** @return The 'N'-th successor of iterator 'Iter'. */
|
||||
template <CInputIterator I>
|
||||
FORCEINLINE constexpr I Next(I Iter, TMakeUnsigned<ptrdiff> N = 1)
|
||||
{
|
||||
Iteration::Advance(Iter, N);
|
||||
return Iter;
|
||||
}
|
||||
|
||||
/** @return The 'N'-th predecessor of iterator 'Iter'. */
|
||||
template <CBidirectionalIterator I>
|
||||
FORCEINLINE constexpr I Prev(I Iter, TMakeUnsigned<ptrdiff> N = 1)
|
||||
{
|
||||
Iteration::Advance(Iter, -N);
|
||||
return Iter;
|
||||
}
|
||||
|
||||
NAMESPACE_END(Iteration)
|
||||
|
||||
template <CIndirectlyReadable J, CIndirectlyWritable<TIteratorReferenceType<J>> I>
|
||||
FORCEINLINE void IndirectlyCopy(I&& Iter, J&& Jter)
|
||||
{
|
||||
*Iter = *Jter;
|
||||
}
|
||||
|
||||
template <CIndirectlyReadable J, CIndirectlyWritable<TIteratorRValueReferenceType<J>> I>
|
||||
FORCEINLINE void IndirectlyMove(I&& Iter, J&& Jter)
|
||||
{
|
||||
*Iter = MoveTemp(*Jter);
|
||||
}
|
||||
|
||||
template <CIndirectlyReadable I, CIndirectlyReadable J> requires (CSwappable<TIteratorReferenceType<I>, TIteratorReferenceType<J>>)
|
||||
FORCEINLINE void IndirectlySwap(I&& Iter, J&& Jter)
|
||||
{
|
||||
Swap(*Iter, *Jter);
|
||||
}
|
||||
|
||||
template <typename I, typename J = I>
|
||||
concept CIndirectlyCopyable = requires(const I Iter, const J Jter) { IndirectlyCopy(Iter, Jter); };
|
||||
|
||||
template <typename I, typename J = I>
|
||||
concept CIndirectlyMovable = requires(const I Iter, const J Jter) { IndirectlyMove(Iter, Jter); };
|
||||
|
||||
template <typename I, typename J = I>
|
||||
concept CIndirectlySwappable = CIndirectlyReadable<I> && CIndirectlyReadable<J>
|
||||
&& 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 <typename T> requires (requires(T&& Container) { { Container.Begin() } -> CForwardIterator; })
|
||||
FORCEINLINE constexpr auto Begin(T&& Container)
|
||||
{
|
||||
return Container.Begin();
|
||||
}
|
||||
|
||||
/** Overloads the Begin algorithm for arrays. */
|
||||
template <typename T, size_t N> FORCEINLINE constexpr T* Begin( T(& Container)[N]) { return Container; }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr T* Begin( T(&& Container)[N]) { return Container; }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr const T* Begin(const T(& Container)[N]) { return Container; }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr const T* Begin(const T(&& Container)[N]) { return Container; }
|
||||
|
||||
/** Overloads the Begin algorithm for initializer_list. */
|
||||
template <typename T>
|
||||
FORCEINLINE constexpr auto Begin(initializer_list<T> Container)
|
||||
{
|
||||
return Container.begin();
|
||||
}
|
||||
|
||||
/** @return The iterator to the end of a container. */
|
||||
template <typename T> requires (requires(T&& Container) { { Container.End() } -> CForwardIterator; })
|
||||
FORCEINLINE constexpr auto End(T&& Container)
|
||||
{
|
||||
return Container.End();
|
||||
}
|
||||
|
||||
/** Overloads the End algorithm for arrays. */
|
||||
template <typename T, size_t N> FORCEINLINE constexpr T* End( T(& Container)[N]) { return Container + N; }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr T* End( T(&& Container)[N]) { return Container + N; }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr const T* End(const T(& Container)[N]) { return Container + N; }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr const T* End(const T(&& Container)[N]) { return Container + N; }
|
||||
|
||||
/** Overloads the End algorithm for initializer_list. */
|
||||
template <typename T>
|
||||
FORCEINLINE constexpr auto End(initializer_list<T> Container)
|
||||
{
|
||||
return Container.end();
|
||||
}
|
||||
|
||||
/** @return The reverse iterator to the beginning of a container. */
|
||||
template <typename T> requires (requires(T&& Container) { { Container.RBegin() } -> CForwardIterator; })
|
||||
FORCEINLINE constexpr auto RBegin(T&& Container)
|
||||
{
|
||||
return Container.RBegin();
|
||||
}
|
||||
|
||||
/** Overloads the RBegin algorithm for arrays. */
|
||||
template <typename T, size_t N> FORCEINLINE constexpr auto RBegin( T(& Container)[N]) { return TReverseIterator(End(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr auto RBegin( T(&& Container)[N]) { return TReverseIterator(End(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr auto RBegin(const T(& Container)[N]) { return TReverseIterator(End(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr auto RBegin(const T(&& Container)[N]) { return TReverseIterator(End(Container)); }
|
||||
|
||||
/** Overloads the RBegin algorithm for initializer_list. */
|
||||
template <typename T>
|
||||
FORCEINLINE constexpr auto RBegin(initializer_list<T> Container)
|
||||
{
|
||||
return TReverseIterator(Container.end());
|
||||
}
|
||||
|
||||
/** @return The reverse iterator to the end of a container. */
|
||||
template <typename T> requires (requires(T&& Container) { { Container.REnd() } -> CForwardIterator; })
|
||||
FORCEINLINE constexpr auto REnd(T&& Container)
|
||||
{
|
||||
return Container.REnd();
|
||||
}
|
||||
|
||||
/** Overloads the REnd algorithm for arrays. */
|
||||
template <typename T, size_t N> FORCEINLINE constexpr auto REnd( T(& Container)[N]) { return TReverseIterator(Begin(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr auto REnd( T(&& Container)[N]) { return TReverseIterator(Begin(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr auto REnd(const T(& Container)[N]) { return TReverseIterator(Begin(Container)); }
|
||||
template <typename T, size_t N> FORCEINLINE constexpr auto REnd(const T(&& Container)[N]) { return TReverseIterator(Begin(Container)); }
|
||||
|
||||
/** Overloads the REnd algorithm for initializer_list. */
|
||||
template <typename T>
|
||||
FORCEINLINE constexpr auto REnd(initializer_list<T> Container)
|
||||
{
|
||||
return TReverseIterator(Container.begin());
|
||||
}
|
||||
|
||||
NAMESPACE_END(Iteration)
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
@ -152,10 +152,12 @@ NODISCARD FORCEINLINE constexpr auto All(R&& InRange)
|
||||
/** Creates A view adapter that includes all elements of a range. */
|
||||
NODISCARD FORCEINLINE constexpr auto All()
|
||||
{
|
||||
return TAdaptorClosure([]<CViewableRange R> requires (requires { Range::All(DeclVal<R>()); }) (R&& Base)
|
||||
using FClosure = decltype([]<CViewableRange R> requires (requires { Range::All(DeclVal<R>()); }) (R&& Base)
|
||||
{
|
||||
return Range::All(Forward<R>(Base));
|
||||
});
|
||||
|
||||
return TAdaptorClosure<FClosure>();
|
||||
}
|
||||
|
||||
/** A view adapter that includes all elements of a range. */
|
||||
|
163
Redcraft.Utility/Source/Public/Range/Conversion.h
Normal file
163
Redcraft.Utility/Source/Public/Range/Conversion.h
Normal file
@ -0,0 +1,163 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "Range/View.h"
|
||||
#include "Range/Utility.h"
|
||||
#include "Range/AllView.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Range/TransformView.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
|
||||
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<R> and CSameAs<TRangeElement<R>, int>);
|
||||
//
|
||||
// TArray Arr(RangeOfInts);
|
||||
// TArray Brr{RangeOfInts};
|
||||
//
|
||||
// If R is TArray<int> than decltype(Arr) is TArray<int> and decltype(Brr) is TArray<int>,
|
||||
// otherwise, decltype(Arr) is TArray<int> and decltype(Brr) is TArray<R>.
|
||||
//
|
||||
// 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 <typename C>
|
||||
concept CReservableContainer = CSizedRange<C>
|
||||
&& requires (C& Container, size_t N)
|
||||
{
|
||||
Container.Reserve(N);
|
||||
{ Container.Max() } -> CSameAs<size_t>;
|
||||
};
|
||||
|
||||
/** A concept specifies a container that can append elements. */
|
||||
template <typename C, typename Ref>
|
||||
concept CAppendableContainer =
|
||||
requires (C& Container, Ref&& Reference)
|
||||
{
|
||||
requires
|
||||
(
|
||||
requires { Container.EmplaceBack (Forward<Ref>(Reference)); } ||
|
||||
requires { Container.PushBack (Forward<Ref>(Reference)); } ||
|
||||
requires { Container.Emplace(Container.End(), Forward<Ref>(Reference)); } ||
|
||||
requires { Container.Insert (Container.End(), Forward<Ref>(Reference)); }
|
||||
);
|
||||
};
|
||||
|
||||
NAMESPACE_BEGIN(Range)
|
||||
|
||||
/** Constructs a non-view object from the elements of the range. */
|
||||
template <typename C, CInputRange R, typename... Ts> requires (!CView<C>)
|
||||
NODISCARD FORCEINLINE constexpr auto To(R&& Range, Ts&&... Args)
|
||||
{
|
||||
if constexpr (!CInputRange<C> || CConvertibleTo<TRangeReference<R>, TRangeElement<C>>)
|
||||
{
|
||||
if constexpr (CConstructibleFrom<C, R, Ts...>)
|
||||
{
|
||||
return C(Forward<R>(Range), Forward<Ts>(Args)...);
|
||||
}
|
||||
|
||||
else if constexpr (CCommonRange<R> && CInputRange<R> && CConstructibleFrom<C, TRangeIterator<R>, TRangeSentinel<R>, Ts...>)
|
||||
{
|
||||
return C(Range::Begin(Range), Range::End(Range), Forward<Ts>(Args)...);
|
||||
}
|
||||
|
||||
else if constexpr (CConstructibleFrom<C, Ts...> && CAppendableContainer<C, TRangeReference<R>>)
|
||||
{
|
||||
C Result(Forward<Ts>(Args)...);
|
||||
|
||||
if constexpr (CSizedRange<R> && CReservableContainer<C>)
|
||||
{
|
||||
Result.Reserve(Range::Num(Range));
|
||||
}
|
||||
|
||||
for (TRangeReference<R> Element : Range)
|
||||
{
|
||||
if constexpr (requires { Result.EmplaceBack(DeclVal<TRangeReference<R>>()); })
|
||||
{
|
||||
Result.EmplaceBack(Forward<TRangeReference<R>>(Element));
|
||||
}
|
||||
|
||||
else if constexpr (requires { Result.PushBack(DeclVal<TRangeReference<R>>()); })
|
||||
{
|
||||
Result.PushBack(Forward<TRangeReference<R>>(Element));
|
||||
}
|
||||
|
||||
else if constexpr (requires { Result.Emplace(Result.End(), DeclVal<TRangeReference<R>>()); })
|
||||
{
|
||||
Result.Emplace(Result.End(), Forward<TRangeReference<R>>(Element));
|
||||
}
|
||||
|
||||
else /* if constexpr (requires { Result.Insert(Result.End(), DeclVal<TRangeReference<R>>()); }) */
|
||||
{
|
||||
Result.Insert(Result.End(), Forward<TRangeReference<R>>(Element));
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
else static_assert(sizeof(R) == -1, "The container type is not constructible from a range");
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr (CInputRange<TRangeReference<C>>)
|
||||
{
|
||||
return Range::To<C>(Range::All(Range) | Range::Transform([]<typename T>(T&& Element) { return Range::To<TRangeElement<C>>(Forward<T>(Element)); }), Forward<Args>(Args)...);
|
||||
}
|
||||
|
||||
else static_assert(sizeof(R) == -1, "The container type is not constructible from a range");
|
||||
}
|
||||
}
|
||||
|
||||
/** Constructs a non-view object from the elements of the range. */
|
||||
template <template <typename...> typename C, CInputRange R, typename... Ts>
|
||||
NODISCARD FORCEINLINE constexpr auto To(R&& Range, Ts&&... Args)
|
||||
{
|
||||
if constexpr (requires { C(DeclVal<R>(), DeclVal<Ts>()...); })
|
||||
{
|
||||
return Range::To<decltype(C(DeclVal<R>(), DeclVal<Ts>()...))>(Forward<R>(Range), Forward<Ts>(Args)...);
|
||||
}
|
||||
|
||||
else if constexpr (requires { C(DeclVal<TRangeIterator<R>>(), DeclVal<TRangeSentinel<R>>(), DeclVal<Args>()...); })
|
||||
{
|
||||
return Range::To<decltype(C(DeclVal<TRangeIterator<R>>(), DeclVal<TRangeSentinel<R>>(), DeclVal<Args>()...))>(Forward<R>(Range), Forward<Ts>(Args)...);
|
||||
}
|
||||
|
||||
else static_assert(sizeof(R) == -1, "The container type is not constructible from a range");
|
||||
}
|
||||
|
||||
/** Constructs a non-view object from the elements of the range. */
|
||||
template <typename C, typename... Ts> requires (!CView<C>)
|
||||
NODISCARD FORCEINLINE constexpr auto To(Ts&&... Args)
|
||||
{
|
||||
using FClosure = decltype([]<CInputRange R, typename... Us> requires (requires { Range::To<C>(DeclVal<R>(), DeclVal<Us>()...); }) (R&& Range, Us&&... Args)
|
||||
{
|
||||
return Range::To<C>(Forward<R>(Range), Forward<Us>(Args)...);
|
||||
});
|
||||
|
||||
return TAdaptorClosure<FClosure, TDecay<Ts>...>(Forward<Ts>(Args)...);
|
||||
}
|
||||
|
||||
/** Constructs a non-view object from the elements of the range. */
|
||||
template <template <typename...> typename C, typename... Ts>
|
||||
NODISCARD FORCEINLINE constexpr auto To(Ts&&... Args)
|
||||
{
|
||||
using FClosure = decltype([]<CInputRange R, typename... Us> requires (requires { Range::To<C>(DeclVal<R>(), DeclVal<Us>()...); }) (R&& Range, Us&&... Args)
|
||||
{
|
||||
return Range::To<C>(Forward<R>(Range), Forward<Us>(Args)...);
|
||||
});
|
||||
|
||||
return TAdaptorClosure<FClosure, TDecay<Ts>...>(Forward<Ts>(Args)...);
|
||||
}
|
||||
|
||||
NAMESPACE_END(Range)
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
@ -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<TRangeIterator<V>>;
|
||||
using FElementType = TIteratorElement<TRangeIterator<V>>;
|
||||
|
||||
FORCEINLINE constexpr FIteratorImpl() requires (CDefaultConstructible<TRangeIterator<V>>) { } // Use '{ }' instead of '= default;' to avoid MSVC bug.
|
||||
|
||||
@ -175,10 +176,12 @@ NODISCARD FORCEINLINE constexpr auto Filter(R&& Base, Pred&& Predicate)
|
||||
template <typename Pred>
|
||||
NODISCARD FORCEINLINE constexpr auto Filter(Pred&& Predicate)
|
||||
{
|
||||
return TAdaptorClosure([&Predicate]<CViewableRange R> requires (requires { Range::Filter(DeclVal<R>(), DeclVal<Pred>()); }) (R&& Base)
|
||||
using FClosure = decltype([]<CViewableRange R, typename T> requires (requires { Range::Filter(DeclVal<R>(), DeclVal<T>()); }) (R&& Base, T&& Predicate)
|
||||
{
|
||||
return Range::Filter(Forward<R>(Base), Forward<Pred>(Predicate));
|
||||
return Range::Filter(Forward<R>(Base), Forward<T>(Predicate));
|
||||
});
|
||||
|
||||
return TAdaptorClosure<FClosure, TDecay<Pred>>(Forward<Pred>(Predicate));
|
||||
}
|
||||
|
||||
NAMESPACE_END(Range)
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "Range/Utility.h"
|
||||
#include "Templates/Tuple.h"
|
||||
#include "Templates/Invoke.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
@ -23,50 +24,74 @@ template <CObject D> requires (CSameAs<D, TRemoveCV<D>>)
|
||||
class IAdaptorClosure { };
|
||||
|
||||
/** An adaptor closure helper that wraps a callable object. */
|
||||
template <CMoveConstructible F>
|
||||
class TAdaptorClosure : public IAdaptorClosure<TAdaptorClosure<F>>
|
||||
template <CDefaultConstructible F, CMoveConstructible... Ts> requires (CEmpty<F> && ... && CSameAs<TDecay<Ts>, Ts>)
|
||||
class TAdaptorClosure : public IAdaptorClosure<TAdaptorClosure<F, Ts...>>
|
||||
{
|
||||
public:
|
||||
|
||||
FORCEINLINE constexpr explicit TAdaptorClosure(F InClosure) : Closure(MoveTemp(InClosure)) { }
|
||||
template <typename... Us> requires (CConstructibleFrom<TTuple<Ts...>, Us...> && ... && CSameAs<TDecay<Us>, Ts>)
|
||||
FORCEINLINE constexpr explicit TAdaptorClosure(Us&&... InArgs) : Args(Forward<Us>(InArgs)...) { }
|
||||
|
||||
template <typename R> requires (CInvocable<F&, R>)
|
||||
template <typename R> requires (CInvocable<F, R, Ts&...>)
|
||||
NODISCARD FORCEINLINE constexpr auto operator()(R&& Range) &
|
||||
{
|
||||
return Invoke(Closure, Forward<R>(Range));
|
||||
return [this, &Range]<size_t... Indices>(TIndexSequence<Indices...>)
|
||||
{
|
||||
return Invoke(F(), Forward<R>(Range), Args.template GetValue<Indices>()...);
|
||||
}
|
||||
(TMakeIndexSequence<sizeof...(Ts)>());
|
||||
}
|
||||
|
||||
template <typename R> requires (CInvocable<const F&, R>)
|
||||
template <typename R> requires (CInvocable<F, R, const Ts&...>)
|
||||
NODISCARD FORCEINLINE constexpr auto operator()(R&& Range) const&
|
||||
{
|
||||
return Invoke(Closure, Forward<R>(Range));
|
||||
return [this, &Range]<size_t... Indices>(TIndexSequence<Indices...>)
|
||||
{
|
||||
return Invoke(F(), Forward<R>(Range), Args.template GetValue<Indices>()...);
|
||||
}
|
||||
(TMakeIndexSequence<sizeof...(Ts)>());
|
||||
}
|
||||
|
||||
template <typename R> requires (CInvocable<F&&, R>)
|
||||
template <typename R> requires (CInvocable<F, R, Ts&&...>)
|
||||
NODISCARD FORCEINLINE constexpr auto operator()(R&& Range) &&
|
||||
{
|
||||
return Invoke(MoveTemp(Closure), Forward<R>(Range));
|
||||
return [this, &Range]<size_t... Indices>(TIndexSequence<Indices...>)
|
||||
{
|
||||
return Invoke(F(), Forward<R>(Range), MoveTemp(Args).template GetValue<Indices>()...);
|
||||
}
|
||||
(TMakeIndexSequence<sizeof...(Ts)>());
|
||||
}
|
||||
|
||||
template <typename R> requires (CInvocable<const F&&, R>)
|
||||
template <typename R> requires (CInvocable<F, R, const Ts&&...>)
|
||||
NODISCARD FORCEINLINE constexpr auto operator()(R&& Range) const&&
|
||||
{
|
||||
return Invoke(MoveTemp(Closure), Forward<R>(Range));
|
||||
return [this, &Range]<size_t... Indices>(TIndexSequence<Indices...>)
|
||||
{
|
||||
return Invoke(F(), Forward<R>(Range), MoveTemp(Args).template GetValue<Indices>()...);
|
||||
}
|
||||
(TMakeIndexSequence<sizeof...(Ts)>());
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
NO_UNIQUE_ADDRESS F Closure;
|
||||
NO_UNIQUE_ADDRESS TTuple<Ts...> Args;
|
||||
|
||||
};
|
||||
|
||||
/** A pipe closure that wraps two adaptor closures. */
|
||||
template <CMoveConstructible T, CMoveConstructible U> requires (CDerivedFrom<T, IAdaptorClosure<T>> && CDerivedFrom<U, IAdaptorClosure<U>>)
|
||||
template <CMoveConstructible T, CMoveConstructible U>
|
||||
requires (CSameAs<TRemoveCVRef<T>, T> && CDerivedFrom<T, IAdaptorClosure<T>>
|
||||
&& CSameAs<TRemoveCVRef<U>, U> && CDerivedFrom<U, IAdaptorClosure<U>>)
|
||||
class TPipeClosure final : public IAdaptorClosure<TPipeClosure<T, U>>
|
||||
{
|
||||
public:
|
||||
|
||||
FORCEINLINE constexpr explicit TPipeClosure(T InLHS, U InRHS) : LHS(MoveTemp(InLHS)), RHS(MoveTemp(InRHS)) { }
|
||||
template <typename V, typename W>
|
||||
requires (CSameAs<TRemoveCVRef<V>, T> && CConstructibleFrom<T, V>
|
||||
&& CSameAs<TRemoveCVRef<W>, U> && CConstructibleFrom<U, W>)
|
||||
FORCEINLINE constexpr explicit TPipeClosure(V InLHS, W InRHS)
|
||||
: LHS(Forward<V>(InLHS)), RHS(Forward<W>(InRHS))
|
||||
{ }
|
||||
|
||||
template <typename R> requires (CInvocable<T&, R> && CInvocable<U&, TInvokeResult<T&, R>>)
|
||||
NODISCARD FORCEINLINE constexpr auto operator()(R&& Range) &
|
||||
@ -106,10 +131,12 @@ NODISCARD FORCEINLINE constexpr auto operator|(R&& Range, T&& Closure)
|
||||
}
|
||||
|
||||
/** Create a pipe closure that wraps two adaptor closures. */
|
||||
template <CMoveConstructible T, CMoveConstructible U> requires (CDerivedFrom<T, IAdaptorClosure<T>> && CDerivedFrom<U, IAdaptorClosure<U>>)
|
||||
NODISCARD FORCEINLINE constexpr auto operator|(T LHS, U RHS)
|
||||
template <CMoveConstructible T, CMoveConstructible U>
|
||||
requires (CDerivedFrom<TRemoveCVRef<T>, IAdaptorClosure<TRemoveCVRef<T>>>
|
||||
&& CDerivedFrom<TRemoveCVRef<U>, IAdaptorClosure<TRemoveCVRef<U>>>)
|
||||
NODISCARD FORCEINLINE constexpr auto operator|(T&& LHS, U&& RHS)
|
||||
{
|
||||
return TPipeClosure(MoveTemp(LHS), MoveTemp(RHS));
|
||||
return TPipeClosure<TRemoveCVRef<T>, TRemoveCVRef<U>>(Forward<T>(LHS), Forward<U>(RHS));
|
||||
}
|
||||
|
||||
NAMESPACE_END(Range)
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "CoreTypes.h"
|
||||
#include "Range/Utility.h"
|
||||
#include "Range/View.h"
|
||||
#include "Range/Conversion.h"
|
||||
#include "Range/Factory.h"
|
||||
#include "Range/Pipe.h"
|
||||
#include "Range/AllView.h"
|
||||
|
@ -222,10 +222,12 @@ NODISCARD FORCEINLINE constexpr auto Transform(R&& Base, F&& Func)
|
||||
template <typename F>
|
||||
NODISCARD FORCEINLINE constexpr auto Transform(F&& Func)
|
||||
{
|
||||
return TAdaptorClosure([&Func]<CViewableRange R> requires (requires { Range::Transform(DeclVal<R>(), DeclVal<F>()); }) (R&& Base)
|
||||
using FClosure = decltype([]<CViewableRange R, typename T> requires (requires { Range::Transform(DeclVal<R>(), DeclVal<T>()); }) (R&& Base, T&& Func)
|
||||
{
|
||||
return Range::Transform(Forward<R>(Base), Forward<F>(Func));
|
||||
return Range::Transform(Forward<R>(Base), Forward<T>(Func));
|
||||
});
|
||||
|
||||
return TAdaptorClosure<FClosure, TDecay<F>>(Forward<F>(Func));
|
||||
}
|
||||
|
||||
NAMESPACE_END(Range)
|
||||
|
@ -37,7 +37,7 @@ NODISCARD FORCEINLINE constexpr auto Begin(T&& Container)
|
||||
|
||||
/** Overloads the Begin algorithm for initializer_list. */
|
||||
template <typename T>
|
||||
NODISCARD FORCEINLINE constexpr auto Begin(initializer_list<T>& Container)
|
||||
NODISCARD FORCEINLINE constexpr const T* Begin(initializer_list<T>& Container)
|
||||
{
|
||||
return Container.begin();
|
||||
}
|
||||
@ -67,7 +67,7 @@ NODISCARD FORCEINLINE constexpr auto End(T&& Container)
|
||||
|
||||
/** Overloads the End algorithm for initializer_list. */
|
||||
template <typename T>
|
||||
NODISCARD FORCEINLINE constexpr auto End(initializer_list<T>& Container)
|
||||
NODISCARD FORCEINLINE constexpr const T* End(initializer_list<T>& Container)
|
||||
{
|
||||
return Container.end();
|
||||
}
|
||||
@ -180,6 +180,13 @@ NODISCARD FORCEINLINE constexpr size_t Num(T&& Container)
|
||||
return Range::End(Forward<T>(Container)) - Range::Begin(Forward<T>(Container));
|
||||
}
|
||||
|
||||
/** Overloads the Num algorithm for initializer_list. */
|
||||
template <typename T>
|
||||
NODISCARD FORCEINLINE constexpr size_t Num(initializer_list<T>& Container)
|
||||
{
|
||||
return Container.size();
|
||||
}
|
||||
|
||||
/** @return true if the container is empty, false otherwise. */
|
||||
template <typename T> requires (requires(T&& Container) { { Container.IsEmpty() } -> CBooleanTestable; })
|
||||
NODISCARD FORCEINLINE constexpr bool IsEmpty(T&& Container)
|
||||
|
@ -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<TRangeView<I, S>>
|
||||
{
|
||||
public:
|
||||
|
||||
using FElementType = TIteratorElementType<I>;
|
||||
using FElementType = TIteratorElement<I>;
|
||||
|
||||
FORCEINLINE constexpr TRangeView() requires (CDefaultConstructible<I>) = default;
|
||||
|
||||
|
@ -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<T> 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;
|
||||
|
||||
|
@ -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<FElementType> View) : TString(View.Begin(), View.End()) { }
|
||||
|
||||
/** Constructs the string with the contents of the range ['First', 'Last'). */
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReferenceType<I>>)
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReference<I>>)
|
||||
FORCEINLINE TString(I First, S Last) : FSuper(MoveTemp(First), MoveTemp(Last)) { }
|
||||
|
||||
/** Constructs the string with the contents of the range. */
|
||||
template <CInputRange R> requires (!CSameAs<TRemoveCVRef<R>, TString>
|
||||
&& !CSameAs<TRemoveCVRef<R>, TStringView<FElementType>> && CConstructibleFrom<FElementType, TRangeReference<R>>)
|
||||
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<FElementType> IL) : TString(Iteration::Begin(IL), Iteration::End(IL)) { }
|
||||
FORCEINLINE TString(initializer_list<FElementType> 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 <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReferenceType<I>>)
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReference<I>>)
|
||||
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 <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReferenceType<I>>)
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReference<I>>)
|
||||
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<FElementType> 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<FElementType>(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<FElementType>(InPtr)); }
|
||||
|
||||
FORCEINLINE TString& Append(nullptr_t) = delete;
|
||||
|
||||
/** Appends the contents of the range ['First', 'Last') to the end of the string. */
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReferenceType<I>>)
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReference<I>>)
|
||||
TString& Append(I First, S Last)
|
||||
{
|
||||
if constexpr (CForwardIterator<I>)
|
||||
{
|
||||
if constexpr (CSizedSentinelFor<S, I>) { 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<S, I>)
|
||||
{
|
||||
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 <CInputRange R> requires (CConstructibleFrom<FElementType, TRangeReference<R>>)
|
||||
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<FElementType> IL) { return Append(Iteration::Begin(IL), Iteration::End(IL)); }
|
||||
FORCEINLINE TString& Append(initializer_list<FElementType> 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<FElementType> 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 <CInputRange R> requires (CConstructibleFrom<FElementType, TRangeReference<R>>)
|
||||
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<FElementType> 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<FElementType> 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<FElementType> 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<FElementType>(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<FElementType>(InPtr));
|
||||
}
|
||||
|
||||
/** Replace the substring [Index, Index + CountToReplace) with the contents of the range ['First', 'Last'). */
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReferenceType<I>>)
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReference<I>>)
|
||||
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 <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReferenceType<I>>)
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReference<I>>)
|
||||
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<I>)
|
||||
{
|
||||
if constexpr (CSizedSentinelFor<S, I>) { 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<S, I>)
|
||||
{
|
||||
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 <CInputRange R> requires (CConstructibleFrom<FElementType, TRangeReference<R>>)
|
||||
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<R>(Range));
|
||||
}
|
||||
|
||||
/** Replace the substring ['First', 'Last') with the contents of the range. */
|
||||
template <CInputRange R> requires (CConstructibleFrom<FElementType, TRangeReference<R>>)
|
||||
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<FElementType> 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<FElementType>(*this).Substr(Offset, Count);
|
||||
return TString(TStringView<FElementType>(*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<T>;
|
||||
template<typename T>
|
||||
TString(TStringView<T>) -> TString<T>;
|
||||
|
||||
template<CForwardIterator I, typename S>
|
||||
TString(I, S) -> TString<TIteratorElementType<I>>;
|
||||
template<typename I, typename S>
|
||||
TString(I, S) -> TString<TIteratorElement<I>>;
|
||||
|
||||
template<typename R>
|
||||
TString(R) -> TString<TRangeElement<R>>;
|
||||
|
||||
template <typename T>
|
||||
TString(initializer_list<T>) -> TString<T>;
|
||||
|
@ -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 <cstring>
|
||||
#include <cwchar>
|
||||
@ -86,7 +85,7 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
using FElementType = T;
|
||||
using FElementType = TRemoveCV<T>;
|
||||
|
||||
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 <CContiguousIterator I> requires (CConvertibleTo<TIteratorElementType<I>(*)[], const FElementType(*)[]>)
|
||||
template <CContiguousIterator I> requires (CConvertibleTo<TIteratorReference<I>, T> && CSameAs<TRemoveCVRef<TIteratorReference<I>>, TRemoveCVRef<T>>)
|
||||
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 <CContiguousIterator I, CSizedSentinelFor<I> S> requires (CConvertibleTo<TIteratorElementType<I>(*)[], const FElementType(*)[]>)
|
||||
template <CContiguousIterator I, CSizedSentinelFor<I> S> requires (CConvertibleTo<TIteratorReference<I>, T> && CSameAs<TRemoveCVRef<TIteratorReference<I>>, TRemoveCVRef<T>>)
|
||||
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 <CPointer I>
|
||||
TStringView(I) -> TStringView<TIteratorElement<I>>;
|
||||
|
||||
template <typename I, typename S>
|
||||
TStringView(I, S) -> TStringView<TIteratorElementType<I>>;
|
||||
TStringView(I, S) -> TStringView<TIteratorElement<I>>;
|
||||
|
||||
template<typename T, typename Allocator>
|
||||
TStringView(TString<T, Allocator>) -> TStringView<T>;
|
||||
|
@ -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 <typename T, T... Ints>
|
||||
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
|
||||
|
@ -56,8 +56,8 @@ public:
|
||||
FORCEINLINE constexpr TOptional(FInvalid) : TOptional() { }
|
||||
|
||||
/** Constructs an object with initial content an object, direct-initialized from Forward<U>(InValue). */
|
||||
template <typename U = T> requires (CConstructibleFrom<T, U&&>)
|
||||
&& (!CSameAs<TRemoveCVRef<U>, FInPlace>) && (!CSameAs<TOptional, TRemoveCVRef<U>>)
|
||||
template <typename U = T> requires (CConstructibleFrom<T, U&&>
|
||||
&& !CSameAs<TRemoveCVRef<U>, FInPlace> && !CSameAs<TOptional, TRemoveCVRef<U>>)
|
||||
FORCEINLINE constexpr explicit (!CConvertibleTo<U&&, T>) TOptional(U&& InValue)
|
||||
: TOptional(InPlace, Forward<U>(InValue))
|
||||
{ }
|
||||
|
@ -94,6 +94,20 @@ FORCEINLINE constexpr size_t GetTypeHash(const T& A)
|
||||
return GetTypeHash(A.hash_code());
|
||||
}
|
||||
|
||||
/** Overloads the GetTypeHash algorithm for arrays. */
|
||||
template <typename T, size_t N> requires (requires(const T& A) { { GetTypeHash(A) } -> CSameAs<size_t>; })
|
||||
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 <typename T>
|
||||
concept CHashable = requires(const T& A) { { GetTypeHash(A) } -> CSameAs<size_t>; };
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "TypeTraits/CompositeType.h"
|
||||
#include "TypeTraits/Miscellaneous.h"
|
||||
#include "TypeTraits/SupportedOperations.h"
|
||||
|
||||
@ -73,6 +72,16 @@ FORCEINLINE constexpr void Swap(T& A, T& B)
|
||||
B = MoveTemp(Temp);
|
||||
}
|
||||
|
||||
/** Overloads the Swap algorithm for arrays. */
|
||||
template <typename T, size_t N> requires (requires(T& A, T& B) { Swap(A, B); })
|
||||
FORCEINLINE constexpr void Swap(T(&A)[N], T(&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 <typename T, typename U = T> requires (CMoveConstructible<T> && CAssignableFrom<T&, U>)
|
||||
FORCEINLINE constexpr T Exchange(T& A, U&& B)
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user