fennec
Loading...
Searching...
No Matches
object_pool.h
Go to the documentation of this file.
1// =====================================================================================================================
2// fennec, a free and open source game engine
3// Copyright © 2025 Medusa Slockbower
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <https://www.gnu.org/licenses/>.
17// =====================================================================================================================
18
30
31#ifndef FENNEC_CONTAINERS_OBJECT_POOL_H
32#define FENNEC_CONTAINERS_OBJECT_POOL_H
33
37
38namespace fennec
39{
40
45template<typename TypeT, typename AllocT = allocator<TypeT>>
47
48// Definitions =========================================================================================================
49public:
50 using value_t = TypeT;
54
55 class iterator;
56 class const_iterator;
57
58
59// Constructors & Destructor ===========================================================================================
60
63
66 constexpr object_pool()
67 : _size(0) {
68 }
69
72 constexpr ~object_pool() = default;
73
75
76
77// Properties ==========================================================================================================
78
81
84 constexpr size_t size() const {
85 return _size;
86 }
87
90 constexpr size_t capacity() const {
91 return _table.capacity();
92 }
93
96 constexpr bool empty() const {
97 return size() == 0;
98 }
99
105 constexpr size_t next_id() const {
106 size_t next = _size;
107 if (not _freed.empty()) {
108 next = _freed.front();
109 }
110 return next;
111 }
112
114
115// Access ==============================================================================================================
116
119
124 constexpr value_t& operator[](size_t i) {
125 assert(i < capacity(), "Index out of Bounds!");
126 assert(_table[i], "Attempted to access null object.")
127 return *_table[i];
128 }
129
134 constexpr const value_t& operator[](size_t i) const {
135 assert(i < capacity(), "Index out of Bounds!");
136 assert(_table[i], "Attempted to access null object.")
137 return *_table[i];
138 }
139
141
142
143// Modifiers ===========================================================================================================
144
147
152 constexpr size_t insert(value_t&& x) {
153 return this->_insert(fennec::forward<value_t>(x));
154 }
155
160 constexpr size_t insert(const value_t& x) {
161 return this->_insert(x);
162 }
163
164
169 template<typename...ArgsT>
170 constexpr size_t emplace(ArgsT&&...args) {
171 return this->_insert(fennec::forward<ArgsT>(args)...);
172 }
173
177 constexpr void erase(size_t i) {
178 _table[i] = nullopt;
179 _freed.push_back(i);
180 --_size;
181 }
182
185 constexpr void clear() {
186 for (auto& it : _table) {
187 it = nullopt;
188 }
189 _size = 0;
190 _freed.clear();
191 }
192
194
195
196// Iterator ============================================================================================================
197
198 iterator begin() {
199 return iterator(this, 0);
200 }
201
202 iterator end() {
203 return iterator(this, _size);
204 }
205
206 const_iterator begin() const {
207 return iterator(this, 0);
208 }
209
210 const_iterator end() const {
211 return iterator(this, _size);
212 }
213
214 class iterator {
215 public:
216 iterator(object_pool* pool, size_t start)
217 : pool(pool), curr(start) {
218 _fix();
219 }
220
221 iterator(const iterator&) = default;
222 iterator(iterator&&) noexcept = default;
223
224 ~iterator() = default;
225
226 iterator& operator=(const iterator&) = default;
227 iterator& operator=(iterator&&) noexcept = default;
228
229 iterator operator++(int) {
230 iterator ret = *this;
231 ++curr;
232 _fix();
233 return ret;
234 }
235
236 iterator& operator++() {
237 ++curr;
238 _fix();
239 return *this;
240 }
241
242 value_t& operator*() const {
243 return *pool->_table[curr];
244 }
245
246 value_t* operator->() const {
247 return *pool->_table[curr];
248 }
249
250 bool operator==(const iterator& it) {
251 return pool == it.pool and curr == it.curr;
252 }
253
254 bool operator!=(const iterator& it) {
255 return pool != it.pool or curr != it.curr;
256 }
257
258 private:
259 object_pool* pool;
260 size_t curr;
261
262 void _fix() {
263 while (curr < pool->_size and not pool->_table[curr]) {
264 ++curr;
265 }
266 }
267 };
268
269 class const_iterator {
270 public:
271 const_iterator(const object_pool* pool, size_t start)
272 : pool(pool), curr(start) {
273 _fix();
274 }
275
276 const_iterator(const const_iterator&) = default;
277 const_iterator(const_iterator&&) noexcept = default;
278
279 ~const_iterator() = default;
280
281 const_iterator& operator=(const const_iterator&) = default;
282 const_iterator& operator=(const_iterator&&) noexcept = default;
283
284 const_iterator operator++(int) {
285 const_iterator ret = *this;
286 ++curr;
287 _fix();
288 return ret;
289 }
290
291 const_iterator& operator++() {
292 ++curr;
293 _fix();
294 return *this;
295 }
296
297 const value_t& operator*() const {
298 return *pool->_table[curr];
299 }
300
301 const value_t* operator->() const {
302 return *pool->_table[curr];
303 }
304
305 bool operator==(const const_iterator& it) {
306 return pool == it.pool and curr == it.curr;
307 }
308
309 bool operator!=(const const_iterator& it) {
310 return pool != it.pool or curr != it.curr;
311 }
312
313 private:
314 const object_pool* pool;
315 size_t curr;
316
317 void _fix() {
318 while (curr < pool->_size and not pool->_table[curr]) {
319 ++curr;
320 }
321 }
322 };
323
324private:
325 table_t _table;
326 freed_t _freed;
327 size_t _size;
328
329 size_t _next_free() {
330 size_t next = _size;
331 if (not _freed.empty()) {
332 next = _freed.front();
333 _freed.pop_front();
334 }
335 ++_size;
336 return next;
337 }
338
339 template<typename...ArgsT>
340 size_t _insert(ArgsT&&...args) {
341 size_t i = _next_free();
342 if (i >= _table.size()) {
343 _table.resize(fennec::max(_table.size() * 2, size_t(8)));
344 }
345 _table[i].emplace(fennec::forward<ArgsT>(args)...);
346 return i;
347 }
348};
349
350}
351
352#endif // FENNEC_CONTAINERS_OBJECT_POOL_H
A header containing the definition for a dynamically allocated array.
A header containing the definition for a linked list of values.
A header containing the definition for a container with an optionally present variable.
Wrapper for dynamically sized and allocated arrays.
Definition dynarray.h:64
constexpr size_t capacity() const
Definition dynarray.h:337
Data Structure defining lists of elements.
Definition list.h:67
constexpr bool empty() const
Definition list.h:181
constexpr void clear()
Clears the list, destructing all elements in order.
Definition list.h:392
constexpr size_t push_back(const value_t &x)
Push Back Copy.
Definition list.h:342
constexpr value_t & front()
Access Front Element.
Definition list.h:222
Struct which holds a pool of objects associated with ids.
Definition object_pool.h:46
constexpr bool empty() const
Definition object_pool.h:96
constexpr ~object_pool()=default
Default Destructor, destructs objects then releases the allocation.
constexpr size_t emplace(ArgsT &&...args)
Emplacement, constructs a new object using args...
Definition object_pool.h:170
constexpr const value_t & operator[](size_t i) const
Array Const Access Operator.
Definition object_pool.h:134
constexpr void clear()
Clear the object pool.
Definition object_pool.h:185
constexpr size_t capacity() const
Definition object_pool.h:90
constexpr size_t next_id() const
Retrieve the next id i that would be assigned to an object o were it added to the object pool.
Definition object_pool.h:105
constexpr size_t insert(const value_t &x)
Move Insertion, inserts a copy of x into the pool.
Definition object_pool.h:160
constexpr size_t insert(value_t &&x)
Move Insertion, inserts x into the pool.
Definition object_pool.h:152
constexpr void erase(size_t i)
Erase an object from the pool.
Definition object_pool.h:177
constexpr value_t & operator[](size_t i)
Array Access Operator.
Definition object_pool.h:124
constexpr size_t size() const
Definition object_pool.h:84
constexpr object_pool()
Default Constructor, initializes an empty object pool.
Definition object_pool.h:66