diff --git a/Redcraft.Utility/Source/Private/Testing/ContainersTesting.cpp b/Redcraft.Utility/Source/Private/Testing/ContainersTesting.cpp index ad21371..785c44f 100644 --- a/Redcraft.Utility/Source/Private/Testing/ContainersTesting.cpp +++ b/Redcraft.Utility/Source/Private/Testing/ContainersTesting.cpp @@ -280,7 +280,7 @@ void TestBitset() FBitset BitsetXORA = BitsetA; BitsetXORA &= BitsetB; FBitset BitsetXORB = BitsetB; BitsetXORB &= BitsetA; - + uint64 IntANDA = IntA; IntANDA &= IntB; uint32 IntANDB = IntB; IntANDB &= IntA; @@ -297,7 +297,7 @@ void TestBitset() always_check((BitsetXORA.ToIntegral() == IntXORA)); always_check((BitsetXORB.ToIntegral() == IntXORB)); } - + { FBitset BitsetA(64, 0x0139'0239'0339'0439ull); uint64 IntA = 0x0139'0239'0339'0439ull; @@ -420,7 +420,7 @@ void TestStaticBitset() TStaticBitset<32> BitsetXORA = BitsetA; BitsetXORA &= BitsetB; TStaticBitset<32> BitsetXORB = BitsetB; BitsetXORB &= BitsetA; - + uint32 IntANDA = IntA; IntANDA &= IntB; uint32 IntANDB = IntB; IntANDB &= IntA; @@ -437,7 +437,7 @@ void TestStaticBitset() always_check((BitsetXORA.ToIntegral() == IntXORA)); always_check((BitsetXORB.ToIntegral() == IntXORB)); } - + { TStaticBitset<32> BitsetA(0x0139'0239ull); uint32 IntA = 0x0139'0239ull; @@ -589,7 +589,7 @@ void TestList() List.PopBack(); always_check((List == TList({ 1, 2, 3, 4, 5 }))); - + List.EmplaceFront(1) = 0; always_check((List == TList({ 0, 1, 2, 3, 4, 5 }))); diff --git a/Redcraft.Utility/Source/Public/Containers/Array.h b/Redcraft.Utility/Source/Public/Containers/Array.h index a70b256..637e8ff 100644 --- a/Redcraft.Utility/Source/Public/Containers/Array.h +++ b/Redcraft.Utility/Source/Public/Containers/Array.h @@ -11,6 +11,7 @@ #include "Memory/MemoryOperator.h" #include "Memory/ObserverPointer.h" #include "Miscellaneous/AssertionMacros.h" +#include "Miscellaneous/ConstantIterator.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) @@ -57,16 +58,8 @@ public: /** Constructs the container with 'Count' copies of elements with 'InValue'. */ TArray(size_t Count, const ElementType& InValue) requires (CCopyConstructible) - { - Impl.ArrayNum = Count; - Impl.ArrayMax = Impl->CalculateSlackReserve(Num()); - Impl.Pointer = Impl->Allocate(Max()); - - for (size_t Index = 0; Index < Num(); ++Index) - { - new (Impl.Pointer + Index) ElementType(InValue); - } - } + : TArray(MakeCountedConstantIterator(InValue, Count), DefaultSentinel) + { } /** Constructs the container with the contents of the range ['First', 'Last'). */ template S> requires (CConstructibleFrom> && CMovable) @@ -412,98 +405,7 @@ public: { checkf(IsValidIterator(Iter), TEXT("Read access violation. Please check IsValidIterator().")); - const size_t InsertIndex = Iter - Begin(); - - if (Count == 0) return Iterator(this, Impl.Pointer + InsertIndex); - - const size_t NumToAllocate = Num() + Count > Max() ? Impl->CalculateSlackGrow(Num() + Count, Max()) : Max(); - - check(NumToAllocate >= Num() + Count); - - if (NumToAllocate != Max()) - { - ElementType* OldAllocation = Impl.Pointer; - const size_t NumToDestruct = Num(); - - Impl.ArrayNum = Num() + Count; - Impl.ArrayMax = NumToAllocate; - Impl.Pointer = Impl->Allocate(Max()); - - Memory::MoveConstruct(Impl.Pointer, OldAllocation, InsertIndex); - - for (size_t Index = InsertIndex; Index != InsertIndex + Count; ++Index) - { - new (Impl.Pointer + Index) ElementType(InValue); - } - - Memory::MoveConstruct(Impl.Pointer + InsertIndex + Count, OldAllocation + InsertIndex, NumToDestruct - InsertIndex); - - Memory::Destruct(OldAllocation, NumToDestruct); - Impl->Deallocate(OldAllocation); - - return Iterator(this, Impl.Pointer + InsertIndex); - } - - /* - * NO(XA) - No Operation - * IA(AB) - Insert Assignment - * IC(BC) - Insert Construction - * MA(CD) - Move Assignment - * MC(DO) - Move Construction - * - * IR(AC) - Insert Range - * UI(UO) - Uninitialized - * - * |X|-------------------| |-UI-|O| - * |X|----|A|-IR-| C|-----------|O| - * |X|-NO-|A|-IA-|BC|-MA-|D|-MC-|O| - * - * |X|-----------------| |-UI-|O| - * |X|----------|A|-IR-| CD|----|O| - * |X|----NO----|A|-IA-|BCD|-MC-|O| - * - * |X|-----------| |-----UI-----|O| - * |X|----|A|----IR-----|C |----|O| - * |X|-NO-|A|-IA-|B|-IC-|CD|-MC-|O| - * - * |X|----------------| |-UI-| O| - * |X|----------------|A |-IR-|C O| - * |X|-------NO-------|AB|-IC-|CDO| - * - * |X|-----------| |----UI----| O| - * |X|----------------|A |-IR-|C O| - * |X|-------NO-------|AB|-IC-|CDO| - */ - - const size_t IndexA = InsertIndex; - const size_t IndexC = InsertIndex + Count; - const size_t IndexB = Num() > IndexA ? (Num() < IndexC ? Num() : IndexC) : IndexA; - const size_t IndexD = Num() > IndexC ? Num() : IndexC; - const size_t IndexO = Num() + Count; - - for (size_t TargetIndex = IndexO - 1; TargetIndex != IndexD - 1; --TargetIndex) - { - new (Impl.Pointer + TargetIndex) ElementType(MoveTemp(Impl.Pointer[TargetIndex - Count])); - } - - for (size_t TargetIndex = IndexD - 1; TargetIndex != IndexC - 1; --TargetIndex) - { - Impl.Pointer[TargetIndex] = MoveTemp(Impl.Pointer[TargetIndex - Count]); - } - - for (size_t TargetIndex = IndexA; TargetIndex != IndexB; ++TargetIndex) - { - Impl.Pointer[TargetIndex] = InValue; - } - - for (size_t TargetIndex = IndexB; TargetIndex != IndexC; ++TargetIndex) - { - new (Impl.Pointer + TargetIndex) ElementType(InValue); - } - - Impl.ArrayNum = Num() + Count; - - return Iterator(this, Impl.Pointer + InsertIndex); + return Insert(Iter, MakeCountedConstantIterator(InValue, Count), DefaultSentinel); } /** Inserts elements from range ['First', 'Last') before 'Iter'. */ @@ -550,14 +452,43 @@ public: return Iterator(this, Impl.Pointer + InsertIndex); } + /* + * NO(XA) - No Operation + * IA(AB) - Insert Assignment + * IC(BC) - Insert Construction + * MA(CD) - Move Assignment + * MC(DO) - Move Construction + * + * IR(AC) - Insert Range + * UI(UO) - Uninitialized + * + * |X|-------------------| |-UI-|O| + * |X|----|A|-IR-| C|-----------|O| + * |X|-NO-|A|-IA-|BC|-MA-|D|-MC-|O| + * + * |X|-----------------| |-UI-|O| + * |X|----------|A|-IR-| CD|----|O| + * |X|----NO----|A|-IA-|BCD|-MC-|O| + * + * |X|-----------| |-----UI-----|O| + * |X|----|A|----IR-----|C |----|O| + * |X|-NO-|A|-IA-|B|-IC-|CD|-MC-|O| + * + * |X|----------------| |-UI-| O| + * |X|----------------|A |-IR-|C O| + * |X|-------NO-------|AB|-IC-|CDO| + * + * |X|-----------| |----UI----| O| + * |X|----------------|A |-IR-|C O| + * |X|-------NO-------|AB|-IC-|CDO| + */ + const size_t IndexA = InsertIndex; const size_t IndexC = InsertIndex + Count; const size_t IndexB = Num() > IndexA ? (Num() < IndexC ? Num() : IndexC) : IndexA; const size_t IndexD = Num() > IndexC ? Num() : IndexC; const size_t IndexO = Num() + Count; - size_t TargetIndex = Num() + Count - 1; - for (size_t TargetIndex = IndexO - 1; TargetIndex != IndexD - 1; --TargetIndex) { new (Impl.Pointer + TargetIndex) ElementType(MoveTemp(Impl.Pointer[TargetIndex - Count])); diff --git a/Redcraft.Utility/Source/Public/Containers/List.h b/Redcraft.Utility/Source/Public/Containers/List.h index aeb7077..16aa4e4 100644 --- a/Redcraft.Utility/Source/Public/Containers/List.h +++ b/Redcraft.Utility/Source/Public/Containers/List.h @@ -11,6 +11,7 @@ #include "Memory/MemoryOperator.h" #include "Memory/ObserverPointer.h" #include "Miscellaneous/AssertionMacros.h" +#include "Miscellaneous/ConstantIterator.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) @@ -75,25 +76,9 @@ public: } /** Constructs the container with 'Count' copies of elements with 'InValue'. */ - TList(size_t Count, const ElementType& InValue) requires (CCopyable) : TList() - { - FNode* EndNode = Impl.HeadNode->PrevNode; - - while (Count > Impl.ListNum) - { - FNode* Node = new (Impl->Allocate(1)) FNode(InPlace, InValue); - - EndNode->NextNode = Node; - Node->PrevNode = EndNode; - - ++Impl.ListNum; - - EndNode = Node; - } - - EndNode->NextNode = Impl.HeadNode; - Impl.HeadNode->PrevNode = EndNode; - } + TList(size_t Count, const ElementType& InValue) requires (CCopyable) + : TList(MakeCountedConstantIterator(InValue, Count), DefaultSentinel) + { } /** Constructs the container with the contents of the range ['First', 'Last'). */ template S> requires (CConstructibleFrom>) @@ -260,35 +245,7 @@ public: /** Inserts 'Count' copies of the 'InValue' before 'Iter' in the container. */ Iterator Insert(ConstIterator Iter, size_t Count, const ElementType& InValue) requires (CCopyConstructible) { - if (Count == 0) return Iterator(Iter.Pointer); - - FNode* InsertNode = Iter.Pointer->PrevNode; - - const auto InsertOnce = [&]() -> FNode* - { - FNode* Node = new (Impl->Allocate(1)) FNode(InPlace, InValue); - - InsertNode->NextNode = Node; - Node->PrevNode = InsertNode; - - ++Impl.ListNum; - - InsertNode = Node; - - return Node; - }; - - FNode* FirstNode = InsertOnce(); - - for (size_t Index = 0; Index != Count - 1; ++Index) - { - InsertOnce(); - } - - InsertNode->NextNode = Iter.Pointer; - Iter.Pointer->PrevNode = InsertNode; - - return Iterator(FirstNode); + return Insert(Iter, MakeCountedConstantIterator(InValue, Count), DefaultSentinel); } /** Inserts elements from range ['First', 'Last') before 'Iter'. */ @@ -334,7 +291,7 @@ public: Iterator Emplace(ConstIterator Iter, Ts&&... Args) { FNode* Node = new (Impl->Allocate(1)) FNode(InPlace, Forward(Args)...); - + ++Impl.ListNum; Node->PrevNode = Iter.Pointer->PrevNode; @@ -430,7 +387,7 @@ public: Erase(First, End()); Impl.ListNum = Count; - + return; }