Gamedev Framework (gf) 1.2.0
A C++17 framework for 2D games
BlockAllocator.h
1/*
2 * Gamedev Framework (gf)
3 * Copyright (C) 2016-2022 Julien Bernard
4 *
5 * This software is provided 'as-is', without any express or implied
6 * warranty. In no event will the authors be held liable for any damages
7 * arising from the use of this software.
8 *
9 * Permission is granted to anyone to use this software for any purpose,
10 * including commercial applications, and to alter it and redistribute it
11 * freely, subject to the following restrictions:
12 *
13 * 1. The origin of this software must not be misrepresented; you must not
14 * claim that you wrote the original software. If you use this software
15 * in a product, an acknowledgment in the product documentation would be
16 * appreciated but is not required.
17 * 2. Altered source versions must be plainly marked as such, and must not be
18 * misrepresented as being the original software.
19 * 3. This notice may not be removed or altered from any source distribution.
20 */
21#ifndef GF_SPATIAL_BLOCK_ALLOCATOR_H
22#define GF_SPATIAL_BLOCK_ALLOCATOR_H
23
24#include <cassert>
25#include <vector>
26
27namespace gf {
28#ifndef DOXYGEN_SHOULD_SKIP_THIS
29inline namespace v1 {
30#endif
31
38 constexpr std::size_t NullIndex = static_cast<std::size_t>(-1);
39
44 template<typename T>
46 public:
51 : m_firstFreeBlock(NullIndex)
52 , m_allocated(0)
53 {
54 }
55
61 std::size_t allocate() {
62 std::size_t index = NullIndex;
63
64 if (m_firstFreeBlock != NullIndex) {
65 index = m_firstFreeBlock;
66 m_firstFreeBlock = m_blocks[index].next;
67 m_blocks[index].next = NullIndex;
68 } else {
69 index = m_blocks.size();
70 m_blocks.push_back(Block());
71 }
72
73 assert(index < m_blocks.size());
74 assert(m_blocks[index].next == NullIndex);
75
76 ++m_allocated;
77 return index;
78 }
79
87 void dispose(std::size_t index) {
88 assert(index < m_blocks.size());
89 m_blocks[index].next = m_firstFreeBlock;
90 m_firstFreeBlock = index;
91 --m_allocated;
92 }
93
99 T& operator[](std::size_t index) {
100 assert(index < m_blocks.size());
101 assert(m_blocks[index].next == NullIndex);
102 return m_blocks[index].data;
103 }
104
110 const T& operator[](std::size_t index) const {
111 assert(index < m_blocks.size());
112 assert(m_blocks[index].next == NullIndex);
113 return m_blocks[index].data;
114 }
115
119 void clear() {
120 m_firstFreeBlock = NullIndex;
121 m_blocks.clear();
122 }
123
129 std::size_t getAllocated() const {
130 return m_allocated;
131 }
132
133 private:
134 struct Block {
135 T data;
136 std::size_t next = NullIndex;
137 };
138
139 std::size_t m_firstFreeBlock;
140 std::vector<Block> m_blocks;
141 std::size_t m_allocated;
142 };
143
144
145#ifndef DOXYGEN_SHOULD_SKIP_THIS
146}
147#endif
148}
149
150
151#endif // GF_SPATIAL_BLOCK_ALLOCATOR_H
An allocator of objects referenced by an index.
Definition: BlockAllocator.h:45
std::size_t allocate()
Allocate an object.
Definition: BlockAllocator.h:61
void dispose(std::size_t index)
Deallocate the object at the given index.
Definition: BlockAllocator.h:87
std::size_t getAllocated() const
Get the number of allocated objects.
Definition: BlockAllocator.h:129
T & operator[](std::size_t index)
Access the object at a given index.
Definition: BlockAllocator.h:99
void clear()
Remove all objects at once.
Definition: BlockAllocator.h:119
BlockAllocator()
Default constructor.
Definition: BlockAllocator.h:50
const T & operator[](std::size_t index) const
Access the object at a given index.
Definition: BlockAllocator.h:110
constexpr std::size_t NullIndex
A null index in a block allocator.
Definition: BlockAllocator.h:38
@ Block
The socket would have blocked.
The namespace for gf classes.