UraniumCompute 0.1.0
A GPU accelerated parallel task scheduler
HeapArray.h
1#pragma once
2#include <UnCompute/Containers/ArraySlice.h>
3#include <UnCompute/Memory/IAllocator.h>
4#include <UnCompute/Memory/SystemAllocator.h>
5
6namespace UN
7{
12 template<class T>
13 class HeapArray final
14 {
15 static_assert(!std::is_const_v<T>);
16
17 ArraySlice<T> m_Storage{};
18 IAllocator* m_pAllocator{};
19
20 inline void AllocateStorage(USize count)
21 {
22 if (m_pAllocator == nullptr)
23 {
24 // This is required because in C# the default constructor will only set all pointers to null.
25 m_pAllocator = SystemAllocator::Get();
26 }
27
28 void* pData = m_pAllocator->Allocate(count * sizeof(T), std::max(static_cast<USize>(16), alignof(T)));
29 m_Storage = ArraySlice<T>(static_cast<T*>(pData), count);
30 }
31
32 inline void AllocateStorage(USize count, const T& value)
33 {
34 AllocateStorage(count);
35 for (USize i = 0; i < count; ++i)
36 {
37 m_Storage[i] = value;
38 }
39 }
40
41 inline void DeallocateStorage(const ArraySlice<T>& storage)
42 {
43 if (storage.Empty())
44 {
45 return;
46 }
47
48 m_pAllocator->Deallocate(storage.Data());
49 }
50
51 inline void DeallocateStorage()
52 {
53 DeallocateStorage(m_Storage);
54 m_Storage = {};
55 }
56
57 public:
59 inline HeapArray() = default;
60
62 inline HeapArray(const HeapArray& other)
63 : m_pAllocator(other.m_pAllocator)
64 {
65 AllocateStorage(other.Length());
66 other.CopyDataTo(m_Storage);
67 }
68
70 inline HeapArray(HeapArray&& other) noexcept
71 : m_Storage(other.m_Storage)
72 , m_pAllocator(other.m_pAllocator)
73 {
74 other.m_Storage = {};
75 }
76
80 inline explicit HeapArray(const ArraySlice<const T>& data)
81 : m_pAllocator(SystemAllocator::Get())
82 {
83 AllocateStorage(data.Length());
84 data.CopyDataTo(m_Storage);
85 }
86
88 inline HeapArray& operator=(const HeapArray& other)
89 {
90 if (this == &other)
91 {
92 return *this;
93 }
94
95 DeallocateStorage();
96 AllocateStorage(other.Length());
97 other.CopyDataTo(m_Storage);
98
99 return *this;
100 }
101
103 inline HeapArray& operator=(HeapArray&& other) noexcept
104 {
105 DeallocateStorage();
106 m_Storage = other.m_Storage;
107 m_pAllocator = other.m_pAllocator;
108 other.m_Storage = {};
109 return *this;
110 }
111
112 inline ~HeapArray()
113 {
114 DeallocateStorage();
115 }
116
120 inline explicit HeapArray(IAllocator* pAllocator)
121 : m_pAllocator(pAllocator)
122 {
123 }
124
129 inline explicit HeapArray(USize size, const T& value = {})
130 : m_pAllocator(SystemAllocator::Get())
131 {
132 AllocateStorage(size, value);
133 }
134
140 inline HeapArray(IAllocator* pAllocator, USize size, const T& value = {})
141 : m_pAllocator(pAllocator)
142 {
143 AllocateStorage(size, value);
144 }
145
150 inline void Resize(USize size, const T& value = {})
151 {
152 ArraySlice<T> temp = m_Storage;
153 AllocateStorage(size);
154 temp.CopyDataTo(m_Storage);
155 for (USize i = temp.Length(); i < Length(); ++i)
156 {
157 m_Storage[i] = value;
158 }
159 DeallocateStorage(temp);
160 }
161
168 inline ArraySlice<T> operator()(USize beginIndex, USize endIndex) const noexcept
169 {
170 return m_Storage(beginIndex, endIndex);
171 }
172
176 inline T& operator[](USize index) const noexcept
177 {
178 return m_Storage[index];
179 }
180
186 [[nodiscard]] inline SSize IndexOf(const T& value) const
187 {
188 return m_Storage.IndexOf(value);
189 }
190
196 [[nodiscard]] inline SSize LastIndexOf(const T& value) const
197 {
198 return m_Storage.LastIndexOf(value);
199 }
200
204 [[nodiscard]] inline bool Contains(const T& value)
205 {
206 return IndexOf(value) != -1;
207 }
208
210 [[nodiscard]] inline USize Length() const
211 {
212 return m_Storage.Length();
213 }
214
216 [[nodiscard]] inline bool Empty() const
217 {
218 return Length() == 0;
219 }
220
222 [[nodiscard]] inline bool Any() const
223 {
224 return Length() > 0;
225 }
226
228 inline void Reset()
229 {
230 DeallocateStorage();
231 }
232
234 [[nodiscard]] inline T* Data()
235 {
236 return m_Storage.Data();
237 }
238
240 [[nodiscard]] inline const T* Data() const
241 {
242 return m_Storage.Data();
243 }
244
250 inline USize CopyDataTo(ArraySlice<T> destination) const
251 {
252 return m_Storage.CopyDataTo(destination);
253 }
254
258 [[nodiscard]] inline static HeapArray<T> CopyFrom(const ArraySlice<const T>& arraySlice)
259 {
260 return HeapArray<T>(arraySlice);
261 }
262
263 [[nodiscard]] inline const T* begin() const
264 {
265 return m_Storage.begin();
266 }
267
268 [[nodiscard]] inline const T* end() const
269 {
270 return m_Storage.end();
271 }
272
273 inline operator ArraySlice<const T>() const // NOLINT(google-explicit-constructor)
274 {
275 return m_Storage;
276 }
277
278 inline operator ArraySlice<T>() // NOLINT(google-explicit-constructor)
279 {
280 return m_Storage;
281 }
282 };
283} // namespace UN
This class represents a non-owning slice of contiguously stored elements.
Definition: ArraySlice.h:12
T * Data() const noexcept
Get pointer to the beginning of the slice.
Definition: ArraySlice.h:185
bool Empty() const noexcept
Check if the slice is empty.
Definition: ArraySlice.h:167
USize CopyDataTo(ArraySlice< std::remove_const_t< T > > destination) const
Copy data from this slice to another.
Definition: ArraySlice.h:195
USize Length() const noexcept
Length of the slice.
Definition: ArraySlice.h:161
Fixed-size heap-allocated array.
Definition: HeapArray.h:14
void Reset()
Reset the array to empty state.
Definition: HeapArray.h:228
HeapArray & operator=(HeapArray &&other) noexcept
Move assignment.
Definition: HeapArray.h:103
bool Empty() const
Check if the array is empty.
Definition: HeapArray.h:216
ArraySlice< T > operator()(USize beginIndex, USize endIndex) const noexcept
Create a subslice from this array.
Definition: HeapArray.h:168
bool Contains(const T &value)
Check if the element is present in the array.
Definition: HeapArray.h:204
HeapArray()=default
Create an empty array.
bool Any() const
Check if the array has any elements.
Definition: HeapArray.h:222
HeapArray(USize size, const T &value={})
Create an array.
Definition: HeapArray.h:129
USize CopyDataTo(ArraySlice< T > destination) const
Copy data from this array to a slice.
Definition: HeapArray.h:250
const T * Data() const
Get pointer to the beginning of the array.
Definition: HeapArray.h:240
HeapArray(IAllocator *pAllocator)
Create an array.
Definition: HeapArray.h:120
SSize LastIndexOf(const T &value) const
Get index of the last element equal to the passed value.
Definition: HeapArray.h:196
HeapArray(const ArraySlice< const T > &data)
Create an array.
Definition: HeapArray.h:80
HeapArray(const HeapArray &other)
Copy constructor.
Definition: HeapArray.h:62
HeapArray & operator=(const HeapArray &other)
Copy assignment.
Definition: HeapArray.h:88
T & operator[](USize index) const noexcept
Get an element by index.
Definition: HeapArray.h:176
SSize IndexOf(const T &value) const
Get index of the first element equal to the passed value.
Definition: HeapArray.h:186
HeapArray(HeapArray &&other) noexcept
Move constructor.
Definition: HeapArray.h:70
T * Data()
Get pointer to the beginning of the array.
Definition: HeapArray.h:234
static HeapArray< T > CopyFrom(const ArraySlice< const T > &arraySlice)
Create a heap array by copying data from another container.
Definition: HeapArray.h:258
HeapArray(IAllocator *pAllocator, USize size, const T &value={})
Create an array.
Definition: HeapArray.h:140
USize Length() const
\bried Length of the array.
Definition: HeapArray.h:210
void Resize(USize size, const T &value={})
Set size of the array.
Definition: HeapArray.h:150
An interface for memory allocators.
Definition: IAllocator.h:8
virtual void Deallocate(void *pointer)=0
Deallocate memory.
virtual void * Allocate(USize size, USize alignment)=0
Allocate memory.
This allocator uses platform-specific aligned versions of malloc() and free().
Definition: SystemAllocator.h:8
static SystemAllocator * Get()
Get global static instance of the system allocator.
Definition: SystemAllocator.h:17