2template <
typename T, plUInt16 Size>
5template <
typename T, plUInt16 Size>
9 m_uiUserData = other.m_uiUserData;
12template <
typename T, plUInt16 Size>
15 CopyFrom(other, pAllocator);
18template <
typename T, plUInt16 Size>
21 MoveFrom(std::move(other), pAllocator);
24template <
typename T, plUInt16 Size>
27 PL_ASSERT_DEBUG(m_uiCount == 0,
"The derived class did not destruct all objects. Count is {0}.", m_uiCount);
28 PL_ASSERT_DEBUG(m_pElements ==
nullptr,
"The derived class did not free its memory.");
31template <
typename T, plUInt16 Size>
34 PL_ASSERT_DEV(other.
GetCount() <= plSmallInvalidIndex,
"Can't copy {} elements to small array. Maximum count is {}", other.
GetCount(), plSmallInvalidIndex);
36 if (GetData() == other.
GetPtr())
41 PL_ASSERT_DEV(m_uiCount > other.
GetCount(),
"Dangling array pointer. The given array pointer points to invalid memory.");
42 T* pElements = GetElementsPtr();
44 m_uiCount =
static_cast<plUInt16
>(other.
GetCount());
48 const plUInt32 uiOldCount = m_uiCount;
49 const plUInt32 uiNewCount = other.
GetCount();
51 if (uiNewCount > uiOldCount)
53 Reserve(
static_cast<plUInt16
>(uiNewCount), pAllocator);
54 T* pElements = GetElementsPtr();
60 T* pElements = GetElementsPtr();
65 m_uiCount =
static_cast<plUInt16
>(uiNewCount);
68template <
typename T, plUInt16 Size>
73 if (other.m_uiCapacity > Size)
75 if (m_uiCapacity > Size)
78 PL_DELETE_RAW_BUFFER(pAllocator, m_pElements);
81 m_uiCapacity = other.m_uiCapacity;
82 m_pElements = other.m_pElements;
89 m_uiCount = other.m_uiCount;
90 m_uiUserData = other.m_uiUserData;
93 other.m_pElements =
nullptr;
95 other.m_uiCapacity = 0;
98template <
typename T, plUInt16 Size>
104template <
typename T, plUInt16 Size>
110template <
typename T, plUInt16 Size>
116#if PL_DISABLED(PL_USE_CPP20_OPERATORS)
117template <
typename T, plUInt16 Size>
127template <
typename T, plUInt16 Size>
130 PL_ASSERT_DEBUG(uiIndex < m_uiCount,
"Out of bounds access. Array has {0} elements, trying to access element at index {1}.", m_uiCount, uiIndex);
131 return GetElementsPtr()[uiIndex];
134template <
typename T, plUInt16 Size>
137 PL_ASSERT_DEBUG(uiIndex < m_uiCount,
"Out of bounds access. Array has {0} elements, trying to access element at index {1}.", m_uiCount, uiIndex);
138 return GetElementsPtr()[uiIndex];
141template <
typename T, plUInt16 Size>
144 const plUInt32 uiOldCount = m_uiCount;
145 const plUInt32 uiNewCount = uiCount;
147 if (uiNewCount > uiOldCount)
149 Reserve(
static_cast<plUInt16
>(uiNewCount), pAllocator);
152 else if (uiNewCount < uiOldCount)
160template <
typename T, plUInt16 Size>
163 const plUInt32 uiOldCount = m_uiCount;
164 const plUInt32 uiNewCount = uiCount;
166 if (uiNewCount > uiOldCount)
168 Reserve(uiCount, pAllocator);
171 else if (uiNewCount < uiOldCount)
179template <
typename T, plUInt16 Size>
182 if (uiCount > m_uiCount)
184 SetCount(uiCount, pAllocator);
188template <
typename T, plUInt16 Size>
192 static_assert(
plIsPodType<T>::value == plTypeIsPod::value,
"SetCountUninitialized is only supported for POD types.");
193 const plUInt16 uiOldCount = m_uiCount;
194 const plUInt16 uiNewCount = uiCount;
196 if (uiNewCount > uiOldCount)
198 Reserve(uiNewCount, pAllocator);
201 else if (uiNewCount < uiOldCount)
209template <
typename T, plUInt16 Size>
215template <
typename T, plUInt16 Size>
218 return m_uiCount == 0;
221template <
typename T, plUInt16 Size>
228template <
typename T, plUInt16 Size>
231 return IndexOf(value) != plInvalidIndex;
234template <
typename T, plUInt16 Size>
237 PL_ASSERT_DEV(uiIndex <= m_uiCount,
"Invalid index. Array has {0} elements, trying to insert element at index {1}.", m_uiCount, uiIndex);
239 Reserve(m_uiCount + 1, pAllocator);
245template <
typename T, plUInt16 Size>
248 PL_ASSERT_DEV(uiIndex <= m_uiCount,
"Invalid index. Array has {0} elements, trying to insert element at index {1}.", m_uiCount, uiIndex);
250 Reserve(m_uiCount + 1, pAllocator);
256template <
typename T, plUInt16 Size>
259 plUInt32 uiIndex = IndexOf(value);
261 if (uiIndex == plInvalidIndex)
264 RemoveAtAndCopy(uiIndex);
268template <
typename T, plUInt16 Size>
271 plUInt32 uiIndex = IndexOf(value);
273 if (uiIndex == plInvalidIndex)
276 RemoveAtAndSwap(uiIndex);
280template <
typename T, plUInt16 Size>
283 PL_ASSERT_DEV(uiIndex + uiNumElements <= m_uiCount,
"Out of bounds access. Array has {0} elements, trying to remove element at index {1}.", m_uiCount, uiIndex + uiNumElements - 1);
285 T* pElements = GetElementsPtr();
287 m_uiCount -= uiNumElements;
291template <
typename T, plUInt16 Size>
294 PL_ASSERT_DEV(uiIndex + uiNumElements <= m_uiCount,
"Out of bounds access. Array has {0} elements, trying to remove element at index {1}.", m_uiCount, uiIndex + uiNumElements - 1);
296 T* pElements = GetElementsPtr();
298 for (plUInt32 i = 0; i < uiNumElements; ++i)
302 if (m_uiCount != uiIndex)
304 pElements[uiIndex] = std::move(pElements[m_uiCount]);
311template <
typename T, plUInt16 Size>
314 const T* pElements = GetElementsPtr();
316 for (plUInt32 i = uiStartIndex; i < m_uiCount; i++)
321 return plInvalidIndex;
324template <
typename T, plUInt16 Size>
327 const T* pElements = GetElementsPtr();
334 return plInvalidIndex;
337template <
typename T, plUInt16 Size>
340 Reserve(m_uiCount + 1, pAllocator);
342 T* pElements = GetElementsPtr();
346 T& ReturnRef = *(pElements + m_uiCount);
353template <
typename T, plUInt16 Size>
356 Reserve(m_uiCount + 1, pAllocator);
362template <
typename T, plUInt16 Size>
365 Reserve(m_uiCount + 1, pAllocator);
371template <
typename T, plUInt16 Size>
374 PL_ASSERT_DEBUG(m_uiCount < m_uiCapacity,
"Appending unchecked to array with insufficient capacity.");
380template <
typename T, plUInt16 Size>
383 PL_ASSERT_DEBUG(m_uiCount < m_uiCapacity,
"Appending unchecked to array with insufficient capacity.");
389template <
typename T, plUInt16 Size>
392 const plUInt32 uiRangeCount = range.
GetCount();
393 Reserve(m_uiCount + uiRangeCount, pAllocator);
396 m_uiCount += uiRangeCount;
399template <
typename T, plUInt16 Size>
402 PL_ASSERT_DEBUG(m_uiCount >= uiCountToRemove,
"Out of bounds access. Array has {0} elements, trying to pop {1} elements.", m_uiCount, uiCountToRemove);
404 m_uiCount -= uiCountToRemove;
408template <
typename T, plUInt16 Size>
411 PL_ASSERT_DEBUG(m_uiCount > 0,
"Out of bounds access. Trying to peek into an empty array.");
412 return GetElementsPtr()[m_uiCount - 1];
415template <
typename T, plUInt16 Size>
418 PL_ASSERT_DEBUG(m_uiCount > 0,
"Out of bounds access. Trying to peek into an empty array.");
419 return GetElementsPtr()[m_uiCount - 1];
422template <
typename T, plUInt16 Size>
423template <
typename Comparer>
433template <
typename T, plUInt16 Size>
443template <
typename T, plUInt16 Size>
449 return GetElementsPtr();
452template <
typename T, plUInt16 Size>
458 return GetElementsPtr();
461template <
typename T, plUInt16 Size>
467template <
typename T, plUInt16 Size>
473template <
typename T, plUInt16 Size>
479template <
typename T, plUInt16 Size>
485template <
typename T, plUInt16 Size>
488 if (m_uiCapacity >= uiCapacity)
491 const plUInt32 uiCurCap =
static_cast<plUInt32
>(m_uiCapacity);
492 plUInt32 uiNewCapacity = uiCurCap + (uiCurCap / 2);
498 SetCapacity(
static_cast<plUInt16
>(uiNewCapacity), pAllocator);
501template <
typename T, plUInt16 Size>
506 if (m_uiCapacity > Size)
509 PL_DELETE_RAW_BUFFER(pAllocator, m_pElements);
513 m_pElements =
nullptr;
515 else if (m_uiCapacity > Size)
520 if (m_uiCapacity != uiNewCapacity)
521 SetCapacity(
static_cast<plUInt16
>(uiNewCapacity), pAllocator);
525template <
typename T, plUInt16 Size>
528 return m_uiCapacity <= Size ? 0 : m_uiCapacity *
sizeof(T);
531template <
typename T, plUInt16 Size>
535 static_assert(
sizeof(U) <=
sizeof(plUInt32));
536 return reinterpret_cast<const U&
>(m_uiUserData);
539template <
typename T, plUInt16 Size>
543 static_assert(
sizeof(U) <=
sizeof(plUInt32));
544 return reinterpret_cast<U&
>(m_uiUserData);
547template <
typename T, plUInt16 Size>
550 if (m_uiCapacity > Size && uiCapacity > m_uiCapacity)
552 m_pElements = PL_EXTEND_RAW_BUFFER(pAllocator, m_pElements, m_uiCount, uiCapacity);
553 m_uiCapacity = uiCapacity;
558 T* pOldElements = GetElementsPtr();
560 const plUInt32 uiOldCapacity = m_uiCapacity;
561 const plUInt32 uiNewCapacity = uiCapacity;
564 if (uiNewCapacity > Size)
567 T* pNewElements = PL_NEW_RAW_BUFFER(pAllocator, T, uiCapacity);
569 m_pElements = pNewElements;
577 if (uiOldCapacity > Size)
579 PL_DELETE_RAW_BUFFER(pAllocator, pOldElements);
584template <
typename T, plUInt16 Size>
587 return m_uiCapacity <= Size ? reinterpret_cast<T*>(m_StaticData) : m_pElements;
590template <
typename T, plUInt16 Size>
593 return m_uiCapacity <= Size ? reinterpret_cast<const T*>(m_StaticData) : m_pElements;
598template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
601template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
603 : SUPER(other, AllocatorWrapper::GetAllocator())
607template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
609 : SUPER(other, AllocatorWrapper::GetAllocator())
613template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
615 : SUPER(static_cast<SUPER&&>(other), AllocatorWrapper::GetAllocator())
619template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
623 SUPER::Compact(AllocatorWrapper::GetAllocator());
626template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
630 this->m_uiUserData = rhs.m_uiUserData;
633template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
636 SUPER::CopyFrom(rhs, AllocatorWrapper::GetAllocator());
639template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
642 SUPER::MoveFrom(std::move(rhs), AllocatorWrapper::GetAllocator());
645template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
648 SUPER::SetCount(uiCount, AllocatorWrapper::GetAllocator());
651template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
654 SUPER::SetCount(uiCount, fillValue, AllocatorWrapper::GetAllocator());
657template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
660 SUPER::EnsureCount(uiCount, AllocatorWrapper::GetAllocator());
663template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
667 SUPER::SetCountUninitialized(uiCount, AllocatorWrapper::GetAllocator());
670template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
673 SUPER::Insert(value, uiIndex, AllocatorWrapper::GetAllocator());
676template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
679 SUPER::Insert(value, uiIndex, AllocatorWrapper::GetAllocator());
682template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
685 return SUPER::ExpandAndGetRef(AllocatorWrapper::GetAllocator());
688template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
691 SUPER::PushBack(value, AllocatorWrapper::GetAllocator());
694template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
697 SUPER::PushBack(std::move(value), AllocatorWrapper::GetAllocator());
700template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
703 SUPER::PushBackRange(range, AllocatorWrapper::GetAllocator());
706template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
709 SUPER::Reserve(uiCapacity, AllocatorWrapper::GetAllocator());
712template <
typename T, plUInt16 Size,
typename AllocatorWrapper >
715 SUPER::Compact(AllocatorWrapper::GetAllocator());
720template <
typename T, plUInt16 Size>
723 return ref_container.
GetData();
726template <
typename T, plUInt16 Size>
732template <
typename T, plUInt16 Size>
738template <
typename T, plUInt16 Size>
744template <
typename T, plUInt16 Size>
750template <
typename T, plUInt16 Size>
756template <
typename T, plUInt16 Size>
762template <
typename T, plUInt16 Size>
768template <
typename T, plUInt16 Size>
774template <
typename T, plUInt16 Size>
780template <
typename T, plUInt16 Size>
786template <
typename T, plUInt16 Size>
Base class for all memory allocators.
Definition Allocator.h:23
This class encapsulates an array and it's size. It is recommended to use this class instead of plain ...
Definition ArrayPtr.h:37
PL_ALWAYS_INLINE plUInt32 GetCount() const
Returns the number of elements in the array.
Definition ArrayPtr.h:142
PL_ALWAYS_INLINE PointerType GetPtr() const
Returns the pointer to the array.
Definition ArrayPtr.h:118
PL_ALWAYS_INLINE plArrayPtr< const ByteType > ToByteArray() const
Reinterprets this array as a byte array.
Definition ArrayPtr.h:165
static void CopyConstruct(Destination *pDestination, const Source ©, size_t uiCount=1)
Constructs uiCount objects of type T in a raw buffer at pDestination, by creating uiCount copies of c...
static void CopyConstructArray(T *pDestination, const T *pSource, size_t uiCount)
Constructs uiCount objects of type T in a raw buffer at pDestination from an existing array of object...
static bool IsEqual(const T *a, const T *b, size_t uiCount=1)
Tests if objects of type T from pSource and pDestination are equal.
static void RelocateConstruct(T *pDestination, T *pSource, size_t uiCount=1)
Constructs uiCount objects of type T in a raw buffer at pDestination from an existing array of object...
static void Construct(T *pDestination, size_t uiCount=1)
Constructs uiCount objects of type T in a raw buffer at pDestination.
static void Prepend(T *pDestination, const T &source, size_t uiCount)
Moves uiCount objects in pDestination by one object and copies source to the free space.
static void Copy(T *pDestination, const T *pSource, size_t uiCount=1)
Copies objects of type T from pSource to pDestination.
static void MoveConstruct(T *pDestination, T &&source)
Constructs an object of type T in a raw buffer at pDestination, by using move construction from sourc...
static void RelocateOverlapped(T *pDestination, T *pSource, size_t uiCount=1)
Moves objects of type T from pSource to pDestination.
static T AlignSize(T uiSize, T uiAlignment)
Aligns the given size uiSize by rounding up to the next multiple of the size.
static void Destruct(T *pDestination, size_t uiCount=1)
Destructs uiCount objects of type T at pDestination.
Implementation of a dynamically growing array with in-place storage and small memory overhead.
Definition SmallArray.h:17
void PopBack(plUInt32 uiCountToRemove=1)
Removes count elements from the end of the array.
Definition SmallArray_inl.h:400
void PushBackRange(const plArrayPtr< const T > &range, plAllocator *pAllocator)
Pushes all elements in range at the end of the array. Increases the capacity if necessary.
Definition SmallArray_inl.h:390
void Clear()
Clears the array.
Definition SmallArray_inl.h:222
void SetCount(plUInt16 uiCount, plAllocator *pAllocator)
Resizes the array to have exactly uiCount elements. Default constructs extra elements if the array is...
Definition SmallArray_inl.h:142
void RemoveAtAndSwap(plUInt32 uiIndex, plUInt16 uiNumElements=1)
Removes the element at index and fills the gap by swapping in the last element.
Definition SmallArray_inl.h:292
void MoveFrom(plSmallArrayBase< T, Size > &&other, plAllocator *pAllocator)
Moves the data from some other array into this one.
Definition SmallArray_inl.h:69
void SetCountUninitialized(plUInt16 uiCount, plAllocator *pAllocator)
Resizes the array to have exactly uiCount elements. Extra elements might be uninitialized.
Definition SmallArray_inl.h:190
void Sort()
Sort with default comparer.
Definition SmallArray_inl.h:434
void Compact(plAllocator *pAllocator)
Tries to compact the array to avoid wasting memory. The resulting capacity is at least 'GetCount' (no...
Definition SmallArray_inl.h:502
void Reserve(plUInt16 uiCapacity, plAllocator *pAllocator)
Expands the array so it can at least store the given capacity.
Definition SmallArray_inl.h:486
void Insert(const T &value, plUInt32 uiIndex, plAllocator *pAllocator)
Inserts value at index by shifting all following elements.
Definition SmallArray_inl.h:235
void CopyFrom(const plArrayPtr< const T > &other, plAllocator *pAllocator)
Copies the data from some other array into this one.
Definition SmallArray_inl.h:32
bool RemoveAndCopy(const T &value)
Removes the first occurrence of value and fills the gap by shifting all following elements.
Definition SmallArray_inl.h:257
plArrayPtr< typename plArrayPtr< T >::ByteType > GetByteArrayPtr()
Returns a byte array pointer to the array data, or an empty array pointer if the array is empty.
Definition SmallArray_inl.h:474
void EnsureCount(plUInt16 uiCount, plAllocator *pAllocator)
Ensures the container has at least uiCount elements. Ie. calls SetCount() if the container has fewer ...
Definition SmallArray_inl.h:180
T * GetData()
Returns a pointer to the array data, or nullptr if the array is empty.
Definition SmallArray_inl.h:444
plUInt64 GetHeapMemoryUsage() const
Returns the amount of bytes that are currently allocated on the heap.
Definition SmallArray_inl.h:526
T & PeekBack()
Returns the last element of the array.
Definition SmallArray_inl.h:409
T & ExpandAndGetRef(plAllocator *pAllocator)
Grows the array by one element and returns a reference to the newly created element.
Definition SmallArray_inl.h:338
plUInt32 LastIndexOf(const T &value, plUInt32 uiStartIndex=plSmallInvalidIndex) const
Searches for the last occurrence of the given value and returns its index or plInvalidIndex if not fo...
Definition SmallArray_inl.h:325
plArrayPtr< T > GetArrayPtr()
Returns an array pointer to the array data, or an empty array pointer if the array is empty.
Definition SmallArray_inl.h:462
plUInt32 GetCount() const
Returns the number of active elements in the array.
Definition SmallArray_inl.h:210
const T & operator[](plUInt32 uiIndex) const
Returns the element at the given index. Does bounds checks in debug builds.
Definition SmallArray_inl.h:128
void RemoveAtAndCopy(plUInt32 uiIndex, plUInt16 uiNumElements=1)
Removes the element at index and fills the gap by shifting all following elements.
Definition SmallArray_inl.h:281
void PushBackUnchecked(const T &value)
Pushes value at the end of the array. Does NOT ensure capacity.
Definition SmallArray_inl.h:372
bool IsEmpty() const
Returns true, if the array does not contain any elements.
Definition SmallArray_inl.h:216
void PushBack(const T &value, plAllocator *pAllocator)
Pushes value at the end of the array.
Definition SmallArray_inl.h:354
plUInt32 IndexOf(const T &value, plUInt32 uiStartIndex=0) const
Searches for the first occurrence of the given value and returns its index or plInvalidIndex if not f...
Definition SmallArray_inl.h:312
bool operator==(const plSmallArrayBase< T, Size > &rhs) const
Compares this array to another contiguous array type.
Definition SmallArray_inl.h:111
bool RemoveAndSwap(const T &value)
Removes the first occurrence of value and fills the gap by swapping in the last element.
Definition SmallArray_inl.h:269
bool Contains(const T &value) const
Checks whether the given value can be found in the array. O(n) complexity.
Definition SmallArray_inl.h:229
Definition SmallArray.h:219
static void QuickSort(Container &inout_container, const Comparer &comparer=Comparer())
Sorts the elements in container using a in-place quick sort implementation (not stable).
Definition Sorting_inl.h:3
constexpr PL_ALWAYS_INLINE T Min(T f1, T f2)
Returns the smaller value, f1 or f2.
Definition Math_inl.h:27
constexpr PL_ALWAYS_INLINE T Max(T f1, T f2)
Returns the greater value, f1 or f2.
Definition Math_inl.h:39
Base class for Pointer like reverse iterators.
Definition ArrayIterator.h:152
A comparer object is used in sorting algorithms to compare to objects of the same type.
Definition Comparer.h:7
If there is an % operator which takes a TypeIsPod and returns a CompileTimeTrueType T is Pod....
Definition TypeTraits.h:43
Non-Const class for Pointer like reverse iterators.
Definition ArrayIterator.h:216