30#ifndef LIBSBX_SPARSE_SET_HPP_
31#define LIBSBX_SPARSE_SET_HPP_
35#include <unordered_map>
42#include <libsbx/utility/assert.hpp>
43#include <libsbx/utility/fast_mod.hpp>
44#include <libsbx/utility/algorithm.hpp>
45#include <libsbx/utility/hashed_string.hpp>
47#include <libsbx/memory/concepts.hpp>
49#include <libsbx/ecs/detail/sparse_set_iterator.hpp>
60 unspecified = swap_and_pop
69template<
typename Entity, memory::allocator_for<Entity> Allocator = std::allocator<Entity>>
72 using allocator_traits = std::allocator_traits<Allocator>;
75 using dense_storage_type = std::vector<Entity, Allocator>;
76 using sparse_storage_type = std::vector<typename allocator_traits::pointer, typename allocator_traits::rebind_alloc<typename allocator_traits::pointer>>;
78 inline static constexpr auto max_size =
static_cast<std::size_t
>(entity_traits::to_entity(null_entity));
82 using allocator_type = Allocator;
83 using entity_type = entity_traits::value_type;
84 using version_type = entity_traits::version_type;
85 using pointer =
typename dense_storage_type::pointer;
86 using const_pointer =
typename dense_storage_type::const_pointer;
87 using reference =
typename dense_storage_type::reference;
88 using size_type = std::size_t;
89 using difference_type = std::ptrdiff_t;
92 using reverse_iterator = std::reverse_iterator<iterator>;
93 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
186 [[nodiscard]]
constexpr auto get_allocator() const noexcept -> allocator_type;
196 [[nodiscard]] auto
free_list() const noexcept -> size_type;
206 [[nodiscard]] virtual auto
capacity() const noexcept -> size_type;
211 [[nodiscard]] auto
extent() const noexcept -> size_type;
216 [[nodiscard]] auto
size() const noexcept -> size_type;
221 [[nodiscard]] auto
is_empty() const noexcept ->
bool;
231 [[nodiscard]] auto
data() const noexcept -> const_pointer;
236 [[nodiscard]] auto
data() noexcept -> pointer;
241 auto
bump(const entity_type entity) -> version_type;
256 [[nodiscard]] auto
end() const noexcept ->
iterator;
266 [[nodiscard]]
bool contains(const entity_type entity) const noexcept;
271 [[nodiscard]] auto
current(const entity_type entity) const noexcept -> version_type;
281 [[nodiscard]] auto
index(const entity_type entity) const noexcept -> size_type;
286 auto
erase(const entity_type entity) ->
void;
291 auto
remove(const entity_type entity) ->
bool;
296 template<typename Compare, typename Sort = utility::std_sort, typename... Args>
297 auto
sort(Compare compare, Sort
sort = Sort{}, Args&&... args) ->
void;
303 auto sort_n(
const size_type length, Compare compare, Sort
sort = Sort{}, Args&&... args) ->
void;
308 auto clear() -> void;
317 using basic_iterator = iterator;
324 void swap_only(
const basic_iterator iterator);
326 auto swap_and_pop(
const basic_iterator iterator) -> void;
328 auto in_place_pop(
const basic_iterator iterator) -> void;
330 virtual auto pop(basic_iterator first, basic_iterator last) -> void;
332 virtual auto pop_all() -> void;
334 virtual auto try_emplace(
const entity_type entity,
const bool force_back) -> basic_iterator;
338 [[nodiscard]]
virtual auto get_at(
const std::size_t)
const ->
const void*;
340 virtual auto _swap_or_move(
const std::size_t from,
const std::size_t to) -> void;
342 [[nodiscard]]
auto _policy_to_head() const noexcept -> size_type;
344 [[nodiscard]] auto _entity_to_position(const entity_type entity) const noexcept;
346 [[nodiscard]] auto _position_to_page(const size_type position) const noexcept;
348 [[nodiscard]] auto _sparse_pointer(const entity_type entity) const -> pointer;
350 [[nodiscard]] auto _sparse_reference(const entity_type entity) const -> reference;
352 void _release_sparse_pages();
354 [[nodiscard]] auto _to_iterator(const entity_type entity) const noexcept -> iterator;
356 [[nodiscard]] auto _assure_at_least(const entity_type entity) -> reference;
358 auto _swap_at(const size_type lhs, const size_type rhs) ->
void;
360 dense_storage_type _dense;
361 sparse_storage_type _sparse;
369#include <libsbx/ecs/sparse_set.ipp>
Sparse set container for entity identifiers.
Definition: sparse_set.hpp:70
auto current(const entity_type entity) const noexcept -> version_type
Returns the current version of an entity.
Definition: sparse_set.ipp:152
auto bump(const entity_type entity) -> version_type
Updates the version of an entity.
Definition: sparse_set.ipp:109
auto remove(const entity_type entity) -> bool
Removes an entity if present.
Definition: sparse_set.ipp:177
auto cbegin() const noexcept -> const_iterator
Returns const iterator to the first element.
Definition: sparse_set.ipp:127
auto begin() const noexcept -> iterator
Returns iterator to the first element.
Definition: sparse_set.ipp:121
auto data() const noexcept -> const_pointer
Returns pointer to dense storage.
Definition: sparse_set.ipp:99
auto find(const entity_type entity) const noexcept -> const_iterator
Finds an entity iterator.
Definition: sparse_set.ipp:160
virtual auto call(const utility::hashed_string &tag, const entity_type entity) -> void
Virtual callback hook.
Definition: sparse_set.ipp:201
virtual ~basic_sparse_set()
Destroys the sparse set.
Definition: sparse_set.ipp:30
auto extent() const noexcept -> size_type
Returns sparse storage extent.
Definition: sparse_set.ipp:79
auto free_list() const noexcept -> size_type
Returns the index of the free-list head.
Definition: sparse_set.ipp:64
auto swap(basic_sparse_set &other) noexcept -> void
Swaps the contents of two sparse sets.
Definition: sparse_set.ipp:44
virtual auto capacity() const noexcept -> size_type
Returns dense storage capacity.
Definition: sparse_set.ipp:74
virtual void reserve(const size_type capacity)
Reserves dense storage capacity.
Definition: sparse_set.ipp:69
basic_sparse_set(const basic_sparse_set &other)=delete
Deleted copy constructor.
auto operator=(const basic_sparse_set &other) -> basic_sparse_set &=delete
Deleted copy assignment operator.
auto erase(const entity_type entity) -> void
Removes an entity.
Definition: sparse_set.ipp:171
auto is_contiguous() const noexcept -> bool
Checks whether the dense storage is contiguous.
Definition: sparse_set.ipp:94
auto end() const noexcept -> iterator
Returns iterator to the end.
Definition: sparse_set.ipp:132
auto index(const entity_type entity) const noexcept -> size_type
Returns the dense index of an entity.
Definition: sparse_set.ipp:165
auto size() const noexcept -> size_type
Returns the number of stored entities.
Definition: sparse_set.ipp:84
auto clear() -> void
Clears all entities.
Definition: sparse_set.ipp:187
auto cend() const noexcept -> const_iterator
Returns const iterator to the end.
Definition: sparse_set.ipp:137
auto invoke(const utility::hashed_string &tag, const entity_type entity) -> void
Invokes a tagged callback on an entity.
Definition: sparse_set.ipp:194
auto policy() const noexcept -> deletion_policy
Returns the deletion policy.
Definition: sparse_set.ipp:59
constexpr auto get_allocator() const noexcept -> allocator_type
Returns the allocator associated with the container.
Definition: sparse_set.ipp:54
bool contains(const entity_type entity) const noexcept
Checks whether an entity exists in the set.
Definition: sparse_set.ipp:142
auto sort_n(const size_type length, Compare compare, Sort sort=Sort{}, Args &&... args) -> void
Sorts the first N entities.
auto is_empty() const noexcept -> bool
Checks whether the set is empty.
Definition: sparse_set.ipp:89
auto sort(Compare compare, Sort sort=Sort{}, Args &&... args) -> void
Sorts entities using a comparator.
Definition: sparse_set_iterator.hpp:10
Definition: hashed_string.hpp:17
deletion_policy
Deletion behavior policy for sparse sets.
Definition: sparse_set.hpp:56
Entity traits.
Definition: entity.hpp:73
Definition: algorithm.hpp:13