refactor(*): make type alias identifiers conform to the style for general type identifiers
This commit is contained in:
@ -27,41 +27,41 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
using ElementType = T;
|
||||
using AllocatorType = Allocator;
|
||||
using FElementType = T;
|
||||
using FAllocatorType = Allocator;
|
||||
|
||||
using Reference = T&;
|
||||
using ConstReference = const T&;
|
||||
using FReference = T&;
|
||||
using FConstReference = const T&;
|
||||
|
||||
using Iterator = TIteratorImpl<false>;
|
||||
using ConstIterator = TIteratorImpl<true >;
|
||||
using FIterator = TIteratorImpl<false>;
|
||||
using FConstIterator = TIteratorImpl<true >;
|
||||
|
||||
using ReverseIterator = TReverseIterator< Iterator>;
|
||||
using ConstReverseIterator = TReverseIterator<ConstIterator>;
|
||||
using FReverseIterator = TReverseIterator< FIterator>;
|
||||
using FConstReverseIterator = TReverseIterator<FConstIterator>;
|
||||
|
||||
static_assert(CContiguousIterator< Iterator>);
|
||||
static_assert(CContiguousIterator<ConstIterator>);
|
||||
static_assert(CContiguousIterator< FIterator>);
|
||||
static_assert(CContiguousIterator<FConstIterator>);
|
||||
|
||||
/** Default constructor. Constructs an empty container with a default-constructed allocator. */
|
||||
FORCEINLINE TArray() : TArray(0) { }
|
||||
|
||||
/** Constructs the container with 'Count' default instances of T. */
|
||||
explicit TArray(size_t Count) requires (CDefaultConstructible<ElementType>)
|
||||
explicit TArray(size_t Count) requires (CDefaultConstructible<FElementType>)
|
||||
{
|
||||
Impl.ArrayNum = Count;
|
||||
Impl.ArrayMax = Impl->CalculateSlackReserve(Num());
|
||||
Impl.Pointer = Impl->Allocate(Max());
|
||||
|
||||
Memory::DefaultConstruct<ElementType>(Impl.Pointer, Num());
|
||||
Memory::DefaultConstruct<FElementType>(Impl.Pointer, Num());
|
||||
}
|
||||
|
||||
/** Constructs the container with 'Count' copies of elements with 'InValue'. */
|
||||
TArray(size_t Count, const ElementType& InValue) requires (CCopyConstructible<ElementType>)
|
||||
TArray(size_t Count, const FElementType& InValue) requires (CCopyConstructible<FElementType>)
|
||||
: TArray(MakeCountedConstantIterator(InValue, Count), DefaultSentinel)
|
||||
{ }
|
||||
|
||||
/** Constructs the container with the contents of the range ['First', 'Last'). */
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<ElementType, TIteratorReferenceType<I>> && CMovable<ElementType>)
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReferenceType<I>> && CMovable<FElementType>)
|
||||
TArray(I First, S Last)
|
||||
{
|
||||
if constexpr (CForwardIterator<I>)
|
||||
@ -76,7 +76,7 @@ public:
|
||||
|
||||
for (size_t Index = 0; Index != Count; ++Index)
|
||||
{
|
||||
new (Impl.Pointer + Index) ElementType(*First++);
|
||||
new (Impl.Pointer + Index) FElementType(*First++);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -94,17 +94,17 @@ public:
|
||||
}
|
||||
|
||||
/** Copy constructor. Constructs the container with the copy of the contents of 'InValue'. */
|
||||
TArray(const TArray& InValue) requires (CCopyConstructible<ElementType>)
|
||||
TArray(const TArray& InValue) requires (CCopyConstructible<FElementType>)
|
||||
{
|
||||
Impl.ArrayNum = InValue.Num();
|
||||
Impl.ArrayMax = Impl->CalculateSlackReserve(Num());
|
||||
Impl.Pointer = Impl->Allocate(Max());
|
||||
|
||||
Memory::CopyConstruct<ElementType>(Impl.Pointer, InValue.Impl.Pointer, Num());
|
||||
Memory::CopyConstruct<FElementType>(Impl.Pointer, InValue.Impl.Pointer, Num());
|
||||
}
|
||||
|
||||
/** Move constructor. After the move, 'InValue' is guaranteed to be empty. */
|
||||
TArray(TArray&& InValue) requires (CMoveConstructible<ElementType>)
|
||||
TArray(TArray&& InValue) requires (CMoveConstructible<FElementType>)
|
||||
{
|
||||
Impl.ArrayNum = InValue.Num();
|
||||
|
||||
@ -122,14 +122,14 @@ public:
|
||||
Impl.ArrayMax = Impl->CalculateSlackReserve(Num());
|
||||
Impl.Pointer = Impl->Allocate(Max());
|
||||
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer, InValue.Impl.Pointer, Num());
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer, InValue.Impl.Pointer, Num());
|
||||
}
|
||||
|
||||
InValue.Reset();
|
||||
}
|
||||
|
||||
/** Constructs the container with the contents of the initializer list. */
|
||||
FORCEINLINE TArray(initializer_list<ElementType> IL) requires (CCopyConstructible<ElementType>) : TArray(Iteration::Begin(IL), Iteration::End(IL)) { }
|
||||
FORCEINLINE TArray(initializer_list<FElementType> IL) requires (CCopyConstructible<FElementType>) : TArray(Iteration::Begin(IL), Iteration::End(IL)) { }
|
||||
|
||||
/** Destructs the array. The destructors of the elements are called and the used storage is deallocated. */
|
||||
~TArray()
|
||||
@ -139,7 +139,7 @@ public:
|
||||
}
|
||||
|
||||
/** Copy assignment operator. Replaces the contents with a copy of the contents of 'InValue'. */
|
||||
TArray& operator=(const TArray& InValue) requires (CCopyable<ElementType>)
|
||||
TArray& operator=(const TArray& InValue) requires (CCopyable<FElementType>)
|
||||
{
|
||||
if (&InValue == this) UNLIKELY return *this;
|
||||
|
||||
@ -157,7 +157,7 @@ public:
|
||||
Impl.ArrayMax = NumToAllocate;
|
||||
Impl.Pointer = Impl->Allocate(Max());
|
||||
|
||||
Memory::CopyConstruct<ElementType>(Impl.Pointer, InValue.Impl.Pointer, Num());
|
||||
Memory::CopyConstruct<FElementType>(Impl.Pointer, InValue.Impl.Pointer, Num());
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -170,7 +170,7 @@ public:
|
||||
else if (InValue.Num() <= Max())
|
||||
{
|
||||
Memory::CopyAssign(Impl.Pointer, InValue.Impl.Pointer, Num());
|
||||
Memory::CopyConstruct<ElementType>(Impl.Pointer + Num(), InValue.Impl.Pointer + Num(), InValue.Num() - Num());
|
||||
Memory::CopyConstruct<FElementType>(Impl.Pointer + Num(), InValue.Impl.Pointer + Num(), InValue.Num() - Num());
|
||||
}
|
||||
else check_no_entry();
|
||||
|
||||
@ -180,7 +180,7 @@ public:
|
||||
}
|
||||
|
||||
/** Move assignment operator. After the move, 'InValue' is guaranteed to be empty. */
|
||||
TArray& operator=(TArray&& InValue) requires (CMovable<ElementType>)
|
||||
TArray& operator=(TArray&& InValue) requires (CMovable<FElementType>)
|
||||
{
|
||||
if (&InValue == this) UNLIKELY return *this;
|
||||
|
||||
@ -214,7 +214,7 @@ public:
|
||||
Impl.ArrayMax = NumToAllocate;
|
||||
Impl.Pointer = Impl->Allocate(Max());
|
||||
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer, InValue.Impl.Pointer, Num());
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer, InValue.Impl.Pointer, Num());
|
||||
|
||||
InValue.Reset();
|
||||
|
||||
@ -229,7 +229,7 @@ public:
|
||||
else if (InValue.Num() <= Max())
|
||||
{
|
||||
Memory::MoveAssign(Impl.Pointer, InValue.Impl.Pointer, Num());
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer + Num(), InValue.Impl.Pointer + Num(), InValue.Num() - Num());
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer + Num(), InValue.Impl.Pointer + Num(), InValue.Num() - Num());
|
||||
}
|
||||
else check_no_entry();
|
||||
|
||||
@ -241,7 +241,7 @@ public:
|
||||
}
|
||||
|
||||
/** Replaces the contents with those identified by initializer list. */
|
||||
TArray& operator=(initializer_list<ElementType> IL) requires (CCopyable<ElementType>)
|
||||
TArray& operator=(initializer_list<FElementType> IL) requires (CCopyable<FElementType>)
|
||||
{
|
||||
size_t NumToAllocate = GetNum(IL);
|
||||
|
||||
@ -257,7 +257,7 @@ public:
|
||||
Impl.ArrayMax = NumToAllocate;
|
||||
Impl.Pointer = Impl->Allocate(Max());
|
||||
|
||||
Memory::CopyConstruct<ElementType>(Impl.Pointer, NAMESPACE_REDCRAFT::GetData(IL), Num());
|
||||
Memory::CopyConstruct<FElementType>(Impl.Pointer, NAMESPACE_REDCRAFT::GetData(IL), Num());
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -270,7 +270,7 @@ public:
|
||||
else if (GetNum(IL) <= Max())
|
||||
{
|
||||
Memory::CopyAssign(Impl.Pointer, NAMESPACE_REDCRAFT::GetData(IL), Num());
|
||||
Memory::CopyConstruct<ElementType>(Impl.Pointer + Num(), NAMESPACE_REDCRAFT::GetData(IL) + Num(), GetNum(IL) - Num());
|
||||
Memory::CopyConstruct<FElementType>(Impl.Pointer + Num(), NAMESPACE_REDCRAFT::GetData(IL) + Num(), GetNum(IL) - Num());
|
||||
}
|
||||
else check_no_entry();
|
||||
|
||||
@ -280,7 +280,7 @@ public:
|
||||
}
|
||||
|
||||
/** Compares the contents of two arrays. */
|
||||
NODISCARD friend bool operator==(const TArray& LHS, const TArray& RHS) requires (CWeaklyEqualityComparable<ElementType>)
|
||||
NODISCARD friend bool operator==(const TArray& LHS, const TArray& RHS) requires (CWeaklyEqualityComparable<FElementType>)
|
||||
{
|
||||
if (LHS.Num() != RHS.Num()) return false;
|
||||
|
||||
@ -293,7 +293,7 @@ public:
|
||||
}
|
||||
|
||||
/** Compares the contents of 'LHS' and 'RHS' lexicographically. */
|
||||
NODISCARD friend auto operator<=>(const TArray& LHS, const TArray& RHS) requires (CSynthThreeWayComparable<ElementType>)
|
||||
NODISCARD friend auto operator<=>(const TArray& LHS, const TArray& RHS) requires (CSynthThreeWayComparable<FElementType>)
|
||||
{
|
||||
const size_t NumToCompare = LHS.Num() < RHS.Num() ? LHS.Num() : RHS.Num();
|
||||
|
||||
@ -306,7 +306,7 @@ public:
|
||||
}
|
||||
|
||||
/** Inserts 'InValue' before 'Iter' in the container. */
|
||||
Iterator Insert(ConstIterator Iter, const ElementType& InValue) requires (CCopyable<ElementType>)
|
||||
FIterator Insert(FConstIterator Iter, const FElementType& InValue) requires (CCopyable<FElementType>)
|
||||
{
|
||||
checkf(IsValidIterator(Iter), TEXT("Read access violation. Please check IsValidIterator()."));
|
||||
|
||||
@ -318,26 +318,26 @@ public:
|
||||
|
||||
if (NumToAllocate != Max())
|
||||
{
|
||||
ElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = Num();
|
||||
FElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = Num();
|
||||
|
||||
Impl.ArrayNum = Num() + 1;
|
||||
Impl.ArrayMax = NumToAllocate;
|
||||
Impl.Pointer = Impl->Allocate(Max());
|
||||
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer, OldAllocation, InsertIndex);
|
||||
new (Impl.Pointer + InsertIndex) ElementType(InValue);
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer + InsertIndex + 1, OldAllocation + InsertIndex, NumToDestruct - InsertIndex);
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer, OldAllocation, InsertIndex);
|
||||
new (Impl.Pointer + InsertIndex) FElementType(InValue);
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer + InsertIndex + 1, OldAllocation + InsertIndex, NumToDestruct - InsertIndex);
|
||||
|
||||
Memory::Destruct(OldAllocation, NumToDestruct);
|
||||
Impl->Deallocate(OldAllocation);
|
||||
|
||||
return Iterator(this, Impl.Pointer + InsertIndex);
|
||||
return FIterator(this, Impl.Pointer + InsertIndex);
|
||||
}
|
||||
|
||||
if (InsertIndex != Num())
|
||||
{
|
||||
new (Impl.Pointer + Num()) ElementType(MoveTemp(Impl.Pointer[Num() - 1]));
|
||||
new (Impl.Pointer + Num()) FElementType(MoveTemp(Impl.Pointer[Num() - 1]));
|
||||
|
||||
for (size_t Index = Num() - 1; Index != InsertIndex; --Index)
|
||||
{
|
||||
@ -346,15 +346,15 @@ public:
|
||||
|
||||
Impl.Pointer[InsertIndex] = InValue;
|
||||
}
|
||||
else new (Impl.Pointer + Num()) ElementType(InValue);
|
||||
else new (Impl.Pointer + Num()) FElementType(InValue);
|
||||
|
||||
Impl.ArrayNum = Num() + 1;
|
||||
|
||||
return Iterator(this, Impl.Pointer + InsertIndex);
|
||||
return FIterator(this, Impl.Pointer + InsertIndex);
|
||||
}
|
||||
|
||||
/** Inserts 'InValue' before 'Iter' in the container. */
|
||||
Iterator Insert(ConstIterator Iter, ElementType&& InValue) requires (CMovable<ElementType>)
|
||||
FIterator Insert(FConstIterator Iter, FElementType&& InValue) requires (CMovable<FElementType>)
|
||||
{
|
||||
checkf(IsValidIterator(Iter), TEXT("Read access violation. Please check IsValidIterator()."));
|
||||
|
||||
@ -366,26 +366,26 @@ public:
|
||||
|
||||
if (NumToAllocate != Max())
|
||||
{
|
||||
ElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = Num();
|
||||
FElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = Num();
|
||||
|
||||
Impl.ArrayNum = Num() + 1;
|
||||
Impl.ArrayMax = NumToAllocate;
|
||||
Impl.Pointer = Impl->Allocate(Max());
|
||||
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer, OldAllocation, InsertIndex);
|
||||
new (Impl.Pointer + InsertIndex) ElementType(MoveTemp(InValue));
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer + InsertIndex + 1, OldAllocation + InsertIndex, NumToDestruct - InsertIndex);
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer, OldAllocation, InsertIndex);
|
||||
new (Impl.Pointer + InsertIndex) FElementType(MoveTemp(InValue));
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer + InsertIndex + 1, OldAllocation + InsertIndex, NumToDestruct - InsertIndex);
|
||||
|
||||
Memory::Destruct(OldAllocation, NumToDestruct);
|
||||
Impl->Deallocate(OldAllocation);
|
||||
|
||||
return Iterator(this, Impl.Pointer + InsertIndex);
|
||||
return FIterator(this, Impl.Pointer + InsertIndex);
|
||||
}
|
||||
|
||||
if (InsertIndex != Num())
|
||||
{
|
||||
new (Impl.Pointer + Num()) ElementType(MoveTemp(Impl.Pointer[Num() - 1]));
|
||||
new (Impl.Pointer + Num()) FElementType(MoveTemp(Impl.Pointer[Num() - 1]));
|
||||
|
||||
for (size_t Index = Num() - 1; Index != InsertIndex; --Index)
|
||||
{
|
||||
@ -394,15 +394,15 @@ public:
|
||||
|
||||
Impl.Pointer[InsertIndex] = MoveTemp(InValue);
|
||||
}
|
||||
else new (Impl.Pointer + Num()) ElementType(MoveTemp(InValue));
|
||||
else new (Impl.Pointer + Num()) FElementType(MoveTemp(InValue));
|
||||
|
||||
Impl.ArrayNum = Num() + 1;
|
||||
|
||||
return Iterator(this, Impl.Pointer + InsertIndex);
|
||||
return FIterator(this, Impl.Pointer + InsertIndex);
|
||||
}
|
||||
|
||||
/** Inserts 'Count' copies of the 'InValue' before 'Iter' in the container. */
|
||||
Iterator Insert(ConstIterator Iter, size_t Count, const ElementType& InValue) requires (CCopyable<ElementType>)
|
||||
FIterator Insert(FConstIterator Iter, size_t Count, const FElementType& InValue) requires (CCopyable<FElementType>)
|
||||
{
|
||||
checkf(IsValidIterator(Iter), TEXT("Read access violation. Please check IsValidIterator()."));
|
||||
|
||||
@ -410,9 +410,9 @@ public:
|
||||
}
|
||||
|
||||
/** Inserts elements from range ['First', 'Last') before 'Iter'. */
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<ElementType, TIteratorReferenceType<I>>
|
||||
&& CAssignableFrom<ElementType&, TIteratorReferenceType<I>> && CMovable<ElementType>)
|
||||
Iterator Insert(ConstIterator Iter, I First, S Last)
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReferenceType<I>>
|
||||
&& CAssignableFrom<FElementType&, TIteratorReferenceType<I>> && CMovable<FElementType>)
|
||||
FIterator Insert(FConstIterator Iter, I First, S Last)
|
||||
{
|
||||
checkf(IsValidIterator(Iter), TEXT("Read access violation. Please check IsValidIterator()."));
|
||||
|
||||
@ -423,7 +423,7 @@ public:
|
||||
const size_t InsertIndex = Iter - Begin();
|
||||
const size_t Count = Iteration::Distance(First, Last);
|
||||
|
||||
if (Count == 0) return Iterator(this, Impl.Pointer + InsertIndex);
|
||||
if (Count == 0) return FIterator(this, Impl.Pointer + InsertIndex);
|
||||
|
||||
const size_t NumToAllocate = Num() + Count > Max() ? Impl->CalculateSlackGrow(Num() + Count, Max()) : Max();
|
||||
|
||||
@ -431,26 +431,26 @@ public:
|
||||
|
||||
if (NumToAllocate != Max())
|
||||
{
|
||||
ElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = Num();
|
||||
FElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = Num();
|
||||
|
||||
Impl.ArrayNum = Num() + Count;
|
||||
Impl.ArrayMax = NumToAllocate;
|
||||
Impl.Pointer = Impl->Allocate(Max());
|
||||
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer, OldAllocation, InsertIndex);
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer, OldAllocation, InsertIndex);
|
||||
|
||||
for (size_t Index = InsertIndex; Index != InsertIndex + Count; ++Index)
|
||||
{
|
||||
new (Impl.Pointer + Index) ElementType(*First++);
|
||||
new (Impl.Pointer + Index) FElementType(*First++);
|
||||
}
|
||||
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer + InsertIndex + Count, OldAllocation + InsertIndex, NumToDestruct - InsertIndex);
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer + InsertIndex + Count, OldAllocation + InsertIndex, NumToDestruct - InsertIndex);
|
||||
|
||||
Memory::Destruct(OldAllocation, NumToDestruct);
|
||||
Impl->Deallocate(OldAllocation);
|
||||
|
||||
return Iterator(this, Impl.Pointer + InsertIndex);
|
||||
return FIterator(this, Impl.Pointer + InsertIndex);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -492,7 +492,7 @@ public:
|
||||
|
||||
for (size_t TargetIndex = IndexO - 1; TargetIndex != IndexD - 1; --TargetIndex)
|
||||
{
|
||||
new (Impl.Pointer + TargetIndex) ElementType(MoveTemp(Impl.Pointer[TargetIndex - Count]));
|
||||
new (Impl.Pointer + TargetIndex) FElementType(MoveTemp(Impl.Pointer[TargetIndex - Count]));
|
||||
}
|
||||
|
||||
for (size_t TargetIndex = IndexD - 1; TargetIndex != IndexC - 1; --TargetIndex)
|
||||
@ -507,14 +507,14 @@ public:
|
||||
|
||||
for (size_t TargetIndex = IndexB; TargetIndex != IndexC; ++TargetIndex)
|
||||
{
|
||||
new (Impl.Pointer + TargetIndex) ElementType(*First++);
|
||||
new (Impl.Pointer + TargetIndex) FElementType(*First++);
|
||||
}
|
||||
|
||||
check(First == Last);
|
||||
|
||||
Impl.ArrayNum = Num() + Count;
|
||||
|
||||
return Iterator(this, Impl.Pointer + InsertIndex);
|
||||
return FIterator(this, Impl.Pointer + InsertIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -524,14 +524,14 @@ public:
|
||||
}
|
||||
|
||||
/** Inserts elements from initializer list before 'Iter' in the container. */
|
||||
FORCEINLINE Iterator Insert(ConstIterator Iter, initializer_list<ElementType> IL) requires (CCopyable<ElementType>)
|
||||
FORCEINLINE FIterator Insert(FConstIterator Iter, initializer_list<FElementType> IL) requires (CCopyable<FElementType>)
|
||||
{
|
||||
return Insert(Iter, Iteration::Begin(IL), Iteration::End(IL));
|
||||
}
|
||||
|
||||
/** Inserts a new element into the container directly before 'Iter'. */
|
||||
template <typename... Ts> requires (CConstructibleFrom<ElementType, Ts...> && CMovable<ElementType>)
|
||||
Iterator Emplace(ConstIterator Iter, Ts&&... Args)
|
||||
template <typename... Ts> requires (CConstructibleFrom<FElementType, Ts...> && CMovable<FElementType>)
|
||||
FIterator Emplace(FConstIterator Iter, Ts&&... Args)
|
||||
{
|
||||
checkf(IsValidIterator(Iter), TEXT("Read access violation. Please check IsValidIterator()."));
|
||||
|
||||
@ -543,43 +543,43 @@ public:
|
||||
|
||||
if (NumToAllocate != Max())
|
||||
{
|
||||
ElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = Num();
|
||||
FElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = Num();
|
||||
|
||||
Impl.ArrayNum = Num() + 1;
|
||||
Impl.ArrayMax = NumToAllocate;
|
||||
Impl.Pointer = Impl->Allocate(Max());
|
||||
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer, OldAllocation, InsertIndex);
|
||||
new (Impl.Pointer + InsertIndex) ElementType(Forward<Ts>(Args)...);
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer + InsertIndex + 1, OldAllocation + InsertIndex, NumToDestruct - InsertIndex);
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer, OldAllocation, InsertIndex);
|
||||
new (Impl.Pointer + InsertIndex) FElementType(Forward<Ts>(Args)...);
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer + InsertIndex + 1, OldAllocation + InsertIndex, NumToDestruct - InsertIndex);
|
||||
|
||||
Memory::Destruct(OldAllocation, NumToDestruct);
|
||||
Impl->Deallocate(OldAllocation);
|
||||
|
||||
return Iterator(this, Impl.Pointer + InsertIndex);
|
||||
return FIterator(this, Impl.Pointer + InsertIndex);
|
||||
}
|
||||
|
||||
if (InsertIndex != Num())
|
||||
{
|
||||
new (Impl.Pointer + Num()) ElementType(MoveTemp(Impl.Pointer[Num() - 1]));
|
||||
new (Impl.Pointer + Num()) FElementType(MoveTemp(Impl.Pointer[Num() - 1]));
|
||||
|
||||
for (size_t Index = Num() - 1; Index != InsertIndex; --Index)
|
||||
{
|
||||
Impl.Pointer[Index] = MoveTemp(Impl.Pointer[Index - 1]);
|
||||
}
|
||||
|
||||
Impl.Pointer[InsertIndex] = ElementType(Forward<Ts>(Args)...);
|
||||
Impl.Pointer[InsertIndex] = FElementType(Forward<Ts>(Args)...);
|
||||
}
|
||||
else new (Impl.Pointer + Num()) ElementType(Forward<Ts>(Args)...);
|
||||
else new (Impl.Pointer + Num()) FElementType(Forward<Ts>(Args)...);
|
||||
|
||||
Impl.ArrayNum = Num() + 1;
|
||||
|
||||
return Iterator(this, Impl.Pointer + InsertIndex);
|
||||
return FIterator(this, Impl.Pointer + InsertIndex);
|
||||
}
|
||||
|
||||
/** Removes the element at 'Iter' in the container. Without changing the order of elements. */
|
||||
FORCEINLINE Iterator StableErase(ConstIterator Iter, bool bAllowShrinking = true) requires (CMovable<ElementType>)
|
||||
FORCEINLINE FIterator StableErase(FConstIterator Iter, bool bAllowShrinking = true) requires (CMovable<FElementType>)
|
||||
{
|
||||
checkf(IsValidIterator(Iter) && Iter != End(), TEXT("Read access violation. Please check IsValidIterator()."));
|
||||
|
||||
@ -587,33 +587,33 @@ public:
|
||||
}
|
||||
|
||||
/** Removes the elements in the range ['First', 'Last') in the container. Without changing the order of elements. */
|
||||
Iterator StableErase(ConstIterator First, ConstIterator Last, bool bAllowShrinking = true) requires (CMovable<ElementType>)
|
||||
FIterator StableErase(FConstIterator First, FConstIterator Last, bool bAllowShrinking = true) requires (CMovable<FElementType>)
|
||||
{
|
||||
checkf(IsValidIterator(First) && IsValidIterator(Last) && First <= Last, TEXT("Read access violation. Please check IsValidIterator()."));
|
||||
|
||||
const size_t EraseIndex = First - Begin();
|
||||
const size_t EraseCount = Last - First;
|
||||
|
||||
if (EraseCount == 0) return Iterator(this, Impl.Pointer + EraseIndex);
|
||||
if (EraseCount == 0) return FIterator(this, Impl.Pointer + EraseIndex);
|
||||
|
||||
const size_t NumToAllocate = bAllowShrinking ? Impl->CalculateSlackShrink(Num() - EraseCount, Max()) : Max();
|
||||
|
||||
if (NumToAllocate != Max())
|
||||
{
|
||||
ElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = Num();
|
||||
FElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = Num();
|
||||
|
||||
Impl.ArrayNum = Num() - EraseCount;
|
||||
Impl.ArrayMax = NumToAllocate;
|
||||
Impl.Pointer = Impl->Allocate(Max());
|
||||
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer, OldAllocation, EraseIndex);
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer + EraseIndex, OldAllocation + EraseIndex + EraseCount, NumToDestruct - EraseIndex - EraseCount);
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer, OldAllocation, EraseIndex);
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer + EraseIndex, OldAllocation + EraseIndex + EraseCount, NumToDestruct - EraseIndex - EraseCount);
|
||||
|
||||
Memory::Destruct(OldAllocation, NumToDestruct);
|
||||
Impl->Deallocate(OldAllocation);
|
||||
|
||||
return Iterator(this, Impl.Pointer + EraseIndex);
|
||||
return FIterator(this, Impl.Pointer + EraseIndex);
|
||||
}
|
||||
|
||||
for (size_t Index = EraseIndex + EraseCount; Index != Num(); ++Index)
|
||||
@ -625,11 +625,11 @@ public:
|
||||
|
||||
Impl.ArrayNum = Num() - EraseCount;
|
||||
|
||||
return Iterator(this, Impl.Pointer + EraseIndex);
|
||||
return FIterator(this, Impl.Pointer + EraseIndex);
|
||||
}
|
||||
|
||||
/** Removes the element at 'Iter' in the container. But it may change the order of elements. */
|
||||
FORCEINLINE Iterator Erase(ConstIterator Iter, bool bAllowShrinking = true) requires (CMovable<ElementType>)
|
||||
FORCEINLINE FIterator Erase(FConstIterator Iter, bool bAllowShrinking = true) requires (CMovable<FElementType>)
|
||||
{
|
||||
checkf(IsValidIterator(Iter) && Iter != End(), TEXT("Read access violation. Please check IsValidIterator()."));
|
||||
|
||||
@ -637,33 +637,33 @@ public:
|
||||
}
|
||||
|
||||
/** Removes the elements in the range ['First', 'Last') in the container. But it may change the order of elements. */
|
||||
Iterator Erase(ConstIterator First, ConstIterator Last, bool bAllowShrinking = true) requires (CMovable<ElementType>)
|
||||
FIterator Erase(FConstIterator First, FConstIterator Last, bool bAllowShrinking = true) requires (CMovable<FElementType>)
|
||||
{
|
||||
checkf(IsValidIterator(First) && IsValidIterator(Last) && First <= Last, TEXT("Read access violation. Please check IsValidIterator()."));
|
||||
|
||||
const size_t EraseIndex = First - Begin();
|
||||
const size_t EraseCount = Last - First;
|
||||
|
||||
if (EraseCount == 0) return Iterator(this, Impl.Pointer + EraseIndex);
|
||||
if (EraseCount == 0) return FIterator(this, Impl.Pointer + EraseIndex);
|
||||
|
||||
const size_t NumToAllocate = bAllowShrinking ? Impl->CalculateSlackShrink(Num() - EraseCount, Max()) : Max();
|
||||
|
||||
if (NumToAllocate != Max())
|
||||
{
|
||||
ElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = Num();
|
||||
FElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = Num();
|
||||
|
||||
Impl.ArrayNum = Num() - EraseCount;
|
||||
Impl.ArrayMax = NumToAllocate;
|
||||
Impl.Pointer = Impl->Allocate(Max());
|
||||
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer, OldAllocation, EraseIndex);
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer + EraseIndex, OldAllocation + EraseIndex + EraseCount, NumToDestruct - EraseIndex - EraseCount);
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer, OldAllocation, EraseIndex);
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer + EraseIndex, OldAllocation + EraseIndex + EraseCount, NumToDestruct - EraseIndex - EraseCount);
|
||||
|
||||
Memory::Destruct(OldAllocation, NumToDestruct);
|
||||
Impl->Deallocate(OldAllocation);
|
||||
|
||||
return Iterator(this, Impl.Pointer + EraseIndex);
|
||||
return FIterator(this, Impl.Pointer + EraseIndex);
|
||||
}
|
||||
|
||||
for (size_t Index = 0; Index != EraseCount; ++Index)
|
||||
@ -677,24 +677,24 @@ public:
|
||||
|
||||
Impl.ArrayNum = Num() - EraseCount;
|
||||
|
||||
return Iterator(this, Impl.Pointer + EraseIndex);
|
||||
return FIterator(this, Impl.Pointer + EraseIndex);
|
||||
}
|
||||
|
||||
/** Appends the given element value to the end of the container. */
|
||||
FORCEINLINE void PushBack(const ElementType& InValue) requires (CCopyable<ElementType>)
|
||||
FORCEINLINE void PushBack(const FElementType& InValue) requires (CCopyable<FElementType>)
|
||||
{
|
||||
EmplaceBack(InValue);
|
||||
}
|
||||
|
||||
/** Appends the given element value to the end of the container. */
|
||||
FORCEINLINE void PushBack(ElementType&& InValue) requires (CMovable<ElementType>)
|
||||
FORCEINLINE void PushBack(FElementType&& InValue) requires (CMovable<FElementType>)
|
||||
{
|
||||
EmplaceBack(MoveTemp(InValue));
|
||||
}
|
||||
|
||||
/** Appends a new element to the end of the container. */
|
||||
template <typename... Ts> requires (CConstructibleFrom<ElementType, Ts...> && CMovable<ElementType>)
|
||||
ElementType& EmplaceBack(Ts&&... Args)
|
||||
template <typename... Ts> requires (CConstructibleFrom<FElementType, Ts...> && CMovable<FElementType>)
|
||||
FElementType& EmplaceBack(Ts&&... Args)
|
||||
{
|
||||
const size_t NumToAllocate = Num() + 1 > Max() ? Impl->CalculateSlackGrow(Num() + 1, Max()) : Max();
|
||||
|
||||
@ -702,15 +702,15 @@ public:
|
||||
|
||||
if (NumToAllocate != Max())
|
||||
{
|
||||
ElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = Num();
|
||||
FElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = Num();
|
||||
|
||||
Impl.ArrayNum = Num() + 1;
|
||||
Impl.ArrayMax = NumToAllocate;
|
||||
Impl.Pointer = Impl->Allocate(Max());
|
||||
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer, OldAllocation, Num() - 1);
|
||||
new (Impl.Pointer + Num() - 1) ElementType(Forward<Ts>(Args)...);
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer, OldAllocation, Num() - 1);
|
||||
new (Impl.Pointer + Num() - 1) FElementType(Forward<Ts>(Args)...);
|
||||
|
||||
Memory::Destruct(OldAllocation, NumToDestruct);
|
||||
Impl->Deallocate(OldAllocation);
|
||||
@ -718,7 +718,7 @@ public:
|
||||
return Impl.Pointer[Num() - 1];
|
||||
}
|
||||
|
||||
new (Impl.Pointer + Num()) ElementType(Forward<Ts>(Args)...);
|
||||
new (Impl.Pointer + Num()) FElementType(Forward<Ts>(Args)...);
|
||||
|
||||
Impl.ArrayNum = Num() + 1;
|
||||
|
||||
@ -726,13 +726,13 @@ public:
|
||||
}
|
||||
|
||||
/** Removes the last element of the container. The array cannot be empty. */
|
||||
FORCEINLINE void PopBack(bool bAllowShrinking = true) requires (CMovable<ElementType>)
|
||||
FORCEINLINE void PopBack(bool bAllowShrinking = true) requires (CMovable<FElementType>)
|
||||
{
|
||||
Erase(End() - 1, bAllowShrinking);
|
||||
}
|
||||
|
||||
/** Resizes the container to contain 'Count' elements. Additional default elements are appended. */
|
||||
void SetNum(size_t Count, bool bAllowShrinking = true) requires (CDefaultConstructible<ElementType> && CMovable<ElementType>)
|
||||
void SetNum(size_t Count, bool bAllowShrinking = true) requires (CDefaultConstructible<FElementType> && CMovable<FElementType>)
|
||||
{
|
||||
size_t NumToAllocate = Count;
|
||||
|
||||
@ -741,8 +741,8 @@ public:
|
||||
|
||||
if (NumToAllocate != Max())
|
||||
{
|
||||
ElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = Num();
|
||||
FElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = Num();
|
||||
|
||||
Impl.ArrayNum = Count;
|
||||
Impl.ArrayMax = NumToAllocate;
|
||||
@ -750,12 +750,12 @@ public:
|
||||
|
||||
if (NumToDestruct <= Num())
|
||||
{
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer, OldAllocation, NumToDestruct);
|
||||
Memory::DefaultConstruct<ElementType>(Impl.Pointer + NumToDestruct, Num() - NumToDestruct);
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer, OldAllocation, NumToDestruct);
|
||||
Memory::DefaultConstruct<FElementType>(Impl.Pointer + NumToDestruct, Num() - NumToDestruct);
|
||||
}
|
||||
else
|
||||
{
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer, OldAllocation, Num());
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer, OldAllocation, Num());
|
||||
}
|
||||
|
||||
Memory::Destruct(OldAllocation, NumToDestruct);
|
||||
@ -770,7 +770,7 @@ public:
|
||||
}
|
||||
else if (Count <= Max())
|
||||
{
|
||||
Memory::DefaultConstruct<ElementType>(Impl.Pointer + Num(), Count - Num());
|
||||
Memory::DefaultConstruct<FElementType>(Impl.Pointer + Num(), Count - Num());
|
||||
}
|
||||
else check_no_entry();
|
||||
|
||||
@ -778,7 +778,7 @@ public:
|
||||
}
|
||||
|
||||
/** Resizes the container to contain 'Count' elements. Additional copies of 'InValue' are appended. */
|
||||
void SetNum(size_t Count, const ElementType& InValue, bool bAllowShrinking = true) requires (CCopyConstructible<ElementType> && CMovable<ElementType>)
|
||||
void SetNum(size_t Count, const FElementType& InValue, bool bAllowShrinking = true) requires (CCopyConstructible<FElementType> && CMovable<FElementType>)
|
||||
{
|
||||
size_t NumToAllocate = Count;
|
||||
|
||||
@ -787,8 +787,8 @@ public:
|
||||
|
||||
if (NumToAllocate != Max())
|
||||
{
|
||||
ElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = Num();
|
||||
FElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = Num();
|
||||
|
||||
Impl.ArrayNum = Count;
|
||||
Impl.ArrayMax = NumToAllocate;
|
||||
@ -796,16 +796,16 @@ public:
|
||||
|
||||
if (NumToDestruct <= Num())
|
||||
{
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer, OldAllocation, NumToDestruct);
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer, OldAllocation, NumToDestruct);
|
||||
|
||||
for (size_t Index = NumToDestruct; Index != Num(); ++Index)
|
||||
{
|
||||
new (Impl.Pointer + Index) ElementType(InValue);
|
||||
new (Impl.Pointer + Index) FElementType(InValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer, OldAllocation, Num());
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer, OldAllocation, Num());
|
||||
}
|
||||
|
||||
Memory::Destruct(OldAllocation, NumToDestruct);
|
||||
@ -822,7 +822,7 @@ public:
|
||||
{
|
||||
for (size_t Index = Num(); Index != Count; ++Index)
|
||||
{
|
||||
new (Impl.Pointer + Index) ElementType(InValue);
|
||||
new (Impl.Pointer + Index) FElementType(InValue);
|
||||
}
|
||||
}
|
||||
else check_no_entry();
|
||||
@ -831,19 +831,19 @@ public:
|
||||
}
|
||||
|
||||
/** Increase the max capacity of the array to a value that's greater or equal to 'Count'. */
|
||||
void Reserve(size_t Count) requires (CMovable<ElementType>)
|
||||
void Reserve(size_t Count) requires (CMovable<FElementType>)
|
||||
{
|
||||
if (Count <= Max()) return;
|
||||
|
||||
const size_t NumToAllocate = Impl->CalculateSlackReserve(Count);
|
||||
ElementType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToAllocate = Impl->CalculateSlackReserve(Count);
|
||||
FElementType* OldAllocation = Impl.Pointer;
|
||||
|
||||
check(NumToAllocate > Max());
|
||||
|
||||
Impl.ArrayMax = NumToAllocate;
|
||||
Impl.Pointer = Impl->Allocate(Max());
|
||||
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer, OldAllocation, Num());
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer, OldAllocation, Num());
|
||||
|
||||
Memory::Destruct(OldAllocation, Num());
|
||||
Impl->Deallocate(OldAllocation);
|
||||
@ -858,32 +858,32 @@ public:
|
||||
|
||||
if (NumToAllocate == Max()) return;
|
||||
|
||||
ElementType* OldAllocation = Impl.Pointer;
|
||||
FElementType* OldAllocation = Impl.Pointer;
|
||||
|
||||
Impl.ArrayMax = NumToAllocate;
|
||||
Impl.Pointer = Impl->Allocate(Max());
|
||||
|
||||
Memory::MoveConstruct<ElementType>(Impl.Pointer, OldAllocation, Num());
|
||||
Memory::MoveConstruct<FElementType>(Impl.Pointer, OldAllocation, Num());
|
||||
Memory::Destruct(OldAllocation, Num());
|
||||
|
||||
Impl->Deallocate(OldAllocation);
|
||||
}
|
||||
|
||||
/** @return The pointer to the underlying element storage. */
|
||||
NODISCARD FORCEINLINE ElementType* GetData() { return Impl.Pointer; }
|
||||
NODISCARD FORCEINLINE const ElementType* GetData() const { return Impl.Pointer; }
|
||||
NODISCARD FORCEINLINE FElementType* GetData() { return Impl.Pointer; }
|
||||
NODISCARD FORCEINLINE const FElementType* GetData() const { return Impl.Pointer; }
|
||||
|
||||
/** @return The iterator to the first or end element. */
|
||||
NODISCARD FORCEINLINE Iterator Begin() { return Iterator(this, Impl.Pointer); }
|
||||
NODISCARD FORCEINLINE ConstIterator Begin() const { return ConstIterator(this, Impl.Pointer); }
|
||||
NODISCARD FORCEINLINE Iterator End() { return Iterator(this, Impl.Pointer + Num()); }
|
||||
NODISCARD FORCEINLINE ConstIterator End() const { return ConstIterator(this, Impl.Pointer + Num()); }
|
||||
NODISCARD FORCEINLINE FIterator Begin() { return FIterator(this, Impl.Pointer); }
|
||||
NODISCARD FORCEINLINE FConstIterator Begin() const { return FConstIterator(this, Impl.Pointer); }
|
||||
NODISCARD FORCEINLINE FIterator End() { return FIterator(this, Impl.Pointer + Num()); }
|
||||
NODISCARD FORCEINLINE FConstIterator End() const { return FConstIterator(this, Impl.Pointer + Num()); }
|
||||
|
||||
/** @return The reverse iterator to the first or end element. */
|
||||
NODISCARD FORCEINLINE ReverseIterator RBegin() { return ReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE ConstReverseIterator RBegin() const { return ConstReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE ReverseIterator REnd() { return ReverseIterator(Begin()); }
|
||||
NODISCARD FORCEINLINE ConstReverseIterator REnd() const { return ConstReverseIterator(Begin()); }
|
||||
NODISCARD FORCEINLINE FReverseIterator RBegin() { return FReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE FConstReverseIterator RBegin() const { return FConstReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE FReverseIterator REnd() { return FReverseIterator(Begin()); }
|
||||
NODISCARD FORCEINLINE FConstReverseIterator REnd() const { return FConstReverseIterator(Begin()); }
|
||||
|
||||
/** @return The number of elements in the container. */
|
||||
NODISCARD FORCEINLINE size_t Num() const { return Impl.ArrayNum; }
|
||||
@ -895,17 +895,17 @@ public:
|
||||
NODISCARD FORCEINLINE bool IsEmpty() const { return Num() == 0; }
|
||||
|
||||
/** @return true if the iterator is valid, false otherwise. */
|
||||
NODISCARD FORCEINLINE bool IsValidIterator(ConstIterator Iter) const { return Begin() <= Iter && Iter <= End(); }
|
||||
NODISCARD FORCEINLINE bool IsValidIterator(FConstIterator Iter) const { return Begin() <= Iter && Iter <= End(); }
|
||||
|
||||
/** @return The reference to the requested element. */
|
||||
NODISCARD FORCEINLINE ElementType& operator[](size_t Index) { checkf(Index < Num(), TEXT("Read access violation. Please check IsValidIterator().")); return Impl.Pointer[Index]; }
|
||||
NODISCARD FORCEINLINE const ElementType& operator[](size_t Index) const { checkf(Index < Num(), TEXT("Read access violation. Please check IsValidIterator().")); return Impl.Pointer[Index]; }
|
||||
NODISCARD FORCEINLINE FElementType& operator[](size_t Index) { checkf(Index < Num(), TEXT("Read access violation. Please check IsValidIterator().")); return Impl.Pointer[Index]; }
|
||||
NODISCARD FORCEINLINE const FElementType& operator[](size_t Index) const { checkf(Index < Num(), TEXT("Read access violation. Please check IsValidIterator().")); return Impl.Pointer[Index]; }
|
||||
|
||||
/** @return The reference to the first or last element. */
|
||||
NODISCARD FORCEINLINE ElementType& Front() { return *Begin(); }
|
||||
NODISCARD FORCEINLINE const ElementType& Front() const { return *Begin(); }
|
||||
NODISCARD FORCEINLINE ElementType& Back() { return *(End() - 1); }
|
||||
NODISCARD FORCEINLINE const ElementType& Back() const { return *(End() - 1); }
|
||||
NODISCARD FORCEINLINE FElementType& Front() { return *Begin(); }
|
||||
NODISCARD FORCEINLINE const FElementType& Front() const { return *Begin(); }
|
||||
NODISCARD FORCEINLINE FElementType& Back() { return *(End() - 1); }
|
||||
NODISCARD FORCEINLINE const FElementType& Back() const { return *(End() - 1); }
|
||||
|
||||
/** Erases all elements from the container. After this call, Num() returns zero. */
|
||||
void Reset(bool bAllowShrinking = true)
|
||||
@ -929,11 +929,11 @@ public:
|
||||
}
|
||||
|
||||
/** Overloads the GetTypeHash algorithm for TArray. */
|
||||
NODISCARD friend FORCEINLINE size_t GetTypeHash(const TArray& A) requires (CHashable<ElementType>)
|
||||
NODISCARD friend FORCEINLINE size_t GetTypeHash(const TArray& A) requires (CHashable<FElementType>)
|
||||
{
|
||||
size_t Result = 0;
|
||||
|
||||
for (ConstIterator Iter = A.Begin(); Iter != A.End(); ++Iter)
|
||||
for (FConstIterator Iter = A.Begin(); Iter != A.End(); ++Iter)
|
||||
{
|
||||
Result = HashCombine(Result, GetTypeHash(*Iter));
|
||||
}
|
||||
@ -942,7 +942,7 @@ public:
|
||||
}
|
||||
|
||||
/** Overloads the Swap algorithm for TArray. */
|
||||
friend void Swap(TArray& A, TArray& B) requires (CMovable<ElementType>)
|
||||
friend void Swap(TArray& A, TArray& B) requires (CMovable<FElementType>)
|
||||
{
|
||||
const bool bIsTransferable =
|
||||
A.Impl->IsTransferable(A.Impl.Pointer) &&
|
||||
@ -966,13 +966,13 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
ALLOCATOR_WRAPPER_BEGIN(AllocatorType, ElementType, Impl)
|
||||
ALLOCATOR_WRAPPER_BEGIN(FAllocatorType, FElementType, Impl)
|
||||
{
|
||||
size_t ArrayNum;
|
||||
size_t ArrayMax;
|
||||
ElementType* Pointer;
|
||||
FElementType* Pointer;
|
||||
}
|
||||
ALLOCATOR_WRAPPER_END(AllocatorType, ElementType, Impl)
|
||||
ALLOCATOR_WRAPPER_END(FAllocatorType, FElementType, Impl)
|
||||
|
||||
private:
|
||||
|
||||
@ -981,7 +981,7 @@ private:
|
||||
{
|
||||
public:
|
||||
|
||||
using ElementType = TRemoveCV<T>;
|
||||
using FElementType = TRemoveCV<T>;
|
||||
|
||||
FORCEINLINE TIteratorImpl() = default;
|
||||
|
||||
|
@ -29,15 +29,15 @@ class TArrayView
|
||||
{
|
||||
public:
|
||||
|
||||
using ElementType = T;
|
||||
using FElementType = T;
|
||||
|
||||
using Reference = T&;
|
||||
using FReference = T&;
|
||||
|
||||
class Iterator;
|
||||
class FIterator;
|
||||
|
||||
using ReverseIterator = TReverseIterator<Iterator>;
|
||||
using FReverseIterator = TReverseIterator<FIterator>;
|
||||
|
||||
static_assert(CContiguousIterator<Iterator>);
|
||||
static_assert(CContiguousIterator<FIterator>);
|
||||
|
||||
static constexpr size_t Extent = InExtent;
|
||||
|
||||
@ -53,7 +53,7 @@ public:
|
||||
}
|
||||
|
||||
/** Constructs an array view that is a view over the range ['InFirst', 'InFirst' + 'Count'). */
|
||||
template <CContiguousIterator I> requires (CConvertibleTo<TIteratorElementType<I>(*)[], ElementType(*)[]>)
|
||||
template <CContiguousIterator I> requires (CConvertibleTo<TIteratorElementType<I>(*)[], FElementType(*)[]>)
|
||||
FORCEINLINE constexpr explicit (Extent != DynamicExtent) TArrayView(I InFirst, size_t InCount)
|
||||
{
|
||||
checkf(Extent == DynamicExtent || Extent == InCount, TEXT("Illegal range count. Please check InCount."));
|
||||
@ -67,7 +67,7 @@ public:
|
||||
}
|
||||
|
||||
/** Constructs an array view that is a view over the range ['InFirst', 'InLast'). */
|
||||
template <CContiguousIterator I, CSizedSentinelFor<I> S> requires (CConvertibleTo<TIteratorElementType<I>(*)[], ElementType(*)[]>)
|
||||
template <CContiguousIterator I, CSizedSentinelFor<I> S> requires (CConvertibleTo<TIteratorElementType<I>(*)[], FElementType(*)[]>)
|
||||
FORCEINLINE constexpr explicit (Extent != DynamicExtent) TArrayView(I InFirst, S InLast)
|
||||
{
|
||||
checkf(Extent == DynamicExtent || Extent == InLast - InFirst, TEXT("Illegal range iterator. Please check InLast - InFirst."));
|
||||
@ -82,7 +82,7 @@ public:
|
||||
|
||||
/** Constructs an array view that is a view over the array 'InArray'. */
|
||||
template <size_t N> requires (Extent == DynamicExtent || N == Extent)
|
||||
FORCEINLINE constexpr TArrayView(ElementType(&InArray)[N])
|
||||
FORCEINLINE constexpr TArrayView(FElementType(&InArray)[N])
|
||||
{
|
||||
Impl.Pointer = InArray;
|
||||
|
||||
@ -93,23 +93,23 @@ public:
|
||||
}
|
||||
|
||||
/** Constructs an array view that is a view over the array 'InArray'. */
|
||||
template <typename U, size_t N> requires (CConvertibleTo<U(*)[], ElementType(*)[]>)
|
||||
template <typename U, size_t N> requires (CConvertibleTo<U(*)[], FElementType(*)[]>)
|
||||
FORCEINLINE constexpr TArrayView(TStaticArray<U, N>& InArray) : TArrayView(InArray.GetData(), InArray.Num()) { }
|
||||
|
||||
/** Constructs an array view that is a view over the array 'InArray'. */
|
||||
template <typename U, size_t N> requires (CConvertibleTo<const U(*)[], ElementType(*)[]>)
|
||||
template <typename U, size_t N> requires (CConvertibleTo<const U(*)[], FElementType(*)[]>)
|
||||
FORCEINLINE constexpr TArrayView(const TStaticArray<U, N>& InArray) : TArrayView(InArray.GetData(), InArray.Num()) { }
|
||||
|
||||
/** Constructs an array view that is a view over the array 'InArray'. */
|
||||
template <typename U, typename Allocator> requires (CConvertibleTo<U(*)[], ElementType(*)[]>)
|
||||
template <typename U, typename Allocator> requires (CConvertibleTo<U(*)[], FElementType(*)[]>)
|
||||
FORCEINLINE constexpr TArrayView(TArray<U, Allocator>& InArray) : TArrayView(InArray.GetData(), InArray.Num()) { }
|
||||
|
||||
/** Constructs an array view that is a view over the array 'InArray'. */
|
||||
template <typename U, typename Allocator> requires (CConvertibleTo<const U(*)[], ElementType(*)[]>)
|
||||
template <typename U, typename Allocator> requires (CConvertibleTo<const U(*)[], FElementType(*)[]>)
|
||||
FORCEINLINE constexpr TArrayView(const TArray<U, Allocator>& InArray) : TArrayView(InArray.GetData(), InArray.Num()) { }
|
||||
|
||||
/** Converting constructor from another array view 'InValue'. */
|
||||
template <typename U, size_t N> requires ((Extent == DynamicExtent || N == DynamicExtent || N == Extent) && CConvertibleTo<U(*)[], ElementType(*)[]>)
|
||||
template <typename U, size_t N> requires ((Extent == DynamicExtent || N == DynamicExtent || N == Extent) && CConvertibleTo<U(*)[], FElementType(*)[]>)
|
||||
FORCEINLINE constexpr explicit (Extent != DynamicExtent && N == DynamicExtent) TArrayView(TArrayView<U, N> InValue)
|
||||
{
|
||||
checkf(Extent == DynamicExtent || Extent == InValue.Num(), TEXT("Illegal view extent. Please check InValue.Num()."));
|
||||
@ -129,7 +129,7 @@ public:
|
||||
FORCEINLINE constexpr TArrayView& operator=(const TArrayView&) noexcept = default;
|
||||
|
||||
/** Compares the contents of two array views. */
|
||||
NODISCARD friend constexpr bool operator==(TArrayView LHS, TArrayView RHS) requires (CWeaklyEqualityComparable<ElementType>)
|
||||
NODISCARD friend constexpr bool operator==(TArrayView LHS, TArrayView RHS) requires (CWeaklyEqualityComparable<FElementType>)
|
||||
{
|
||||
if (LHS.Num() != RHS.Num()) return false;
|
||||
|
||||
@ -142,7 +142,7 @@ public:
|
||||
}
|
||||
|
||||
/** Compares the contents of two array views. */
|
||||
NODISCARD friend constexpr auto operator<=>(TArrayView LHS, TArrayView RHS) requires (CSynthThreeWayComparable<ElementType>)
|
||||
NODISCARD friend constexpr auto operator<=>(TArrayView LHS, TArrayView RHS) requires (CSynthThreeWayComparable<FElementType>)
|
||||
{
|
||||
const size_t NumToCompare = LHS.Num() < RHS.Num() ? LHS.Num() : RHS.Num();
|
||||
|
||||
@ -156,36 +156,36 @@ public:
|
||||
|
||||
/** Obtains an array view that is a view over the first 'Count' elements of this array view. */
|
||||
template <size_t Count> requires (Extent == DynamicExtent || Extent >= Count)
|
||||
NODISCARD FORCEINLINE constexpr TArrayView<ElementType, Count> First() const
|
||||
NODISCARD FORCEINLINE constexpr TArrayView<FElementType, Count> First() const
|
||||
{
|
||||
checkf(Count <= Num(), TEXT("Illegal subview range. Please check Count."));
|
||||
|
||||
return TArrayView<ElementType, Count>(Begin(), Count);
|
||||
return TArrayView<FElementType, Count>(Begin(), Count);
|
||||
}
|
||||
|
||||
/** Obtains an array view that is a view over the first 'Count' elements of this array view. */
|
||||
NODISCARD FORCEINLINE constexpr TArrayView<ElementType, DynamicExtent> First(size_t Count) const
|
||||
NODISCARD FORCEINLINE constexpr TArrayView<FElementType, DynamicExtent> First(size_t Count) const
|
||||
{
|
||||
checkf(Count <= Num(), TEXT("Illegal subview range. Please check Count."));
|
||||
|
||||
return TArrayView<ElementType, DynamicExtent>(Begin(), Count);
|
||||
return TArrayView<FElementType, DynamicExtent>(Begin(), Count);
|
||||
}
|
||||
|
||||
/** Obtains an array view that is a view over the last 'Count' elements of this array view. */
|
||||
template <size_t Count> requires (Extent == DynamicExtent || Extent >= Count)
|
||||
NODISCARD FORCEINLINE constexpr TArrayView<ElementType, Count> Last() const
|
||||
NODISCARD FORCEINLINE constexpr TArrayView<FElementType, Count> Last() const
|
||||
{
|
||||
checkf(Count <= Num(), TEXT("Illegal subview range. Please check Count."));
|
||||
|
||||
return TArrayView<ElementType, Count>(End() - Count, Count);
|
||||
return TArrayView<FElementType, Count>(End() - Count, Count);
|
||||
}
|
||||
|
||||
/** Obtains an array view that is a view over the last 'Count' elements of this array view. */
|
||||
NODISCARD FORCEINLINE constexpr TArrayView<ElementType, DynamicExtent> Last(size_t Count) const
|
||||
NODISCARD FORCEINLINE constexpr TArrayView<FElementType, DynamicExtent> Last(size_t Count) const
|
||||
{
|
||||
checkf(Count <= Num(), TEXT("Illegal subview range. Please check Count."));
|
||||
|
||||
return TArrayView<ElementType, DynamicExtent>(End() - Count, Count);
|
||||
return TArrayView<FElementType, DynamicExtent>(End() - Count, Count);
|
||||
}
|
||||
|
||||
/** Obtains an array view that is a view over the 'Count' elements of this array view starting at 'Offset'. */
|
||||
@ -198,11 +198,11 @@ public:
|
||||
|
||||
if constexpr (Count != DynamicExtent)
|
||||
{
|
||||
return TArrayView<ElementType, SubviewExtent>(Begin() + Offset, Count);
|
||||
return TArrayView<FElementType, SubviewExtent>(Begin() + Offset, Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
return TArrayView<ElementType, SubviewExtent>(Begin() + Offset, Num() - Offset);
|
||||
return TArrayView<FElementType, SubviewExtent>(Begin() + Offset, Num() - Offset);
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,20 +213,20 @@ public:
|
||||
|
||||
if (Count != DynamicExtent)
|
||||
{
|
||||
return TArrayView<ElementType, DynamicExtent>(Begin() + Offset, Count);
|
||||
return TArrayView<FElementType, DynamicExtent>(Begin() + Offset, Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
return TArrayView<ElementType, DynamicExtent>(Begin() + Offset, Num() - Offset);
|
||||
return TArrayView<FElementType, DynamicExtent>(Begin() + Offset, Num() - Offset);
|
||||
}
|
||||
}
|
||||
|
||||
/** Obtains an array view to the object representation of the elements of the array view. */
|
||||
NODISCARD FORCEINLINE constexpr auto AsBytes()
|
||||
{
|
||||
constexpr size_t BytesExtent = Extent != DynamicExtent ? sizeof(ElementType) * Extent : DynamicExtent;
|
||||
constexpr size_t BytesExtent = Extent != DynamicExtent ? sizeof(FElementType) * Extent : DynamicExtent;
|
||||
|
||||
if constexpr (!CConst<ElementType>)
|
||||
if constexpr (!CConst<FElementType>)
|
||||
{
|
||||
return TArrayView<uint8, BytesExtent>(reinterpret_cast<uint8*>(GetData()), NumBytes());
|
||||
}
|
||||
@ -239,47 +239,47 @@ public:
|
||||
/** Obtains an array view to the object representation of the elements of the array view. */
|
||||
NODISCARD FORCEINLINE constexpr auto AsBytes() const
|
||||
{
|
||||
constexpr size_t BytesExtent = Extent != DynamicExtent ? sizeof(ElementType) * Extent : DynamicExtent;
|
||||
constexpr size_t BytesExtent = Extent != DynamicExtent ? sizeof(FElementType) * Extent : DynamicExtent;
|
||||
|
||||
return TArrayView<const uint8, BytesExtent>(reinterpret_cast<const uint8*>(GetData()), NumBytes());
|
||||
}
|
||||
|
||||
/** @return The pointer to the underlying element storage. */
|
||||
NODISCARD FORCEINLINE constexpr ElementType* GetData() const { return Impl.Pointer; }
|
||||
NODISCARD FORCEINLINE constexpr FElementType* GetData() const { return Impl.Pointer; }
|
||||
|
||||
/** @return The iterator to the first or end element. */
|
||||
NODISCARD FORCEINLINE constexpr Iterator Begin() const { return Iterator(this, Impl.Pointer); }
|
||||
NODISCARD FORCEINLINE constexpr Iterator End() const { return Iterator(this, Impl.Pointer + Num()); }
|
||||
NODISCARD FORCEINLINE constexpr FIterator Begin() const { return FIterator(this, Impl.Pointer); }
|
||||
NODISCARD FORCEINLINE constexpr FIterator End() const { return FIterator(this, Impl.Pointer + Num()); }
|
||||
|
||||
/** @return The reverse iterator to the first or end element. */
|
||||
NODISCARD FORCEINLINE constexpr ReverseIterator RBegin() const { return ReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE constexpr ReverseIterator REnd() const { return ReverseIterator(Begin()); }
|
||||
NODISCARD FORCEINLINE constexpr FReverseIterator RBegin() const { return FReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE constexpr FReverseIterator REnd() const { return FReverseIterator(Begin()); }
|
||||
|
||||
/** @return The number of elements in the container. */
|
||||
NODISCARD FORCEINLINE constexpr size_t Num() const { if constexpr (Extent == DynamicExtent) { return Impl.ArrayNum; } return Extent; }
|
||||
|
||||
/** @return The number of bytes in the container. */
|
||||
NODISCARD FORCEINLINE constexpr size_t NumBytes() const { return Num() * sizeof(ElementType); }
|
||||
NODISCARD FORCEINLINE constexpr size_t NumBytes() const { return Num() * sizeof(FElementType); }
|
||||
|
||||
/** @return true if the container is empty, false otherwise. */
|
||||
NODISCARD FORCEINLINE constexpr bool IsEmpty() const { return Num() == 0; }
|
||||
|
||||
/** @return true if the iterator is valid, false otherwise. */
|
||||
NODISCARD FORCEINLINE constexpr bool IsValidIterator(Iterator Iter) const { return Begin() <= Iter && Iter <= End(); }
|
||||
NODISCARD FORCEINLINE constexpr bool IsValidIterator(FIterator Iter) const { return Begin() <= Iter && Iter <= End(); }
|
||||
|
||||
/** @return The reference to the requested element. */
|
||||
NODISCARD FORCEINLINE constexpr Reference operator[](size_t Index) const { checkf(Index < Num(), TEXT("Read access violation. Please check IsValidIterator().")); return Impl.Pointer[Index]; }
|
||||
NODISCARD FORCEINLINE constexpr FReference operator[](size_t Index) const { checkf(Index < Num(), TEXT("Read access violation. Please check IsValidIterator().")); return Impl.Pointer[Index]; }
|
||||
|
||||
/** @return The reference to the first or last element. */
|
||||
NODISCARD FORCEINLINE constexpr Reference Front() const { return *Begin(); }
|
||||
NODISCARD FORCEINLINE constexpr Reference Back() const { return *(End() - 1); }
|
||||
NODISCARD FORCEINLINE constexpr FReference Front() const { return *Begin(); }
|
||||
NODISCARD FORCEINLINE constexpr FReference Back() const { return *(End() - 1); }
|
||||
|
||||
/** Overloads the GetTypeHash algorithm for TArrayView. */
|
||||
NODISCARD friend FORCEINLINE constexpr size_t GetTypeHash(TArrayView A) requires (CHashable<ElementType>)
|
||||
NODISCARD friend FORCEINLINE constexpr size_t GetTypeHash(TArrayView A) requires (CHashable<FElementType>)
|
||||
{
|
||||
size_t Result = 0;
|
||||
|
||||
for (Iterator Iter = A.Begin(); Iter != A.End(); ++Iter)
|
||||
for (FIterator Iter = A.Begin(); Iter != A.End(); ++Iter)
|
||||
{
|
||||
Result = HashCombine(Result, GetTypeHash(*Iter));
|
||||
}
|
||||
@ -291,7 +291,7 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
struct FImplWithoutNum { ElementType* Pointer; };
|
||||
struct FImplWithoutNum { FElementType* Pointer; };
|
||||
|
||||
struct FImplWithNum : FImplWithoutNum { size_t ArrayNum; };
|
||||
|
||||
@ -299,42 +299,42 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
class Iterator final
|
||||
class FIterator final
|
||||
{
|
||||
public:
|
||||
|
||||
using ElementType = TRemoveCV<T>;
|
||||
using FElementType = TRemoveCV<T>;
|
||||
|
||||
FORCEINLINE constexpr Iterator() = default;
|
||||
FORCEINLINE constexpr Iterator(const Iterator&) = default;
|
||||
FORCEINLINE constexpr Iterator(Iterator&&) = default;
|
||||
FORCEINLINE constexpr Iterator& operator=(const Iterator&) = default;
|
||||
FORCEINLINE constexpr Iterator& operator=(Iterator&&) = default;
|
||||
FORCEINLINE constexpr FIterator() = default;
|
||||
FORCEINLINE constexpr FIterator(const FIterator&) = default;
|
||||
FORCEINLINE constexpr FIterator(FIterator&&) = default;
|
||||
FORCEINLINE constexpr FIterator& operator=(const FIterator&) = default;
|
||||
FORCEINLINE constexpr FIterator& operator=(FIterator&&) = default;
|
||||
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const Iterator& LHS, const Iterator& RHS) { return LHS.Pointer == RHS.Pointer; }
|
||||
NODISCARD friend FORCEINLINE constexpr bool operator==(const FIterator& LHS, const FIterator& RHS) { return LHS.Pointer == RHS.Pointer; }
|
||||
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const Iterator& LHS, const Iterator& RHS) { return LHS.Pointer <=> RHS.Pointer; }
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const FIterator& LHS, const FIterator& RHS) { return LHS.Pointer <=> RHS.Pointer; }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr T& operator*() const { CheckThis(true ); return *Pointer; }
|
||||
NODISCARD FORCEINLINE constexpr T* operator->() const { CheckThis(false); return Pointer; }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr T& operator[](ptrdiff Index) const { Iterator Temp = *this + Index; return *Temp; }
|
||||
NODISCARD FORCEINLINE constexpr T& operator[](ptrdiff Index) const { FIterator Temp = *this + Index; return *Temp; }
|
||||
|
||||
FORCEINLINE constexpr Iterator& operator++() { ++Pointer; CheckThis(); return *this; }
|
||||
FORCEINLINE constexpr Iterator& operator--() { --Pointer; CheckThis(); return *this; }
|
||||
FORCEINLINE constexpr FIterator& operator++() { ++Pointer; CheckThis(); return *this; }
|
||||
FORCEINLINE constexpr FIterator& operator--() { --Pointer; CheckThis(); return *this; }
|
||||
|
||||
FORCEINLINE constexpr Iterator operator++(int) { Iterator Temp = *this; ++*this; return Temp; }
|
||||
FORCEINLINE constexpr Iterator operator--(int) { Iterator Temp = *this; --*this; return Temp; }
|
||||
FORCEINLINE constexpr FIterator operator++(int) { FIterator Temp = *this; ++*this; return Temp; }
|
||||
FORCEINLINE constexpr FIterator operator--(int) { FIterator Temp = *this; --*this; return Temp; }
|
||||
|
||||
FORCEINLINE constexpr Iterator& operator+=(ptrdiff Offset) { Pointer += Offset; CheckThis(); return *this; }
|
||||
FORCEINLINE constexpr Iterator& operator-=(ptrdiff Offset) { Pointer -= Offset; CheckThis(); return *this; }
|
||||
FORCEINLINE constexpr FIterator& operator+=(ptrdiff Offset) { Pointer += Offset; CheckThis(); return *this; }
|
||||
FORCEINLINE constexpr FIterator& operator-=(ptrdiff Offset) { Pointer -= Offset; CheckThis(); return *this; }
|
||||
|
||||
NODISCARD friend FORCEINLINE constexpr Iterator operator+(Iterator Iter, ptrdiff Offset) { Iterator Temp = Iter; Temp += Offset; return Temp; }
|
||||
NODISCARD friend FORCEINLINE constexpr Iterator operator+(ptrdiff Offset, Iterator Iter) { Iterator Temp = Iter; Temp += Offset; return Temp; }
|
||||
NODISCARD friend FORCEINLINE constexpr FIterator operator+(FIterator Iter, ptrdiff Offset) { FIterator Temp = Iter; Temp += Offset; return Temp; }
|
||||
NODISCARD friend FORCEINLINE constexpr FIterator operator+(ptrdiff Offset, FIterator Iter) { FIterator Temp = Iter; Temp += Offset; return Temp; }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr Iterator operator-(ptrdiff Offset) const { Iterator Temp = *this; Temp -= Offset; return Temp; }
|
||||
NODISCARD FORCEINLINE constexpr FIterator operator-(ptrdiff Offset) const { FIterator Temp = *this; Temp -= Offset; return Temp; }
|
||||
|
||||
NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const Iterator& LHS, const Iterator& RHS) { LHS.CheckThis(); RHS.CheckThis(); return LHS.Pointer - RHS.Pointer; }
|
||||
NODISCARD friend FORCEINLINE constexpr ptrdiff operator-(const FIterator& LHS, const FIterator& RHS) { LHS.CheckThis(); RHS.CheckThis(); return LHS.Pointer - RHS.Pointer; }
|
||||
|
||||
private:
|
||||
|
||||
@ -345,11 +345,11 @@ public:
|
||||
T* Pointer = nullptr;
|
||||
|
||||
# if DO_CHECK
|
||||
FORCEINLINE constexpr Iterator(const TArrayView* InContainer, T* InPointer)
|
||||
FORCEINLINE constexpr FIterator(const TArrayView* InContainer, T* InPointer)
|
||||
: Owner(InContainer), Pointer(InPointer)
|
||||
{ }
|
||||
# else
|
||||
FORCEINLINE constexpr Iterator(const TArrayView* InContainer, T* InPointer)
|
||||
FORCEINLINE constexpr FIterator(const TArrayView* InContainer, T* InPointer)
|
||||
: Pointer(InPointer)
|
||||
{ }
|
||||
# endif
|
||||
|
@ -30,23 +30,23 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
using BlockType = InBlockType;
|
||||
using ElementType = bool;
|
||||
using AllocatorType = Allocator;
|
||||
using FBlockType = InBlockType;
|
||||
using FElementType = bool;
|
||||
using FAllocatorType = Allocator;
|
||||
|
||||
class Reference;
|
||||
using ConstReference = bool;
|
||||
class FReference;
|
||||
using FConstReference = bool;
|
||||
|
||||
using Iterator = TIteratorImpl<false>;
|
||||
using ConstIterator = TIteratorImpl<true >;
|
||||
using FIterator = TIteratorImpl<false>;
|
||||
using FConstIterator = TIteratorImpl<true >;
|
||||
|
||||
using ReverseIterator = TReverseIterator< Iterator>;
|
||||
using ConstReverseIterator = TReverseIterator<ConstIterator>;
|
||||
using FReverseIterator = TReverseIterator< FIterator>;
|
||||
using FConstReverseIterator = TReverseIterator<FConstIterator>;
|
||||
|
||||
static_assert(CRandomAccessIterator< Iterator>);
|
||||
static_assert(CRandomAccessIterator<ConstIterator>);
|
||||
static_assert(CRandomAccessIterator< FIterator>);
|
||||
static_assert(CRandomAccessIterator<FConstIterator>);
|
||||
|
||||
static constexpr size_t BlockWidth = sizeof(BlockType) * 8;
|
||||
static constexpr size_t BlockWidth = sizeof(FBlockType) * 8;
|
||||
|
||||
/** Default constructor. Constructs an empty bitset. */
|
||||
FORCEINLINE TBitset() : TBitset(0) { }
|
||||
@ -62,40 +62,40 @@ public:
|
||||
/** Constructs a bitset from an integer. */
|
||||
TBitset(size_t InCount, uint64 InValue) : TBitset(InCount > 64 ? InCount : 64)
|
||||
{
|
||||
static_assert(sizeof(BlockType) <= sizeof(uint64), "The block width of TBitset is unexpected");
|
||||
static_assert(sizeof(FBlockType) <= sizeof(uint64), "The block width of TBitset is unexpected");
|
||||
|
||||
if constexpr (sizeof(BlockType) == sizeof(uint8))
|
||||
if constexpr (sizeof(FBlockType) == sizeof(uint8))
|
||||
{
|
||||
Impl.Pointer[0] = static_cast<BlockType>(InValue >> 0);
|
||||
Impl.Pointer[1] = static_cast<BlockType>(InValue >> 8);
|
||||
Impl.Pointer[2] = static_cast<BlockType>(InValue >> 16);
|
||||
Impl.Pointer[3] = static_cast<BlockType>(InValue >> 24);
|
||||
Impl.Pointer[4] = static_cast<BlockType>(InValue >> 32);
|
||||
Impl.Pointer[5] = static_cast<BlockType>(InValue >> 40);
|
||||
Impl.Pointer[6] = static_cast<BlockType>(InValue >> 48);
|
||||
Impl.Pointer[7] = static_cast<BlockType>(InValue >> 56);
|
||||
Impl.Pointer[0] = static_cast<FBlockType>(InValue >> 0);
|
||||
Impl.Pointer[1] = static_cast<FBlockType>(InValue >> 8);
|
||||
Impl.Pointer[2] = static_cast<FBlockType>(InValue >> 16);
|
||||
Impl.Pointer[3] = static_cast<FBlockType>(InValue >> 24);
|
||||
Impl.Pointer[4] = static_cast<FBlockType>(InValue >> 32);
|
||||
Impl.Pointer[5] = static_cast<FBlockType>(InValue >> 40);
|
||||
Impl.Pointer[6] = static_cast<FBlockType>(InValue >> 48);
|
||||
Impl.Pointer[7] = static_cast<FBlockType>(InValue >> 56);
|
||||
}
|
||||
else if constexpr (sizeof(BlockType) == sizeof(uint16))
|
||||
else if constexpr (sizeof(FBlockType) == sizeof(uint16))
|
||||
{
|
||||
Impl.Pointer[0] = static_cast<BlockType>(InValue >> 0);
|
||||
Impl.Pointer[1] = static_cast<BlockType>(InValue >> 16);
|
||||
Impl.Pointer[2] = static_cast<BlockType>(InValue >> 32);
|
||||
Impl.Pointer[3] = static_cast<BlockType>(InValue >> 48);
|
||||
Impl.Pointer[0] = static_cast<FBlockType>(InValue >> 0);
|
||||
Impl.Pointer[1] = static_cast<FBlockType>(InValue >> 16);
|
||||
Impl.Pointer[2] = static_cast<FBlockType>(InValue >> 32);
|
||||
Impl.Pointer[3] = static_cast<FBlockType>(InValue >> 48);
|
||||
}
|
||||
else if constexpr (sizeof(BlockType) == sizeof(uint32))
|
||||
else if constexpr (sizeof(FBlockType) == sizeof(uint32))
|
||||
{
|
||||
Impl.Pointer[0] = static_cast<BlockType>(InValue >> 0);
|
||||
Impl.Pointer[1] = static_cast<BlockType>(InValue >> 32);
|
||||
Impl.Pointer[0] = static_cast<FBlockType>(InValue >> 0);
|
||||
Impl.Pointer[1] = static_cast<FBlockType>(InValue >> 32);
|
||||
}
|
||||
else if constexpr (sizeof(BlockType) == sizeof(uint64))
|
||||
else if constexpr (sizeof(FBlockType) == sizeof(uint64))
|
||||
{
|
||||
Impl.Pointer[0] = static_cast<BlockType>(InValue >> 0);
|
||||
Impl.Pointer[0] = static_cast<FBlockType>(InValue >> 0);
|
||||
}
|
||||
else check_no_entry();
|
||||
|
||||
size_t BlockInteger = sizeof(uint64) / sizeof(BlockType);
|
||||
size_t BlockInteger = sizeof(uint64) / sizeof(FBlockType);
|
||||
|
||||
Memory::Memset(Impl.Pointer + BlockInteger, 0, (NumBlocks() - BlockInteger) * sizeof(BlockType));
|
||||
Memory::Memset(Impl.Pointer + BlockInteger, 0, (NumBlocks() - BlockInteger) * sizeof(FBlockType));
|
||||
|
||||
Impl.BitsetNum = InCount;
|
||||
}
|
||||
@ -112,9 +112,7 @@ public:
|
||||
|
||||
new (this) TBitset(InCount);
|
||||
|
||||
BlockType* CurrentBlock = Impl.Pointer - 1;
|
||||
|
||||
for (Reference Ref: *this) Ref = *First++;
|
||||
for (FReference Ref: *this) Ref = *First++;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -135,7 +133,7 @@ public:
|
||||
Impl.BlocksMax = Impl->CalculateSlackReserve(NumBlocks());
|
||||
Impl.Pointer = Impl->Allocate(MaxBlocks());
|
||||
|
||||
Memory::Memcpy(Impl.Pointer, InValue.Impl.Pointer, NumBlocks() * sizeof(BlockType));
|
||||
Memory::Memcpy(Impl.Pointer, InValue.Impl.Pointer, NumBlocks() * sizeof(FBlockType));
|
||||
}
|
||||
|
||||
/** Move constructor. After the move, 'InValue' is guaranteed to be empty. */
|
||||
@ -157,7 +155,7 @@ public:
|
||||
Impl.BlocksMax = Impl->CalculateSlackReserve(NumBlocks());
|
||||
Impl.Pointer = Impl->Allocate(MaxBlocks());
|
||||
|
||||
Memory::Memcpy(Impl.Pointer, InValue.Impl.Pointer, NumBlocks() * sizeof(BlockType));
|
||||
Memory::Memcpy(Impl.Pointer, InValue.Impl.Pointer, NumBlocks() * sizeof(FBlockType));
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,7 +186,7 @@ public:
|
||||
Impl.BlocksMax = NumToAllocate;
|
||||
Impl.Pointer = Impl->Allocate(MaxBlocks());
|
||||
|
||||
Memory::Memcpy(Impl.Pointer, InValue.Impl.Pointer, NumBlocks() * sizeof(BlockType));
|
||||
Memory::Memcpy(Impl.Pointer, InValue.Impl.Pointer, NumBlocks() * sizeof(FBlockType));
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -197,7 +195,7 @@ public:
|
||||
|
||||
Impl.BitsetNum = InValue.Num();
|
||||
|
||||
Memory::Memcpy(Impl.Pointer, InValue.Impl.Pointer, NumBlocks() * sizeof(BlockType));
|
||||
Memory::Memcpy(Impl.Pointer, InValue.Impl.Pointer, NumBlocks() * sizeof(FBlockType));
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -247,14 +245,14 @@ public:
|
||||
Impl.BlocksMax = NumToAllocate;
|
||||
Impl.Pointer = Impl->Allocate(MaxBlocks());
|
||||
|
||||
for (Reference Ref : *this) Ref = *First++;
|
||||
for (FReference Ref : *this) Ref = *First++;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Impl.BitsetNum = GetNum(IL);
|
||||
|
||||
for (Reference Ref : *this) Ref = *First++;
|
||||
for (FReference Ref : *this) Ref = *First++;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -271,7 +269,7 @@ public:
|
||||
if (LHS.Impl.Pointer[Index] != RHS.Impl.Pointer[Index]) return false;
|
||||
}
|
||||
|
||||
const BlockType LastBlockBitmask = LHS.Num() % BlockWidth != 0 ? (1ull << LHS.Num() % BlockWidth) - 1 : -1;
|
||||
const FBlockType LastBlockBitmask = LHS.Num() % BlockWidth != 0 ? (1ull << LHS.Num() % BlockWidth) - 1 : -1;
|
||||
|
||||
return (LHS.Impl.Pointer[LHS.NumBlocks() - 1] & LastBlockBitmask) == (RHS.Impl.Pointer[LHS.NumBlocks() - 1] & LastBlockBitmask);
|
||||
}
|
||||
@ -301,7 +299,7 @@ public:
|
||||
Impl.Pointer[Index] &= InValue.Impl.Pointer[Index];
|
||||
}
|
||||
|
||||
const BlockType LastBlockBitmask = InValue.Num() % BlockWidth != 0 ? (1ull << InValue.Num() % BlockWidth) - 1 : -1;
|
||||
const FBlockType LastBlockBitmask = InValue.Num() % BlockWidth != 0 ? (1ull << InValue.Num() % BlockWidth) - 1 : -1;
|
||||
|
||||
Impl.Pointer[LastBlock] &= InValue.Impl.Pointer[LastBlock] & LastBlockBitmask;
|
||||
|
||||
@ -339,7 +337,7 @@ public:
|
||||
Impl.Pointer[Index] |= InValue.Impl.Pointer[Index];
|
||||
}
|
||||
|
||||
const BlockType LastBlockBitmask = InValue.Num() % BlockWidth != 0 ? (1ull << InValue.Num() % BlockWidth) - 1 : -1;
|
||||
const FBlockType LastBlockBitmask = InValue.Num() % BlockWidth != 0 ? (1ull << InValue.Num() % BlockWidth) - 1 : -1;
|
||||
|
||||
Impl.Pointer[LastBlock] |= InValue.Impl.Pointer[LastBlock] & LastBlockBitmask;
|
||||
}
|
||||
@ -372,7 +370,7 @@ public:
|
||||
Impl.Pointer[Index] ^= InValue.Impl.Pointer[Index];
|
||||
}
|
||||
|
||||
const BlockType LastBlockBitmask = InValue.Num() % BlockWidth != 0 ? (1ull << InValue.Num() % BlockWidth) - 1 : -1;
|
||||
const FBlockType LastBlockBitmask = InValue.Num() % BlockWidth != 0 ? (1ull << InValue.Num() % BlockWidth) - 1 : -1;
|
||||
|
||||
Impl.Pointer[LastBlock] ^= InValue.Impl.Pointer[LastBlock] & LastBlockBitmask;
|
||||
}
|
||||
@ -473,7 +471,7 @@ public:
|
||||
if (Impl.Pointer[Index] != -1) return false;
|
||||
}
|
||||
|
||||
const BlockType LastBlockBitmask = Num() % BlockWidth != 0 ? (1ull << Num() % BlockWidth) - 1 : -1;
|
||||
const FBlockType LastBlockBitmask = Num() % BlockWidth != 0 ? (1ull << Num() % BlockWidth) - 1 : -1;
|
||||
|
||||
return (Impl.Pointer[NumBlocks() - 1] | ~LastBlockBitmask) == -1;
|
||||
}
|
||||
@ -488,7 +486,7 @@ public:
|
||||
if (Impl.Pointer[Index] != 0) return true;
|
||||
}
|
||||
|
||||
const BlockType LastBlockBitmask = Num() % BlockWidth != 0 ? (1ull << Num() % BlockWidth) - 1 : -1;
|
||||
const FBlockType LastBlockBitmask = Num() % BlockWidth != 0 ? (1ull << Num() % BlockWidth) - 1 : -1;
|
||||
|
||||
return (Impl.Pointer[NumBlocks() - 1] & LastBlockBitmask) != 0;
|
||||
}
|
||||
@ -503,24 +501,24 @@ public:
|
||||
|
||||
size_t Result = 0;
|
||||
|
||||
constexpr auto BlockCount = [](BlockType Block)
|
||||
constexpr auto BlockCount = [](FBlockType Block)
|
||||
{
|
||||
static_assert(sizeof(BlockType) <= sizeof(uint64), "The block width of TBitset is unexpected");
|
||||
static_assert(sizeof(FBlockType) <= sizeof(uint64), "The block width of TBitset is unexpected");
|
||||
|
||||
if constexpr (sizeof(BlockType) == sizeof(uint8))
|
||||
if constexpr (sizeof(FBlockType) == sizeof(uint8))
|
||||
{
|
||||
Block = (Block & 0x55ull) + ((Block >> 1) & 0x55ull);
|
||||
Block = (Block & 0x33ull) + ((Block >> 2) & 0x33ull);
|
||||
Block = (Block & 0x0Full) + ((Block >> 4) & 0x0Full);
|
||||
}
|
||||
else if constexpr (sizeof(BlockType) == sizeof(uint16))
|
||||
else if constexpr (sizeof(FBlockType) == sizeof(uint16))
|
||||
{
|
||||
Block = (Block & 0x5555ull) + ((Block >> 1) & 0x5555ull);
|
||||
Block = (Block & 0x3333ull) + ((Block >> 2) & 0x3333ull);
|
||||
Block = (Block & 0x0F0Full) + ((Block >> 4) & 0x0F0Full);
|
||||
Block = (Block & 0x00FFull) + ((Block >> 8) & 0x00FFull);
|
||||
}
|
||||
else if constexpr (sizeof(BlockType) == sizeof(uint32))
|
||||
else if constexpr (sizeof(FBlockType) == sizeof(uint32))
|
||||
{
|
||||
Block = (Block & 0x55555555ull) + ((Block >> 1) & 0x55555555ull);
|
||||
Block = (Block & 0x33333333ull) + ((Block >> 2) & 0x33333333ull);
|
||||
@ -528,7 +526,7 @@ public:
|
||||
Block = (Block & 0x00FF00FFull) + ((Block >> 8) & 0x00FF00FFull);
|
||||
Block = (Block & 0x0000FFFFull) + ((Block >> 16) & 0x0000FFFFull);
|
||||
}
|
||||
else if constexpr (sizeof(BlockType) == sizeof(uint64))
|
||||
else if constexpr (sizeof(FBlockType) == sizeof(uint64))
|
||||
{
|
||||
Block = (Block & 0x5555555555555555ull) + ((Block >> 1) & 0x5555555555555555ull);
|
||||
Block = (Block & 0x3333333333333333ull) + ((Block >> 2) & 0x3333333333333333ull);
|
||||
@ -547,7 +545,7 @@ public:
|
||||
Result += BlockCount(Impl.Pointer[Index]);
|
||||
}
|
||||
|
||||
const BlockType LastBlockBitmask = Num() % BlockWidth != 0 ? (1ull << Num() % BlockWidth) - 1 : -1;
|
||||
const FBlockType LastBlockBitmask = Num() % BlockWidth != 0 ? (1ull << Num() % BlockWidth) - 1 : -1;
|
||||
|
||||
Result += BlockCount(Impl.Pointer[NumBlocks() - 1] & LastBlockBitmask);
|
||||
|
||||
@ -557,7 +555,7 @@ public:
|
||||
/** Sets all bits to true. */
|
||||
TBitset& Set(bool InValue = true)
|
||||
{
|
||||
Memory::Memset(Impl.Pointer, static_cast<uint8>(InValue ? -1 : 0), NumBlocks() * sizeof(BlockType));
|
||||
Memory::Memset(Impl.Pointer, static_cast<uint8>(InValue ? -1 : 0), NumBlocks() * sizeof(FBlockType));
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -591,17 +589,17 @@ public:
|
||||
checkf(Impl.Pointer[Index] != 0, TEXT("The bitset can not be represented in uint64. Please check Num()."));
|
||||
}
|
||||
|
||||
const BlockType LastBlockBitmask = Num() % BlockWidth != 0 ? (1ull << Num() % BlockWidth) - 1 : -1;
|
||||
const BlockType LastBlock = Impl.Pointer[NumBlocks() - 1] & LastBlockBitmask;
|
||||
const FBlockType LastBlockBitmask = Num() % BlockWidth != 0 ? (1ull << Num() % BlockWidth) - 1 : -1;
|
||||
const FBlockType LastBlock = Impl.Pointer[NumBlocks() - 1] & LastBlockBitmask;
|
||||
|
||||
checkf(LastBlock != 0, TEXT("The bitset can not be represented in uint64. Please check Num()."));
|
||||
}
|
||||
|
||||
uint64 Result = 0;
|
||||
|
||||
static_assert(sizeof(BlockType) <= sizeof(uint64), "The block width of TBitset is unexpected");
|
||||
static_assert(sizeof(FBlockType) <= sizeof(uint64), "The block width of TBitset is unexpected");
|
||||
|
||||
if constexpr (sizeof(BlockType) == sizeof(uint8))
|
||||
if constexpr (sizeof(FBlockType) == sizeof(uint8))
|
||||
{
|
||||
Result |= static_cast<uint64>(Impl.Pointer[0]) << 0;
|
||||
Result |= static_cast<uint64>(Impl.Pointer[1]) << 8;
|
||||
@ -612,19 +610,19 @@ public:
|
||||
Result |= static_cast<uint64>(Impl.Pointer[6]) << 48;
|
||||
Result |= static_cast<uint64>(Impl.Pointer[7]) << 56;
|
||||
}
|
||||
else if constexpr (sizeof(BlockType) == sizeof(uint16))
|
||||
else if constexpr (sizeof(FBlockType) == sizeof(uint16))
|
||||
{
|
||||
Result |= static_cast<uint64>(Impl.Pointer[0]) << 0;
|
||||
Result |= static_cast<uint64>(Impl.Pointer[1]) << 16;
|
||||
Result |= static_cast<uint64>(Impl.Pointer[2]) << 32;
|
||||
Result |= static_cast<uint64>(Impl.Pointer[3]) << 48;
|
||||
}
|
||||
else if constexpr (sizeof(BlockType) == sizeof(uint32))
|
||||
else if constexpr (sizeof(FBlockType) == sizeof(uint32))
|
||||
{
|
||||
Result |= static_cast<uint64>(Impl.Pointer[0]) << 0;
|
||||
Result |= static_cast<uint64>(Impl.Pointer[1]) << 32;
|
||||
}
|
||||
else if constexpr (sizeof(BlockType) == sizeof(uint64))
|
||||
else if constexpr (sizeof(FBlockType) == sizeof(uint64))
|
||||
{
|
||||
Result |= static_cast<uint64>(Impl.Pointer[0]) << 0;
|
||||
}
|
||||
@ -661,7 +659,7 @@ public:
|
||||
|
||||
if (NumToAllocate != MaxBlocks())
|
||||
{
|
||||
BlockType* OldAllocation = Impl.Pointer;
|
||||
FBlockType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = NumBlocks();
|
||||
|
||||
Impl.BitsetNum = InCount;
|
||||
@ -670,11 +668,11 @@ public:
|
||||
|
||||
if (NumToDestruct <= Num())
|
||||
{
|
||||
Memory::Memcpy(Impl.Pointer, OldAllocation, NumToDestruct * sizeof(BlockType));
|
||||
Memory::Memcpy(Impl.Pointer, OldAllocation, NumToDestruct * sizeof(FBlockType));
|
||||
}
|
||||
else
|
||||
{
|
||||
Memory::Memcpy(Impl.Pointer, OldAllocation, BlocksCount * sizeof(BlockType));
|
||||
Memory::Memcpy(Impl.Pointer, OldAllocation, BlocksCount * sizeof(FBlockType));
|
||||
}
|
||||
|
||||
Impl->Deallocate(OldAllocation);
|
||||
@ -697,12 +695,12 @@ public:
|
||||
NumToAllocate = NumToAllocate > MaxBlocks() ? Impl->CalculateSlackGrow(BlocksCount, MaxBlocks()) : NumToAllocate;
|
||||
NumToAllocate = NumToAllocate < MaxBlocks() ? (bAllowShrinking ? Impl->CalculateSlackShrink(BlocksCount, MaxBlocks()) : MaxBlocks()) : NumToAllocate;
|
||||
|
||||
const BlockType LastBlockBitmask = Num() % BlockWidth != 0 ? (1ull << Num() % BlockWidth) - 1 : -1;
|
||||
const BlockType BlocksValueToSet = static_cast<BlockType>(InValue ? -1 : 0);
|
||||
const FBlockType LastBlockBitmask = Num() % BlockWidth != 0 ? (1ull << Num() % BlockWidth) - 1 : -1;
|
||||
const FBlockType BlocksValueToSet = static_cast<FBlockType>(InValue ? -1 : 0);
|
||||
|
||||
if (NumToAllocate != MaxBlocks())
|
||||
{
|
||||
BlockType* OldAllocation = Impl.Pointer;
|
||||
FBlockType* OldAllocation = Impl.Pointer;
|
||||
const size_t NumToDestruct = NumBlocks();
|
||||
|
||||
Impl.BitsetNum = InCount;
|
||||
@ -713,16 +711,16 @@ public:
|
||||
{
|
||||
if (NumToDestruct != 0)
|
||||
{
|
||||
Memory::Memcpy(Impl.Pointer, OldAllocation, (NumToDestruct - 1) * sizeof(BlockType));
|
||||
Memory::Memcpy(Impl.Pointer, OldAllocation, (NumToDestruct - 1) * sizeof(FBlockType));
|
||||
|
||||
Impl.Pointer[NumToDestruct - 1] = OldAllocation[NumToDestruct - 1] & LastBlockBitmask | BlocksValueToSet & ~LastBlockBitmask;
|
||||
}
|
||||
|
||||
Memory::Memset(Impl.Pointer + NumToDestruct, static_cast<uint8>(BlocksValueToSet), (BlocksCount - NumToDestruct) * sizeof(BlockType));
|
||||
Memory::Memset(Impl.Pointer + NumToDestruct, static_cast<uint8>(BlocksValueToSet), (BlocksCount - NumToDestruct) * sizeof(FBlockType));
|
||||
}
|
||||
else
|
||||
{
|
||||
Memory::Memcpy(Impl.Pointer, OldAllocation, BlocksCount * sizeof(BlockType));
|
||||
Memory::Memcpy(Impl.Pointer, OldAllocation, BlocksCount * sizeof(FBlockType));
|
||||
}
|
||||
|
||||
Impl->Deallocate(OldAllocation);
|
||||
@ -739,7 +737,7 @@ public:
|
||||
Impl.Pointer[NumBlocks() - 1] = Impl.Pointer[NumBlocks() - 1] & LastBlockBitmask | BlocksValueToSet & ~LastBlockBitmask;
|
||||
}
|
||||
|
||||
Memory::Memset(Impl.Pointer + NumBlocks(), static_cast<uint8>(BlocksValueToSet), (BlocksCount - NumBlocks()) * sizeof(BlockType));
|
||||
Memory::Memset(Impl.Pointer + NumBlocks(), static_cast<uint8>(BlocksValueToSet), (BlocksCount - NumBlocks()) * sizeof(FBlockType));
|
||||
}
|
||||
|
||||
Impl.BitsetNum = InCount;
|
||||
@ -753,14 +751,14 @@ public:
|
||||
const size_t BlocksCount = (InCount + BlockWidth - 1) / BlockWidth;
|
||||
|
||||
const size_t NumToAllocate = Impl->CalculateSlackReserve(BlocksCount);
|
||||
BlockType* OldAllocation = Impl.Pointer;
|
||||
FBlockType* OldAllocation = Impl.Pointer;
|
||||
|
||||
check(NumToAllocate > MaxBlocks());
|
||||
|
||||
Impl.BlocksMax = NumToAllocate;
|
||||
Impl.Pointer = Impl->Allocate(MaxBlocks());
|
||||
|
||||
Memory::Memcpy(Impl.Pointer, OldAllocation, NumBlocks() * sizeof(BlockType));
|
||||
Memory::Memcpy(Impl.Pointer, OldAllocation, NumBlocks() * sizeof(FBlockType));
|
||||
|
||||
Impl->Deallocate(OldAllocation);
|
||||
}
|
||||
@ -774,31 +772,31 @@ public:
|
||||
|
||||
if (NumToAllocate == MaxBlocks()) return;
|
||||
|
||||
BlockType* OldAllocation = Impl.Pointer;
|
||||
FBlockType* OldAllocation = Impl.Pointer;
|
||||
|
||||
Impl.BitsetNum = NumToAllocate * BlockWidth;
|
||||
Impl.Pointer = Impl->Allocate(MaxBlocks());
|
||||
|
||||
Memory::Memcpy(Impl.Pointer, OldAllocation, NumBlocks() * sizeof(BlockType));
|
||||
Memory::Memcpy(Impl.Pointer, OldAllocation, NumBlocks() * sizeof(FBlockType));
|
||||
|
||||
Impl->Deallocate(OldAllocation);
|
||||
}
|
||||
|
||||
/** @return The pointer to the underlying element storage. */
|
||||
NODISCARD FORCEINLINE BlockType* GetData() { return Impl.Pointer; }
|
||||
NODISCARD FORCEINLINE const BlockType* GetData() const { return Impl.Pointer; }
|
||||
NODISCARD FORCEINLINE FBlockType* GetData() { return Impl.Pointer; }
|
||||
NODISCARD FORCEINLINE const FBlockType* GetData() const { return Impl.Pointer; }
|
||||
|
||||
/** @return The iterator to the first or end bit. */
|
||||
NODISCARD FORCEINLINE Iterator Begin() { return Iterator(this, Impl.Pointer, 0); }
|
||||
NODISCARD FORCEINLINE ConstIterator Begin() const { return ConstIterator(this, Impl.Pointer, 0); }
|
||||
NODISCARD FORCEINLINE Iterator End() { return Iterator(this, Impl.Pointer, Num()); }
|
||||
NODISCARD FORCEINLINE ConstIterator End() const { return ConstIterator(this, Impl.Pointer, Num()); }
|
||||
NODISCARD FORCEINLINE FIterator Begin() { return FIterator(this, Impl.Pointer, 0); }
|
||||
NODISCARD FORCEINLINE FConstIterator Begin() const { return FConstIterator(this, Impl.Pointer, 0); }
|
||||
NODISCARD FORCEINLINE FIterator End() { return FIterator(this, Impl.Pointer, Num()); }
|
||||
NODISCARD FORCEINLINE FConstIterator End() const { return FConstIterator(this, Impl.Pointer, Num()); }
|
||||
|
||||
/** @return The reverse iterator to the first or end bit. */
|
||||
NODISCARD FORCEINLINE ReverseIterator RBegin() { return ReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE ConstReverseIterator RBegin() const { return ConstReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE ReverseIterator REnd() { return ReverseIterator(Begin()); }
|
||||
NODISCARD FORCEINLINE ConstReverseIterator REnd() const { return ConstReverseIterator(Begin()); }
|
||||
NODISCARD FORCEINLINE FReverseIterator RBegin() { return FReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE FConstReverseIterator RBegin() const { return FConstReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE FReverseIterator REnd() { return FReverseIterator(Begin()); }
|
||||
NODISCARD FORCEINLINE FConstReverseIterator REnd() const { return FConstReverseIterator(Begin()); }
|
||||
|
||||
/** @return The number of bits in the bitset. */
|
||||
NODISCARD FORCEINLINE size_t Num() const { return Impl.BitsetNum; }
|
||||
@ -816,17 +814,17 @@ public:
|
||||
NODISCARD FORCEINLINE bool IsEmpty() const { return Num() == 0; }
|
||||
|
||||
/** @return true if the iterator is valid, false otherwise. */
|
||||
NODISCARD FORCEINLINE bool IsValidIterator(ConstIterator Iter) const { return Begin() <= Iter && Iter <= End(); }
|
||||
NODISCARD FORCEINLINE bool IsValidIterator(FConstIterator Iter) const { return Begin() <= Iter && Iter <= End(); }
|
||||
|
||||
/** @return The reference to the requested bit. */
|
||||
NODISCARD FORCEINLINE Reference operator[](size_t Index) { checkf(Index < Num(), TEXT("Read access violation. Please check IsValidIterator().")); return *(Begin() + Index); }
|
||||
NODISCARD FORCEINLINE ConstReference operator[](size_t Index) const { checkf(Index < Num(), TEXT("Read access violation. Please check IsValidIterator().")); return *(Begin() + Index); }
|
||||
NODISCARD FORCEINLINE FReference operator[](size_t Index) { checkf(Index < Num(), TEXT("Read access violation. Please check IsValidIterator().")); return *(Begin() + Index); }
|
||||
NODISCARD FORCEINLINE FConstReference operator[](size_t Index) const { checkf(Index < Num(), TEXT("Read access violation. Please check IsValidIterator().")); return *(Begin() + Index); }
|
||||
|
||||
/** @return The reference to the first or last bit. */
|
||||
NODISCARD FORCEINLINE Reference Front() { return *Begin(); }
|
||||
NODISCARD FORCEINLINE ConstReference Front() const { return *Begin(); }
|
||||
NODISCARD FORCEINLINE Reference Back() { return *(End() - 1); }
|
||||
NODISCARD FORCEINLINE ConstReference Back() const { return *(End() - 1); }
|
||||
NODISCARD FORCEINLINE FReference Front() { return *Begin(); }
|
||||
NODISCARD FORCEINLINE FConstReference Front() const { return *Begin(); }
|
||||
NODISCARD FORCEINLINE FReference Back() { return *(End() - 1); }
|
||||
NODISCARD FORCEINLINE FConstReference Back() const { return *(End() - 1); }
|
||||
|
||||
/** Erases all bits from the bitset. After this call, Num() returns zero. */
|
||||
void Reset(bool bAllowShrinking = true)
|
||||
@ -859,7 +857,7 @@ public:
|
||||
Result = HashCombine(Result, GetTypeHash(A.Impl.Pointer[Index]));
|
||||
}
|
||||
|
||||
const BlockType LastBlockBitmask = A.Num() % BlockWidth != 0 ? (1ull << A.Num() % BlockWidth) - 1 : -1;
|
||||
const FBlockType LastBlockBitmask = A.Num() % BlockWidth != 0 ? (1ull << A.Num() % BlockWidth) - 1 : -1;
|
||||
|
||||
return HashCombine(Result, GetTypeHash(A.Impl.Pointer[A.NumBlocks() - 1] & LastBlockBitmask));
|
||||
}
|
||||
@ -889,27 +887,27 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
ALLOCATOR_WRAPPER_BEGIN(AllocatorType, BlockType, Impl)
|
||||
ALLOCATOR_WRAPPER_BEGIN(FAllocatorType, FBlockType, Impl)
|
||||
{
|
||||
size_t BitsetNum;
|
||||
size_t BlocksMax;
|
||||
BlockType* Pointer;
|
||||
FBlockType* Pointer;
|
||||
}
|
||||
ALLOCATOR_WRAPPER_END(AllocatorType, BlockType, Impl)
|
||||
ALLOCATOR_WRAPPER_END(FAllocatorType, FBlockType, Impl)
|
||||
|
||||
public:
|
||||
|
||||
class Reference final : private FSingleton
|
||||
class FReference final : private FSingleton
|
||||
{
|
||||
public:
|
||||
|
||||
FORCEINLINE Reference& operator=(bool InValue) { Data = (Data & ~Mask) | (InValue ? Mask : 0); return *this; }
|
||||
FORCEINLINE FReference& operator=(bool InValue) { Data = (Data & ~Mask) | (InValue ? Mask : 0); return *this; }
|
||||
|
||||
FORCEINLINE Reference& operator=(const Reference& InValue) { *this = static_cast<bool>(InValue); return *this; }
|
||||
FORCEINLINE FReference& operator=(const FReference& InValue) { *this = static_cast<bool>(InValue); return *this; }
|
||||
|
||||
FORCEINLINE Reference& operator&=(bool InValue) { Data &= InValue ? -1 : ~Mask; return *this; }
|
||||
FORCEINLINE Reference& operator|=(bool InValue) { Data |= InValue ? Mask : 0; return *this; }
|
||||
FORCEINLINE Reference& operator^=(bool InValue) { *this = InValue ^ *this; return *this; }
|
||||
FORCEINLINE FReference& operator&=(bool InValue) { Data &= InValue ? -1 : ~Mask; return *this; }
|
||||
FORCEINLINE FReference& operator|=(bool InValue) { Data |= InValue ? Mask : 0; return *this; }
|
||||
FORCEINLINE FReference& operator^=(bool InValue) { *this = InValue ^ *this; return *this; }
|
||||
|
||||
FORCEINLINE bool operator~() const { return !*this; }
|
||||
|
||||
@ -917,14 +915,14 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
FORCEINLINE Reference(BlockType& InData, BlockType InMask)
|
||||
FORCEINLINE FReference(FBlockType& InData, FBlockType InMask)
|
||||
: Data(InData), Mask(InMask)
|
||||
{ }
|
||||
|
||||
BlockType& Data;
|
||||
BlockType Mask;
|
||||
FBlockType& Data;
|
||||
FBlockType Mask;
|
||||
|
||||
friend Iterator;
|
||||
friend FIterator;
|
||||
|
||||
};
|
||||
|
||||
@ -935,7 +933,7 @@ private:
|
||||
{
|
||||
public:
|
||||
|
||||
using ElementType = bool;
|
||||
using FElementType = bool;
|
||||
|
||||
FORCEINLINE TIteratorImpl() = default;
|
||||
|
||||
@ -958,8 +956,8 @@ private:
|
||||
|
||||
NODISCARD friend FORCEINLINE strong_ordering operator<=>(const TIteratorImpl& LHS, const TIteratorImpl& RHS) { check(LHS.Pointer == RHS.Pointer); return LHS.BitOffset <=> RHS.BitOffset; }
|
||||
|
||||
NODISCARD FORCEINLINE Reference operator*() const requires (!bConst) { CheckThis(true); return Reference(*(Pointer + BitOffset / BlockWidth), 1ull << BitOffset % BlockWidth); }
|
||||
NODISCARD FORCEINLINE ConstReference operator*() const requires ( bConst) { CheckThis(true); return (*(Pointer + BitOffset / BlockWidth) & (1ull << BitOffset % BlockWidth)); }
|
||||
NODISCARD FORCEINLINE FReference operator*() const requires (!bConst) { CheckThis(true); return FReference(*(Pointer + BitOffset / BlockWidth), 1ull << BitOffset % BlockWidth); }
|
||||
NODISCARD FORCEINLINE FConstReference operator*() const requires ( bConst) { CheckThis(true); return (*(Pointer + BitOffset / BlockWidth) & (1ull << BitOffset % BlockWidth)); }
|
||||
|
||||
NODISCARD FORCEINLINE auto operator[](ptrdiff Index) const { TIteratorImpl Temp = *this + Index; return *Temp; }
|
||||
|
||||
@ -985,17 +983,17 @@ private:
|
||||
const TBitset* Owner = nullptr;
|
||||
# endif
|
||||
|
||||
using BlockPtr = TConditional<bConst, const BlockType*, BlockType*>;
|
||||
using FBlockPtr = TConditional<bConst, const FBlockType*, FBlockType*>;
|
||||
|
||||
BlockPtr Pointer = nullptr;
|
||||
size_t BitOffset = 0;
|
||||
FBlockPtr Pointer = nullptr;
|
||||
size_t BitOffset = 0;
|
||||
|
||||
# if DO_CHECK
|
||||
FORCEINLINE TIteratorImpl(const TBitset* InContainer, BlockPtr InPointer, size_t Offset)
|
||||
FORCEINLINE TIteratorImpl(const TBitset* InContainer, FBlockPtr InPointer, size_t Offset)
|
||||
: Owner(InContainer), Pointer(InPointer), BitOffset(Offset)
|
||||
{ }
|
||||
# else
|
||||
FORCEINLINE TIteratorImpl(const TBitset* InContainer, BlockPtr InPointer, size_t Offset)
|
||||
FORCEINLINE TIteratorImpl(const TBitset* InContainer, FBlockPtr InPointer, size_t Offset)
|
||||
: Pointer(InPointer), BitOffset(Offset)
|
||||
{ }
|
||||
# endif
|
||||
|
@ -28,20 +28,20 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
using ElementType = T;
|
||||
using AllocatorType = Allocator;
|
||||
using FElementType = T;
|
||||
using FAllocatorType = Allocator;
|
||||
|
||||
using Reference = T&;
|
||||
using ConstReference = const T&;
|
||||
using FReference = T&;
|
||||
using FConstReference = const T&;
|
||||
|
||||
using Iterator = TIteratorImpl<false>;
|
||||
using ConstIterator = TIteratorImpl<true >;
|
||||
using FIterator = TIteratorImpl<false>;
|
||||
using FConstIterator = TIteratorImpl<true >;
|
||||
|
||||
using ReverseIterator = TReverseIterator< Iterator>;
|
||||
using ConstReverseIterator = TReverseIterator<ConstIterator>;
|
||||
using FReverseIterator = TReverseIterator< FIterator>;
|
||||
using FConstReverseIterator = TReverseIterator<FConstIterator>;
|
||||
|
||||
static_assert(CBidirectionalIterator< Iterator>);
|
||||
static_assert(CBidirectionalIterator<ConstIterator>);
|
||||
static_assert(CBidirectionalIterator< FIterator>);
|
||||
static_assert(CBidirectionalIterator<FConstIterator>);
|
||||
|
||||
/** Default constructor. Constructs an empty container with a default-constructed allocator. */
|
||||
TList()
|
||||
@ -54,7 +54,7 @@ public:
|
||||
}
|
||||
|
||||
/** Constructs the container with 'Count' default instances of T. */
|
||||
explicit TList(size_t Count) requires (CDefaultConstructible<ElementType>) : TList()
|
||||
explicit TList(size_t Count) requires (CDefaultConstructible<FElementType>) : TList()
|
||||
{
|
||||
FNode* EndNode = Impl.HeadNode->PrevNode;
|
||||
|
||||
@ -75,12 +75,12 @@ public:
|
||||
}
|
||||
|
||||
/** Constructs the container with 'Count' copies of elements with 'InValue'. */
|
||||
TList(size_t Count, const ElementType& InValue) requires (CCopyable<ElementType>)
|
||||
TList(size_t Count, const FElementType& InValue) requires (CCopyable<FElementType>)
|
||||
: TList(MakeCountedConstantIterator(InValue, Count), DefaultSentinel)
|
||||
{ }
|
||||
|
||||
/** Constructs the container with the contents of the range ['First', 'Last'). */
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<ElementType, TIteratorReferenceType<I>>)
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReferenceType<I>>)
|
||||
TList(I First, S Last) : TList()
|
||||
{
|
||||
FNode* EndNode = Impl.HeadNode->PrevNode;
|
||||
@ -102,13 +102,13 @@ public:
|
||||
}
|
||||
|
||||
/** Copy constructor. Constructs the container with the copy of the contents of 'InValue'. */
|
||||
FORCEINLINE TList(const TList& InValue) requires (CCopyConstructible<ElementType>) : TList(InValue.Begin(), InValue.End()) { }
|
||||
FORCEINLINE TList(const TList& InValue) requires (CCopyConstructible<FElementType>) : TList(InValue.Begin(), InValue.End()) { }
|
||||
|
||||
/** Move constructor. After the move, 'InValue' is guaranteed to be empty. */
|
||||
FORCEINLINE TList(TList&& InValue) : TList() { Swap(*this, InValue); }
|
||||
|
||||
/** Constructs the container with the contents of the initializer list. */
|
||||
FORCEINLINE TList(initializer_list<ElementType> IL) requires (CCopyConstructible<ElementType>) : TList(Iteration::Begin(IL), Iteration::End(IL)) { }
|
||||
FORCEINLINE TList(initializer_list<FElementType> IL) requires (CCopyConstructible<FElementType>) : TList(Iteration::Begin(IL), Iteration::End(IL)) { }
|
||||
|
||||
/** Destructs the list. The destructors of the elements are called and the used storage is deallocated. */
|
||||
~TList()
|
||||
@ -129,12 +129,12 @@ public:
|
||||
}
|
||||
|
||||
/** Copy assignment operator. Replaces the contents with a copy of the contents of 'InValue'. */
|
||||
TList& operator=(const TList& InValue) requires (CCopyable<ElementType>)
|
||||
TList& operator=(const TList& InValue) requires (CCopyable<FElementType>)
|
||||
{
|
||||
if (&InValue == this) UNLIKELY return *this;
|
||||
|
||||
Iterator ThisIter = Begin();
|
||||
ConstIterator OtherIter = InValue.Begin();
|
||||
FIterator ThisIter = Begin();
|
||||
FConstIterator OtherIter = InValue.Begin();
|
||||
|
||||
while (ThisIter != End() && OtherIter != InValue.End())
|
||||
{
|
||||
@ -166,10 +166,10 @@ public:
|
||||
FORCEINLINE TList& operator=(TList&& InValue) { Swap(*this, InValue); InValue.Reset(); return *this; }
|
||||
|
||||
/** Replaces the contents with those identified by initializer list. */
|
||||
TList& operator=(initializer_list<ElementType> IL) requires (CCopyable<ElementType>)
|
||||
TList& operator=(initializer_list<FElementType> IL) requires (CCopyable<FElementType>)
|
||||
{
|
||||
Iterator ThisIter = Begin();
|
||||
const ElementType* OtherIter = Iteration::Begin(IL);
|
||||
FIterator ThisIter = Begin();
|
||||
const FElementType* OtherIter = Iteration::Begin(IL);
|
||||
|
||||
while (ThisIter != End() && OtherIter != Iteration::End(IL))
|
||||
{
|
||||
@ -198,12 +198,12 @@ public:
|
||||
}
|
||||
|
||||
/** Compares the contents of two lists. */
|
||||
NODISCARD friend bool operator==(const TList& LHS, const TList& RHS) requires (CWeaklyEqualityComparable<ElementType>)
|
||||
NODISCARD friend bool operator==(const TList& LHS, const TList& RHS) requires (CWeaklyEqualityComparable<FElementType>)
|
||||
{
|
||||
if (LHS.Num() != RHS.Num()) return false;
|
||||
|
||||
ConstIterator LHSIter = LHS.Begin();
|
||||
ConstIterator RHSIter = RHS.Begin();
|
||||
FConstIterator LHSIter = LHS.Begin();
|
||||
FConstIterator RHSIter = RHS.Begin();
|
||||
|
||||
while (LHSIter != LHS.End())
|
||||
{
|
||||
@ -219,10 +219,10 @@ public:
|
||||
}
|
||||
|
||||
/** Compares the contents of 'LHS' and 'RHS' lexicographically. */
|
||||
NODISCARD friend auto operator<=>(const TList& LHS, const TList& RHS) requires (CSynthThreeWayComparable<ElementType>)
|
||||
NODISCARD friend auto operator<=>(const TList& LHS, const TList& RHS) requires (CSynthThreeWayComparable<FElementType>)
|
||||
{
|
||||
ConstIterator LHSIter = LHS.Begin();
|
||||
ConstIterator RHSIter = RHS.Begin();
|
||||
FConstIterator LHSIter = LHS.Begin();
|
||||
FConstIterator RHSIter = RHS.Begin();
|
||||
|
||||
while (LHSIter != LHS.End() && RHSIter != RHS.End())
|
||||
{
|
||||
@ -236,22 +236,22 @@ public:
|
||||
}
|
||||
|
||||
/** Inserts 'InValue' before 'Iter' in the container. */
|
||||
FORCEINLINE Iterator Insert(ConstIterator Iter, const ElementType& InValue) requires (CCopyConstructible<ElementType>) { return Emplace(Iter, InValue); }
|
||||
FORCEINLINE FIterator Insert(FConstIterator Iter, const FElementType& InValue) requires (CCopyConstructible<FElementType>) { return Emplace(Iter, InValue); }
|
||||
|
||||
/** Inserts 'InValue' before 'Iter' in the container. */
|
||||
FORCEINLINE Iterator Insert(ConstIterator Iter, ElementType&& InValue) requires (CMoveConstructible<ElementType>) { return Emplace(Iter, MoveTemp(InValue)); }
|
||||
FORCEINLINE FIterator Insert(FConstIterator Iter, FElementType&& InValue) requires (CMoveConstructible<FElementType>) { return Emplace(Iter, MoveTemp(InValue)); }
|
||||
|
||||
/** Inserts 'Count' copies of the 'InValue' before 'Iter' in the container. */
|
||||
Iterator Insert(ConstIterator Iter, size_t Count, const ElementType& InValue) requires (CCopyConstructible<ElementType>)
|
||||
FIterator Insert(FConstIterator Iter, size_t Count, const FElementType& InValue) requires (CCopyConstructible<FElementType>)
|
||||
{
|
||||
return Insert(Iter, MakeCountedConstantIterator(InValue, Count), DefaultSentinel);
|
||||
}
|
||||
|
||||
/** Inserts elements from range ['First', 'Last') before 'Iter'. */
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<ElementType, TIteratorReferenceType<I>>)
|
||||
Iterator Insert(ConstIterator Iter, I First, S Last)
|
||||
template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<FElementType, TIteratorReferenceType<I>>)
|
||||
FIterator Insert(FConstIterator Iter, I First, S Last)
|
||||
{
|
||||
if (First == Last) return Iterator(Iter.Pointer);
|
||||
if (First == Last) return FIterator(Iter.Pointer);
|
||||
|
||||
FNode* InsertNode = Iter.Pointer->PrevNode;
|
||||
|
||||
@ -279,15 +279,15 @@ public:
|
||||
InsertNode->NextNode = Iter.Pointer;
|
||||
Iter.Pointer->PrevNode = InsertNode;
|
||||
|
||||
return Iterator(FirstNode);
|
||||
return FIterator(FirstNode);
|
||||
}
|
||||
|
||||
/** Inserts elements from initializer list before 'Iter' in the container. */
|
||||
FORCEINLINE Iterator Insert(ConstIterator Iter, initializer_list<ElementType> IL) requires (CCopyConstructible<ElementType>) { return Insert(Iter, Iteration::Begin(IL), Iteration::End(IL)); }
|
||||
FORCEINLINE FIterator Insert(FConstIterator Iter, initializer_list<FElementType> IL) requires (CCopyConstructible<FElementType>) { return Insert(Iter, Iteration::Begin(IL), Iteration::End(IL)); }
|
||||
|
||||
/** Inserts a new element into the container directly before 'Iter'. */
|
||||
template <typename... Ts> requires (CConstructibleFrom<ElementType, Ts...>)
|
||||
Iterator Emplace(ConstIterator Iter, Ts&&... Args)
|
||||
template <typename... Ts> requires (CConstructibleFrom<FElementType, Ts...>)
|
||||
FIterator Emplace(FConstIterator Iter, Ts&&... Args)
|
||||
{
|
||||
FNode* Node = new (Impl->Allocate(1)) FNode(InPlace, Forward<Ts>(Args)...);
|
||||
|
||||
@ -299,11 +299,11 @@ public:
|
||||
Node->PrevNode->NextNode = Node;
|
||||
Node->NextNode->PrevNode = Node;
|
||||
|
||||
return Iterator(Node);
|
||||
return FIterator(Node);
|
||||
}
|
||||
|
||||
/** Removes the element at 'Iter' in the container. */
|
||||
Iterator Erase(ConstIterator Iter)
|
||||
FIterator Erase(FConstIterator Iter)
|
||||
{
|
||||
FNode* NodeToErase = Iter.Pointer;
|
||||
|
||||
@ -319,11 +319,11 @@ public:
|
||||
|
||||
--Impl.ListNum;
|
||||
|
||||
return Iterator(NextNode);
|
||||
return FIterator(NextNode);
|
||||
}
|
||||
|
||||
/** Removes the elements in the range ['First', 'Last') in the container. */
|
||||
Iterator Erase(ConstIterator First, ConstIterator Last)
|
||||
FIterator Erase(FConstIterator First, FConstIterator Last)
|
||||
{
|
||||
FNode* FirstToErase = First.Pointer;
|
||||
FNode* LastToErase = Last.Pointer;
|
||||
@ -343,43 +343,43 @@ public:
|
||||
FirstToErase = NextNode;
|
||||
}
|
||||
|
||||
return Iterator(LastToErase);
|
||||
return FIterator(LastToErase);
|
||||
}
|
||||
|
||||
/** Appends the given element value to the end of the container. */
|
||||
FORCEINLINE void PushBack(const ElementType& InValue) requires (CCopyConstructible<ElementType>) { EmplaceBack(InValue); }
|
||||
FORCEINLINE void PushBack(const FElementType& InValue) requires (CCopyConstructible<FElementType>) { EmplaceBack(InValue); }
|
||||
|
||||
/** Appends the given element value to the end of the container. */
|
||||
FORCEINLINE void PushBack(ElementType&& InValue) requires (CMoveConstructible<ElementType>) { EmplaceBack(MoveTemp(InValue)); }
|
||||
FORCEINLINE void PushBack(FElementType&& InValue) requires (CMoveConstructible<FElementType>) { EmplaceBack(MoveTemp(InValue)); }
|
||||
|
||||
/** Appends a new element to the end of the container. */
|
||||
template <typename... Ts> requires (CConstructibleFrom<ElementType, Ts...>)
|
||||
FORCEINLINE Reference EmplaceBack(Ts&&... Args) { return *Emplace(End(), Forward<Ts>(Args)...); }
|
||||
template <typename... Ts> requires (CConstructibleFrom<FElementType, Ts...>)
|
||||
FORCEINLINE FReference EmplaceBack(Ts&&... Args) { return *Emplace(End(), Forward<Ts>(Args)...); }
|
||||
|
||||
/** Removes the last element of the container. The list cannot be empty. */
|
||||
FORCEINLINE void PopBack() { Erase(--End()); }
|
||||
|
||||
/** Prepends the given element value to the beginning of the container. */
|
||||
FORCEINLINE void PushFront(const ElementType& InValue) requires (CCopyConstructible<ElementType>) { EmplaceFront(InValue); }
|
||||
FORCEINLINE void PushFront(const FElementType& InValue) requires (CCopyConstructible<FElementType>) { EmplaceFront(InValue); }
|
||||
|
||||
/** Prepends the given element value to the beginning of the container. */
|
||||
FORCEINLINE void PushFront(ElementType&& InValue) requires (CMoveConstructible<ElementType>) { EmplaceFront(MoveTemp(InValue)); }
|
||||
FORCEINLINE void PushFront(FElementType&& InValue) requires (CMoveConstructible<FElementType>) { EmplaceFront(MoveTemp(InValue)); }
|
||||
|
||||
/** Prepends a new element to the beginning of the container. */
|
||||
template <typename... Ts> requires (CConstructibleFrom<ElementType, Ts...>)
|
||||
FORCEINLINE Reference EmplaceFront(Ts&&... Args) { return *Emplace(Begin(), Forward<Ts>(Args)...); }
|
||||
template <typename... Ts> requires (CConstructibleFrom<FElementType, Ts...>)
|
||||
FORCEINLINE FReference EmplaceFront(Ts&&... Args) { return *Emplace(Begin(), Forward<Ts>(Args)...); }
|
||||
|
||||
/** Removes the first element of the container. The list cannot be empty. */
|
||||
FORCEINLINE void PopFront() { Erase(Begin()); }
|
||||
|
||||
/** Resizes the container to contain 'Count' elements. Additional default elements are appended. */
|
||||
void SetNum(size_t Count) requires (CDefaultConstructible<ElementType>)
|
||||
void SetNum(size_t Count) requires (CDefaultConstructible<FElementType>)
|
||||
{
|
||||
if (Count == Impl.ListNum) return;
|
||||
|
||||
if (Count < Impl.ListNum)
|
||||
{
|
||||
Iterator First = End();
|
||||
FIterator First = End();
|
||||
|
||||
Iteration::Advance(First, Count - Impl.ListNum);
|
||||
|
||||
@ -409,13 +409,13 @@ public:
|
||||
}
|
||||
|
||||
/** Resizes the container to contain 'Count' elements. Additional copies of 'InValue' are appended. */
|
||||
void SetNum(size_t Count, const ElementType& InValue) requires (CCopyConstructible<ElementType>)
|
||||
void SetNum(size_t Count, const FElementType& InValue) requires (CCopyConstructible<FElementType>)
|
||||
{
|
||||
if (Count == Impl.ListNum) return;
|
||||
|
||||
if (Count < Impl.ListNum)
|
||||
{
|
||||
Iterator First = End();
|
||||
FIterator First = End();
|
||||
|
||||
Iteration::Advance(First, Count - Impl.ListNum);
|
||||
|
||||
@ -445,16 +445,16 @@ public:
|
||||
}
|
||||
|
||||
/** @return The iterator to the first or end element. */
|
||||
NODISCARD FORCEINLINE Iterator Begin() { return Iterator(Impl.HeadNode->NextNode); }
|
||||
NODISCARD FORCEINLINE ConstIterator Begin() const { return ConstIterator(Impl.HeadNode->NextNode); }
|
||||
NODISCARD FORCEINLINE Iterator End() { return Iterator(Impl.HeadNode); }
|
||||
NODISCARD FORCEINLINE ConstIterator End() const { return ConstIterator(Impl.HeadNode); }
|
||||
NODISCARD FORCEINLINE FIterator Begin() { return FIterator(Impl.HeadNode->NextNode); }
|
||||
NODISCARD FORCEINLINE FConstIterator Begin() const { return FConstIterator(Impl.HeadNode->NextNode); }
|
||||
NODISCARD FORCEINLINE FIterator End() { return FIterator(Impl.HeadNode); }
|
||||
NODISCARD FORCEINLINE FConstIterator End() const { return FConstIterator(Impl.HeadNode); }
|
||||
|
||||
/** @return The reverse iterator to the first or end element. */
|
||||
NODISCARD FORCEINLINE ReverseIterator RBegin() { return ReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE ConstReverseIterator RBegin() const { return ConstReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE ReverseIterator REnd() { return ReverseIterator(Begin()); }
|
||||
NODISCARD FORCEINLINE ConstReverseIterator REnd() const { return ConstReverseIterator(Begin()); }
|
||||
NODISCARD FORCEINLINE FReverseIterator RBegin() { return FReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE FConstReverseIterator RBegin() const { return FConstReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE FReverseIterator REnd() { return FReverseIterator(Begin()); }
|
||||
NODISCARD FORCEINLINE FConstReverseIterator REnd() const { return FConstReverseIterator(Begin()); }
|
||||
|
||||
/** @return The number of elements in the container. */
|
||||
NODISCARD FORCEINLINE size_t Num() const { return Impl.ListNum; }
|
||||
@ -463,7 +463,7 @@ public:
|
||||
NODISCARD FORCEINLINE bool IsEmpty() const { return Num() == 0; }
|
||||
|
||||
/** @return true if the iterator is valid, false otherwise. */
|
||||
NODISCARD FORCEINLINE bool IsValidIterator(ConstIterator Iter) const
|
||||
NODISCARD FORCEINLINE bool IsValidIterator(FConstIterator Iter) const
|
||||
{
|
||||
FNode* Current = Impl.HeadNode;
|
||||
|
||||
@ -481,10 +481,10 @@ public:
|
||||
}
|
||||
|
||||
/** @return The reference to the first or last element. */
|
||||
NODISCARD FORCEINLINE ElementType& Front() { return *Begin(); }
|
||||
NODISCARD FORCEINLINE const ElementType& Front() const { return *Begin(); }
|
||||
NODISCARD FORCEINLINE ElementType& Back() { return *(End() - 1); }
|
||||
NODISCARD FORCEINLINE const ElementType& Back() const { return *(End() - 1); }
|
||||
NODISCARD FORCEINLINE FElementType& Front() { return *Begin(); }
|
||||
NODISCARD FORCEINLINE const FElementType& Front() const { return *Begin(); }
|
||||
NODISCARD FORCEINLINE FElementType& Back() { return *(End() - 1); }
|
||||
NODISCARD FORCEINLINE const FElementType& Back() const { return *(End() - 1); }
|
||||
|
||||
/** Erases all elements from the container. After this call, Num() returns zero. */
|
||||
void Reset()
|
||||
@ -508,11 +508,11 @@ public:
|
||||
}
|
||||
|
||||
/** Overloads the GetTypeHash algorithm for TList. */
|
||||
NODISCARD friend FORCEINLINE size_t GetTypeHash(const TList& A) requires (CHashable<ElementType>)
|
||||
NODISCARD friend FORCEINLINE size_t GetTypeHash(const TList& A) requires (CHashable<FElementType>)
|
||||
{
|
||||
size_t Result = 0;
|
||||
|
||||
for (const ElementType& Element : A)
|
||||
for (const FElementType& Element : A)
|
||||
{
|
||||
Result = HashCombine(Result, GetTypeHash(Element));
|
||||
}
|
||||
@ -535,7 +535,7 @@ private:
|
||||
{
|
||||
FNode* PrevNode;
|
||||
FNode* NextNode;
|
||||
ElementType Value;
|
||||
FElementType Value;
|
||||
|
||||
FORCEINLINE FNode() = default;
|
||||
|
||||
@ -543,21 +543,21 @@ private:
|
||||
FORCEINLINE FNode(FInPlace, Ts&&... Args) : Value(Forward<Ts>(Args)...) { }
|
||||
};
|
||||
|
||||
static_assert(CMultipleAllocator<AllocatorType, FNode>);
|
||||
static_assert(CMultipleAllocator<FAllocatorType, FNode>);
|
||||
|
||||
ALLOCATOR_WRAPPER_BEGIN(AllocatorType, FNode, Impl)
|
||||
ALLOCATOR_WRAPPER_BEGIN(FAllocatorType, FNode, Impl)
|
||||
{
|
||||
FNode* HeadNode;
|
||||
size_t ListNum;
|
||||
}
|
||||
ALLOCATOR_WRAPPER_END(AllocatorType, FNode, Impl)
|
||||
ALLOCATOR_WRAPPER_END(FAllocatorType, FNode, Impl)
|
||||
|
||||
template <bool bConst, typename U>
|
||||
class TIteratorImpl final
|
||||
{
|
||||
public:
|
||||
|
||||
using ElementType = TRemoveCV<T>;
|
||||
using FElementType = TRemoveCV<T>;
|
||||
|
||||
FORCEINLINE TIteratorImpl() = default;
|
||||
|
||||
|
@ -25,22 +25,22 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
using ElementType = T;
|
||||
using FElementType = T;
|
||||
|
||||
using Reference = T&;
|
||||
using ConstReference = const T&;
|
||||
using FReference = T&;
|
||||
using FConstReference = const T&;
|
||||
|
||||
using Iterator = TIteratorImpl<false>;
|
||||
using ConstIterator = TIteratorImpl<true >;
|
||||
using FIterator = TIteratorImpl<false>;
|
||||
using FConstIterator = TIteratorImpl<true >;
|
||||
|
||||
using ReverseIterator = TReverseIterator< Iterator>;
|
||||
using ConstReverseIterator = TReverseIterator<ConstIterator>;
|
||||
using FReverseIterator = TReverseIterator< FIterator>;
|
||||
using FConstReverseIterator = TReverseIterator<FConstIterator>;
|
||||
|
||||
static_assert(CContiguousIterator< Iterator>);
|
||||
static_assert(CContiguousIterator<ConstIterator>);
|
||||
static_assert(CContiguousIterator< FIterator>);
|
||||
static_assert(CContiguousIterator<FConstIterator>);
|
||||
|
||||
/** Compares the contents of two arrays. */
|
||||
NODISCARD friend constexpr bool operator==(const TStaticArray& LHS, const TStaticArray& RHS) requires (CWeaklyEqualityComparable<ElementType>)
|
||||
NODISCARD friend constexpr bool operator==(const TStaticArray& LHS, const TStaticArray& RHS) requires (CWeaklyEqualityComparable<FElementType>)
|
||||
{
|
||||
if (LHS.Num() != RHS.Num()) return false;
|
||||
|
||||
@ -53,7 +53,7 @@ public:
|
||||
}
|
||||
|
||||
/** Compares the contents of 'LHS' and 'RHS' lexicographically. */
|
||||
NODISCARD friend constexpr auto operator<=>(const TStaticArray& LHS, const TStaticArray& RHS) requires (CSynthThreeWayComparable<ElementType>)
|
||||
NODISCARD friend constexpr auto operator<=>(const TStaticArray& LHS, const TStaticArray& RHS) requires (CSynthThreeWayComparable<FElementType>)
|
||||
{
|
||||
const size_t NumToCompare = LHS.Num() < RHS.Num() ? LHS.Num() : RHS.Num();
|
||||
|
||||
@ -66,20 +66,20 @@ public:
|
||||
}
|
||||
|
||||
/** @return The pointer to the underlying element storage. */
|
||||
NODISCARD FORCEINLINE constexpr ElementType* GetData() { return _; }
|
||||
NODISCARD FORCEINLINE constexpr const ElementType* GetData() const { return _; }
|
||||
NODISCARD FORCEINLINE constexpr FElementType* GetData() { return _; }
|
||||
NODISCARD FORCEINLINE constexpr const FElementType* GetData() const { return _; }
|
||||
|
||||
/** @return The iterator to the first or end element. */
|
||||
NODISCARD FORCEINLINE constexpr Iterator Begin() { return Iterator(this, _); }
|
||||
NODISCARD FORCEINLINE constexpr ConstIterator Begin() const { return ConstIterator(this, _); }
|
||||
NODISCARD FORCEINLINE constexpr Iterator End() { return Iterator(this, _ + Num()); }
|
||||
NODISCARD FORCEINLINE constexpr ConstIterator End() const { return ConstIterator(this, _ + Num()); }
|
||||
NODISCARD FORCEINLINE constexpr FIterator Begin() { return FIterator(this, _); }
|
||||
NODISCARD FORCEINLINE constexpr FConstIterator Begin() const { return FConstIterator(this, _); }
|
||||
NODISCARD FORCEINLINE constexpr FIterator End() { return FIterator(this, _ + Num()); }
|
||||
NODISCARD FORCEINLINE constexpr FConstIterator End() const { return FConstIterator(this, _ + Num()); }
|
||||
|
||||
/** @return The reverse iterator to the first or end element. */
|
||||
NODISCARD FORCEINLINE constexpr ReverseIterator RBegin() { return ReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE constexpr ConstReverseIterator RBegin() const { return ConstReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE constexpr ReverseIterator REnd() { return ReverseIterator(Begin()); }
|
||||
NODISCARD FORCEINLINE constexpr ConstReverseIterator REnd() const { return ConstReverseIterator(Begin()); }
|
||||
NODISCARD FORCEINLINE constexpr FReverseIterator RBegin() { return FReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE constexpr FConstReverseIterator RBegin() const { return FConstReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE constexpr FReverseIterator REnd() { return FReverseIterator(Begin()); }
|
||||
NODISCARD FORCEINLINE constexpr FConstReverseIterator REnd() const { return FConstReverseIterator(Begin()); }
|
||||
|
||||
/** @return The number of elements in the container. */
|
||||
NODISCARD FORCEINLINE constexpr size_t Num() const { return N; }
|
||||
@ -88,24 +88,24 @@ public:
|
||||
NODISCARD FORCEINLINE constexpr bool IsEmpty() const { return Num() == 0; }
|
||||
|
||||
/** @return true if the iterator is valid, false otherwise. */
|
||||
NODISCARD FORCEINLINE constexpr bool IsValidIterator(ConstIterator Iter) const { return Begin() <= Iter && Iter <= End(); }
|
||||
NODISCARD FORCEINLINE constexpr bool IsValidIterator(FConstIterator Iter) const { return Begin() <= Iter && Iter <= End(); }
|
||||
|
||||
/** @return The reference to the requested element. */
|
||||
NODISCARD FORCEINLINE constexpr ElementType& operator[](size_t Index) { checkf(Index < Num(), TEXT("Read access violation. Please check IsValidIterator().")); return _[Index]; }
|
||||
NODISCARD FORCEINLINE constexpr const ElementType& operator[](size_t Index) const { checkf(Index < Num(), TEXT("Read access violation. Please check IsValidIterator().")); return _[Index]; }
|
||||
NODISCARD FORCEINLINE constexpr FElementType& operator[](size_t Index) { checkf(Index < Num(), TEXT("Read access violation. Please check IsValidIterator().")); return _[Index]; }
|
||||
NODISCARD FORCEINLINE constexpr const FElementType& operator[](size_t Index) const { checkf(Index < Num(), TEXT("Read access violation. Please check IsValidIterator().")); return _[Index]; }
|
||||
|
||||
/** @return The reference to the first or last element. */
|
||||
NODISCARD FORCEINLINE constexpr ElementType& Front() { return *Begin(); }
|
||||
NODISCARD FORCEINLINE constexpr const ElementType& Front() const { return *Begin(); }
|
||||
NODISCARD FORCEINLINE constexpr ElementType& Back() { return *(End() - 1); }
|
||||
NODISCARD FORCEINLINE constexpr const ElementType& Back() const { return *(End() - 1); }
|
||||
NODISCARD FORCEINLINE constexpr FElementType& Front() { return *Begin(); }
|
||||
NODISCARD FORCEINLINE constexpr const FElementType& Front() const { return *Begin(); }
|
||||
NODISCARD FORCEINLINE constexpr FElementType& Back() { return *(End() - 1); }
|
||||
NODISCARD FORCEINLINE constexpr const FElementType& Back() const { return *(End() - 1); }
|
||||
|
||||
/** Overloads the GetTypeHash algorithm for TStaticArray. */
|
||||
NODISCARD friend FORCEINLINE constexpr size_t GetTypeHash(const TStaticArray& A) requires (CHashable<ElementType>)
|
||||
NODISCARD friend FORCEINLINE constexpr size_t GetTypeHash(const TStaticArray& A) requires (CHashable<FElementType>)
|
||||
{
|
||||
size_t Result = 0;
|
||||
|
||||
for (ConstIterator Iter = A.Begin(); Iter != A.End(); ++Iter)
|
||||
for (FConstIterator Iter = A.Begin(); Iter != A.End(); ++Iter)
|
||||
{
|
||||
Result = HashCombine(Result, GetTypeHash(*Iter));
|
||||
}
|
||||
@ -114,7 +114,7 @@ public:
|
||||
}
|
||||
|
||||
/** Overloads the Swap algorithm for TStaticArray. */
|
||||
friend FORCEINLINE constexpr void Swap(TStaticArray& A, TStaticArray& B) requires (CSwappable<ElementType>) { Swap(A._, B._); }
|
||||
friend FORCEINLINE constexpr void Swap(TStaticArray& A, TStaticArray& B) requires (CSwappable<FElementType>) { Swap(A._, B._); }
|
||||
|
||||
ENABLE_RANGE_BASED_FOR_LOOP_SUPPORT
|
||||
|
||||
@ -127,7 +127,7 @@ private:
|
||||
{
|
||||
public:
|
||||
|
||||
using ElementType = TRemoveCV<T>;
|
||||
using FElementType = TRemoveCV<T>;
|
||||
|
||||
FORCEINLINE constexpr TIteratorImpl() = default;
|
||||
|
||||
@ -224,6 +224,8 @@ NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
||||
|
||||
// ReSharper disable CppInconsistentNaming
|
||||
|
||||
NAMESPACE_STD_BEGIN
|
||||
|
||||
// Support structure binding, should not be directly used.
|
||||
@ -245,3 +247,5 @@ template <size_t Index, typename T, size_t N> FORCEINLINE constexpr decltype(aut
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
||||
|
||||
// ReSharper restore CppInconsistentNaming
|
||||
|
@ -37,22 +37,22 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
using BlockType = InBlockType;
|
||||
using ElementType = bool;
|
||||
using FBlockType = InBlockType;
|
||||
using FElementType = bool;
|
||||
|
||||
class Reference;
|
||||
using ConstReference = bool;
|
||||
class FReference;
|
||||
using FConstReference = bool;
|
||||
|
||||
using Iterator = TIteratorImpl<false>;
|
||||
using ConstIterator = TIteratorImpl<true >;
|
||||
using FIterator = TIteratorImpl<false>;
|
||||
using FConstIterator = TIteratorImpl<true >;
|
||||
|
||||
using ReverseIterator = TReverseIterator< Iterator>;
|
||||
using ConstReverseIterator = TReverseIterator<ConstIterator>;
|
||||
using FReverseIterator = TReverseIterator< FIterator>;
|
||||
using FConstReverseIterator = TReverseIterator<FConstIterator>;
|
||||
|
||||
static_assert(CRandomAccessIterator< Iterator>);
|
||||
static_assert(CRandomAccessIterator<ConstIterator>);
|
||||
static_assert(CRandomAccessIterator< FIterator>);
|
||||
static_assert(CRandomAccessIterator<FConstIterator>);
|
||||
|
||||
static constexpr size_t BlockWidth = sizeof(BlockType) * 8;
|
||||
static constexpr size_t BlockWidth = sizeof(FBlockType) * 8;
|
||||
|
||||
/** Default constructor. Constructs an empty bitset. */
|
||||
FORCEINLINE constexpr TStaticBitset() = default;
|
||||
@ -60,38 +60,38 @@ public:
|
||||
/** Constructs a bitset from an integer. */
|
||||
constexpr TStaticBitset(uint64 InValue)
|
||||
{
|
||||
static_assert(sizeof(BlockType) <= sizeof(uint64), "The block width of TStaticBitset is unexpected");
|
||||
static_assert(sizeof(FBlockType) <= sizeof(uint64), "The block width of TStaticBitset is unexpected");
|
||||
|
||||
if constexpr (sizeof(BlockType) == sizeof(uint8))
|
||||
if constexpr (sizeof(FBlockType) == sizeof(uint8))
|
||||
{
|
||||
if constexpr (N > 0) Impl[0] = static_cast<BlockType>(InValue >> 0);
|
||||
if constexpr (N > 8) Impl[1] = static_cast<BlockType>(InValue >> 8);
|
||||
if constexpr (N > 16) Impl[2] = static_cast<BlockType>(InValue >> 16);
|
||||
if constexpr (N > 24) Impl[3] = static_cast<BlockType>(InValue >> 24);
|
||||
if constexpr (N > 32) Impl[4] = static_cast<BlockType>(InValue >> 32);
|
||||
if constexpr (N > 40) Impl[5] = static_cast<BlockType>(InValue >> 40);
|
||||
if constexpr (N > 48) Impl[6] = static_cast<BlockType>(InValue >> 48);
|
||||
if constexpr (N > 56) Impl[7] = static_cast<BlockType>(InValue >> 56);
|
||||
if constexpr (N > 0) Impl[0] = static_cast<FBlockType>(InValue >> 0);
|
||||
if constexpr (N > 8) Impl[1] = static_cast<FBlockType>(InValue >> 8);
|
||||
if constexpr (N > 16) Impl[2] = static_cast<FBlockType>(InValue >> 16);
|
||||
if constexpr (N > 24) Impl[3] = static_cast<FBlockType>(InValue >> 24);
|
||||
if constexpr (N > 32) Impl[4] = static_cast<FBlockType>(InValue >> 32);
|
||||
if constexpr (N > 40) Impl[5] = static_cast<FBlockType>(InValue >> 40);
|
||||
if constexpr (N > 48) Impl[6] = static_cast<FBlockType>(InValue >> 48);
|
||||
if constexpr (N > 56) Impl[7] = static_cast<FBlockType>(InValue >> 56);
|
||||
}
|
||||
else if constexpr (sizeof(BlockType) == sizeof(uint16))
|
||||
else if constexpr (sizeof(FBlockType) == sizeof(uint16))
|
||||
{
|
||||
if constexpr (N > 0) Impl[0] = static_cast<BlockType>(InValue >> 0);
|
||||
if constexpr (N > 16) Impl[1] = static_cast<BlockType>(InValue >> 16);
|
||||
if constexpr (N > 32) Impl[2] = static_cast<BlockType>(InValue >> 32);
|
||||
if constexpr (N > 48) Impl[3] = static_cast<BlockType>(InValue >> 48);
|
||||
if constexpr (N > 0) Impl[0] = static_cast<FBlockType>(InValue >> 0);
|
||||
if constexpr (N > 16) Impl[1] = static_cast<FBlockType>(InValue >> 16);
|
||||
if constexpr (N > 32) Impl[2] = static_cast<FBlockType>(InValue >> 32);
|
||||
if constexpr (N > 48) Impl[3] = static_cast<FBlockType>(InValue >> 48);
|
||||
}
|
||||
else if constexpr (sizeof(BlockType) == sizeof(uint32))
|
||||
else if constexpr (sizeof(FBlockType) == sizeof(uint32))
|
||||
{
|
||||
if constexpr (N > 0) Impl[0] = static_cast<BlockType>(InValue >> 0);
|
||||
if constexpr (N > 32) Impl[1] = static_cast<BlockType>(InValue >> 32);
|
||||
if constexpr (N > 0) Impl[0] = static_cast<FBlockType>(InValue >> 0);
|
||||
if constexpr (N > 32) Impl[1] = static_cast<FBlockType>(InValue >> 32);
|
||||
}
|
||||
else if constexpr (sizeof(BlockType) == sizeof(uint64))
|
||||
else if constexpr (sizeof(FBlockType) == sizeof(uint64))
|
||||
{
|
||||
if constexpr (N > 0) Impl[0] = static_cast<BlockType>(InValue >> 0);
|
||||
if constexpr (N > 0) Impl[0] = static_cast<FBlockType>(InValue >> 0);
|
||||
}
|
||||
else check_no_entry();
|
||||
|
||||
constexpr size_t BlockInteger = sizeof(uint64) / sizeof(BlockType);
|
||||
constexpr size_t BlockInteger = sizeof(uint64) / sizeof(FBlockType);
|
||||
|
||||
if constexpr ((N + BlockWidth - 1) / BlockWidth <= BlockInteger) return;
|
||||
|
||||
@ -126,7 +126,7 @@ public:
|
||||
if (LHS.Impl[Index] != RHS.Impl[Index]) return false;
|
||||
}
|
||||
|
||||
const BlockType LastBlockBitmask = LHS.Num() % BlockWidth != 0 ? (1ull << LHS.Num() % BlockWidth) - 1 : -1;
|
||||
const FBlockType LastBlockBitmask = LHS.Num() % BlockWidth != 0 ? (1ull << LHS.Num() % BlockWidth) - 1 : -1;
|
||||
|
||||
return (LHS.Impl[LHS.NumBlocks() - 1] & LastBlockBitmask) == (RHS.Impl[LHS.NumBlocks() - 1] & LastBlockBitmask);
|
||||
}
|
||||
@ -269,7 +269,7 @@ public:
|
||||
if (Impl[Index] != -1) return false;
|
||||
}
|
||||
|
||||
const BlockType LastBlockBitmask = Num() % BlockWidth != 0 ? (1ull << Num() % BlockWidth) - 1 : -1;
|
||||
const FBlockType LastBlockBitmask = Num() % BlockWidth != 0 ? (1ull << Num() % BlockWidth) - 1 : -1;
|
||||
|
||||
return (Impl[NumBlocks() - 1] | ~LastBlockBitmask) == -1;
|
||||
}
|
||||
@ -284,7 +284,7 @@ public:
|
||||
if (Impl[Index] != 0) return true;
|
||||
}
|
||||
|
||||
const BlockType LastBlockBitmask = Num() % BlockWidth != 0 ? (1ull << Num() % BlockWidth) - 1 : -1;
|
||||
const FBlockType LastBlockBitmask = Num() % BlockWidth != 0 ? (1ull << Num() % BlockWidth) - 1 : -1;
|
||||
|
||||
return (Impl[NumBlocks() - 1] & LastBlockBitmask) != 0;
|
||||
}
|
||||
@ -299,24 +299,24 @@ public:
|
||||
|
||||
size_t Result = 0;
|
||||
|
||||
constexpr auto BlockCount = [](BlockType Block) constexpr
|
||||
constexpr auto BlockCount = [](FBlockType Block) constexpr
|
||||
{
|
||||
static_assert(sizeof(BlockType) <= sizeof(uint64), "The block width of TStaticBitset is unexpected");
|
||||
static_assert(sizeof(FBlockType) <= sizeof(uint64), "The block width of TStaticBitset is unexpected");
|
||||
|
||||
if constexpr (sizeof(BlockType) == sizeof(uint8))
|
||||
if constexpr (sizeof(FBlockType) == sizeof(uint8))
|
||||
{
|
||||
Block = (Block & 0x55ull) + ((Block >> 1) & 0x55ull);
|
||||
Block = (Block & 0x33ull) + ((Block >> 2) & 0x33ull);
|
||||
Block = (Block & 0x0Full) + ((Block >> 4) & 0x0Full);
|
||||
}
|
||||
else if constexpr (sizeof(BlockType) == sizeof(uint16))
|
||||
else if constexpr (sizeof(FBlockType) == sizeof(uint16))
|
||||
{
|
||||
Block = (Block & 0x5555ull) + ((Block >> 1) & 0x5555ull);
|
||||
Block = (Block & 0x3333ull) + ((Block >> 2) & 0x3333ull);
|
||||
Block = (Block & 0x0F0Full) + ((Block >> 4) & 0x0F0Full);
|
||||
Block = (Block & 0x00FFull) + ((Block >> 8) & 0x00FFull);
|
||||
}
|
||||
else if constexpr (sizeof(BlockType) == sizeof(uint32))
|
||||
else if constexpr (sizeof(FBlockType) == sizeof(uint32))
|
||||
{
|
||||
Block = (Block & 0x55555555ull) + ((Block >> 1) & 0x55555555ull);
|
||||
Block = (Block & 0x33333333ull) + ((Block >> 2) & 0x33333333ull);
|
||||
@ -324,7 +324,7 @@ public:
|
||||
Block = (Block & 0x00FF00FFull) + ((Block >> 8) & 0x00FF00FFull);
|
||||
Block = (Block & 0x0000FFFFull) + ((Block >> 16) & 0x0000FFFFull);
|
||||
}
|
||||
else if constexpr (sizeof(BlockType) == sizeof(uint64))
|
||||
else if constexpr (sizeof(FBlockType) == sizeof(uint64))
|
||||
{
|
||||
Block = (Block & 0x5555555555555555ull) + ((Block >> 1) & 0x5555555555555555ull);
|
||||
Block = (Block & 0x3333333333333333ull) + ((Block >> 2) & 0x3333333333333333ull);
|
||||
@ -343,7 +343,7 @@ public:
|
||||
Result += BlockCount(Impl[Index]);
|
||||
}
|
||||
|
||||
const BlockType LastBlockBitmask = Num() % BlockWidth != 0 ? (1ull << Num() % BlockWidth) - 1 : -1;
|
||||
const FBlockType LastBlockBitmask = Num() % BlockWidth != 0 ? (1ull << Num() % BlockWidth) - 1 : -1;
|
||||
|
||||
Result += BlockCount(Impl[NumBlocks() - 1] & LastBlockBitmask);
|
||||
|
||||
@ -355,7 +355,7 @@ public:
|
||||
{
|
||||
for (size_t Index = 0; Index != NumBlocks(); ++Index)
|
||||
{
|
||||
Impl[Index] = static_cast<BlockType>(InValue ? -1 : 0);
|
||||
Impl[Index] = static_cast<FBlockType>(InValue ? -1 : 0);
|
||||
}
|
||||
|
||||
return *this;
|
||||
@ -387,20 +387,20 @@ public:
|
||||
{
|
||||
for (size_t Index = 64 / BlockWidth; Index < NumBlocks() - 1; ++Index)
|
||||
{
|
||||
checkf(Impl.Pointer[Index] != 0, TEXT("The bitset can not be represented in uint64. Please check Num()."));
|
||||
checkf(Impl[Index] != 0, TEXT("The bitset can not be represented in uint64. Please check Num()."));
|
||||
}
|
||||
|
||||
const BlockType LastBlockBitmask = Num() % BlockWidth != 0 ? (1ull << Num() % BlockWidth) - 1 : -1;
|
||||
const BlockType LastBlock = Impl.Pointer[NumBlocks() - 1] & LastBlockBitmask;
|
||||
const FBlockType LastBlockBitmask = Num() % BlockWidth != 0 ? (1ull << Num() % BlockWidth) - 1 : -1;
|
||||
const FBlockType LastBlock = Impl[NumBlocks() - 1] & LastBlockBitmask;
|
||||
|
||||
checkf(LastBlock != 0, TEXT("The bitset can not be represented in uint64. Please check Num()."));
|
||||
}
|
||||
|
||||
uint64 Result = 0;
|
||||
|
||||
static_assert(sizeof(BlockType) <= sizeof(uint64), "The block width of TStaticBitset is unexpected");
|
||||
static_assert(sizeof(FBlockType) <= sizeof(uint64), "The block width of TStaticBitset is unexpected");
|
||||
|
||||
if constexpr (sizeof(BlockType) == sizeof(uint8))
|
||||
if constexpr (sizeof(FBlockType) == sizeof(uint8))
|
||||
{
|
||||
if constexpr (N > 0) Result |= static_cast<uint64>(Impl[0]) << 0;
|
||||
if constexpr (N > 8) Result |= static_cast<uint64>(Impl[1]) << 8;
|
||||
@ -411,19 +411,19 @@ public:
|
||||
if constexpr (N > 48) Result |= static_cast<uint64>(Impl[6]) << 48;
|
||||
if constexpr (N > 56) Result |= static_cast<uint64>(Impl[7]) << 56;
|
||||
}
|
||||
else if constexpr (sizeof(BlockType) == sizeof(uint16))
|
||||
else if constexpr (sizeof(FBlockType) == sizeof(uint16))
|
||||
{
|
||||
if constexpr (N > 0) Result |= static_cast<uint64>(Impl[0]) << 0;
|
||||
if constexpr (N > 16) Result |= static_cast<uint64>(Impl[1]) << 16;
|
||||
if constexpr (N > 32) Result |= static_cast<uint64>(Impl[2]) << 32;
|
||||
if constexpr (N > 48) Result |= static_cast<uint64>(Impl[3]) << 48;
|
||||
}
|
||||
else if constexpr (sizeof(BlockType) == sizeof(uint32))
|
||||
else if constexpr (sizeof(FBlockType) == sizeof(uint32))
|
||||
{
|
||||
if constexpr (N > 0) Result |= static_cast<uint64>(Impl[0]) << 0;
|
||||
if constexpr (N > 32) Result |= static_cast<uint64>(Impl[1]) << 32;
|
||||
}
|
||||
else if constexpr (sizeof(BlockType) == sizeof(uint64))
|
||||
else if constexpr (sizeof(FBlockType) == sizeof(uint64))
|
||||
{
|
||||
if constexpr (N > 0) Result |= static_cast<uint64>(Impl[0]) << 0;
|
||||
}
|
||||
@ -435,20 +435,20 @@ public:
|
||||
}
|
||||
|
||||
/** @return The pointer to the underlying element storage. */
|
||||
NODISCARD FORCEINLINE constexpr BlockType* GetData() { return Impl; }
|
||||
NODISCARD FORCEINLINE constexpr const BlockType* GetData() const { return Impl; }
|
||||
NODISCARD FORCEINLINE constexpr FBlockType* GetData() { return Impl; }
|
||||
NODISCARD FORCEINLINE constexpr const FBlockType* GetData() const { return Impl; }
|
||||
|
||||
/** @return The iterator to the first or end bit. */
|
||||
NODISCARD FORCEINLINE constexpr Iterator Begin() { return Iterator(this, Impl, 0); }
|
||||
NODISCARD FORCEINLINE constexpr ConstIterator Begin() const { return ConstIterator(this, Impl, 0); }
|
||||
NODISCARD FORCEINLINE constexpr Iterator End() { return Iterator(this, Impl, Num()); }
|
||||
NODISCARD FORCEINLINE constexpr ConstIterator End() const { return ConstIterator(this, Impl, Num()); }
|
||||
NODISCARD FORCEINLINE constexpr FIterator Begin() { return FIterator(this, Impl, 0); }
|
||||
NODISCARD FORCEINLINE constexpr FConstIterator Begin() const { return FConstIterator(this, Impl, 0); }
|
||||
NODISCARD FORCEINLINE constexpr FIterator End() { return FIterator(this, Impl, Num()); }
|
||||
NODISCARD FORCEINLINE constexpr FConstIterator End() const { return FConstIterator(this, Impl, Num()); }
|
||||
|
||||
/** @return The reverse iterator to the first or end bit. */
|
||||
NODISCARD FORCEINLINE constexpr ReverseIterator RBegin() { return ReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE constexpr ConstReverseIterator RBegin() const { return ConstReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE constexpr ReverseIterator REnd() { return ReverseIterator(Begin()); }
|
||||
NODISCARD FORCEINLINE constexpr ConstReverseIterator REnd() const { return ConstReverseIterator(Begin()); }
|
||||
NODISCARD FORCEINLINE constexpr FReverseIterator RBegin() { return FReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE constexpr FConstReverseIterator RBegin() const { return FConstReverseIterator(End()); }
|
||||
NODISCARD FORCEINLINE constexpr FReverseIterator REnd() { return FReverseIterator(Begin()); }
|
||||
NODISCARD FORCEINLINE constexpr FConstReverseIterator REnd() const { return FConstReverseIterator(Begin()); }
|
||||
|
||||
/** @return The number of bits in the bitset. */
|
||||
NODISCARD FORCEINLINE constexpr size_t Num() const { return N; }
|
||||
@ -460,17 +460,17 @@ public:
|
||||
NODISCARD FORCEINLINE constexpr bool IsEmpty() const { return Num() == 0; }
|
||||
|
||||
/** @return true if the iterator is valid, false otherwise. */
|
||||
NODISCARD FORCEINLINE constexpr bool IsValidIterator(ConstIterator Iter) const { return Begin() <= Iter && Iter <= End(); }
|
||||
NODISCARD FORCEINLINE constexpr bool IsValidIterator(FConstIterator Iter) const { return Begin() <= Iter && Iter <= End(); }
|
||||
|
||||
/** @return The reference to the requested bit. */
|
||||
NODISCARD FORCEINLINE constexpr Reference operator[](size_t Index) { checkf(Index < Num(), TEXT("Read access violation. Please check IsValidIterator().")); return *(Begin() + Index); }
|
||||
NODISCARD FORCEINLINE constexpr ConstReference operator[](size_t Index) const { checkf(Index < Num(), TEXT("Read access violation. Please check IsValidIterator().")); return *(Begin() + Index); }
|
||||
NODISCARD FORCEINLINE constexpr FReference operator[](size_t Index) { checkf(Index < Num(), TEXT("Read access violation. Please check IsValidIterator().")); return *(Begin() + Index); }
|
||||
NODISCARD FORCEINLINE constexpr FConstReference operator[](size_t Index) const { checkf(Index < Num(), TEXT("Read access violation. Please check IsValidIterator().")); return *(Begin() + Index); }
|
||||
|
||||
/** @return The reference to the first or last bit. */
|
||||
NODISCARD FORCEINLINE constexpr Reference Front() { return *Begin(); }
|
||||
NODISCARD FORCEINLINE constexpr ConstReference Front() const { return *Begin(); }
|
||||
NODISCARD FORCEINLINE constexpr Reference Back() { return *(End() - 1); }
|
||||
NODISCARD FORCEINLINE constexpr ConstReference Back() const { return *(End() - 1); }
|
||||
NODISCARD FORCEINLINE constexpr FReference Front() { return *Begin(); }
|
||||
NODISCARD FORCEINLINE constexpr FConstReference Front() const { return *Begin(); }
|
||||
NODISCARD FORCEINLINE constexpr FReference Back() { return *(End() - 1); }
|
||||
NODISCARD FORCEINLINE constexpr FConstReference Back() const { return *(End() - 1); }
|
||||
|
||||
/** Overloads the GetTypeHash algorithm for TStaticBitset. */
|
||||
NODISCARD friend FORCEINLINE constexpr size_t GetTypeHash(const TStaticBitset& A)
|
||||
@ -484,7 +484,7 @@ public:
|
||||
Result = HashCombine(Result, GetTypeHash(A.Impl[Index]));
|
||||
}
|
||||
|
||||
const BlockType LastBlockBitmask = A.Num() % BlockWidth != 0 ? (1ull << A.Num() % BlockWidth) - 1 : -1;
|
||||
const FBlockType LastBlockBitmask = A.Num() % BlockWidth != 0 ? (1ull << A.Num() % BlockWidth) - 1 : -1;
|
||||
|
||||
return HashCombine(Result, GetTypeHash(A.Impl[A.NumBlocks() - 1] & LastBlockBitmask));
|
||||
}
|
||||
@ -496,21 +496,21 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
BlockType Impl[N != 0 ? (N + BlockWidth - 1) / BlockWidth : 1];
|
||||
FBlockType Impl[N != 0 ? (N + BlockWidth - 1) / BlockWidth : 1];
|
||||
|
||||
public:
|
||||
|
||||
class Reference final : private FSingleton
|
||||
class FReference final : private FSingleton
|
||||
{
|
||||
public:
|
||||
|
||||
FORCEINLINE constexpr Reference& operator=(bool InValue) { Data = (Data & ~Mask) | (InValue ? Mask : 0); return *this; }
|
||||
FORCEINLINE constexpr FReference& operator=(bool InValue) { Data = (Data & ~Mask) | (InValue ? Mask : 0); return *this; }
|
||||
|
||||
FORCEINLINE constexpr Reference& operator=(const Reference& InValue) { *this = static_cast<bool>(InValue); return *this; }
|
||||
FORCEINLINE constexpr FReference& operator=(const FReference& InValue) { *this = static_cast<bool>(InValue); return *this; }
|
||||
|
||||
FORCEINLINE constexpr Reference& operator&=(bool InValue) { Data &= InValue ? -1 : ~Mask; return *this; }
|
||||
FORCEINLINE constexpr Reference& operator|=(bool InValue) { Data |= InValue ? Mask : 0; return *this; }
|
||||
FORCEINLINE constexpr Reference& operator^=(bool InValue) { *this = InValue ^ *this; return *this; }
|
||||
FORCEINLINE constexpr FReference& operator&=(bool InValue) { Data &= InValue ? -1 : ~Mask; return *this; }
|
||||
FORCEINLINE constexpr FReference& operator|=(bool InValue) { Data |= InValue ? Mask : 0; return *this; }
|
||||
FORCEINLINE constexpr FReference& operator^=(bool InValue) { *this = InValue ^ *this; return *this; }
|
||||
|
||||
FORCEINLINE constexpr bool operator~() const { return !*this; }
|
||||
|
||||
@ -518,14 +518,14 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
FORCEINLINE constexpr Reference(BlockType& InData, BlockType InMask)
|
||||
FORCEINLINE constexpr FReference(FBlockType& InData, FBlockType InMask)
|
||||
: Data(InData), Mask(InMask)
|
||||
{ }
|
||||
|
||||
BlockType& Data;
|
||||
BlockType Mask;
|
||||
FBlockType& Data;
|
||||
FBlockType Mask;
|
||||
|
||||
friend Iterator;
|
||||
friend FIterator;
|
||||
|
||||
};
|
||||
|
||||
@ -538,7 +538,7 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
using ElementType = bool;
|
||||
using FElementType = bool;
|
||||
|
||||
FORCEINLINE constexpr TIteratorImpl() = default;
|
||||
|
||||
@ -561,8 +561,8 @@ private:
|
||||
|
||||
NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TIteratorImpl& LHS, const TIteratorImpl& RHS) { check(LHS.Pointer == RHS.Pointer); return LHS.BitOffset <=> RHS.BitOffset; }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr Reference operator*() const requires (!bConst) { CheckThis(true); return Reference(*(Pointer + BitOffset / BlockWidth), 1ull << BitOffset % BlockWidth); }
|
||||
NODISCARD FORCEINLINE constexpr ConstReference operator*() const requires ( bConst) { CheckThis(true); return (*(Pointer + BitOffset / BlockWidth) & (1ull << BitOffset % BlockWidth)); }
|
||||
NODISCARD FORCEINLINE constexpr FReference operator*() const requires (!bConst) { CheckThis(true); return FReference(*(Pointer + BitOffset / BlockWidth), 1ull << BitOffset % BlockWidth); }
|
||||
NODISCARD FORCEINLINE constexpr FConstReference operator*() const requires ( bConst) { CheckThis(true); return (*(Pointer + BitOffset / BlockWidth) & (1ull << BitOffset % BlockWidth)); }
|
||||
|
||||
NODISCARD FORCEINLINE constexpr auto operator[](ptrdiff Index) const { TIteratorImpl Temp = *this + Index; return *Temp; }
|
||||
|
||||
@ -588,17 +588,17 @@ private:
|
||||
const TStaticBitset* Owner = nullptr;
|
||||
# endif
|
||||
|
||||
using BlockPtr = TConditional<bConst, const BlockType*, BlockType*>;
|
||||
using FBlockPtr = TConditional<bConst, const FBlockType*, FBlockType*>;
|
||||
|
||||
BlockPtr Pointer = nullptr;
|
||||
size_t BitOffset = 0;
|
||||
FBlockPtr Pointer = nullptr;
|
||||
size_t BitOffset = 0;
|
||||
|
||||
# if DO_CHECK
|
||||
FORCEINLINE constexpr TIteratorImpl(const TStaticBitset* InContainer, BlockPtr InPointer, size_t Offset)
|
||||
FORCEINLINE constexpr TIteratorImpl(const TStaticBitset* InContainer, FBlockPtr InPointer, size_t Offset)
|
||||
: Owner(InContainer), Pointer(InPointer), BitOffset(Offset)
|
||||
{ }
|
||||
# else
|
||||
FORCEINLINE constexpr TIteratorImpl(const TStaticBitset* InContainer, BlockPtr InPointer, size_t Offset)
|
||||
FORCEINLINE constexpr TIteratorImpl(const TStaticBitset* InContainer, FBlockPtr InPointer, size_t Offset)
|
||||
: Pointer(InPointer), BitOffset(Offset)
|
||||
{ }
|
||||
# endif
|
||||
|
Reference in New Issue
Block a user