4#include "../Foundation/Assert.h"
5#include "../Foundation/Memory.h"
6#include "ArenaMapKey.h"
43 T* newItems =
reinterpret_cast<T*
>(
Memory::allocate(other.itemsSize *
sizeof(T)));
45 typename Key::Generation* newGenerations =
reinterpret_cast<typename Key::Generation*
>(
49 ::memset(newGenerations, 0, other.itemsSize *
sizeof(
typename Key::Generation));
51 generations = newGenerations;
52 itemsSize = other.itemsSize;
53 for (
size_t idx = 0; idx < other.itemsSize; ++idx)
55 if (other.generations[idx].used)
57 new (&items[idx], PlacementNew()) T(other.items[idx]);
59 generations[idx] = other.generations[idx];
61 numUsed = other.numUsed;
69 itemsSize = other.itemsSize;
70 other.items =
nullptr;
72 generations = other.generations;
73 other.generations =
nullptr;
74 numUsed = other.numUsed;
82 template <
typename MapType>
85 MapType* map =
nullptr;
90 const auto numAllocated = map->getNumAllocated();
91 for (++index; index < numAllocated; ++index)
93 if (map->generations[index].used)
103 return it.index == index;
108 return it.index != index;
111 auto& operator*()
const {
return map->items[index]; }
112 auto* operator->()
const {
return &map->items[index]; }
118 ConstIterator cend()
const {
return end(); }
119 ConstIterator begin()
const
123 if (generations[idx].used)
125 return {
this,
static_cast<uint32_t>(idx)};
137 if (generations[idx].used)
139 return {
this,
static_cast<uint32_t>(idx)};
149 for (
size_t idx = 0; idx < itemsSize; ++idx)
151 if (generations[idx].used)
155 generations[idx].used = 0;
163 generations =
nullptr;
168 [[nodiscard]]
size_t size()
const {
return numUsed; }
171 [[nodiscard]]
size_t capacity()
const {
return itemsSize; }
174 [[nodiscard]]
bool isFull()
const {
return itemsSize == numUsed; }
180 [[nodiscard]]
bool resize(
size_t newSize)
184 if (newSize > Key::MaxIndex)
191 generations =
nullptr;
196 typename Key::Generation* newGenerations =
197 reinterpret_cast<typename Key::Generation*
>(
Memory::allocate(newSize *
sizeof(
typename Key::Generation)));
198 if (not newGenerations)
200 ::memset(newGenerations, 0, newSize *
sizeof(
typename Key::Generation));
201 generations = newGenerations;
207 template <
typename Value>
208 [[nodiscard]] Key insert(
const Value&
object)
210 Key key = allocateNewKeySlot();
213 new (&items[key.index], PlacementNew()) T(
object);
218 [[nodiscard]] Key allocate()
220 Key key = allocateNewKeySlot();
223 new (&items[key.index], PlacementNew()) T();
228 template <
typename Value>
229 [[nodiscard]] Key insert(Value&&
object)
231 Key key = allocateNewKeySlot();
234 new (&items[key.index], PlacementNew()) T(
move(
object));
239 [[nodiscard]]
bool containsKey(Key key)
const
241 return key.isValid() and generations[key.index].used != 0 and
242 generations[key.index].generation == key.generation.generation;
245 template <
typename ComparableToValue>
246 [[nodiscard]]
bool containsValue(
const ComparableToValue& value, Key* optionalKey =
nullptr)
const
248 for (
size_t idx = 0; idx < itemsSize; ++idx)
250 if (generations[idx].used and items[idx] == value)
254 optionalKey->index =
static_cast<uint32_t>(idx);
255 optionalKey->generation = generations[idx];
263 [[nodiscard]]
bool remove(Key key)
265 if (generations[key.index] != key.generation)
267 if (generations[key.index].generation + 1 <= Key::MaxGenerations)
269 generations[key.index].generation++;
274 generations[key.index].generation++;
276 generations[key.index].used = 0;
277 items[key.index].~T();
282 [[nodiscard]] T* get(Key key)
284 if (generations[key.index] != key.generation)
286 return &items[key.index];
289 [[nodiscard]]
const T* get(Key key)
const
291 if (generations[key.index] != key.generation)
293 return &items[key.index];
298 size_t itemsSize = 0;
300 typename Key::Generation* generations =
nullptr;
304 [[nodiscard]] Key allocateNewKeySlot()
306 for (
size_t idx = 0; idx < itemsSize; ++idx)
308 if (generations[idx].used == 0)
310 generations[idx].used = 1;
313 key.generation = generations[idx];
314 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:84
A sparse vector keeping objects at a stable memory location.
Definition: ArenaMap.h:29
bool resize(size_t newSize)
Changes the size of the arena.
Definition: ArenaMap.h:180
size_t size() const
Get the number of used slots in the arena.
Definition: ArenaMap.h:168
uint32_t getNumAllocated() const
Get the maximum number of objects that can be stored in this map.
Definition: ArenaMap.h:80
size_t capacity() const
Get the total number slots in the arena.
Definition: ArenaMap.h:171
bool isFull() const
Returns true if size() == capacity(), that means the arena is full.
Definition: ArenaMap.h:174
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.