SleakEngine
0.1.0
C++23 multi-backend game engine
Toggle main menu visibility
Loading...
Searching...
No Matches
List.hpp
Go to the documentation of this file.
1
#ifndef _LIST_H_
2
#define _LIST_H_
3
4
#include <
Utility/Exception.hpp
>
5
#include <algorithm>
// For std::swap
6
#include <functional>
7
8
namespace
Sleak
{
9
/**
10
* @class List
11
* @brief Implements a dynamic array-like list for storing and managing a
12
* collection of elements.
13
*
14
* The List class provides a flexible and efficient way to store and access
15
* elements in a linear order. It is suitable for scenarios where you need to
16
* dynamically resize the collection or access elements by index.
17
* @ingroup utility
18
*/
19
template
<
typename
T>
20
class
List
{
21
private
:
22
T* data =
nullptr
;
23
size_t
size = 0;
24
size_t
capacity = 0;
25
26
/// Recursive quicksort driving sort().
27
void
quickSort(
int
low,
int
high,
28
std::function<
bool
(
const
T&,
const
T&)> compare) {
29
if
(low < high) {
30
int
pivotIndex = partition(low, high, compare);
31
quickSort(low, pivotIndex - 1, compare);
32
quickSort(pivotIndex + 1, high, compare);
33
}
34
}
35
36
/// Lomuto partition step for quickSort; returns the pivot's final index.
37
int
partition(
int
low,
int
high,
38
std::function<
bool
(
const
T&,
const
T&)> compare) {
39
T pivot = data[high];
40
int
i = low - 1;
41
42
for
(
int
j = low; j < high; j++) {
43
if
(compare(data[j], pivot)) {
44
i++;
45
std::swap(data[i], data[j]);
46
}
47
}
48
49
std::swap(data[i + 1], data[high]);
50
return
i + 1;
51
}
52
53
public
:
54
List
() noexcept = default;
55
56
/// Adopts an existing buffer directly; List takes ownership.
57
List
(T* Data,
size_t
Size) : data(Data), size(Size), capacity(Size) {}
58
59
// Copy constructor
60
List
(
const
List
& other) : size(other.size), capacity(other.capacity) {
61
data =
new
T[capacity];
62
for
(
size_t
i = 0; i < size; ++i) {
63
data[i] = other.data[i];
64
}
65
}
66
67
// Move constructor
68
List
(
List
&& other) noexcept
69
: data(other.data), size(other.size), capacity(other.capacity) {
70
other.data =
nullptr
;
71
other.size = 0;
72
other.capacity = 0;
73
}
74
75
// Copy assignment
76
List
&
operator=
(
const
List
& other) {
77
if
(
this
!= &other) {
78
delete
[] data;
79
size = other.size;
80
capacity = other.capacity;
81
data =
new
T[capacity];
82
for
(
size_t
i = 0; i < size; ++i) {
83
data[i] = other.data[i];
84
}
85
}
86
return
*
this
;
87
}
88
89
// Move assignment
90
List
&
operator=
(
List
&& other)
noexcept
{
91
if
(
this
!= &other) {
92
delete
[] data;
93
data = other.data;
94
size = other.size;
95
capacity = other.capacity;
96
other.data =
nullptr
;
97
other.size = 0;
98
other.capacity = 0;
99
}
100
return
*
this
;
101
}
102
103
List
(std::initializer_list<T> initList) {
104
for
(
const
T& value : initList) {
105
add
(value);
106
}
107
}
108
109
/// Frees the backing array.
110
~List
() {
delete
[] data; }
111
112
// Element addition
113
void
add
(
const
T& value) {
114
if
(size == capacity)
resize
();
115
data[size++] = value;
116
}
117
118
void
add
(T&& value) {
119
if
(size == capacity)
resize
();
120
data[size++] = std::move(value);
121
}
122
123
void
add
(std::initializer_list<T> AddList) {
124
for
(
auto
&& item : AddList) {
125
add
(std::move(item));
126
}
127
}
128
129
// Element access
130
T&
operator[]
(
size_t
index) {
131
if
(index >= size)
throw
Sleak::IndexOutOfBoundsException
();
132
return
data[index];
133
}
134
135
const
T&
operator[]
(
size_t
index)
const
{
136
if
(index >= size)
throw
Sleak::IndexOutOfBoundsException
();
137
return
data[index];
138
}
139
140
T&
at
(
size_t
index) {
141
if
(index >= size)
throw
Sleak::IndexOutOfBoundsException
();
142
return
data[index];
143
}
144
145
const
T&
at
(
size_t
index)
const
{
146
if
(index >= size)
throw
Sleak::IndexOutOfBoundsException
();
147
return
data[index];
148
}
149
150
// Capacity
151
size_t
GetSize
()
const
{
return
size; }
152
size_t
GetByteSize
()
const
{
return
size *
sizeof
(T); }
153
size_t
GetCapacity
()
const
{
return
capacity; }
154
bool
empty
()
const
{
return
size == 0; }
155
156
// Data access
157
T*
GetData
() {
return
data; }
158
const
T*
GetData
()
const
{
return
data; }
159
void
*
GetRawData
() {
return
static_cast<
void
*
>
(data); }
160
const
void
*
GetRawData
()
const
{
return
static_cast<
const
void
*
>
(data); }
161
162
// Iterators
163
T*
begin
() {
return
data; }
164
const
T*
begin
()
const
{
return
data; }
165
T*
end
() {
return
data + size; }
166
const
T*
end
()
const
{
return
data + size; }
167
168
// Modifiers
169
void
clear
() {
170
// Reset each live slot to a default-constructed T so that any
171
// resources the elements own (e.g. RefPtr refcounts) are released.
172
// Setting size=0 alone leaks everything until the backing array
173
// is reallocated or destroyed.
174
for
(
size_t
i = 0; i < size; ++i) {
175
data[i] = T();
176
}
177
size = 0;
178
}
179
180
void
release
() {
181
delete
[] data;
182
data =
nullptr
;
183
size = 0;
184
capacity = 0;
185
}
186
187
void
resize
() {
188
size_t
newCapacity = (capacity == 0) ? 1 : capacity * 2;
189
resize
(newCapacity);
190
}
191
192
void
resize
(
size_t
newCapacity) {
193
if
(newCapacity <= capacity)
return
;
194
195
T* newData =
new
T[newCapacity];
196
for
(
size_t
i = 0; i < size; ++i) {
197
newData[i] = std::move(data[i]);
198
}
199
delete
[] data;
200
data = newData;
201
capacity = newCapacity;
202
}
203
204
void
insert
(
size_t
index,
const
T& value) {
205
if
(index > size)
throw
Sleak::IndexOutOfBoundsException
();
206
if
(size == capacity)
resize
();
207
208
for
(
size_t
i = size; i > index; --i) {
209
data[i] = data[i - 1];
210
}
211
data[index] = value;
212
++size;
213
}
214
215
void
erase
(
size_t
index) {
216
if
(index >= size)
throw
Sleak::IndexOutOfBoundsException
();
217
218
for
(
size_t
i = index; i < size - 1; ++i) {
219
data[i] = std::move(data[i + 1]);
220
}
221
// Release the now-unused tail slot; otherwise it keeps owning
222
// the last element (RefPtrs pin their pointees forever).
223
data[size - 1] = T();
224
--size;
225
}
226
227
// Operations
228
void
sort
(std::function<
bool
(
const
T&,
const
T&)> compare) {
229
quickSort(0, size - 1, compare);
230
}
231
232
void
reverse
() {
233
for
(
size_t
i = 0; i < size / 2; ++i) {
234
std::swap(data[i], data[size - 1 - i]);
235
}
236
}
237
238
void
swap
(
List
& other)
noexcept
{
239
std::swap(data, other.data);
240
std::swap(size, other.size);
241
std::swap(capacity, other.capacity);
242
}
243
244
// Search
245
T*
find
(std::function<
bool
(
const
T&)> predicate) {
246
for
(
size_t
i = 0; i < size; ++i) {
247
if
(predicate(data[i]))
return
&data[i];
248
}
249
return
nullptr
;
250
}
251
252
const
T*
find
(std::function<
bool
(
const
T&)> predicate)
const
{
253
for
(
size_t
i = 0; i < size; ++i) {
254
if
(predicate(data[i]))
return
&data[i];
255
}
256
return
nullptr
;
257
}
258
259
int32_t
indexOf
(
const
T& value) {
260
for
(
int
i = 0; i < size; i++)
261
if
(data[i] == value)
262
return
i;
263
264
return
-1;
265
}
266
};
267
}
// namespace Sleak
268
269
#endif
// _LIST_H_
Exception.hpp
Sleak::IndexOutOfBoundsException
Definition
Exception.hpp:22
Sleak::List::GetRawData
void * GetRawData()
Definition
List.hpp:159
Sleak::List::end
T * end()
Definition
List.hpp:165
Sleak::List::clear
void clear()
Definition
List.hpp:169
Sleak::List::reverse
void reverse()
Definition
List.hpp:232
Sleak::List::GetRawData
const void * GetRawData() const
Definition
List.hpp:160
Sleak::List::GetData
T * GetData()
Definition
List.hpp:157
Sleak::List::GetData
const T * GetData() const
Definition
List.hpp:158
Sleak::List::end
const T * end() const
Definition
List.hpp:166
Sleak::List::add
void add(std::initializer_list< T > AddList)
Definition
List.hpp:123
Sleak::List::begin
const T * begin() const
Definition
List.hpp:164
Sleak::List::find
T * find(std::function< bool(const T &)> predicate)
Definition
List.hpp:245
Sleak::List< IndexType >::add
void add(const IndexType &value)
Definition
List.hpp:113
Sleak::List::begin
T * begin()
Definition
List.hpp:163
Sleak::List::GetByteSize
size_t GetByteSize() const
Definition
List.hpp:152
Sleak::List::List
List(const List &other)
Definition
List.hpp:60
Sleak::List::~List
~List()
Frees the backing array.
Definition
List.hpp:110
Sleak::List::empty
bool empty() const
Definition
List.hpp:154
Sleak::List::at
const T & at(size_t index) const
Definition
List.hpp:145
Sleak::List::release
void release()
Definition
List.hpp:180
Sleak::List::GetSize
size_t GetSize() const
Definition
List.hpp:151
Sleak::List::resize
void resize(size_t newCapacity)
Definition
List.hpp:192
Sleak::List::operator[]
T & operator[](size_t index)
Definition
List.hpp:130
Sleak::List::List
List(List &&other) noexcept
Definition
List.hpp:68
Sleak::List< IndexType >::resize
void resize()
Definition
List.hpp:187
Sleak::List::List
List() noexcept=default
Sleak::List::operator=
List & operator=(List &&other) noexcept
Definition
List.hpp:90
Sleak::List::erase
void erase(size_t index)
Definition
List.hpp:215
Sleak::List::sort
void sort(std::function< bool(const T &, const T &)> compare)
Definition
List.hpp:228
Sleak::List::operator=
List & operator=(const List &other)
Definition
List.hpp:76
Sleak::List::find
const T * find(std::function< bool(const T &)> predicate) const
Definition
List.hpp:252
Sleak::List::at
T & at(size_t index)
Definition
List.hpp:140
Sleak::List::swap
void swap(List &other) noexcept
Definition
List.hpp:238
Sleak::List::operator[]
const T & operator[](size_t index) const
Definition
List.hpp:135
Sleak::List::insert
void insert(size_t index, const T &value)
Definition
List.hpp:204
Sleak::List::add
void add(T &&value)
Definition
List.hpp:118
Sleak::List::List
List(std::initializer_list< T > initList)
Definition
List.hpp:103
Sleak::List::GetCapacity
size_t GetCapacity() const
Definition
List.hpp:153
Sleak::List::indexOf
int32_t indexOf(const T &value)
Definition
List.hpp:259
Sleak
Root namespace for everything the engine exposes.
Definition
Camera.hpp:10
include
public
Utility
Container
List.hpp
Generated on
for SleakEngine by
1.18.0