refactor(*): replace the old with the new iterator and range library
This commit is contained in:
parent
0a37460f24
commit
6a37e91639
@ -1,16 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
|
#include "Range/Range.h"
|
||||||
#include "Memory/Allocator.h"
|
#include "Memory/Allocator.h"
|
||||||
|
#include "Iterator/Iterator.h"
|
||||||
#include "Templates/Utility.h"
|
#include "Templates/Utility.h"
|
||||||
#include "Templates/TypeHash.h"
|
#include "Templates/TypeHash.h"
|
||||||
#include "TypeTraits/TypeTraits.h"
|
#include "TypeTraits/TypeTraits.h"
|
||||||
#include "Miscellaneous/Compare.h"
|
#include "Miscellaneous/Compare.h"
|
||||||
#include "Memory/MemoryOperator.h"
|
#include "Memory/MemoryOperator.h"
|
||||||
#include "Miscellaneous/Iterator.h"
|
|
||||||
#include "Miscellaneous/Container.h"
|
|
||||||
#include "Miscellaneous/AssertionMacros.h"
|
#include "Miscellaneous/AssertionMacros.h"
|
||||||
#include "Miscellaneous/ConstantIterator.h"
|
|
||||||
|
|
||||||
NAMESPACE_REDCRAFT_BEGIN
|
NAMESPACE_REDCRAFT_BEGIN
|
||||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||||
@ -57,18 +56,24 @@ public:
|
|||||||
|
|
||||||
/** Constructs the container with 'Count' copies of elements with 'InValue'. */
|
/** Constructs the container with 'Count' copies of elements with 'InValue'. */
|
||||||
TArray(size_t Count, const FElementType& InValue) requires (CCopyConstructible<FElementType>)
|
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'). */
|
/** 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)
|
TArray(I First, S Last)
|
||||||
{
|
{
|
||||||
if constexpr (CForwardIterator<I>)
|
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.ArrayNum = Count;
|
||||||
Impl.ArrayMax = Impl->CalculateSlackReserve(Num());
|
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'. */
|
/** Copy constructor. Constructs the container with the copy of the contents of 'InValue'. */
|
||||||
TArray(const TArray& InValue) requires (CCopyConstructible<FElementType>)
|
TArray(const TArray& InValue) requires (CCopyConstructible<FElementType>)
|
||||||
{
|
{
|
||||||
@ -129,7 +138,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Constructs the container with the contents of the initializer list. */
|
/** 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. */
|
/** Destructs the array. The destructors of the elements are called and the used storage is deallocated. */
|
||||||
~TArray()
|
~TArray()
|
||||||
@ -243,38 +252,38 @@ public:
|
|||||||
/** Replaces the contents with those identified by initializer list. */
|
/** Replaces the contents with those identified by initializer list. */
|
||||||
TArray& operator=(initializer_list<FElementType> IL) requires (CCopyable<FElementType>)
|
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->CalculateSlackGrow (Range::Num(IL), Max()) : NumToAllocate;
|
||||||
NumToAllocate = NumToAllocate < Max() ? Impl->CalculateSlackShrink(GetNum(IL), Max()) : NumToAllocate;
|
NumToAllocate = NumToAllocate < Max() ? Impl->CalculateSlackShrink(Range::Num(IL), Max()) : NumToAllocate;
|
||||||
|
|
||||||
if (NumToAllocate != Max())
|
if (NumToAllocate != Max())
|
||||||
{
|
{
|
||||||
Memory::Destruct(Impl.Pointer, Num());
|
Memory::Destruct(Impl.Pointer, Num());
|
||||||
Impl->Deallocate(Impl.Pointer);
|
Impl->Deallocate(Impl.Pointer);
|
||||||
|
|
||||||
Impl.ArrayNum = GetNum(IL);
|
Impl.ArrayNum = Range::Num(IL);
|
||||||
Impl.ArrayMax = NumToAllocate;
|
Impl.ArrayMax = NumToAllocate;
|
||||||
Impl.Pointer = Impl->Allocate(Max());
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetNum(IL) <= Num())
|
if (Range::Num(IL) <= Num())
|
||||||
{
|
{
|
||||||
Memory::CopyAssign(Impl.Pointer, NAMESPACE_REDCRAFT::GetData(IL), GetNum(IL));
|
Memory::CopyAssign(Impl.Pointer, Range::GetData(IL), Range::Num(IL));
|
||||||
Memory::Destruct(Impl.Pointer + GetNum(IL), Num() - GetNum(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::CopyAssign(Impl.Pointer, Range::GetData(IL), Num());
|
||||||
Memory::CopyConstruct<FElementType>(Impl.Pointer + Num(), NAMESPACE_REDCRAFT::GetData(IL) + Num(), GetNum(IL) - Num());
|
Memory::CopyConstruct<FElementType>(Impl.Pointer + Num(), Range::GetData(IL) + Num(), Range::Num(IL) - Num());
|
||||||
}
|
}
|
||||||
else check_no_entry();
|
else check_no_entry();
|
||||||
|
|
||||||
Impl.ArrayNum = GetNum(IL);
|
Impl.ArrayNum = Range::Num(IL);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -406,22 +415,29 @@ public:
|
|||||||
{
|
{
|
||||||
checkf(IsValidIterator(Iter), TEXT("Read access violation. Please check IsValidIterator()."));
|
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'. */
|
/** 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>>
|
||||||
&& CAssignableFrom<FElementType&, TIteratorReferenceType<I>> && CMovable<FElementType>)
|
&& CAssignableFrom<FElementType&, TIteratorReference<I>> && CMovable<FElementType>)
|
||||||
FIterator Insert(FConstIterator Iter, I First, S Last)
|
FIterator Insert(FConstIterator Iter, I First, S Last)
|
||||||
{
|
{
|
||||||
checkf(IsValidIterator(Iter), TEXT("Read access violation. Please check IsValidIterator()."));
|
checkf(IsValidIterator(Iter), TEXT("Read access violation. Please check IsValidIterator()."));
|
||||||
|
|
||||||
if constexpr (CForwardIterator<I>)
|
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 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);
|
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. */
|
/** Inserts elements from initializer list before 'Iter' in the container. */
|
||||||
FORCEINLINE FIterator Insert(FConstIterator Iter, initializer_list<FElementType> IL) requires (CCopyable<FElementType>)
|
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'. */
|
/** Inserts a new element into the container directly before 'Iter'. */
|
||||||
@ -1058,7 +1082,10 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename I, typename S>
|
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>
|
template <typename T>
|
||||||
TArray(initializer_list<T>) -> TArray<T>;
|
TArray(initializer_list<T>) -> TArray<T>;
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
|
#include "Range/Range.h"
|
||||||
#include "Memory/Address.h"
|
#include "Memory/Address.h"
|
||||||
#include "Memory/Allocator.h"
|
#include "Memory/Allocator.h"
|
||||||
#include "Containers/Array.h"
|
#include "Containers/Array.h"
|
||||||
|
#include "Iterator/Iterator.h"
|
||||||
#include "Templates/Utility.h"
|
#include "Templates/Utility.h"
|
||||||
#include "Templates/TypeHash.h"
|
#include "Templates/TypeHash.h"
|
||||||
#include "Containers/StaticArray.h"
|
#include "Containers/StaticArray.h"
|
||||||
#include "TypeTraits/TypeTraits.h"
|
#include "TypeTraits/TypeTraits.h"
|
||||||
#include "Miscellaneous/Compare.h"
|
#include "Miscellaneous/Compare.h"
|
||||||
#include "Miscellaneous/Iterator.h"
|
|
||||||
#include "Miscellaneous/Container.h"
|
|
||||||
#include "Miscellaneous/AssertionMacros.h"
|
#include "Miscellaneous/AssertionMacros.h"
|
||||||
|
|
||||||
NAMESPACE_REDCRAFT_BEGIN
|
NAMESPACE_REDCRAFT_BEGIN
|
||||||
@ -29,7 +29,7 @@ class TArrayView
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using FElementType = T;
|
using FElementType = TRemoveCV<T>;
|
||||||
|
|
||||||
using FReference = T&;
|
using FReference = T&;
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Constructs an array view that is a view over the range ['InFirst', 'InFirst' + 'Count'). */
|
/** 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)
|
FORCEINLINE constexpr explicit (Extent != DynamicExtent) TArrayView(I InFirst, size_t InCount)
|
||||||
{
|
{
|
||||||
checkf(Extent == DynamicExtent || Extent == InCount, TEXT("Illegal range count. Please check 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'). */
|
/** 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)
|
FORCEINLINE constexpr explicit (Extent != DynamicExtent) TArrayView(I InFirst, S InLast)
|
||||||
{
|
{
|
||||||
checkf(Extent == DynamicExtent || Extent == InLast - InFirst, TEXT("Illegal range iterator. Please check InLast - InFirst."));
|
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. */
|
/** 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)
|
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."));
|
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. */
|
/** 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."));
|
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. */
|
/** 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)
|
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."));
|
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. */
|
/** 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."));
|
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'. */
|
/** 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)
|
if constexpr (Count != DynamicExtent)
|
||||||
{
|
{
|
||||||
return TArrayView<FElementType, SubviewExtent>(Begin() + Offset, Count);
|
return TArrayView<T, SubviewExtent>(Begin() + Offset, Count);
|
||||||
}
|
}
|
||||||
else
|
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)
|
if (Count != DynamicExtent)
|
||||||
{
|
{
|
||||||
return TArrayView<FElementType, DynamicExtent>(Begin() + Offset, Count);
|
return TArrayView<T, DynamicExtent>(Begin() + Offset, Count);
|
||||||
}
|
}
|
||||||
else
|
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. */
|
/** @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. */
|
/** @return The iterator to the first or end element. */
|
||||||
NODISCARD FORCEINLINE constexpr FIterator Begin() const { return FIterator(this, Impl.Pointer); }
|
NODISCARD FORCEINLINE constexpr FIterator Begin() const { return FIterator(this, Impl.Pointer); }
|
||||||
@ -291,7 +291,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct FImplWithoutNum { FElementType* Pointer; };
|
struct FImplWithoutNum { T* Pointer; };
|
||||||
|
|
||||||
struct FImplWithNum : FImplWithoutNum { size_t ArrayNum; };
|
struct FImplWithNum : FImplWithoutNum { size_t ArrayNum; };
|
||||||
|
|
||||||
@ -367,7 +367,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename I, typename S>
|
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>
|
template <typename T, size_t N>
|
||||||
TArrayView(T(&)[N]) -> TArrayView<T, N>;
|
TArrayView(T(&)[N]) -> TArrayView<T, N>;
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
|
#include "Range/Range.h"
|
||||||
#include "Memory/Memory.h"
|
#include "Memory/Memory.h"
|
||||||
#include "Memory/Allocator.h"
|
#include "Memory/Allocator.h"
|
||||||
|
#include "Iterator/Iterator.h"
|
||||||
#include "Templates/Utility.h"
|
#include "Templates/Utility.h"
|
||||||
#include "Templates/TypeHash.h"
|
#include "Templates/TypeHash.h"
|
||||||
#include "Templates/Noncopyable.h"
|
#include "Templates/Noncopyable.h"
|
||||||
#include "TypeTraits/TypeTraits.h"
|
#include "TypeTraits/TypeTraits.h"
|
||||||
#include "Miscellaneous/Compare.h"
|
#include "Miscellaneous/Compare.h"
|
||||||
#include "Memory/MemoryOperator.h"
|
#include "Memory/MemoryOperator.h"
|
||||||
#include "Miscellaneous/Iterator.h"
|
|
||||||
#include "Miscellaneous/Container.h"
|
|
||||||
#include "Miscellaneous/AssertionMacros.h"
|
#include "Miscellaneous/AssertionMacros.h"
|
||||||
|
|
||||||
NAMESPACE_REDCRAFT_BEGIN
|
NAMESPACE_REDCRAFT_BEGIN
|
||||||
@ -101,16 +101,22 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Constructs the bitset with the bits of the range ['First', 'Last'). */
|
/** 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)
|
TBitset(I First, S Last)
|
||||||
{
|
{
|
||||||
if constexpr (CForwardIterator<I>)
|
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++;
|
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'. */
|
/** Copy constructor. Constructs the bitset with the copy of the bits of 'InValue'. */
|
||||||
FORCEINLINE TBitset(const TBitset& InValue)
|
FORCEINLINE TBitset(const TBitset& InValue)
|
||||||
{
|
{
|
||||||
@ -160,7 +170,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Constructs the bitset with the bits of the initializer list. */
|
/** 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. */
|
/** Destructs the bitset. The storage is deallocated. */
|
||||||
~TBitset()
|
~TBitset()
|
||||||
@ -228,9 +238,9 @@ public:
|
|||||||
/** Replaces the bits with those identified by initializer list. */
|
/** Replaces the bits with those identified by initializer list. */
|
||||||
TBitset& operator=(initializer_list<bool> IL)
|
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;
|
size_t NumToAllocate = BlocksCount;
|
||||||
|
|
||||||
@ -241,7 +251,7 @@ public:
|
|||||||
{
|
{
|
||||||
Impl->Deallocate(Impl.Pointer);
|
Impl->Deallocate(Impl.Pointer);
|
||||||
|
|
||||||
Impl.BitsetNum = GetNum(IL);
|
Impl.BitsetNum = Range::Num(IL);
|
||||||
Impl.BlocksMax = NumToAllocate;
|
Impl.BlocksMax = NumToAllocate;
|
||||||
Impl.Pointer = Impl->Allocate(MaxBlocks());
|
Impl.Pointer = Impl->Allocate(MaxBlocks());
|
||||||
|
|
||||||
@ -250,7 +260,7 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Impl.BitsetNum = GetNum(IL);
|
Impl.BitsetNum = Range::Num(IL);
|
||||||
|
|
||||||
for (FReference Ref : *this) Ref = *First++;
|
for (FReference Ref : *this) Ref = *First++;
|
||||||
|
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
|
#include "Range/Range.h"
|
||||||
#include "Memory/Allocator.h"
|
#include "Memory/Allocator.h"
|
||||||
|
#include "Iterator/Iterator.h"
|
||||||
#include "Templates/Utility.h"
|
#include "Templates/Utility.h"
|
||||||
#include "Templates/TypeHash.h"
|
#include "Templates/TypeHash.h"
|
||||||
#include "TypeTraits/TypeTraits.h"
|
#include "TypeTraits/TypeTraits.h"
|
||||||
#include "Miscellaneous/Compare.h"
|
#include "Miscellaneous/Compare.h"
|
||||||
#include "Memory/MemoryOperator.h"
|
#include "Memory/MemoryOperator.h"
|
||||||
#include "Miscellaneous/Iterator.h"
|
|
||||||
#include "Miscellaneous/Container.h"
|
|
||||||
#include "Miscellaneous/AssertionMacros.h"
|
#include "Miscellaneous/AssertionMacros.h"
|
||||||
#include "Miscellaneous/ConstantIterator.h"
|
|
||||||
|
|
||||||
NAMESPACE_REDCRAFT_BEGIN
|
NAMESPACE_REDCRAFT_BEGIN
|
||||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||||
@ -76,11 +75,11 @@ public:
|
|||||||
|
|
||||||
/** Constructs the container with 'Count' copies of elements with 'InValue'. */
|
/** Constructs the container with 'Count' copies of elements with 'InValue'. */
|
||||||
TList(size_t Count, const FElementType& InValue) requires (CCopyable<FElementType>)
|
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'). */
|
/** 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()
|
TList(I First, S Last) : TList()
|
||||||
{
|
{
|
||||||
FNode* EndNode = Impl.HeadNode->PrevNode;
|
FNode* EndNode = Impl.HeadNode->PrevNode;
|
||||||
@ -101,6 +100,10 @@ public:
|
|||||||
Impl.HeadNode->PrevNode = EndNode;
|
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'. */
|
/** 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()) { }
|
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); }
|
FORCEINLINE TList(TList&& InValue) : TList() { Swap(*this, InValue); }
|
||||||
|
|
||||||
/** Constructs the container with the contents of the initializer list. */
|
/** 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. */
|
/** Destructs the list. The destructors of the elements are called and the used storage is deallocated. */
|
||||||
~TList()
|
~TList()
|
||||||
@ -168,10 +171,10 @@ public:
|
|||||||
/** Replaces the contents with those identified by initializer list. */
|
/** Replaces the contents with those identified by initializer list. */
|
||||||
TList& operator=(initializer_list<FElementType> IL) requires (CCopyable<FElementType>)
|
TList& operator=(initializer_list<FElementType> IL) requires (CCopyable<FElementType>)
|
||||||
{
|
{
|
||||||
FIterator ThisIter = Begin();
|
FIterator ThisIter = Begin();
|
||||||
const FElementType* OtherIter = Iteration::Begin(IL);
|
const FElementType* OtherIter = Range::Begin(IL);
|
||||||
|
|
||||||
while (ThisIter != End() && OtherIter != Iteration::End(IL))
|
while (ThisIter != End() && OtherIter != Range::End(IL))
|
||||||
{
|
{
|
||||||
*ThisIter = *OtherIter;
|
*ThisIter = *OtherIter;
|
||||||
|
|
||||||
@ -181,18 +184,18 @@ public:
|
|||||||
|
|
||||||
if (ThisIter == End())
|
if (ThisIter == End())
|
||||||
{
|
{
|
||||||
while (OtherIter != Iteration::End(IL))
|
while (OtherIter != Range::End(IL))
|
||||||
{
|
{
|
||||||
EmplaceBack(*OtherIter);
|
EmplaceBack(*OtherIter);
|
||||||
++OtherIter;
|
++OtherIter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (OtherIter == Iteration::End(IL))
|
else if (OtherIter == Range::End(IL))
|
||||||
{
|
{
|
||||||
Erase(ThisIter, End());
|
Erase(ThisIter, End());
|
||||||
}
|
}
|
||||||
|
|
||||||
Impl.ListNum = GetNum(IL);
|
Impl.ListNum = Range::Num(IL);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -244,11 +247,11 @@ public:
|
|||||||
/** Inserts 'Count' copies of the 'InValue' before 'Iter' in the container. */
|
/** Inserts 'Count' copies of the 'InValue' before 'Iter' in the container. */
|
||||||
FIterator Insert(FConstIterator Iter, size_t Count, const FElementType& InValue) requires (CCopyConstructible<FElementType>)
|
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'. */
|
/** 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)
|
FIterator Insert(FConstIterator Iter, I First, S Last)
|
||||||
{
|
{
|
||||||
if (First == Last) return FIterator(Iter.Pointer);
|
if (First == Last) return FIterator(Iter.Pointer);
|
||||||
@ -282,8 +285,12 @@ public:
|
|||||||
return FIterator(FirstNode);
|
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. */
|
/** 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'. */
|
/** Inserts a new element into the container directly before 'Iter'. */
|
||||||
template <typename... Ts> requires (CConstructibleFrom<FElementType, Ts...>)
|
template <typename... Ts> requires (CConstructibleFrom<FElementType, Ts...>)
|
||||||
@ -381,7 +388,7 @@ public:
|
|||||||
{
|
{
|
||||||
FIterator First = End();
|
FIterator First = End();
|
||||||
|
|
||||||
Iteration::Advance(First, Count - Impl.ListNum);
|
for (size_t Index = 0; Index != Impl.ListNum - Count; ++Index) --First;
|
||||||
|
|
||||||
Erase(First, End());
|
Erase(First, End());
|
||||||
|
|
||||||
@ -417,7 +424,7 @@ public:
|
|||||||
{
|
{
|
||||||
FIterator First = End();
|
FIterator First = End();
|
||||||
|
|
||||||
Iteration::Advance(First, Count - Impl.ListNum);
|
for (size_t Index = 0; Index != Impl.ListNum - Count; ++Index) --First;
|
||||||
|
|
||||||
Erase(First, End());
|
Erase(First, End());
|
||||||
|
|
||||||
@ -598,7 +605,10 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename I, typename S>
|
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>
|
template <typename T>
|
||||||
TList(initializer_list<T>) -> TList<T>;
|
TList(initializer_list<T>) -> TList<T>;
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
|
#include "Range/Range.h"
|
||||||
#include "Templates/Meta.h"
|
#include "Templates/Meta.h"
|
||||||
|
#include "Iterator/Iterator.h"
|
||||||
#include "Templates/Utility.h"
|
#include "Templates/Utility.h"
|
||||||
#include "Templates/TypeHash.h"
|
#include "Templates/TypeHash.h"
|
||||||
#include "TypeTraits/TypeTraits.h"
|
#include "TypeTraits/TypeTraits.h"
|
||||||
#include "Miscellaneous/Compare.h"
|
#include "Miscellaneous/Compare.h"
|
||||||
#include "Miscellaneous/Iterator.h"
|
|
||||||
#include "Miscellaneous/Container.h"
|
|
||||||
#include "Miscellaneous/AssertionMacros.h"
|
#include "Miscellaneous/AssertionMacros.h"
|
||||||
|
|
||||||
NAMESPACE_REDCRAFT_BEGIN
|
NAMESPACE_REDCRAFT_BEGIN
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
|
#include "Range/Range.h"
|
||||||
|
#include "Iterator/Iterator.h"
|
||||||
#include "Templates/Utility.h"
|
#include "Templates/Utility.h"
|
||||||
#include "Templates/TypeHash.h"
|
#include "Templates/TypeHash.h"
|
||||||
#include "Templates/Noncopyable.h"
|
#include "Templates/Noncopyable.h"
|
||||||
#include "TypeTraits/TypeTraits.h"
|
#include "TypeTraits/TypeTraits.h"
|
||||||
#include "Miscellaneous/Compare.h"
|
#include "Miscellaneous/Compare.h"
|
||||||
#include "Memory/MemoryOperator.h"
|
#include "Memory/MemoryOperator.h"
|
||||||
#include "Miscellaneous/Iterator.h"
|
|
||||||
#include "Miscellaneous/Container.h"
|
|
||||||
#include "Miscellaneous/AssertionMacros.h"
|
#include "Miscellaneous/AssertionMacros.h"
|
||||||
|
|
||||||
NAMESPACE_REDCRAFT_BEGIN
|
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
|
|
@ -12,6 +12,20 @@ NAMESPACE_REDCRAFT_BEGIN
|
|||||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||||
NAMESPACE_MODULE_BEGIN(Utility)
|
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. */
|
/** A concept specifies a container that can reserve size. */
|
||||||
template <typename C>
|
template <typename C>
|
||||||
concept CReservableContainer = CSizedRange<C>
|
concept CReservableContainer = CSizedRange<C>
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "Range/AllView.h"
|
#include "Range/AllView.h"
|
||||||
#include "Memory/Address.h"
|
#include "Memory/Address.h"
|
||||||
#include "Templates/Invoke.h"
|
#include "Templates/Invoke.h"
|
||||||
|
#include "Iterator/Iterator.h"
|
||||||
#include "Templates/Utility.h"
|
#include "Templates/Utility.h"
|
||||||
#include "TypeTraits/TypeTraits.h"
|
#include "TypeTraits/TypeTraits.h"
|
||||||
|
|
||||||
@ -79,7 +80,7 @@ private:
|
|||||||
|
|
||||||
public:
|
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.
|
FORCEINLINE constexpr FIteratorImpl() requires (CDefaultConstructible<TRangeIterator<V>>) { } // Use '{ }' instead of '= default;' to avoid MSVC bug.
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ NODISCARD FORCEINLINE constexpr auto Begin(T&& Container)
|
|||||||
|
|
||||||
/** Overloads the Begin algorithm for initializer_list. */
|
/** Overloads the Begin algorithm for initializer_list. */
|
||||||
template <typename T>
|
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();
|
return Container.begin();
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ NODISCARD FORCEINLINE constexpr auto End(T&& Container)
|
|||||||
|
|
||||||
/** Overloads the End algorithm for initializer_list. */
|
/** Overloads the End algorithm for initializer_list. */
|
||||||
template <typename T>
|
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();
|
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));
|
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. */
|
/** @return true if the container is empty, false otherwise. */
|
||||||
template <typename T> requires (requires(T&& Container) { { Container.IsEmpty() } -> CBooleanTestable; })
|
template <typename T> requires (requires(T&& Container) { { Container.IsEmpty() } -> CBooleanTestable; })
|
||||||
NODISCARD FORCEINLINE constexpr bool IsEmpty(T&& Container)
|
NODISCARD FORCEINLINE constexpr bool IsEmpty(T&& Container)
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
#include "Range/Utility.h"
|
#include "Range/Utility.h"
|
||||||
|
#include "Iterator/Iterator.h"
|
||||||
#include "Templates/Utility.h"
|
#include "Templates/Utility.h"
|
||||||
#include "TypeTraits/TypeTraits.h"
|
#include "TypeTraits/TypeTraits.h"
|
||||||
|
|
||||||
@ -100,7 +101,7 @@ class TRangeView : public IBasicViewInterface<TRangeView<I, S>>
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using FElementType = TIteratorElementType<I>;
|
using FElementType = TIteratorElement<I>;
|
||||||
|
|
||||||
FORCEINLINE constexpr TRangeView() requires (CDefaultConstructible<I>) = default;
|
FORCEINLINE constexpr TRangeView() requires (CDefaultConstructible<I>) = default;
|
||||||
|
|
||||||
|
@ -900,7 +900,7 @@ struct TStringObjectFormatter
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Format the container value by format string.
|
// 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();
|
auto FillAndAlign = ParseFillAndAlign();
|
||||||
|
|
||||||
@ -951,7 +951,7 @@ struct TStringObjectFormatter
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Iteration::Begin(Object) == Iteration::End(Object))
|
if (Range::Begin(Object) == Range::End(Object))
|
||||||
{
|
{
|
||||||
Result += Begin;
|
Result += Begin;
|
||||||
Result += End;
|
Result += End;
|
||||||
@ -966,7 +966,7 @@ struct TStringObjectFormatter
|
|||||||
struct { TStringView<T> Fmt; } ElementParam = { Subfmt };
|
struct { TStringView<T> Fmt; } ElementParam = { Subfmt };
|
||||||
|
|
||||||
// It is assumed that if the first element is successfully formatted, all elements will succeed.
|
// 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)
|
if (!bIsSuccessful)
|
||||||
{
|
{
|
||||||
@ -977,9 +977,9 @@ struct TStringObjectFormatter
|
|||||||
Result += Begin;
|
Result += Begin;
|
||||||
Result += Buffer;
|
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;
|
Result += Separator;
|
||||||
|
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
|
#include "Range/Range.h"
|
||||||
#include "String/Char.h"
|
#include "String/Char.h"
|
||||||
#include "Containers/Array.h"
|
#include "Containers/Array.h"
|
||||||
#include "String/StringView.h"
|
#include "String/StringView.h"
|
||||||
|
#include "Iterator/Iterator.h"
|
||||||
#include "Templates/Utility.h"
|
#include "Templates/Utility.h"
|
||||||
#include "Templates/Optional.h"
|
#include "Templates/Optional.h"
|
||||||
#include "TypeTraits/TypeTraits.h"
|
#include "TypeTraits/TypeTraits.h"
|
||||||
#include "Templates/Noncopyable.h"
|
#include "Templates/Noncopyable.h"
|
||||||
#include "Miscellaneous/Iterator.h"
|
|
||||||
#include "Miscellaneous/Container.h"
|
|
||||||
#include "Miscellaneous/AssertionMacros.h"
|
#include "Miscellaneous/AssertionMacros.h"
|
||||||
|
|
||||||
NAMESPACE_REDCRAFT_BEGIN
|
NAMESPACE_REDCRAFT_BEGIN
|
||||||
@ -80,9 +80,14 @@ public:
|
|||||||
FORCEINLINE TString(TStringView<FElementType> View) : TString(View.Begin(), View.End()) { }
|
FORCEINLINE TString(TStringView<FElementType> View) : TString(View.Begin(), View.End()) { }
|
||||||
|
|
||||||
/** Constructs the string with the contents of the range ['First', 'Last'). */
|
/** 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)) { }
|
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'. */
|
/** Copy constructor. Constructs the string with the copy of the contents of 'InValue'. */
|
||||||
FORCEINLINE TString(const TString&) = default;
|
FORCEINLINE TString(const TString&) = default;
|
||||||
|
|
||||||
@ -90,7 +95,7 @@ public:
|
|||||||
FORCEINLINE TString(TString&&) = default;
|
FORCEINLINE TString(TString&&) = default;
|
||||||
|
|
||||||
/** Constructs the string with the contents of the initializer list. */
|
/** 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'. */
|
/** Copy assignment operator. Replaces the contents with a copy of the contents of 'InValue'. */
|
||||||
FORCEINLINE TString& operator=(const TString&) = default;
|
FORCEINLINE TString& operator=(const TString&) = default;
|
||||||
@ -167,7 +172,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Inserts characters from the range ['First', 'Last') before 'Index' in the string. */
|
/** 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)
|
FORCEINLINE FIterator Insert(size_t Index, I First, S Last)
|
||||||
{
|
{
|
||||||
checkf(Index <= this->Num(), TEXT("Illegal index. Please check Index <= Num()."));
|
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'. */
|
/** 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)
|
FORCEINLINE FIterator Insert(FConstIterator Iter, I First, S Last)
|
||||||
{
|
{
|
||||||
checkf(this->IsValidIterator(Iter), TEXT("Read access violation. Please check IsValidIterator()."));
|
checkf(this->IsValidIterator(Iter), TEXT("Read access violation. Please check IsValidIterator()."));
|
||||||
@ -237,20 +242,33 @@ public:
|
|||||||
void StableErase(...) = delete;
|
void StableErase(...) = delete;
|
||||||
|
|
||||||
/** Appends 'Count' copies of the 'InValue' to the end of the string. */
|
/** 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. */
|
/** Appends the contents of the range ['InPtr', 'InPtr' + 'Count') to the end of the string. */
|
||||||
FORCEINLINE TString& Append(TStringView<FElementType> View) { return Append(View.Begin(), View.End()); }
|
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. */
|
/** 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)
|
TString& Append(I First, S Last)
|
||||||
{
|
{
|
||||||
if constexpr (CForwardIterator<I>)
|
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();
|
const size_t CurrentNum = this->Num();
|
||||||
|
|
||||||
@ -269,14 +287,24 @@ public:
|
|||||||
return *this;
|
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. */
|
/** 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. */
|
/** Appends the given character value to the end of the string. */
|
||||||
FORCEINLINE TString& operator+=(FElementType InChar) { return Append(1, InChar); }
|
FORCEINLINE TString& operator+=(FElementType InChar) { return Append(1, InChar); }
|
||||||
|
|
||||||
/** Appends the contents of the 'View' to the end of the string. */
|
/** Appends the contents of the range ['InPtr', '\0') to the end of the string. */
|
||||||
FORCEINLINE TString& operator+=(TStringView<FElementType> View) { return Append(View); }
|
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. */
|
/** Appends the contents of the range ['First', 'Last') to the end of the string. */
|
||||||
FORCEINLINE TString& operator+=(initializer_list<FElementType> IL) { return Append(IL); }
|
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()."));
|
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'. */
|
/** Replace the substring [Index, Index + CountToReplace) with the contents of the ['InPtr', 'InPtr' + 'Count'). */
|
||||||
FORCEINLINE TString& Replace(size_t Index, size_t CountToReplace, TStringView<FElementType> View)
|
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."));
|
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(size_t, size_t, nullptr_t, size_t) = delete;
|
||||||
FORCEINLINE TString& Replace(FConstIterator First, FConstIterator Last, TStringView<FElementType> View)
|
|
||||||
|
/** 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()."));
|
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'). */
|
/** 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)
|
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."));
|
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'). */
|
/** 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)
|
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()."));
|
checkf(this->IsValidIterator(First) && this->IsValidIterator(Last) && First <= Last, TEXT("Read access violation. Please check IsValidIterator()."));
|
||||||
|
|
||||||
if constexpr (CForwardIterator<I>)
|
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 InsertIndex = First - this->Begin();
|
||||||
|
const size_t RemoveCount = Last - First;
|
||||||
|
|
||||||
const size_t RemoveCount = Iteration::Distance(First, Last);
|
size_t InsertCount = 0;
|
||||||
const size_t InsertCount = Iteration::Distance(InString, Sentinel);
|
|
||||||
|
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;
|
const size_t NumToReset = this->Num() - RemoveCount + InsertCount;
|
||||||
|
|
||||||
@ -519,6 +577,24 @@ public:
|
|||||||
return *this;
|
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. */
|
/** 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)
|
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()."));
|
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'. */
|
/** 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."));
|
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. */
|
/** Copies the characters of this string to the destination buffer without null-termination. */
|
||||||
@ -725,7 +801,7 @@ public:
|
|||||||
|
|
||||||
do
|
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;
|
if (BeginFrom == NextFrom) return false;
|
||||||
|
|
||||||
@ -773,7 +849,7 @@ public:
|
|||||||
|
|
||||||
do
|
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;
|
if (BeginFrom == NextFrom) return false;
|
||||||
|
|
||||||
@ -1360,8 +1436,11 @@ TString(const T*) -> TString<T>;
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
TString(TStringView<T>) -> TString<T>;
|
TString(TStringView<T>) -> TString<T>;
|
||||||
|
|
||||||
template<CForwardIterator I, typename S>
|
template<typename I, typename S>
|
||||||
TString(I, S) -> TString<TIteratorElementType<I>>;
|
TString(I, S) -> TString<TIteratorElement<I>>;
|
||||||
|
|
||||||
|
template<typename R>
|
||||||
|
TString(R) -> TString<TRangeElement<R>>;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TString(initializer_list<T>) -> TString<T>;
|
TString(initializer_list<T>) -> TString<T>;
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
|
#include "Range/Range.h"
|
||||||
#include "String/Char.h"
|
#include "String/Char.h"
|
||||||
#include "Memory/Allocator.h"
|
#include "Memory/Allocator.h"
|
||||||
|
#include "Iterator/Iterator.h"
|
||||||
#include "Templates/Utility.h"
|
#include "Templates/Utility.h"
|
||||||
#include "Templates/TypeHash.h"
|
#include "Templates/TypeHash.h"
|
||||||
#include "Containers/ArrayView.h"
|
#include "Containers/ArrayView.h"
|
||||||
#include "TypeTraits/TypeTraits.h"
|
#include "TypeTraits/TypeTraits.h"
|
||||||
#include "Memory/MemoryOperator.h"
|
#include "Memory/MemoryOperator.h"
|
||||||
#include "Miscellaneous/Iterator.h"
|
|
||||||
#include "Miscellaneous/Container.h"
|
|
||||||
#include "Miscellaneous/AssertionMacros.h"
|
#include "Miscellaneous/AssertionMacros.h"
|
||||||
#include "Miscellaneous/ConstantIterator.h"
|
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cwchar>
|
#include <cwchar>
|
||||||
@ -86,7 +85,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using FElementType = T;
|
using FElementType = TRemoveCV<T>;
|
||||||
|
|
||||||
using FReference = typename FSuper::FReference;
|
using FReference = typename FSuper::FReference;
|
||||||
|
|
||||||
@ -99,11 +98,11 @@ public:
|
|||||||
FORCEINLINE constexpr TStringView() = default;
|
FORCEINLINE constexpr TStringView() = default;
|
||||||
|
|
||||||
/** Constructs a string view that is a view over the range ['InFirst', 'InFirst' + 'Count'). */
|
/** 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) { }
|
FORCEINLINE constexpr TStringView(I InFirst, size_t InCount) : FSuper(InFirst, InCount) { }
|
||||||
|
|
||||||
/** Constructs a string view that is a view over the range ['InFirst', 'InLast'). */
|
/** 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) { }
|
FORCEINLINE constexpr TStringView(I InFirst, S InLast) : FSuper(InFirst, InLast) { }
|
||||||
|
|
||||||
/** Constructs a string view that is a view over the string 'InString'. */
|
/** 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>
|
template <typename I, typename S>
|
||||||
TStringView(I, S) -> TStringView<TIteratorElementType<I>>;
|
TStringView(I, S) -> TStringView<TIteratorElement<I>>;
|
||||||
|
|
||||||
template<typename T, typename Allocator>
|
template<typename T, typename Allocator>
|
||||||
TStringView(TString<T, Allocator>) -> TStringView<T>;
|
TStringView(TString<T, Allocator>) -> TStringView<T>;
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
#include "Templates/Utility.h"
|
#include "Templates/Utility.h"
|
||||||
#include "TypeTraits/TypeTraits.h"
|
#include "TypeTraits/TypeTraits.h"
|
||||||
#include "Miscellaneous/Container.h"
|
|
||||||
|
|
||||||
NAMESPACE_REDCRAFT_BEGIN
|
NAMESPACE_REDCRAFT_BEGIN
|
||||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||||
@ -13,8 +12,7 @@ template <typename T, T... Ints>
|
|||||||
struct TIntegerSequence
|
struct TIntegerSequence
|
||||||
{
|
{
|
||||||
using FValueType = T;
|
using FValueType = T;
|
||||||
FORCEINLINE static constexpr size_t Num() { return sizeof...(Ints); }
|
FORCEINLINE static constexpr size_t Num() { return sizeof...(Ints); }
|
||||||
FORCEINLINE static constexpr const T* GetData() { return NAMESPACE_REDCRAFT::GetData({ Ints... }); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NAMESPACE_PRIVATE_BEGIN
|
NAMESPACE_PRIVATE_BEGIN
|
||||||
|
@ -56,8 +56,8 @@ public:
|
|||||||
FORCEINLINE constexpr TOptional(FInvalid) : TOptional() { }
|
FORCEINLINE constexpr TOptional(FInvalid) : TOptional() { }
|
||||||
|
|
||||||
/** Constructs an object with initial content an object, direct-initialized from Forward<U>(InValue). */
|
/** Constructs an object with initial content an object, direct-initialized from Forward<U>(InValue). */
|
||||||
template <typename U = T> requires (CConstructibleFrom<T, U&&>)
|
template <typename U = T> requires (CConstructibleFrom<T, U&&>
|
||||||
&& (!CSameAs<TRemoveCVRef<U>, FInPlace>) && (!CSameAs<TOptional, TRemoveCVRef<U>>)
|
&& !CSameAs<TRemoveCVRef<U>, FInPlace> && !CSameAs<TOptional, TRemoveCVRef<U>>)
|
||||||
FORCEINLINE constexpr explicit (!CConvertibleTo<U&&, T>) TOptional(U&& InValue)
|
FORCEINLINE constexpr explicit (!CConvertibleTo<U&&, T>) TOptional(U&& InValue)
|
||||||
: TOptional(InPlace, Forward<U>(InValue))
|
: TOptional(InPlace, Forward<U>(InValue))
|
||||||
{ }
|
{ }
|
||||||
|
@ -94,6 +94,20 @@ FORCEINLINE constexpr size_t GetTypeHash(const T& A)
|
|||||||
return GetTypeHash(A.hash_code());
|
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>
|
template <typename T>
|
||||||
concept CHashable = requires(const T& A) { { GetTypeHash(A) } -> CSameAs<size_t>; };
|
concept CHashable = requires(const T& A) { { GetTypeHash(A) } -> CSameAs<size_t>; };
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
#include "TypeTraits/CompositeType.h"
|
#include "TypeTraits/Common.h"
|
||||||
#include "TypeTraits/Miscellaneous.h"
|
#include "TypeTraits/Miscellaneous.h"
|
||||||
#include "TypeTraits/SupportedOperations.h"
|
#include "TypeTraits/SupportedOperations.h"
|
||||||
|
|
||||||
@ -73,6 +73,17 @@ FORCEINLINE constexpr void Swap(T& A, T& B)
|
|||||||
B = MoveTemp(Temp);
|
B = MoveTemp(Temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Overloads the Swap algorithm for arrays. */
|
||||||
|
template <typename T, typename U, size_t N> requires (CCommonReference<T, U>
|
||||||
|
&& 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'. */
|
/** 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>)
|
template <typename T, typename U = T> requires (CMoveConstructible<T> && CAssignableFrom<T&, U>)
|
||||||
FORCEINLINE constexpr T Exchange(T& A, U&& B)
|
FORCEINLINE constexpr T Exchange(T& A, U&& B)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
|
#include "Range/Utility.h"
|
||||||
#include "Templates/Meta.h"
|
#include "Templates/Meta.h"
|
||||||
#include "Templates/Invoke.h"
|
#include "Templates/Invoke.h"
|
||||||
#include "Templates/Utility.h"
|
#include "Templates/Utility.h"
|
||||||
@ -478,7 +479,7 @@ struct TVariantVisitImpl
|
|||||||
for (size_t Index = 0; Index < sizeof...(VariantTypes); ++Index)
|
for (size_t Index = 0; Index < sizeof...(VariantTypes); ++Index)
|
||||||
{
|
{
|
||||||
Result *= VariantNums[Index];
|
Result *= VariantNums[Index];
|
||||||
Result += GetData(Indices)[Index];
|
Result += Range::Begin(Indices)[Index];
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
|
Loading…
Reference in New Issue
Block a user