4#include "../Foundation/Assert.h"
5#include "../Foundation/Memory.h"
6#include "ArenaMapKey.h"
41 T* newItems =
reinterpret_cast<T*
>(
Memory::allocate(other.itemsSize *
sizeof(T)));
43 typename Key::Generation* newGenerations =
reinterpret_cast<typename Key::Generation*
>(
47 ::memset(newGenerations, 0, other.itemsSize *
sizeof(
typename Key::Generation));
49 generations = newGenerations;
50 itemsSize = other.itemsSize;
51 for (
size_t idx = 0; idx < other.itemsSize; ++idx)
53 if (other.generations[idx].used)
55 new (&items[idx], PlacementNew()) T(other.items[idx]);
57 generations[idx] = other.generations[idx];
59 numUsed = other.numUsed;
67 itemsSize = other.itemsSize;
68 other.items =
nullptr;
70 generations = other.generations;
71 other.generations =
nullptr;
72 numUsed = other.numUsed;
80 template <
typename MapType>
83 MapType* map =
nullptr;
88 const auto numAllocated = map->getNumAllocated();
89 for (++index; index < numAllocated; ++index)
91 if (map->generations[index].used)
101 return it.index == index;
106 return it.index != index;
109 auto& operator*()
const {
return map->items[index]; }
110 auto* operator->()
const {
return &map->items[index]; }
116 ConstIterator cend()
const {
return end(); }
117 ConstIterator begin()
const
121 if (generations[idx].used)
123 return {
this,
static_cast<uint32_t>(idx)};
135 if (generations[idx].used)
137 return {
this,
static_cast<uint32_t>(idx)};
147 for (
size_t idx = 0; idx < itemsSize; ++idx)
149 if (generations[idx].used)
153 generations[idx].used = 0;
161 generations =
nullptr;
166 [[nodiscard]]
size_t size()
const {
return numUsed; }
169 [[nodiscard]]
size_t capacity()
const {
return itemsSize; }
172 [[nodiscard]]
bool isFull()
const {
return itemsSize == numUsed; }
178 [[nodiscard]]
bool resize(
size_t newSize)
182 if (newSize > Key::MaxIndex)
189 generations =
nullptr;
194 typename Key::Generation* newGenerations =
195 reinterpret_cast<typename Key::Generation*
>(
Memory::allocate(newSize *
sizeof(
typename Key::Generation)));
196 if (not newGenerations)
198 ::memset(newGenerations, 0, newSize *
sizeof(
typename Key::Generation));
199 generations = newGenerations;
205 template <
typename Value>
206 [[nodiscard]] Key insert(
const Value&
object)
208 Key key = allocateNewKeySlot();
211 new (&items[key.index], PlacementNew()) T(
object);
216 [[nodiscard]] Key allocate()
218 Key key = allocateNewKeySlot();
221 new (&items[key.index], PlacementNew()) T();
226 template <
typename Value>
227 [[nodiscard]] Key insert(Value&&
object)
229 Key key = allocateNewKeySlot();
232 new (&items[key.index], PlacementNew()) T(
move(
object));
237 [[nodiscard]]
bool containsKey(Key key)
const
239 return key.isValid() and generations[key.index].used != 0 and
240 generations[key.index].generation == key.generation.generation;
243 template <
typename ComparableToValue>
244 [[nodiscard]]
bool containsValue(
const ComparableToValue& value, Key* optionalKey =
nullptr)
const
246 for (
size_t idx = 0; idx < itemsSize; ++idx)
248 if (generations[idx].used and items[idx] == value)
252 optionalKey->index =
static_cast<uint32_t>(idx);
253 optionalKey->generation = generations[idx];
261 [[nodiscard]]
bool remove(Key key)
263 if (generations[key.index] != key.generation)
265 if (generations[key.index].generation + 1 <= Key::MaxGenerations)
267 generations[key.index].generation++;
272 generations[key.index].generation++;
274 generations[key.index].used = 0;
275 items[key.index].~T();
280 [[nodiscard]] T* get(Key key)
282 if (generations[key.index] != key.generation)
284 return &items[key.index];
287 [[nodiscard]]
const T* get(Key key)
const
289 if (generations[key.index] != key.generation)
291 return &items[key.index];
296 size_t itemsSize = 0;
298 typename Key::Generation* generations =
nullptr;
302 [[nodiscard]] Key allocateNewKeySlot()
304 for (
size_t idx = 0; idx < itemsSize; ++idx)
306 if (generations[idx].used == 0)
308 generations[idx].used = 1;
311 key.generation = generations[idx];
312 key.index =
static_cast<uint32_t>(idx);
#define SC_ASSERT_DEBUG(e)
Assert expression e to be true.
Definition: Assert.h:82
#define SC_ASSERT_RELEASE(e)
Assert expression e to be true.
Definition: Assert.h:66
constexpr T && move(T &value)
Converts an lvalue to an rvalue reference.
Definition: Compiler.h:269
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition: PrimitiveTypes.h:38
Definition: ArenaMap.h:82
A sparse vector keeping objects at a stable memory location.
Definition: ArenaMap.h:27
bool resize(size_t newSize)
Changes the size of the arena.
Definition: ArenaMap.h:178
size_t size() const
Get the number of used slots in the arena.
Definition: ArenaMap.h:166
uint32_t getNumAllocated() const
Get the maximum number of objects that can be stored in this map.
Definition: ArenaMap.h:78
size_t capacity() const
Get the total number slots in the arena.
Definition: ArenaMap.h:169
bool isFull() const
Returns true if size() == capacity(), that means the arena is full.
Definition: ArenaMap.h:172
A sparse vector keeping objects at a stable memory location.
Definition: ArenaMapKey.h:22
static SC_COMPILER_EXPORT void * allocate(size_t numBytes)
Allocates numBytes bytes of memory.
static SC_COMPILER_EXPORT void release(void *allocatedMemory)
Free memory allocated by Memory::allocate and / or reallocated by Memory::reallocate.