Plasma Engine  2.0
Loading...
Searching...
No Matches
SmallArray.h
1#pragma once
2
3#include <Foundation/Algorithm/Sorting.h>
4#include <Foundation/Math/Math.h>
5#include <Foundation/Memory/AllocatorWrapper.h>
6#include <Foundation/Types/ArrayPtr.h>
7
8constexpr plUInt32 plSmallInvalidIndex = 0xFFFF;
9
15template <typename T, plUInt16 Size>
17{
18public:
19 // Only if the stored type is either POD or relocatable the hybrid array itself is also relocatable.
20 PL_DECLARE_MEM_RELOCATABLE_TYPE_CONDITIONAL(T);
21
22 plSmallArrayBase(); // [tested]
23 plSmallArrayBase(const plSmallArrayBase<T, Size>& other, plAllocator* pAllocator); // [tested]
24 plSmallArrayBase(const plArrayPtr<const T>& other, plAllocator* pAllocator); // [tested]
25 plSmallArrayBase(plSmallArrayBase<T, Size>&& other, plAllocator* pAllocator); // [tested]
26
27 ~plSmallArrayBase(); // [tested]
28
29 // Can't use regular assignment operators since we need to pass an allocator. Use CopyFrom or MoveFrom methods instead.
30 void operator=(const plSmallArrayBase<T, Size>& rhs) = delete;
31 void operator=(plSmallArrayBase<T, Size>&& rhs) = delete;
32
34 void CopyFrom(const plArrayPtr<const T>& other, plAllocator* pAllocator); // [tested]
35
37 void MoveFrom(plSmallArrayBase<T, Size>&& other, plAllocator* pAllocator); // [tested]
38
40 operator plArrayPtr<const T>() const; // [tested]
41
43 operator plArrayPtr<T>(); // [tested]
44
46 bool operator==(const plSmallArrayBase<T, Size>& rhs) const; // [tested]
47 PL_ADD_DEFAULT_OPERATOR_NOTEQUAL(const plSmallArrayBase<T, Size>&);
48
49#if PL_DISABLED(PL_USE_CPP20_OPERATORS)
50 bool operator==(const plArrayPtr<const T>& rhs) const; // [tested]
51 PL_ADD_DEFAULT_OPERATOR_NOTEQUAL(const plArrayPtr<const T>&);
52#endif
54 const T& operator[](plUInt32 uiIndex) const; // [tested]
55
57 T& operator[](plUInt32 uiIndex); // [tested]
58
60 void SetCount(plUInt16 uiCount, plAllocator* pAllocator); // [tested]
61
63 void SetCount(plUInt16 uiCount, const T& fillValue, plAllocator* pAllocator); // [tested]
64
66 template <typename = void> // Template is used to only conditionally compile this function in when it is actually used.
67 void SetCountUninitialized(plUInt16 uiCount, plAllocator* pAllocator); // [tested]
68
71 void EnsureCount(plUInt16 uiCount, plAllocator* pAllocator); // [tested]
72
74 plUInt32 GetCount() const; // [tested]
75
77 bool IsEmpty() const; // [tested]
78
80 void Clear(); // [tested]
81
83 bool Contains(const T& value) const; // [tested]
84
86 void Insert(const T& value, plUInt32 uiIndex, plAllocator* pAllocator); // [tested]
87
89 void Insert(T&& value, plUInt32 uiIndex, plAllocator* pAllocator); // [tested]
90
92 bool RemoveAndCopy(const T& value); // [tested]
93
95 bool RemoveAndSwap(const T& value); // [tested]
96
98 void RemoveAtAndCopy(plUInt32 uiIndex, plUInt16 uiNumElements = 1); // [tested]
99
101 void RemoveAtAndSwap(plUInt32 uiIndex, plUInt16 uiNumElements = 1); // [tested]
102
104 plUInt32 IndexOf(const T& value, plUInt32 uiStartIndex = 0) const; // [tested]
105
107 plUInt32 LastIndexOf(const T& value, plUInt32 uiStartIndex = plSmallInvalidIndex) const; // [tested]
108
110 T& ExpandAndGetRef(plAllocator* pAllocator); // [tested]
111
113 void PushBack(const T& value, plAllocator* pAllocator); // [tested]
114
116 void PushBack(T&& value, plAllocator* pAllocator); // [tested]
117
119 void PushBackUnchecked(const T& value); // [tested]
120
122 void PushBackUnchecked(T&& value); // [tested]
123
125 void PushBackRange(const plArrayPtr<const T>& range, plAllocator* pAllocator); // [tested]
126
128 void PopBack(plUInt32 uiCountToRemove = 1); // [tested]
129
131 T& PeekBack(); // [tested]
132
134 const T& PeekBack() const; // [tested]
135
137 template <typename Comparer>
138 void Sort(const Comparer& comparer); // [tested]
139
141 void Sort(); // [tested]
142
144 T* GetData();
145
147 const T* GetData() const;
148
150 plArrayPtr<T> GetArrayPtr(); // [tested]
151
153 plArrayPtr<const T> GetArrayPtr() const; // [tested]
154
157
160
162 void Reserve(plUInt16 uiCapacity, plAllocator* pAllocator); // [tested]
163
166 void Compact(plAllocator* pAllocator); // [tested]
167
169 plUInt32 GetCapacity() const { return m_uiCapacity; }
170
172 plUInt64 GetHeapMemoryUsage() const; // [tested]
173
174 using value_type = T;
175 using const_reference = const T&;
176 using const_iterator = const T*;
177 using const_reverse_iterator = const_reverse_pointer_iterator<T>;
178 using iterator = T*;
179 using reverse_iterator = reverse_pointer_iterator<T>;
180
181 template <typename U>
182 const U& GetUserData() const; // [tested]
183
184 template <typename U>
185 U& GetUserData(); // [tested]
186
187protected:
188 enum
189 {
190 CAPACITY_ALIGNMENT = 4
191 };
192
193 void SetCapacity(plUInt16 uiCapacity, plAllocator* pAllocator);
194
195 T* GetElementsPtr();
196 const T* GetElementsPtr() const;
197
198 plUInt16 m_uiCount = 0;
199 plUInt16 m_uiCapacity = Size;
200
201 plUInt32 m_uiUserData = 0;
202
203 union
204 {
205 struct alignas(PL_ALIGNMENT_OF(T))
206 {
207 plUInt8 m_StaticData[Size * sizeof(T)];
208 };
209
210 T* m_pElements = nullptr;
211 };
212};
213
215
217template <typename T, plUInt16 Size, typename AllocatorWrapper = plDefaultAllocatorWrapper>
218class plSmallArray : public plSmallArrayBase<T, Size>
219{
221
222public:
223 // Only if the stored type is either POD or relocatable the hybrid array itself is also relocatable.
224 PL_DECLARE_MEM_RELOCATABLE_TYPE_CONDITIONAL(T);
225
226 plSmallArray();
227
229 plSmallArray(const plArrayPtr<const T>& other);
231
233
234 void operator=(const plSmallArray<T, Size, AllocatorWrapper>& rhs);
235 void operator=(const plArrayPtr<const T>& rhs);
236 void operator=(plSmallArray<T, Size, AllocatorWrapper>&& rhs) noexcept;
237
238 void SetCount(plUInt16 uiCount); // [tested]
239 void SetCount(plUInt16 uiCount, const T& fillValue); // [tested]
240 void EnsureCount(plUInt16 uiCount); // [tested]
241
242 template <typename = void>
243 void SetCountUninitialized(plUInt16 uiCount); // [tested]
244
245 void InsertAt(plUInt32 uiIndex, const T& value); // [tested]
246 void InsertAt(plUInt32 uiIndex, T&& value); // [tested]
247
248 T& ExpandAndGetRef(); // [tested]
249 void PushBack(const T& value); // [tested]
250 void PushBack(T&& value); // [tested]
251 void PushBackRange(const plArrayPtr<const T>& range); // [tested]
252
253 void Reserve(plUInt16 uiCapacity);
254 void Compact();
255};
256
257#include <Foundation/Containers/Implementation/SmallArray_inl.h>
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
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
plUInt32 GetCapacity() const
Returns the reserved number of elements that the array can hold without reallocating.
Definition SmallArray.h:169
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
Base class for Pointer like reverse iterators.
Definition ArrayIterator.h:152
Non-Const class for Pointer like reverse iterators.
Definition ArrayIterator.h:216