31 SlotMapKey(std::uint32_t i, std::uint32_t g) : index(i), generation(g)
36 std::uint32_t generation;
46 template<
typename V,
typename Key = SlotMapKey>
64 template<
typename V,
typename Key = SlotMapKey>
147 template<
typename V,
typename Key = SlotMapKey>
160 _slots.emplace_back(
Slot());
179 std::uint32_t idx = freelist.head;
182 if(idx == freelist.tail)
185 _slots.push_back(
Slot());
186 freelist.head = freelist.tail = (std::uint32_t)_slots.size() - 1;
191 freelist.head = _slots[idx].index;
194 Slot& slot = _slots[idx];
197 slot.index = (std::uint32_t)_data.size();
200 _data.push_back(std::move(
value));
204 _erase.push_back(idx);
206 return Key(idx, slot.generation);
219 std::uint32_t idx = freelist.head;
221 if(idx == freelist.tail)
224 _slots.push_back(
Slot());
225 freelist.head = freelist.tail = (std::uint32_t)_slots.size() - 1;
230 freelist.head = _slots[idx].index;
233 Slot& slot = _slots[idx];
236 slot.index =
static_cast<std::uint32_t
>(_data.size());
239 _data.push_back(
value);
243 _erase.push_back(idx);
245 return Key(idx, slot.generation);
270 std::swap(_data[slot.index], _data[_data.size() - 1]);
271 std::swap(_erase[slot.index], _erase[_erase.size() - 1]);
274 _slots[_erase[slot.index]].index = slot.index;
281 _slots[freelist.tail].index = key.index;
282 freelist.tail = key.index;
283 _slots[freelist.tail].index = freelist.tail;
330 return (key.index < _slots.size() && _slots[key.index].generation == key.generation);
344 ASSERTM(slot.index < _data.size(),
"Invalid slot index.");
345 return _data[slot.index];
359 ASSERTM(slot.index < _data.size(),
"Invalid slot index.");
360 return _data[slot.index];
382 return _data.capacity();
400 const V* data()
const
405 std::size_t bytes()
const
407 return sizeof(freelist) + _slots.size() *
sizeof(Slot) + _data.size() *
sizeof(V) +
408 _erase.size() *
sizeof(
Index);
435 return &(this->_slotmap) == &(rhs._slotmap) && this->_index == rhs._index;
439 return !(*
this == rhs);
451 std::uint32_t slot_index = _slotmap._erase[_index];
452 Slot& slot = _slotmap._slots[slot_index];
478 return &(this->_slotmap) == &(rhs._slotmap) && this->_index == rhs._index;
482 return !(*
this == rhs);
494 std::uint32_t slot_index = _slotmap._erase[_index];
495 const Slot& slot = _slotmap._slots[slot_index];
509 SlotMapIterator end()
511 return SlotMapIterator(*
this, _data.size());
514 ConstSlotMapIterator begin()
const
516 return ConstSlotMapIterator(*
this, 0);
519 ConstSlotMapIterator end()
const
521 return ConstSlotMapIterator(*
this, _data.size());
530 Slot() : index(0), generation(1)
533 Slot(std::uint32_t i, std::uint32_t g) : index(i), generation(g)
538 std::uint32_t generation;
551 ASSERTM(key.index < _slots.size(),
"Invalid SlotMap key. Index exceeds number of slots.");
552 Slot& slot = _slots[key.index];
553 ASSERTM(key.generation == slot.generation,
"Invalid SlotMap key. Generation mismatch.");
559 ASSERTM(key.index < _slots.size(),
"Invalid SlotMap key. Index exceeds number of slots.");
560 const Slot& slot = _slots[key.index];
561 ASSERTM(key.generation == slot.generation,
"Invalid SlotMap key. Generation mismatch.");
571 std::vector<Slot> _slots;
572 std::vector<V> _data;
573 std::vector<std::uint32_t> _erase;
576 template<
typename V,
typename Key = SlotMapKey>
580 void insert(
const Key& key,
const V&
value)
582 if(key.index >= _slots.size())
584 Index extend_by = 1 + key.index - _slots.size();
585 _slots.insert(_slots.end(), extend_by,
Slot());
589 Slot& slot = _slots[key.index];
590 XASSERTM(slot.generation <= key.generation,
"Trying to insert into SecondaryMap with outdated key!");
591 slot.value = std::optional<V>(
value);
592 slot.generation = key.generation;
595 bool contains_key(
const Key& key)
597 return key.index < _slots.size() && _slots[key.index].generation == key.generation &&
598 _slots[key.index].value.has_value();
611 ASSERTM(key.index < _slots.size(),
"Invalid SecondaryMap key. Index exceeds number of slots.");
612 const Slot& slot = _slots[key.index];
613 ASSERTM(slot.value.has_value(),
"Invalid SecondaryMap key. Slot is unoccupied.");
614 ASSERTM(key.generation == slot.generation,
"Invalid SecondaryMap key. Generation mismatch.");
615 return slot.value.value();
628 ASSERTM(key.index < _slots.size(),
"Invalid SecondaryMap key. Index exceeds number of slots.");
629 Slot& slot = _slots[key.index];
630 ASSERTM(slot.value.has_value(),
"Invalid SecondaryMap key. Slot is unoccupied.");
631 ASSERTM(key.generation == slot.generation,
"Invalid SecondaryMap key. Generation mismatch.");
632 return slot.value.value();
638 Slot() : generation(1),
value(std::nullopt)
641 explicit Slot(V&& v) : generation(1),
value(std::move(v))
645 std::uint32_t generation;
646 std::optional<V>
value;
649 std::vector<Slot> _slots;
#define ASSERTM(expr, msg)
Debug-Assertion macro definition with custom message.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
V & operator[](const Key &key)
Access Operator.
const V & operator[](const Key &key) const
Access Operator.
Const iterator type for the SlotMap.
Iterator type for the SlotMap.
High-performance associative container.
const V & operator[](const Key &key) const
Access Operator.
Key insert(V &&value)
Insert value into the SlotMap.
void reserve(Index capacity)
Reserve at least capacity space in the SlotMap.
V & operator[](const Key &key)
Access Operator.
SlotMap()
Construct SlotMap with initial capacity zero.
Key replace(Key &key, V &&value)
Replace the value stored at key with value.
bool contains_key(const Key &key) const
Check if given key is still valid.
void erase(const Key &key)
Remove a key from the SlotMap.
Index size() const
Retrieve current size of the SlotMap.
Key insert(const V &value)
Insert a value into the SlotMap.
Key replace(Key &key, V &value)
Replace the value stored at key with value.
Index capacity() const
Retrieve current capacity of the SlotMap.
Slot & try_get_slot(const Key &key)
Helper method to retrieve a slot.
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.
Return type for ConstSlotMapIterator.
Return type for SlotMapIterator.
Internal data structure for slots.
Default key type for SlotMap.