perf(containers): refactor TArray and TList some functions by TConstantIterator
This commit is contained in:
		| @@ -280,7 +280,7 @@ void TestBitset() | |||||||
|  |  | ||||||
| 		FBitset BitsetXORA = BitsetA; BitsetXORA &= BitsetB; | 		FBitset BitsetXORA = BitsetA; BitsetXORA &= BitsetB; | ||||||
| 		FBitset BitsetXORB = BitsetB; BitsetXORB &= BitsetA; | 		FBitset BitsetXORB = BitsetB; BitsetXORB &= BitsetA; | ||||||
| 		 |  | ||||||
| 		uint64 IntANDA = IntA; IntANDA &= IntB; | 		uint64 IntANDA = IntA; IntANDA &= IntB; | ||||||
| 		uint32 IntANDB = IntB; IntANDB &= IntA; | 		uint32 IntANDB = IntB; IntANDB &= IntA; | ||||||
|  |  | ||||||
| @@ -297,7 +297,7 @@ void TestBitset() | |||||||
| 		always_check((BitsetXORA.ToIntegral() == IntXORA)); | 		always_check((BitsetXORA.ToIntegral() == IntXORA)); | ||||||
| 		always_check((BitsetXORB.ToIntegral() == IntXORB)); | 		always_check((BitsetXORB.ToIntegral() == IntXORB)); | ||||||
| 	} | 	} | ||||||
| 	 |  | ||||||
| 	{ | 	{ | ||||||
| 		FBitset BitsetA(64, 0x0139'0239'0339'0439ull); | 		FBitset BitsetA(64, 0x0139'0239'0339'0439ull); | ||||||
| 		uint64  IntA =      0x0139'0239'0339'0439ull; | 		uint64  IntA =      0x0139'0239'0339'0439ull; | ||||||
| @@ -420,7 +420,7 @@ void TestStaticBitset() | |||||||
|  |  | ||||||
| 		TStaticBitset<32> BitsetXORA = BitsetA; BitsetXORA &= BitsetB; | 		TStaticBitset<32> BitsetXORA = BitsetA; BitsetXORA &= BitsetB; | ||||||
| 		TStaticBitset<32> BitsetXORB = BitsetB; BitsetXORB &= BitsetA; | 		TStaticBitset<32> BitsetXORB = BitsetB; BitsetXORB &= BitsetA; | ||||||
| 		 |  | ||||||
| 		uint32 IntANDA = IntA; IntANDA &= IntB; | 		uint32 IntANDA = IntA; IntANDA &= IntB; | ||||||
| 		uint32 IntANDB = IntB; IntANDB &= IntA; | 		uint32 IntANDB = IntB; IntANDB &= IntA; | ||||||
|  |  | ||||||
| @@ -437,7 +437,7 @@ void TestStaticBitset() | |||||||
| 		always_check((BitsetXORA.ToIntegral() == IntXORA)); | 		always_check((BitsetXORA.ToIntegral() == IntXORA)); | ||||||
| 		always_check((BitsetXORB.ToIntegral() == IntXORB)); | 		always_check((BitsetXORB.ToIntegral() == IntXORB)); | ||||||
| 	} | 	} | ||||||
| 	 |  | ||||||
| 	{ | 	{ | ||||||
| 		TStaticBitset<32> BitsetA(0x0139'0239ull); | 		TStaticBitset<32> BitsetA(0x0139'0239ull); | ||||||
| 		uint32            IntA =  0x0139'0239ull; | 		uint32            IntA =  0x0139'0239ull; | ||||||
| @@ -589,7 +589,7 @@ void TestList() | |||||||
|  |  | ||||||
| 		List.PopBack(); | 		List.PopBack(); | ||||||
| 		always_check((List == TList<int32>({ 1, 2, 3, 4, 5 }))); | 		always_check((List == TList<int32>({ 1, 2, 3, 4, 5 }))); | ||||||
| 		 |  | ||||||
| 		List.EmplaceFront(1) = 0; | 		List.EmplaceFront(1) = 0; | ||||||
| 		always_check((List == TList<int32>({ 0, 1, 2, 3, 4, 5 }))); | 		always_check((List == TList<int32>({ 0, 1, 2, 3, 4, 5 }))); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ | |||||||
| #include "Memory/MemoryOperator.h" | #include "Memory/MemoryOperator.h" | ||||||
| #include "Memory/ObserverPointer.h" | #include "Memory/ObserverPointer.h" | ||||||
| #include "Miscellaneous/AssertionMacros.h" | #include "Miscellaneous/AssertionMacros.h" | ||||||
|  | #include "Miscellaneous/ConstantIterator.h" | ||||||
|  |  | ||||||
| NAMESPACE_REDCRAFT_BEGIN | NAMESPACE_REDCRAFT_BEGIN | ||||||
| NAMESPACE_MODULE_BEGIN(Redcraft) | NAMESPACE_MODULE_BEGIN(Redcraft) | ||||||
| @@ -57,16 +58,8 @@ public: | |||||||
|  |  | ||||||
| 	/** Constructs the container with 'Count' copies of elements with 'InValue'. */ | 	/** Constructs the container with 'Count' copies of elements with 'InValue'. */ | ||||||
| 	TArray(size_t Count, const ElementType& InValue) requires (CCopyConstructible<ElementType>) | 	TArray(size_t Count, const ElementType& InValue) requires (CCopyConstructible<ElementType>) | ||||||
| 	{ | 		: TArray(MakeCountedConstantIterator(InValue, Count), DefaultSentinel) | ||||||
| 		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); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/** Constructs the container with the contents of the range ['First', 'Last'). */ | 	/** Constructs the container with the contents of the range ['First', 'Last'). */ | ||||||
| 	template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<ElementType, TIteratorReferenceType<I>> && CMovable<ElementType>) | 	template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<ElementType, TIteratorReferenceType<I>> && CMovable<ElementType>) | ||||||
| @@ -412,98 +405,7 @@ public: | |||||||
| 	{ | 	{ | ||||||
| 		checkf(IsValidIterator(Iter), TEXT("Read access violation. Please check IsValidIterator().")); | 		checkf(IsValidIterator(Iter), TEXT("Read access violation. Please check IsValidIterator().")); | ||||||
|  |  | ||||||
| 		const size_t InsertIndex = Iter - Begin(); | 		return Insert(Iter, MakeCountedConstantIterator(InValue, Count), DefaultSentinel); | ||||||
|  |  | ||||||
| 		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<ElementType>(Impl.Pointer, OldAllocation, InsertIndex); |  | ||||||
|  |  | ||||||
| 			for (size_t Index = InsertIndex; Index != InsertIndex + Count; ++Index) |  | ||||||
| 			{ |  | ||||||
| 				new (Impl.Pointer + Index) ElementType(InValue); |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			Memory::MoveConstruct<ElementType>(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); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/** Inserts elements from range ['First', 'Last') before 'Iter'. */ | 	/** Inserts elements from range ['First', 'Last') before 'Iter'. */ | ||||||
| @@ -550,14 +452,43 @@ public: | |||||||
| 				return Iterator(this, Impl.Pointer + InsertIndex); | 				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 IndexA = InsertIndex; | ||||||
| 			const size_t IndexC = InsertIndex + Count; | 			const size_t IndexC = InsertIndex + Count; | ||||||
| 			const size_t IndexB = Num() > IndexA ? (Num() < IndexC ? Num() : IndexC) : IndexA; | 			const size_t IndexB = Num() > IndexA ? (Num() < IndexC ? Num() : IndexC) : IndexA; | ||||||
| 			const size_t IndexD = Num() > IndexC ? Num() : IndexC; | 			const size_t IndexD = Num() > IndexC ? Num() : IndexC; | ||||||
| 			const size_t IndexO = Num() + Count; | 			const size_t IndexO = Num() + Count; | ||||||
|  |  | ||||||
| 			size_t TargetIndex = Num() + Count - 1; |  | ||||||
|  |  | ||||||
| 			for (size_t TargetIndex = IndexO - 1; TargetIndex != IndexD - 1; --TargetIndex) | 			for (size_t TargetIndex = IndexO - 1; TargetIndex != IndexD - 1; --TargetIndex) | ||||||
| 			{ | 			{ | ||||||
| 				new (Impl.Pointer + TargetIndex) ElementType(MoveTemp(Impl.Pointer[TargetIndex - Count])); | 				new (Impl.Pointer + TargetIndex) ElementType(MoveTemp(Impl.Pointer[TargetIndex - Count])); | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ | |||||||
| #include "Memory/MemoryOperator.h" | #include "Memory/MemoryOperator.h" | ||||||
| #include "Memory/ObserverPointer.h" | #include "Memory/ObserverPointer.h" | ||||||
| #include "Miscellaneous/AssertionMacros.h" | #include "Miscellaneous/AssertionMacros.h" | ||||||
|  | #include "Miscellaneous/ConstantIterator.h" | ||||||
|  |  | ||||||
| NAMESPACE_REDCRAFT_BEGIN | NAMESPACE_REDCRAFT_BEGIN | ||||||
| NAMESPACE_MODULE_BEGIN(Redcraft) | NAMESPACE_MODULE_BEGIN(Redcraft) | ||||||
| @@ -75,25 +76,9 @@ public: | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/** Constructs the container with 'Count' copies of elements with 'InValue'. */ | 	/** Constructs the container with 'Count' copies of elements with 'InValue'. */ | ||||||
| 	TList(size_t Count, const ElementType& InValue) requires (CCopyable<ElementType>) : TList() | 	TList(size_t Count, const ElementType& InValue) requires (CCopyable<ElementType>) | ||||||
| 	{ | 		: TList(MakeCountedConstantIterator(InValue, Count), DefaultSentinel) | ||||||
| 		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; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/** Constructs the container with the contents of the range ['First', 'Last'). */ | 	/** Constructs the container with the contents of the range ['First', 'Last'). */ | ||||||
| 	template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<ElementType, TIteratorReferenceType<I>>) | 	template <CInputIterator I, CSentinelFor<I> S> requires (CConstructibleFrom<ElementType, TIteratorReferenceType<I>>) | ||||||
| @@ -260,35 +245,7 @@ public: | |||||||
| 	/** Inserts 'Count' copies of the 'InValue' before 'Iter' in the container. */ | 	/** Inserts 'Count' copies of the 'InValue' before 'Iter' in the container. */ | ||||||
| 	Iterator Insert(ConstIterator Iter, size_t Count, const ElementType& InValue) requires (CCopyConstructible<ElementType>) | 	Iterator Insert(ConstIterator Iter, size_t Count, const ElementType& InValue) requires (CCopyConstructible<ElementType>) | ||||||
| 	{ | 	{ | ||||||
| 		if (Count == 0) return Iterator(Iter.Pointer); | 		return Insert(Iter, MakeCountedConstantIterator(InValue, Count), DefaultSentinel); | ||||||
|  |  | ||||||
| 		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); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/** Inserts elements from range ['First', 'Last') before 'Iter'. */ | 	/** Inserts elements from range ['First', 'Last') before 'Iter'. */ | ||||||
| @@ -334,7 +291,7 @@ public: | |||||||
| 	Iterator Emplace(ConstIterator Iter, Ts&&... Args) | 	Iterator Emplace(ConstIterator Iter, Ts&&... Args) | ||||||
| 	{ | 	{ | ||||||
| 		FNode* Node = new (Impl->Allocate(1)) FNode(InPlace, Forward<Ts>(Args)...); | 		FNode* Node = new (Impl->Allocate(1)) FNode(InPlace, Forward<Ts>(Args)...); | ||||||
| 		 |  | ||||||
| 		++Impl.ListNum; | 		++Impl.ListNum; | ||||||
|  |  | ||||||
| 		Node->PrevNode = Iter.Pointer->PrevNode; | 		Node->PrevNode = Iter.Pointer->PrevNode; | ||||||
| @@ -430,7 +387,7 @@ public: | |||||||
| 			Erase(First, End()); | 			Erase(First, End()); | ||||||
|  |  | ||||||
| 			Impl.ListNum = Count; | 			Impl.ListNum = Count; | ||||||
| 			 |  | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user