2023-02-08 15:30:46 +00:00
# pragma once
# include "CoreTypes.h"
2023-02-13 10:51:53 +00:00
# include "Memory/Allocator.h"
2023-02-08 15:30:46 +00:00
# include "Templates/Utility.h"
# include "Templates/TypeHash.h"
# include "Templates/Container.h"
2023-02-12 15:46:30 +00:00
# include "Containers/Iterator.h"
2023-02-08 15:30:46 +00:00
# include "TypeTraits/TypeTraits.h"
2023-02-12 15:46:30 +00:00
# include "Miscellaneous/Compare.h"
2023-02-08 15:30:46 +00:00
# include "Memory/MemoryOperator.h"
# include "Memory/ObserverPointer.h"
# include "Miscellaneous/AssertionMacros.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN ( Redcraft )
NAMESPACE_MODULE_BEGIN ( Utility )
/** Dynamic array. The elements are stored contiguously, which means that elements can be accessed not only through iterators, but also using offsets to regular pointers to elements. */
2023-02-27 15:25:40 +00:00
template < CElementalObject T , CInstantiableAllocator Allocator = FHeapAllocator > requires ( ! CConst < T > )
2023-02-08 15:30:46 +00:00
class TArray final
{
2023-03-04 11:12:47 +00:00
private :
template < bool bConst >
class IteratorImpl ;
2023-02-08 15:30:46 +00:00
public :
using ElementType = T ;
using AllocatorType = Allocator ;
2023-03-01 10:32:32 +00:00
using Reference = T & ;
using ConstReference = const T & ;
2023-03-04 11:12:47 +00:00
using Iterator = IteratorImpl < false > ;
using ConstIterator = IteratorImpl < true > ;
2023-02-08 15:30:46 +00:00
2023-02-13 11:26:09 +00:00
using ReverseIterator = TReverseIterator < Iterator > ;
using ConstReverseIterator = TReverseIterator < ConstIterator > ;
2023-02-12 15:46:30 +00:00
static_assert ( CContiguousIterator < Iterator > ) ;
static_assert ( CContiguousIterator < ConstIterator > ) ;
2023-02-08 15:30:46 +00:00
/** Default constructor. Constructs an empty container with a default-constructed allocator. */
2023-02-22 15:34:51 +00:00
FORCEINLINE TArray ( ) : TArray ( 0 ) { }
2023-02-08 15:30:46 +00:00
/** Constructs the container with 'Count' default instances of T. */
2023-02-22 15:34:51 +00:00
explicit TArray ( size_t Count ) requires ( CDefaultConstructible < ElementType > )
2023-02-12 15:46:30 +00:00
{
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Count ;
Impl . ArrayMax = Impl - > CalculateSlackReserve ( Num ( ) ) ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Memory : : DefaultConstruct < ElementType > ( Impl . Pointer , Num ( ) ) ;
2023-02-08 15:30:46 +00:00
}
/** Constructs the container with 'Count' copies of elements with 'InValue'. */
2023-02-22 15:34:51 +00:00
TArray ( size_t Count , const ElementType & InValue ) requires ( CCopyConstructible < ElementType > )
2023-02-08 15:30:46 +00:00
{
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Count ;
Impl . ArrayMax = Impl - > CalculateSlackReserve ( Num ( ) ) ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
for ( size_t Index = 0 ; Index < Num ( ) ; + + Index )
{
2023-03-02 14:51:45 +00:00
new ( Impl . Pointer + Index ) ElementType ( InValue ) ;
2023-02-08 15:30:46 +00:00
}
}
2023-02-12 15:46:30 +00:00
/** Constructs the container with the contents of the range ['First', 'Last'). */
template < CInputIterator I , CSentinelFor < I > S > requires ( CConstructibleFrom < ElementType , TIteratorReferenceType < I > > & & CMovable < ElementType > )
2023-02-22 15:34:51 +00:00
TArray ( I First , S Last )
2023-02-12 15:46:30 +00:00
{
if constexpr ( CForwardIterator < I > )
{
2023-03-04 11:12:47 +00:00
if ( CSizedSentinelFor < S , I > ) { checkf ( First < = Last , TEXT ( " Illegal range iterator. Please check First <= Last. " ) ) ; }
2023-02-12 15:46:30 +00:00
const size_t Count = Iteration : : Distance ( First , Last ) ;
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Count ;
Impl . ArrayMax = Impl - > CalculateSlackReserve ( Num ( ) ) ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-12 15:46:30 +00:00
for ( size_t Index = 0 ; Index ! = Count ; + + Index )
{
2023-03-02 14:51:45 +00:00
new ( Impl . Pointer + Index ) ElementType ( * First + + ) ;
2023-02-12 15:46:30 +00:00
}
}
else
{
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = 0 ;
Impl . ArrayMax = Impl - > CalculateSlackReserve ( Num ( ) ) ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-12 15:46:30 +00:00
while ( First ! = Last )
{
PushBack ( * First ) ;
+ + First ;
}
}
}
2023-02-08 15:30:46 +00:00
/** Copy constructor. Constructs the container with the copy of the contents of 'InValue'. */
2023-02-22 15:34:51 +00:00
TArray ( const TArray & InValue ) requires ( CCopyConstructible < ElementType > )
2023-02-08 15:30:46 +00:00
{
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = InValue . Num ( ) ;
Impl . ArrayMax = Impl - > CalculateSlackReserve ( Num ( ) ) ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Memory : : CopyConstruct < ElementType > ( Impl . Pointer , InValue . Impl . Pointer , Num ( ) ) ;
2023-02-08 15:30:46 +00:00
}
/** Move constructor. After the move, 'InValue' is guaranteed to be empty. */
2023-02-22 15:34:51 +00:00
TArray ( TArray & & InValue ) requires ( CMoveConstructible < ElementType > )
2023-02-08 15:30:46 +00:00
{
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = InValue . Num ( ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
if ( InValue . Impl - > IsTransferable ( InValue . Impl . Pointer ) )
2023-02-08 15:30:46 +00:00
{
2023-03-02 14:51:45 +00:00
Impl . ArrayMax = InValue . Max ( ) ;
Impl . Pointer = InValue . Impl . Pointer ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
InValue . Impl . ArrayNum = 0 ;
InValue . Impl . ArrayMax = InValue . Impl - > CalculateSlackReserve ( InValue . Num ( ) ) ;
InValue . Impl . Pointer = InValue . Impl - > Allocate ( InValue . Max ( ) ) ;
2023-02-08 15:30:46 +00:00
}
else
{
2023-03-02 14:51:45 +00:00
Impl . ArrayMax = Impl - > CalculateSlackReserve ( Num ( ) ) ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Memory : : MoveConstruct < ElementType > ( Impl . Pointer , InValue . Impl . Pointer , Num ( ) ) ;
2023-02-08 15:30:46 +00:00
}
}
/** Constructs the container with the contents of the initializer list. */
2023-02-22 15:34:51 +00:00
FORCEINLINE TArray ( initializer_list < ElementType > IL ) requires ( CCopyConstructible < ElementType > ) : TArray ( Iteration : : Begin ( IL ) , Iteration : : End ( IL ) ) { }
2023-02-08 15:30:46 +00:00
/** Destructs the array. The destructors of the elements are called and the used storage is deallocated. */
2023-02-22 15:34:51 +00:00
~ TArray ( )
2023-02-08 15:30:46 +00:00
{
2023-03-02 14:51:45 +00:00
Memory : : Destruct ( Impl . Pointer , Num ( ) ) ;
Impl - > Deallocate ( Impl . Pointer ) ;
2023-02-08 15:30:46 +00:00
}
/** Copy assignment operator. Replaces the contents with a copy of the contents of 'InValue'. */
2023-02-22 15:34:51 +00:00
TArray & operator = ( const TArray & InValue ) requires ( CCopyable < ElementType > )
2023-02-08 15:30:46 +00:00
{
if ( & InValue = = this ) UNLIKELY return * this ;
size_t NumToAllocate = InValue . Num ( ) ;
2023-03-02 14:51:45 +00:00
NumToAllocate = NumToAllocate > Max ( ) ? Impl - > CalculateSlackGrow ( InValue . Num ( ) , Max ( ) ) : NumToAllocate ;
NumToAllocate = NumToAllocate < Max ( ) ? Impl - > CalculateSlackShrink ( InValue . Num ( ) , Max ( ) ) : NumToAllocate ;
2023-02-08 15:30:46 +00:00
if ( NumToAllocate ! = Max ( ) )
{
2023-03-02 14:51:45 +00:00
Memory : : Destruct ( Impl . Pointer , Num ( ) ) ;
Impl - > Deallocate ( Impl . Pointer ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = InValue . Num ( ) ;
Impl . ArrayMax = NumToAllocate ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Memory : : CopyConstruct < ElementType > ( Impl . Pointer , InValue . Impl . Pointer , Num ( ) ) ;
2023-02-08 15:30:46 +00:00
return * this ;
}
if ( InValue . Num ( ) < = Num ( ) )
{
2023-03-02 14:51:45 +00:00
Memory : : CopyAssign ( Impl . Pointer , InValue . Impl . Pointer , InValue . Num ( ) ) ;
Memory : : Destruct ( Impl . Pointer + InValue . Num ( ) , Num ( ) - InValue . Num ( ) ) ;
2023-02-08 15:30:46 +00:00
}
else if ( InValue . Num ( ) < = Max ( ) )
{
2023-03-02 14:51:45 +00:00
Memory : : CopyAssign ( Impl . Pointer , InValue . Impl . Pointer , Num ( ) ) ;
Memory : : CopyConstruct < ElementType > ( Impl . Pointer + Num ( ) , InValue . Impl . Pointer + Num ( ) , InValue . Num ( ) - Num ( ) ) ;
2023-02-08 15:30:46 +00:00
}
else check_no_entry ( ) ;
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = InValue . Num ( ) ;
2023-02-08 15:30:46 +00:00
return * this ;
}
/** Move assignment operator. After the move, 'InValue' is guaranteed to be empty. */
2023-02-22 15:34:51 +00:00
TArray & operator = ( TArray & & InValue ) requires ( CMovable < ElementType > )
2023-02-08 15:30:46 +00:00
{
if ( & InValue = = this ) UNLIKELY return * this ;
2023-03-02 14:51:45 +00:00
if ( InValue . Impl - > IsTransferable ( InValue . Impl . Pointer ) )
2023-02-08 15:30:46 +00:00
{
2023-03-02 14:51:45 +00:00
Memory : : Destruct ( Impl . Pointer , Num ( ) ) ;
Impl - > Deallocate ( Impl . Pointer ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Impl . Pointer = InValue . Impl . Pointer ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
InValue . Impl . ArrayNum = 0 ;
InValue . Impl . ArrayMax = InValue . Impl - > CalculateSlackReserve ( InValue . Num ( ) ) ;
InValue . Impl . Pointer = InValue . Impl - > Allocate ( InValue . Max ( ) ) ;
2023-02-08 15:30:46 +00:00
return * this ;
}
size_t NumToAllocate = InValue . Num ( ) ;
2023-03-02 14:51:45 +00:00
NumToAllocate = NumToAllocate > Max ( ) ? Impl - > CalculateSlackGrow ( InValue . Num ( ) , Max ( ) ) : NumToAllocate ;
NumToAllocate = NumToAllocate < Max ( ) ? Impl - > CalculateSlackShrink ( InValue . Num ( ) , Max ( ) ) : NumToAllocate ;
2023-02-08 15:30:46 +00:00
if ( NumToAllocate ! = Max ( ) )
{
2023-03-02 14:51:45 +00:00
Memory : : Destruct ( Impl . Pointer , Num ( ) ) ;
Impl - > Deallocate ( Impl . Pointer ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = InValue . Num ( ) ;
Impl . ArrayMax = NumToAllocate ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Memory : : MoveConstruct < ElementType > ( Impl . Pointer , InValue . Impl . Pointer , Num ( ) ) ;
2023-02-08 15:30:46 +00:00
InValue . Reset ( ) ;
return * this ;
}
if ( InValue . Num ( ) < = Num ( ) )
{
2023-03-02 14:51:45 +00:00
Memory : : MoveAssign ( Impl . Pointer , InValue . Impl . Pointer , InValue . Num ( ) ) ;
Memory : : Destruct ( Impl . Pointer + InValue . Num ( ) , Num ( ) - InValue . Num ( ) ) ;
2023-02-08 15:30:46 +00:00
}
else if ( InValue . Num ( ) < = Max ( ) )
{
2023-03-02 14:51:45 +00:00
Memory : : MoveAssign ( Impl . Pointer , InValue . Impl . Pointer , Num ( ) ) ;
Memory : : MoveConstruct < ElementType > ( Impl . Pointer + Num ( ) , InValue . Impl . Pointer + Num ( ) , InValue . Num ( ) - Num ( ) ) ;
2023-02-08 15:30:46 +00:00
}
else check_no_entry ( ) ;
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = InValue . Num ( ) ;
2023-02-08 15:30:46 +00:00
InValue . Reset ( ) ;
return * this ;
}
/** Replaces the contents with those identified by initializer list. */
2023-02-22 15:34:51 +00:00
TArray & operator = ( initializer_list < ElementType > IL ) requires ( CCopyable < ElementType > )
2023-02-08 15:30:46 +00:00
{
size_t NumToAllocate = GetNum ( IL ) ;
2023-03-02 14:51:45 +00:00
NumToAllocate = NumToAllocate > Max ( ) ? Impl - > CalculateSlackGrow ( GetNum ( IL ) , Max ( ) ) : NumToAllocate ;
NumToAllocate = NumToAllocate < Max ( ) ? Impl - > CalculateSlackShrink ( GetNum ( IL ) , Max ( ) ) : NumToAllocate ;
2023-02-08 15:30:46 +00:00
if ( NumToAllocate ! = Max ( ) )
{
2023-03-02 14:51:45 +00:00
Memory : : Destruct ( Impl . Pointer , Num ( ) ) ;
Impl - > Deallocate ( Impl . Pointer ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = GetNum ( IL ) ;
Impl . ArrayMax = NumToAllocate ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Memory : : CopyConstruct < ElementType > ( Impl . Pointer , NAMESPACE_REDCRAFT : : GetData ( IL ) . Get ( ) , Num ( ) ) ;
2023-02-08 15:30:46 +00:00
return * this ;
}
if ( GetNum ( IL ) < = Num ( ) )
{
2023-03-02 14:51:45 +00:00
Memory : : CopyAssign ( Impl . Pointer , NAMESPACE_REDCRAFT : : GetData ( IL ) . Get ( ) , GetNum ( IL ) ) ;
Memory : : Destruct ( Impl . Pointer + GetNum ( IL ) , Num ( ) - GetNum ( IL ) ) ;
2023-02-08 15:30:46 +00:00
}
else if ( GetNum ( IL ) < = Max ( ) )
{
2023-03-02 14:51:45 +00:00
Memory : : CopyAssign ( Impl . Pointer , NAMESPACE_REDCRAFT : : GetData ( IL ) . Get ( ) , Num ( ) ) ;
Memory : : CopyConstruct < ElementType > ( Impl . Pointer + Num ( ) , NAMESPACE_REDCRAFT : : GetData ( IL ) . Get ( ) + Num ( ) , GetNum ( IL ) - Num ( ) ) ;
2023-02-08 15:30:46 +00:00
}
else check_no_entry ( ) ;
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = GetNum ( IL ) ;
2023-02-08 15:30:46 +00:00
return * this ;
}
/** Compares the contents of two arrays. */
2023-02-22 15:34:51 +00:00
NODISCARD friend bool operator = = ( const TArray & LHS , const TArray & RHS ) requires ( CWeaklyEqualityComparable < ElementType > )
2023-02-08 15:30:46 +00:00
{
if ( LHS . Num ( ) ! = RHS . Num ( ) ) return false ;
ConstIterator LHSIter = LHS . Begin ( ) ;
ConstIterator RHSIter = RHS . Begin ( ) ;
while ( LHSIter ! = LHS . End ( ) )
{
if ( * LHSIter ! = * RHSIter ) return false ;
+ + LHSIter ;
+ + RHSIter ;
}
check ( RHSIter = = RHS . End ( ) ) ;
return true ;
}
/** Compares the contents of two arrays. */
2023-02-22 15:34:51 +00:00
NODISCARD friend auto operator < = > ( const TArray & LHS , const TArray & RHS ) requires ( CSynthThreeWayComparable < ElementType > )
2023-02-08 15:30:46 +00:00
{
using OrderingType = TSynthThreeWayResult < ElementType > ;
if ( LHS . Num ( ) < RHS . Num ( ) ) return OrderingType : : less ;
if ( LHS . Num ( ) > RHS . Num ( ) ) return OrderingType : : greater ;
ConstIterator LHSIter = LHS . Begin ( ) ;
ConstIterator RHSIter = RHS . Begin ( ) ;
while ( LHSIter ! = LHS . End ( ) )
{
TSynthThreeWayResult < ElementType > Ordering = SynthThreeWayCompare ( * LHSIter , * RHSIter ) ;
if ( Ordering ! = OrderingType : : equivalent ) return Ordering ;
+ + LHSIter ;
+ + RHSIter ;
}
check ( RHSIter = = RHS . End ( ) ) ;
return OrderingType : : equivalent ;
}
/** Inserts 'InValue' before 'Iter' in the container. */
2023-02-22 15:34:51 +00:00
Iterator Insert ( ConstIterator Iter , const ElementType & InValue ) requires ( CCopyable < ElementType > )
2023-02-08 15:30:46 +00:00
{
checkf ( IsValidIterator ( Iter ) , TEXT ( " Read access violation. Please check IsValidIterator(). " ) ) ;
const size_t InsertIndex = Iter - Begin ( ) ;
2023-03-02 14:51:45 +00:00
const size_t NumToAllocate = Num ( ) + 1 > Max ( ) ? Impl - > CalculateSlackGrow ( Num ( ) + 1 , Max ( ) ) : Max ( ) ;
2023-02-08 15:30:46 +00:00
check ( NumToAllocate > = Num ( ) + 1 ) ;
if ( NumToAllocate ! = Max ( ) )
{
2023-03-02 14:51:45 +00:00
ElementType * OldAllocation = Impl . Pointer ;
2023-02-08 15:30:46 +00:00
const size_t NumToDestruct = Num ( ) ;
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Num ( ) + 1 ;
Impl . ArrayMax = NumToAllocate ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Memory : : MoveConstruct < ElementType > ( Impl . Pointer , OldAllocation , InsertIndex ) ;
new ( Impl . Pointer + InsertIndex ) ElementType ( InValue ) ;
Memory : : MoveConstruct < ElementType > ( Impl . Pointer + InsertIndex + 1 , OldAllocation + InsertIndex , NumToDestruct - InsertIndex ) ;
2023-02-08 15:30:46 +00:00
Memory : : Destruct ( OldAllocation , NumToDestruct ) ;
2023-03-02 14:51:45 +00:00
Impl - > Deallocate ( OldAllocation ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
return Iterator ( this , Impl . Pointer + InsertIndex ) ;
2023-02-08 15:30:46 +00:00
}
if ( InsertIndex ! = Num ( ) )
{
2023-03-02 14:51:45 +00:00
new ( Impl . Pointer + Num ( ) ) ElementType ( MoveTemp ( Impl . Pointer [ Num ( ) - 1 ] ) ) ;
2023-02-08 15:30:46 +00:00
for ( size_t Index = Num ( ) - 1 ; Index ! = InsertIndex ; - - Index )
{
2023-03-02 14:51:45 +00:00
Impl . Pointer [ Index ] = MoveTemp ( Impl . Pointer [ Index - 1 ] ) ;
2023-02-08 15:30:46 +00:00
}
2023-03-02 14:51:45 +00:00
Impl . Pointer [ InsertIndex ] = InValue ;
2023-02-08 15:30:46 +00:00
}
2023-03-02 14:51:45 +00:00
else new ( Impl . Pointer + Num ( ) ) ElementType ( InValue ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Num ( ) + 1 ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
return Iterator ( this , Impl . Pointer + InsertIndex ) ;
2023-02-08 15:30:46 +00:00
}
/** Inserts 'InValue' before 'Iter' in the container. */
2023-02-22 15:34:51 +00:00
Iterator Insert ( ConstIterator Iter , ElementType & & InValue ) requires ( CMovable < ElementType > )
2023-02-08 15:30:46 +00:00
{
checkf ( IsValidIterator ( Iter ) , TEXT ( " Read access violation. Please check IsValidIterator(). " ) ) ;
const size_t InsertIndex = Iter - Begin ( ) ;
2023-03-02 14:51:45 +00:00
const size_t NumToAllocate = Num ( ) + 1 > Max ( ) ? Impl - > CalculateSlackGrow ( Num ( ) + 1 , Max ( ) ) : Max ( ) ;
2023-02-08 15:30:46 +00:00
check ( NumToAllocate > = Num ( ) + 1 ) ;
if ( NumToAllocate ! = Max ( ) )
{
2023-03-02 14:51:45 +00:00
ElementType * OldAllocation = Impl . Pointer ;
2023-02-08 15:30:46 +00:00
const size_t NumToDestruct = Num ( ) ;
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Num ( ) + 1 ;
Impl . ArrayMax = NumToAllocate ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
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 ) ;
2023-02-08 15:30:46 +00:00
Memory : : Destruct ( OldAllocation , NumToDestruct ) ;
2023-03-02 14:51:45 +00:00
Impl - > Deallocate ( OldAllocation ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
return Iterator ( this , Impl . Pointer + InsertIndex ) ;
2023-02-08 15:30:46 +00:00
}
if ( InsertIndex ! = Num ( ) )
{
2023-03-02 14:51:45 +00:00
new ( Impl . Pointer + Num ( ) ) ElementType ( MoveTemp ( Impl . Pointer [ Num ( ) - 1 ] ) ) ;
2023-02-08 15:30:46 +00:00
for ( size_t Index = Num ( ) - 1 ; Index ! = InsertIndex ; - - Index )
{
2023-03-02 14:51:45 +00:00
Impl . Pointer [ Index ] = MoveTemp ( Impl . Pointer [ Index - 1 ] ) ;
2023-02-08 15:30:46 +00:00
}
2023-03-02 14:51:45 +00:00
Impl . Pointer [ InsertIndex ] = MoveTemp ( InValue ) ;
2023-02-08 15:30:46 +00:00
}
2023-03-02 14:51:45 +00:00
else new ( Impl . Pointer + Num ( ) ) ElementType ( MoveTemp ( InValue ) ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Num ( ) + 1 ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
return Iterator ( this , Impl . Pointer + InsertIndex ) ;
2023-02-08 15:30:46 +00:00
}
/** Inserts 'Count' copies of the 'InValue' before 'Iter' in the container. */
2023-02-22 15:34:51 +00:00
Iterator Insert ( ConstIterator Iter , size_t Count , const ElementType & InValue ) requires ( CCopyable < ElementType > )
2023-02-08 15:30:46 +00:00
{
checkf ( IsValidIterator ( Iter ) , TEXT ( " Read access violation. Please check IsValidIterator(). " ) ) ;
const size_t InsertIndex = Iter - Begin ( ) ;
2023-03-02 14:51:45 +00:00
if ( Count = = 0 ) return Iterator ( this , Impl . Pointer + InsertIndex ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
const size_t NumToAllocate = Num ( ) + Count > Max ( ) ? Impl - > CalculateSlackGrow ( Num ( ) + Count , Max ( ) ) : Max ( ) ;
2023-02-08 15:30:46 +00:00
check ( NumToAllocate > = Num ( ) + Count ) ;
if ( NumToAllocate ! = Max ( ) )
{
2023-03-02 14:51:45 +00:00
ElementType * OldAllocation = Impl . Pointer ;
2023-02-08 15:30:46 +00:00
const size_t NumToDestruct = Num ( ) ;
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Num ( ) + Count ;
Impl . ArrayMax = NumToAllocate ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Memory : : MoveConstruct < ElementType > ( Impl . Pointer , OldAllocation , InsertIndex ) ;
2023-02-08 15:30:46 +00:00
for ( size_t Index = InsertIndex ; Index ! = InsertIndex + Count ; + + Index )
{
2023-03-02 14:51:45 +00:00
new ( Impl . Pointer + Index ) ElementType ( InValue ) ;
2023-02-08 15:30:46 +00:00
}
2023-03-02 14:51:45 +00:00
Memory : : MoveConstruct < ElementType > ( Impl . Pointer + InsertIndex + Count , OldAllocation + InsertIndex , NumToDestruct - InsertIndex ) ;
2023-02-08 15:30:46 +00:00
Memory : : Destruct ( OldAllocation , NumToDestruct ) ;
2023-03-02 14:51:45 +00:00
Impl - > Deallocate ( OldAllocation ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
return Iterator ( this , Impl . Pointer + InsertIndex ) ;
2023-02-08 15:30:46 +00:00
}
/*
* 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 ;
2023-02-12 15:46:30 +00:00
const size_t IndexO = Num ( ) + Count ;
2023-02-08 15:30:46 +00:00
2023-02-12 15:46:30 +00:00
for ( size_t TargetIndex = IndexO - 1 ; TargetIndex ! = IndexD - 1 ; - - TargetIndex )
2023-02-08 15:30:46 +00:00
{
2023-03-02 14:51:45 +00:00
new ( Impl . Pointer + TargetIndex ) ElementType ( MoveTemp ( Impl . Pointer [ TargetIndex - Count ] ) ) ;
2023-02-08 15:30:46 +00:00
}
2023-02-12 15:46:30 +00:00
for ( size_t TargetIndex = IndexD - 1 ; TargetIndex ! = IndexC - 1 ; - - TargetIndex )
2023-02-08 15:30:46 +00:00
{
2023-03-02 14:51:45 +00:00
Impl . Pointer [ TargetIndex ] = MoveTemp ( Impl . Pointer [ TargetIndex - Count ] ) ;
2023-02-08 15:30:46 +00:00
}
2023-02-12 15:46:30 +00:00
for ( size_t TargetIndex = IndexA ; TargetIndex ! = IndexB ; + + TargetIndex )
2023-02-08 15:30:46 +00:00
{
2023-03-02 14:51:45 +00:00
Impl . Pointer [ TargetIndex ] = InValue ;
2023-02-08 15:30:46 +00:00
}
2023-02-12 15:46:30 +00:00
for ( size_t TargetIndex = IndexB ; TargetIndex ! = IndexC ; + + TargetIndex )
2023-02-08 15:30:46 +00:00
{
2023-03-02 14:51:45 +00:00
new ( Impl . Pointer + TargetIndex ) ElementType ( InValue ) ;
2023-02-08 15:30:46 +00:00
}
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Num ( ) + Count ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
return Iterator ( this , Impl . Pointer + InsertIndex ) ;
2023-02-08 15:30:46 +00:00
}
2023-02-12 15:46:30 +00:00
/** 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 > )
2023-02-22 15:34:51 +00:00
Iterator Insert ( ConstIterator Iter , I First , S Last )
2023-02-08 15:30:46 +00:00
{
checkf ( IsValidIterator ( Iter ) , TEXT ( " Read access violation. Please check IsValidIterator(). " ) ) ;
2023-02-12 15:46:30 +00:00
if constexpr ( CForwardIterator < I > )
{
2023-03-04 11:12:47 +00:00
if ( CSizedSentinelFor < S , I > ) { checkf ( First < = Last , TEXT ( " Illegal range iterator. Please check First <= Last. " ) ) ; }
2023-02-08 15:30:46 +00:00
2023-02-12 15:46:30 +00:00
const size_t InsertIndex = Iter - Begin ( ) ;
const size_t Count = Iteration : : Distance ( First , Last ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
if ( Count = = 0 ) return Iterator ( this , Impl . Pointer + InsertIndex ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
const size_t NumToAllocate = Num ( ) + Count > Max ( ) ? Impl - > CalculateSlackGrow ( Num ( ) + Count , Max ( ) ) : Max ( ) ;
2023-02-08 15:30:46 +00:00
2023-02-12 15:46:30 +00:00
check ( NumToAllocate > = Num ( ) + Count ) ;
2023-02-08 15:30:46 +00:00
2023-02-12 15:46:30 +00:00
if ( NumToAllocate ! = Max ( ) )
{
2023-03-02 14:51:45 +00:00
ElementType * OldAllocation = Impl . Pointer ;
2023-02-12 15:46:30 +00:00
const size_t NumToDestruct = Num ( ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Num ( ) + Count ;
Impl . ArrayMax = NumToAllocate ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Memory : : MoveConstruct < ElementType > ( Impl . Pointer , OldAllocation , InsertIndex ) ;
2023-02-12 15:46:30 +00:00
for ( size_t Index = InsertIndex ; Index ! = InsertIndex + Count ; + + Index )
{
2023-03-02 14:51:45 +00:00
new ( Impl . Pointer + Index ) ElementType ( * First + + ) ;
2023-02-12 15:46:30 +00:00
}
2023-03-02 14:51:45 +00:00
Memory : : MoveConstruct < ElementType > ( Impl . Pointer + InsertIndex + Count , OldAllocation + InsertIndex , NumToDestruct - InsertIndex ) ;
2023-02-12 15:46:30 +00:00
Memory : : Destruct ( OldAllocation , NumToDestruct ) ;
2023-03-02 14:51:45 +00:00
Impl - > Deallocate ( OldAllocation ) ;
2023-02-12 15:46:30 +00:00
2023-03-02 14:51:45 +00:00
return Iterator ( this , Impl . Pointer + InsertIndex ) ;
2023-02-08 15:30:46 +00:00
}
2023-02-12 15:46:30 +00:00
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 ;
2023-02-08 15:30:46 +00:00
2023-02-12 15:46:30 +00:00
size_t TargetIndex = Num ( ) + Count - 1 ;
2023-02-08 15:30:46 +00:00
2023-02-12 15:46:30 +00:00
for ( size_t TargetIndex = IndexO - 1 ; TargetIndex ! = IndexD - 1 ; - - TargetIndex )
{
2023-03-02 14:51:45 +00:00
new ( Impl . Pointer + TargetIndex ) ElementType ( MoveTemp ( Impl . Pointer [ TargetIndex - Count ] ) ) ;
2023-02-12 15:46:30 +00:00
}
2023-02-08 15:30:46 +00:00
2023-02-12 15:46:30 +00:00
for ( size_t TargetIndex = IndexD - 1 ; TargetIndex ! = IndexC - 1 ; - - TargetIndex )
{
2023-03-02 14:51:45 +00:00
Impl . Pointer [ TargetIndex ] = MoveTemp ( Impl . Pointer [ TargetIndex - Count ] ) ;
2023-02-12 15:46:30 +00:00
}
2023-02-08 15:30:46 +00:00
2023-02-12 15:46:30 +00:00
for ( size_t TargetIndex = IndexA ; TargetIndex ! = IndexB ; + + TargetIndex )
{
2023-03-02 14:51:45 +00:00
Impl . Pointer [ TargetIndex ] = * First + + ;
2023-02-12 15:46:30 +00:00
}
2023-02-08 15:30:46 +00:00
2023-02-12 15:46:30 +00:00
for ( size_t TargetIndex = IndexB ; TargetIndex ! = IndexC ; + + TargetIndex )
{
2023-03-02 14:51:45 +00:00
new ( Impl . Pointer + TargetIndex ) ElementType ( * First + + ) ;
2023-02-12 15:46:30 +00:00
}
2023-02-08 15:30:46 +00:00
2023-02-12 15:46:30 +00:00
check ( First = = Last ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Num ( ) + Count ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
return Iterator ( this , Impl . Pointer + InsertIndex ) ;
2023-02-12 15:46:30 +00:00
}
else
2023-02-08 15:30:46 +00:00
{
2023-02-12 15:46:30 +00:00
TArray Temp ( MoveTemp ( First ) , MoveTemp ( Last ) ) ;
2023-02-15 15:36:18 +00:00
return Insert ( Iter , TMoveIterator ( Temp . Begin ( ) ) , TMoveSentinel ( Temp . End ( ) ) ) ;
2023-02-08 15:30:46 +00:00
}
2023-02-12 15:46:30 +00:00
}
2023-02-08 15:30:46 +00:00
2023-02-12 15:46:30 +00:00
/** Inserts elements from initializer list before 'Iter' in the container. */
2023-02-22 15:34:51 +00:00
FORCEINLINE Iterator Insert ( ConstIterator Iter , initializer_list < ElementType > IL ) requires ( CCopyable < ElementType > )
2023-02-12 15:46:30 +00:00
{
return Insert ( Iter , Iteration : : Begin ( IL ) , Iteration : : End ( IL ) ) ;
2023-02-08 15:30:46 +00:00
}
/** Inserts a new element into the container directly before 'Iter'. */
2023-02-12 15:46:30 +00:00
template < typename . . . Ts > requires ( CConstructibleFrom < ElementType , Ts . . . > & & CMovable < ElementType > )
2023-02-22 15:34:51 +00:00
Iterator Emplace ( ConstIterator Iter , Ts & & . . . Args )
2023-02-08 15:30:46 +00:00
{
checkf ( IsValidIterator ( Iter ) , TEXT ( " Read access violation. Please check IsValidIterator(). " ) ) ;
const size_t InsertIndex = Iter - Begin ( ) ;
2023-03-02 14:51:45 +00:00
const size_t NumToAllocate = Num ( ) + 1 > Max ( ) ? Impl - > CalculateSlackGrow ( Num ( ) + 1 , Max ( ) ) : Max ( ) ;
2023-02-08 15:30:46 +00:00
check ( NumToAllocate > = Num ( ) + 1 ) ;
if ( NumToAllocate ! = Max ( ) )
{
2023-03-02 14:51:45 +00:00
ElementType * OldAllocation = Impl . Pointer ;
2023-02-08 15:30:46 +00:00
const size_t NumToDestruct = Num ( ) ;
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Num ( ) + 1 ;
Impl . ArrayMax = NumToAllocate ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
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 ) ;
2023-02-08 15:30:46 +00:00
Memory : : Destruct ( OldAllocation , NumToDestruct ) ;
2023-03-02 14:51:45 +00:00
Impl - > Deallocate ( OldAllocation ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
return Iterator ( this , Impl . Pointer + InsertIndex ) ;
2023-02-08 15:30:46 +00:00
}
if ( InsertIndex ! = Num ( ) )
{
2023-03-02 14:51:45 +00:00
new ( Impl . Pointer + Num ( ) ) ElementType ( MoveTemp ( Impl . Pointer [ Num ( ) - 1 ] ) ) ;
2023-02-08 15:30:46 +00:00
for ( size_t Index = Num ( ) - 1 ; Index ! = InsertIndex ; - - Index )
{
2023-03-02 14:51:45 +00:00
Impl . Pointer [ Index ] = MoveTemp ( Impl . Pointer [ Index - 1 ] ) ;
2023-02-08 15:30:46 +00:00
}
2023-03-02 14:51:45 +00:00
Impl . Pointer [ InsertIndex ] = ElementType ( Forward < Ts > ( Args ) . . . ) ;
2023-02-08 15:30:46 +00:00
}
2023-03-02 14:51:45 +00:00
else new ( Impl . Pointer + Num ( ) ) ElementType ( Forward < Ts > ( Args ) . . . ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Num ( ) + 1 ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
return Iterator ( this , Impl . Pointer + InsertIndex ) ;
2023-02-08 15:30:46 +00:00
}
/** Removes the element at 'Iter' in the container. Without changing the order of elements. */
2023-02-22 15:34:51 +00:00
FORCEINLINE Iterator StableErase ( ConstIterator Iter , bool bAllowShrinking = true ) requires ( CMovable < ElementType > )
2023-02-08 15:30:46 +00:00
{
checkf ( IsValidIterator ( Iter ) & & Iter ! = End ( ) , TEXT ( " Read access violation. Please check IsValidIterator(). " ) ) ;
return StableErase ( Iter , Iter + 1 , bAllowShrinking ) ;
}
2023-02-12 15:46:30 +00:00
/** Removes the elements in the range ['First', 'Last') in the container. Without changing the order of elements. */
2023-02-22 15:34:51 +00:00
Iterator StableErase ( ConstIterator First , ConstIterator Last , bool bAllowShrinking = true ) requires ( CMovable < ElementType > )
2023-02-08 15:30:46 +00:00
{
2023-02-12 15:46:30 +00:00
checkf ( IsValidIterator ( First ) & & IsValidIterator ( Last ) & & First < = Last , TEXT ( " Read access violation. Please check IsValidIterator(). " ) ) ;
2023-02-08 15:30:46 +00:00
2023-02-12 15:46:30 +00:00
const size_t EraseIndex = First - Begin ( ) ;
const size_t EraseCount = Last - First ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
if ( EraseCount = = 0 ) return Iterator ( this , Impl . Pointer + EraseIndex ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
const size_t NumToAllocate = bAllowShrinking ? Impl - > CalculateSlackShrink ( Num ( ) - EraseCount , Max ( ) ) : Max ( ) ;
2023-02-08 15:30:46 +00:00
if ( NumToAllocate ! = Max ( ) )
{
2023-03-02 14:51:45 +00:00
ElementType * OldAllocation = Impl . Pointer ;
2023-02-08 15:30:46 +00:00
const size_t NumToDestruct = Num ( ) ;
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Num ( ) - EraseCount ;
Impl . ArrayMax = NumToAllocate ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Memory : : MoveConstruct < ElementType > ( Impl . Pointer , OldAllocation , EraseIndex ) ;
Memory : : MoveConstruct < ElementType > ( Impl . Pointer + EraseIndex , OldAllocation + EraseIndex + EraseCount , NumToDestruct - EraseIndex - EraseCount ) ;
2023-02-08 15:30:46 +00:00
Memory : : Destruct ( OldAllocation , NumToDestruct ) ;
2023-03-02 14:51:45 +00:00
Impl - > Deallocate ( OldAllocation ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
return Iterator ( this , Impl . Pointer + EraseIndex ) ;
2023-02-08 15:30:46 +00:00
}
for ( size_t Index = EraseIndex + EraseCount ; Index ! = Num ( ) ; + + Index )
{
2023-03-02 14:51:45 +00:00
Impl . Pointer [ Index - EraseCount ] = MoveTemp ( Impl . Pointer [ Index ] ) ;
2023-02-08 15:30:46 +00:00
}
2023-03-02 14:51:45 +00:00
Memory : : Destruct ( Impl . Pointer + Num ( ) - EraseCount , EraseCount ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Num ( ) - EraseCount ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
return Iterator ( this , Impl . Pointer + EraseIndex ) ;
2023-02-08 15:30:46 +00:00
}
/** Removes the element at 'Iter' in the container. But it may change the order of elements. */
2023-02-22 15:34:51 +00:00
FORCEINLINE Iterator Erase ( ConstIterator Iter , bool bAllowShrinking = true ) requires ( CMovable < ElementType > )
2023-02-08 15:30:46 +00:00
{
checkf ( IsValidIterator ( Iter ) & & Iter ! = End ( ) , TEXT ( " Read access violation. Please check IsValidIterator(). " ) ) ;
return Erase ( Iter , Iter + 1 , bAllowShrinking ) ;
}
2023-02-12 15:46:30 +00:00
/** Removes the elements in the range ['First', 'Last') in the container. But it may change the order of elements. */
2023-02-22 15:34:51 +00:00
Iterator Erase ( ConstIterator First , ConstIterator Last , bool bAllowShrinking = true ) requires ( CMovable < ElementType > )
2023-02-08 15:30:46 +00:00
{
2023-02-12 15:46:30 +00:00
checkf ( IsValidIterator ( First ) & & IsValidIterator ( Last ) & & First < = Last , TEXT ( " Read access violation. Please check IsValidIterator(). " ) ) ;
2023-02-08 15:30:46 +00:00
2023-02-12 15:46:30 +00:00
const size_t EraseIndex = First - Begin ( ) ;
const size_t EraseCount = Last - First ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
if ( EraseCount = = 0 ) return Iterator ( this , Impl . Pointer + EraseIndex ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
const size_t NumToAllocate = bAllowShrinking ? Impl - > CalculateSlackShrink ( Num ( ) - EraseCount , Max ( ) ) : Max ( ) ;
2023-02-08 15:30:46 +00:00
if ( NumToAllocate ! = Max ( ) )
{
2023-03-02 14:51:45 +00:00
ElementType * OldAllocation = Impl . Pointer ;
2023-02-08 15:30:46 +00:00
const size_t NumToDestruct = Num ( ) ;
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Num ( ) - EraseCount ;
Impl . ArrayMax = NumToAllocate ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Memory : : MoveConstruct < ElementType > ( Impl . Pointer , OldAllocation , EraseIndex ) ;
Memory : : MoveConstruct < ElementType > ( Impl . Pointer + EraseIndex , OldAllocation + EraseIndex + EraseCount , NumToDestruct - EraseIndex - EraseCount ) ;
2023-02-08 15:30:46 +00:00
Memory : : Destruct ( OldAllocation , NumToDestruct ) ;
2023-03-02 14:51:45 +00:00
Impl - > Deallocate ( OldAllocation ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
return Iterator ( this , Impl . Pointer + EraseIndex ) ;
2023-02-08 15:30:46 +00:00
}
for ( size_t Index = 0 ; Index ! = EraseCount ; + + Index )
{
if ( EraseIndex + Index > = Num ( ) - EraseCount ) break ;
2023-03-02 14:51:45 +00:00
Impl . Pointer [ EraseIndex + Index ] = MoveTemp ( Impl . Pointer [ Num ( ) - Index - 1 ] ) ;
2023-02-08 15:30:46 +00:00
}
2023-03-02 14:51:45 +00:00
Memory : : Destruct ( Impl . Pointer + Num ( ) - EraseCount , EraseCount ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Num ( ) - EraseCount ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
return Iterator ( this , Impl . Pointer + EraseIndex ) ;
2023-02-08 15:30:46 +00:00
}
/** Appends the given element value to the end of the container. */
2023-02-22 15:34:51 +00:00
FORCEINLINE void PushBack ( const ElementType & InValue ) requires ( CCopyable < ElementType > )
2023-02-08 15:30:46 +00:00
{
EmplaceBack ( InValue ) ;
}
/** Appends the given element value to the end of the container. */
2023-02-22 15:34:51 +00:00
FORCEINLINE void PushBack ( ElementType & & InValue ) requires ( CMovable < ElementType > )
2023-02-08 15:30:46 +00:00
{
EmplaceBack ( MoveTemp ( InValue ) ) ;
}
/** Appends a new element to the end of the container. */
2023-02-12 15:46:30 +00:00
template < typename . . . Ts > requires ( CConstructibleFrom < ElementType , Ts . . . > & & CMovable < ElementType > )
2023-02-22 15:34:51 +00:00
ElementType & EmplaceBack ( Ts & & . . . Args )
2023-02-08 15:30:46 +00:00
{
2023-03-02 14:51:45 +00:00
const size_t NumToAllocate = Num ( ) + 1 > Max ( ) ? Impl - > CalculateSlackGrow ( Num ( ) + 1 , Max ( ) ) : Max ( ) ;
2023-02-08 15:30:46 +00:00
check ( NumToAllocate > = Num ( ) + 1 ) ;
if ( NumToAllocate ! = Max ( ) )
{
2023-03-02 14:51:45 +00:00
ElementType * OldAllocation = Impl . Pointer ;
2023-02-08 15:30:46 +00:00
const size_t NumToDestruct = Num ( ) ;
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Num ( ) + 1 ;
Impl . ArrayMax = NumToAllocate ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Memory : : MoveConstruct < ElementType > ( Impl . Pointer , OldAllocation , Num ( ) - 1 ) ;
new ( Impl . Pointer + Num ( ) - 1 ) ElementType ( Forward < Ts > ( Args ) . . . ) ;
2023-02-08 15:30:46 +00:00
Memory : : Destruct ( OldAllocation , NumToDestruct ) ;
2023-03-02 14:51:45 +00:00
Impl - > Deallocate ( OldAllocation ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
return Impl . Pointer [ Num ( ) - 1 ] ;
2023-02-08 15:30:46 +00:00
}
2023-03-02 14:51:45 +00:00
new ( Impl . Pointer + Num ( ) ) ElementType ( Forward < Ts > ( Args ) . . . ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Num ( ) + 1 ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
return Impl . Pointer [ Num ( ) - 1 ] ;
2023-02-08 15:30:46 +00:00
}
/** Removes the last element of the container. The array cannot be empty. */
2023-02-22 15:34:51 +00:00
FORCEINLINE void PopBack ( bool bAllowShrinking = true ) requires ( CMovable < ElementType > )
2023-02-08 15:30:46 +00:00
{
Erase ( End ( ) - 1 , bAllowShrinking ) ;
}
/** Resizes the container to contain 'Count' elements. Additional default elements are appended. */
2023-02-22 15:34:51 +00:00
void SetNum ( size_t Count , bool bAllowShrinking = true ) requires ( CDefaultConstructible < ElementType > & & CMovable < ElementType > )
2023-02-08 15:30:46 +00:00
{
size_t NumToAllocate = Count ;
2023-03-02 14:51:45 +00:00
NumToAllocate = NumToAllocate > Max ( ) ? Impl - > CalculateSlackGrow ( Count , Max ( ) ) : NumToAllocate ;
NumToAllocate = NumToAllocate < Max ( ) ? ( bAllowShrinking ? Impl - > CalculateSlackShrink ( Count , Max ( ) ) : Max ( ) ) : NumToAllocate ;
2023-02-08 15:30:46 +00:00
if ( NumToAllocate ! = Max ( ) )
{
2023-03-02 14:51:45 +00:00
ElementType * OldAllocation = Impl . Pointer ;
2023-02-08 15:30:46 +00:00
const size_t NumToDestruct = Num ( ) ;
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Count ;
Impl . ArrayMax = NumToAllocate ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
if ( NumToDestruct < = Num ( ) )
{
2023-03-02 14:51:45 +00:00
Memory : : MoveConstruct < ElementType > ( Impl . Pointer , OldAllocation , NumToDestruct ) ;
Memory : : DefaultConstruct < ElementType > ( Impl . Pointer + NumToDestruct , Num ( ) - NumToDestruct ) ;
2023-02-08 15:30:46 +00:00
}
else
{
2023-03-02 14:51:45 +00:00
Memory : : MoveConstruct < ElementType > ( Impl . Pointer , OldAllocation , Num ( ) ) ;
2023-02-08 15:30:46 +00:00
}
Memory : : Destruct ( OldAllocation , NumToDestruct ) ;
2023-03-02 14:51:45 +00:00
Impl - > Deallocate ( OldAllocation ) ;
2023-02-08 15:30:46 +00:00
return ;
}
if ( Count < = Num ( ) )
{
2023-03-02 14:51:45 +00:00
Memory : : Destruct ( Impl . Pointer + Count , Num ( ) - Count ) ;
2023-02-08 15:30:46 +00:00
}
else if ( Count < = Max ( ) )
{
2023-03-02 14:51:45 +00:00
Memory : : DefaultConstruct < ElementType > ( Impl . Pointer + Num ( ) , Count - Num ( ) ) ;
2023-02-08 15:30:46 +00:00
}
else check_no_entry ( ) ;
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Count ;
2023-02-08 15:30:46 +00:00
}
/** Resizes the container to contain 'Count' elements. Additional copies of 'InValue' are appended. */
2023-02-22 15:34:51 +00:00
void SetNum ( size_t Count , const ElementType & InValue , bool bAllowShrinking = true ) requires ( CCopyConstructible < ElementType > & & CMovable < ElementType > )
2023-02-08 15:30:46 +00:00
{
size_t NumToAllocate = Count ;
2023-03-02 14:51:45 +00:00
NumToAllocate = NumToAllocate > Max ( ) ? Impl - > CalculateSlackGrow ( Count , Max ( ) ) : NumToAllocate ;
NumToAllocate = NumToAllocate < Max ( ) ? ( bAllowShrinking ? Impl - > CalculateSlackShrink ( Count , Max ( ) ) : Max ( ) ) : NumToAllocate ;
2023-02-08 15:30:46 +00:00
if ( NumToAllocate ! = Max ( ) )
{
2023-03-02 14:51:45 +00:00
ElementType * OldAllocation = Impl . Pointer ;
2023-02-08 15:30:46 +00:00
const size_t NumToDestruct = Num ( ) ;
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Count ;
Impl . ArrayMax = NumToAllocate ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
if ( NumToDestruct < = Num ( ) )
{
2023-03-02 14:51:45 +00:00
Memory : : MoveConstruct < ElementType > ( Impl . Pointer , OldAllocation , NumToDestruct ) ;
2023-02-08 15:30:46 +00:00
for ( size_t Index = NumToDestruct ; Index ! = Num ( ) ; + + Index )
{
2023-03-02 14:51:45 +00:00
new ( Impl . Pointer + Index ) ElementType ( InValue ) ;
2023-02-08 15:30:46 +00:00
}
}
else
{
2023-03-02 14:51:45 +00:00
Memory : : MoveConstruct < ElementType > ( Impl . Pointer , OldAllocation , Num ( ) ) ;
2023-02-08 15:30:46 +00:00
}
Memory : : Destruct ( OldAllocation , NumToDestruct ) ;
2023-03-02 14:51:45 +00:00
Impl - > Deallocate ( OldAllocation ) ;
2023-02-08 15:30:46 +00:00
return ;
}
if ( Count < = Num ( ) )
{
2023-03-02 14:51:45 +00:00
Memory : : Destruct ( Impl . Pointer + Count , Num ( ) - Count ) ;
2023-02-08 15:30:46 +00:00
}
else if ( Count < = Max ( ) )
{
for ( size_t Index = Num ( ) ; Index ! = Count ; + + Index )
{
2023-03-02 14:51:45 +00:00
new ( Impl . Pointer + Index ) ElementType ( InValue ) ;
2023-02-08 15:30:46 +00:00
}
}
else check_no_entry ( ) ;
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = Count ;
2023-02-08 15:30:46 +00:00
}
/** Increase the max capacity of the array to a value that's greater or equal to 'Count'. */
2023-02-22 15:34:51 +00:00
void Reserve ( size_t Count ) requires ( CMovable < ElementType > )
2023-02-08 15:30:46 +00:00
{
if ( Count < = Max ( ) ) return ;
2023-03-02 14:51:45 +00:00
const size_t NumToAllocate = Impl - > CalculateSlackReserve ( Count ) ;
ElementType * OldAllocation = Impl . Pointer ;
2023-02-08 15:30:46 +00:00
check ( NumToAllocate > Max ( ) ) ;
2023-03-02 14:51:45 +00:00
Impl . ArrayMax = NumToAllocate ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Memory : : MoveConstruct < ElementType > ( Impl . Pointer , OldAllocation , Num ( ) ) ;
2023-02-08 15:30:46 +00:00
Memory : : Destruct ( OldAllocation , Num ( ) ) ;
2023-03-02 14:51:45 +00:00
Impl - > Deallocate ( OldAllocation ) ;
2023-02-08 15:30:46 +00:00
}
/** Requests the removal of unused capacity. */
2023-02-22 15:34:51 +00:00
void Shrink ( )
2023-02-08 15:30:46 +00:00
{
2023-03-02 14:51:45 +00:00
size_t NumToAllocate = Impl - > CalculateSlackReserve ( Num ( ) ) ;
2023-02-08 15:30:46 +00:00
check ( NumToAllocate < = Max ( ) ) ;
if ( NumToAllocate = = Max ( ) ) return ;
2023-03-02 14:51:45 +00:00
ElementType * OldAllocation = Impl . Pointer ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Impl . ArrayMax = NumToAllocate ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Memory : : MoveConstruct < ElementType > ( Impl . Pointer , OldAllocation , Num ( ) ) ;
2023-02-08 15:30:46 +00:00
Memory : : Destruct ( OldAllocation , Num ( ) ) ;
2023-03-02 14:51:45 +00:00
Impl - > Deallocate ( OldAllocation ) ;
2023-02-08 15:30:46 +00:00
}
2023-02-27 15:25:40 +00:00
2023-02-08 15:30:46 +00:00
/** @return The pointer to the underlying element storage. */
2023-03-02 14:51:45 +00:00
NODISCARD FORCEINLINE TObserverPtr < ElementType [ ] > GetData ( ) { return TObserverPtr < ElementType [ ] > ( Impl . Pointer ) ; }
NODISCARD FORCEINLINE TObserverPtr < const ElementType [ ] > GetData ( ) const { return TObserverPtr < const ElementType [ ] > ( Impl . Pointer ) ; }
2023-02-08 15:30:46 +00:00
/** @return The iterator to the first or end element. */
2023-03-02 14:51:45 +00:00
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 ( ) ) ; }
2023-02-27 15:25:40 +00:00
2023-02-13 11:26:09 +00:00
/** @return The reverse iterator to the first or end element. */
2023-02-22 15:34:51 +00:00
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 ( ) ) ; }
2023-02-08 15:30:46 +00:00
/** @return The number of elements in the container. */
2023-03-02 14:51:45 +00:00
NODISCARD FORCEINLINE size_t Num ( ) const { return Impl . ArrayNum ; }
2023-02-08 15:30:46 +00:00
/** @return The number of elements that can be held in currently allocated storage. */
2023-03-02 14:51:45 +00:00
NODISCARD FORCEINLINE size_t Max ( ) const { return Impl . ArrayMax ; }
2023-02-08 15:30:46 +00:00
/** @return true if the container is empty, false otherwise. */
2023-02-22 15:34:51 +00:00
NODISCARD FORCEINLINE bool IsEmpty ( ) const { return Num ( ) = = 0 ; }
2023-02-08 15:30:46 +00:00
/** @return true if the iterator is valid, false otherwise. */
2023-02-22 15:34:51 +00:00
NODISCARD FORCEINLINE bool IsValidIterator ( ConstIterator Iter ) const { return Begin ( ) < = Iter & & Iter < = End ( ) ; }
2023-02-08 15:30:46 +00:00
/** @return The reference to the requested element. */
2023-03-02 14:51:45 +00:00
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 ] ; }
2023-02-08 15:30:46 +00:00
/** @return The reference to the first or last element. */
2023-02-22 15:34:51 +00:00
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 ) ; }
2023-02-08 15:30:46 +00:00
/** Erases all elements from the container. After this call, Num() returns zero. */
2023-02-22 15:34:51 +00:00
void Reset ( bool bAllowShrinking = true )
2023-02-08 15:30:46 +00:00
{
2023-03-02 14:51:45 +00:00
const size_t NumToAllocate = Impl - > CalculateSlackReserve ( 0 ) ;
2023-02-08 15:30:46 +00:00
2023-02-12 15:46:30 +00:00
if ( bAllowShrinking & & NumToAllocate ! = Max ( ) )
2023-02-08 15:30:46 +00:00
{
2023-03-02 14:51:45 +00:00
Memory : : Destruct ( Impl . Pointer , Num ( ) ) ;
Impl - > Deallocate ( Impl . Pointer ) ;
2023-02-08 15:30:46 +00:00
2023-03-02 14:51:45 +00:00
Impl . ArrayNum = 0 ;
Impl . ArrayMax = Impl - > CalculateSlackReserve ( Num ( ) ) ;
Impl . Pointer = Impl - > Allocate ( Max ( ) ) ;
2023-02-08 15:30:46 +00:00
return ;
}
2023-03-02 14:51:45 +00:00
Memory : : Destruct ( Impl . Pointer , Num ( ) ) ;
Impl . ArrayNum = 0 ;
2023-02-08 15:30:46 +00:00
}
/** Overloads the GetTypeHash algorithm for TArray. */
2023-02-22 15:34:51 +00:00
NODISCARD friend FORCEINLINE size_t GetTypeHash ( const TArray & A ) requires ( CHashable < ElementType > )
2023-02-08 15:30:46 +00:00
{
size_t Result = 0 ;
2023-02-24 11:09:22 +00:00
for ( ConstIterator Iter = A . Begin ( ) ; Iter ! = A . End ( ) ; + + Iter )
2023-02-08 15:30:46 +00:00
{
2023-02-24 11:09:22 +00:00
Result = HashCombine ( Result , GetTypeHash ( * Iter ) ) ;
2023-02-08 15:30:46 +00:00
}
return Result ;
}
/** Overloads the Swap algorithm for TArray. */
2023-02-22 15:34:51 +00:00
friend void Swap ( TArray & A , TArray & B ) requires ( CMovable < ElementType > )
2023-02-08 15:30:46 +00:00
{
const bool bIsTransferable =
2023-03-02 14:51:45 +00:00
A . Impl - > IsTransferable ( A . Impl . Pointer ) & &
B . Impl - > IsTransferable ( B . Impl . Pointer ) ;
2023-02-08 15:30:46 +00:00
if ( bIsTransferable )
{
2023-03-02 14:51:45 +00:00
Swap ( A . Impl . ArrayNum , B . Impl . ArrayNum ) ;
Swap ( A . Impl . ArrayMax , B . Impl . ArrayMax ) ;
Swap ( A . Impl . Pointer , B . Impl . Pointer ) ;
2023-02-08 15:30:46 +00:00
return ;
}
TArray Temp = MoveTemp ( A ) ;
A = MoveTemp ( B ) ;
B = MoveTemp ( Temp ) ;
}
2023-02-15 15:41:05 +00:00
ENABLE_RANGE_BASED_FOR_LOOP_SUPPORT
2023-02-08 15:30:46 +00:00
private :
2023-03-02 14:51:45 +00:00
ALLOCATOR_WRAPPER_BEGIN ( AllocatorType , ElementType , Impl )
2023-02-27 15:25:40 +00:00
{
size_t ArrayNum ;
size_t ArrayMax ;
2023-03-02 14:51:45 +00:00
ElementType * Pointer ;
}
ALLOCATOR_WRAPPER_END ( AllocatorType , ElementType , Impl )
2023-02-08 15:30:46 +00:00
2023-03-04 11:12:47 +00:00
private :
template < bool bConst >
class IteratorImpl
{
public :
using ElementType = TConditional < bConst , const T , T > ;
FORCEINLINE IteratorImpl ( ) = default ;
# if DO_CHECK
FORCEINLINE IteratorImpl ( const IteratorImpl < false > & InValue ) requires ( bConst )
: Owner ( InValue . Owner ) , Pointer ( InValue . Pointer )
{ }
# else
FORCEINLINE IteratorImpl ( const IteratorImpl < false > & InValue ) requires ( bConst )
: Pointer ( InValue . Pointer )
{ }
# endif
FORCEINLINE IteratorImpl ( const IteratorImpl & ) = default ;
FORCEINLINE IteratorImpl ( IteratorImpl & & ) = default ;
FORCEINLINE IteratorImpl & operator = ( const IteratorImpl & ) = default ;
FORCEINLINE IteratorImpl & operator = ( IteratorImpl & & ) = default ;
NODISCARD friend FORCEINLINE bool operator = = ( const IteratorImpl & LHS , const IteratorImpl & RHS ) { return LHS . Pointer = = RHS . Pointer ; }
NODISCARD friend FORCEINLINE strong_ordering operator < = > ( const IteratorImpl & LHS , const IteratorImpl & RHS ) { return LHS . Pointer < = > RHS . Pointer ; }
NODISCARD FORCEINLINE ElementType & operator * ( ) const { CheckThis ( true ) ; return * Pointer ; }
NODISCARD FORCEINLINE ElementType * operator - > ( ) const { CheckThis ( true ) ; return Pointer ; }
NODISCARD FORCEINLINE ElementType & operator [ ] ( ptrdiff Index ) const { IteratorImpl Temp = * this + Index ; return * Temp ; }
FORCEINLINE IteratorImpl & operator + + ( ) { + + Pointer ; CheckThis ( ) ; return * this ; }
FORCEINLINE IteratorImpl & operator - - ( ) { - - Pointer ; CheckThis ( ) ; return * this ; }
FORCEINLINE IteratorImpl operator + + ( int ) { IteratorImpl Temp = * this ; + + * this ; return Temp ; }
FORCEINLINE IteratorImpl operator - - ( int ) { IteratorImpl Temp = * this ; - - * this ; return Temp ; }
FORCEINLINE IteratorImpl & operator + = ( ptrdiff Offset ) { Pointer + = Offset ; CheckThis ( ) ; return * this ; }
FORCEINLINE IteratorImpl & operator - = ( ptrdiff Offset ) { Pointer - = Offset ; CheckThis ( ) ; return * this ; }
NODISCARD friend FORCEINLINE IteratorImpl operator + ( IteratorImpl Iter , ptrdiff Offset ) { IteratorImpl Temp = Iter ; Temp + = Offset ; return Temp ; }
NODISCARD friend FORCEINLINE IteratorImpl operator + ( ptrdiff Offset , IteratorImpl Iter ) { IteratorImpl Temp = Iter ; Temp + = Offset ; return Temp ; }
NODISCARD FORCEINLINE IteratorImpl operator - ( ptrdiff Offset ) const { IteratorImpl Temp = * this ; Temp - = Offset ; return Temp ; }
NODISCARD friend FORCEINLINE ptrdiff operator - ( const IteratorImpl & LHS , const IteratorImpl & RHS ) { LHS . CheckThis ( ) ; RHS . CheckThis ( ) ; return LHS . Pointer - RHS . Pointer ; }
NODISCARD FORCEINLINE explicit operator TObserverPtr < ElementType [ ] > ( ) const { CheckThis ( ) ; return TObserverPtr < ElementType [ ] > ( Pointer ) ; }
private :
# if DO_CHECK
const TArray * Owner = nullptr ;
# endif
ElementType * Pointer = nullptr ;
# if DO_CHECK
FORCEINLINE IteratorImpl ( const TArray * InContainer , ElementType * InPointer )
: Owner ( InContainer ) , Pointer ( InPointer )
{ }
# else
FORCEINLINE IteratorImpl ( const TArray * InContainer , ElementType * InPointer )
: Pointer ( InPointer )
{ }
# endif
FORCEINLINE void CheckThis ( bool bExceptEnd = false ) const
{
checkf ( Owner & & Owner - > IsValidIterator ( * this ) , TEXT ( " Read access violation. Please check IsValidIterator(). " ) ) ;
checkf ( ! ( bExceptEnd & & Owner - > End ( ) = = * this ) , TEXT ( " Read access violation. Please check IsValidIterator(). " ) ) ;
}
template < bool > friend class IteratorImpl ;
friend TArray ;
} ;
2023-02-08 15:30:46 +00:00
} ;
2023-02-26 11:01:32 +00:00
template < typename I , typename S >
TArray ( I , S ) - > TArray < TIteratorElementType < I > > ;
template < typename T >
TArray ( initializer_list < T > ) - > TArray < T > ;
2023-02-08 15:30:46 +00:00
NAMESPACE_MODULE_END ( Utility )
NAMESPACE_MODULE_END ( Redcraft )
NAMESPACE_REDCRAFT_END