sandbox
Loading...
Searching...
No Matches
sparse_set.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
30#ifndef LIBSBX_SPARSE_SET_HPP_
31#define LIBSBX_SPARSE_SET_HPP_
32
33#include <memory>
34#include <vector>
35#include <unordered_map>
36#include <type_traits>
37#include <utility>
38#include <iterator>
39#include <algorithm>
40#include <functional>
41
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>
46
47#include <libsbx/memory/concepts.hpp>
48
49#include <libsbx/ecs/detail/sparse_set_iterator.hpp>
50
51namespace sbx::ecs {
52
56enum class deletion_policy : std::uint8_t {
57 swap_and_pop = 0u,
58 in_place = 1u,
59 swap_only = 2u,
60 unspecified = swap_and_pop
61}; // enum class deletion_policy
62
69template<typename Entity, memory::allocator_for<Entity> Allocator = std::allocator<Entity>>
71
72 using allocator_traits = std::allocator_traits<Allocator>;
74
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>>;
77
78 inline static constexpr auto max_size = static_cast<std::size_t>(entity_traits::to_entity(null_entity));
79
80public:
81
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>;
94
101 basic_sparse_set(const deletion_policy policy = deletion_policy::unspecified, const allocator_type& allocator = allocator_type{});
102
113 basic_sparse_set(const basic_sparse_set& other) = delete;
114
125 basic_sparse_set(basic_sparse_set&& other) noexcept;
126
139 basic_sparse_set(basic_sparse_set&& other, const allocator_type& allocator);
140
148 virtual ~basic_sparse_set();
149
162 auto operator=(const basic_sparse_set& other) -> basic_sparse_set& = delete;
163
176 auto operator=(basic_sparse_set&& other) noexcept -> basic_sparse_set&;
177
181 auto swap(basic_sparse_set& other) noexcept -> void;
182
186 [[nodiscard]] constexpr auto get_allocator() const noexcept -> allocator_type;
187
191 [[nodiscard]] auto policy() const noexcept -> deletion_policy;
192
196 [[nodiscard]] auto free_list() const noexcept -> size_type;
197
201 virtual void reserve(const size_type capacity);
202
206 [[nodiscard]] virtual auto capacity() const noexcept -> size_type;
207
211 [[nodiscard]] auto extent() const noexcept -> size_type;
212
216 [[nodiscard]] auto size() const noexcept -> size_type;
217
221 [[nodiscard]] auto is_empty() const noexcept -> bool;
222
226 [[nodiscard]] auto is_contiguous() const noexcept -> bool;
227
231 [[nodiscard]] auto data() const noexcept -> const_pointer;
232
236 [[nodiscard]] auto data() noexcept -> pointer;
237
241 auto bump(const entity_type entity) -> version_type;
242
246 [[nodiscard]] auto begin() const noexcept -> iterator;
247
251 [[nodiscard]] auto cbegin() const noexcept -> const_iterator;
252
256 [[nodiscard]] auto end() const noexcept -> iterator;
257
261 [[nodiscard]] auto cend() const noexcept -> const_iterator;
262
266 [[nodiscard]] bool contains(const entity_type entity) const noexcept;
267
271 [[nodiscard]] auto current(const entity_type entity) const noexcept -> version_type;
272
276 [[nodiscard]] auto find(const entity_type entity) const noexcept -> const_iterator;
277
281 [[nodiscard]] auto index(const entity_type entity) const noexcept -> size_type;
282
286 auto erase(const entity_type entity) -> void;
287
291 auto remove(const entity_type entity) -> bool;
292
296 template<typename Compare, typename Sort = utility::std_sort, typename... Args>
297 auto sort(Compare compare, Sort sort = Sort{}, Args&&... args) -> void;
298
302 template<typename Compare, typename Sort = utility::std_sort, typename... Args>
303 auto sort_n(const size_type length, Compare compare, Sort sort = Sort{}, Args&&... args) -> void;
304
308 auto clear() -> void;
309
313 auto invoke(const utility::hashed_string& tag, const entity_type entity) -> void;
314
315protected:
316
317 using basic_iterator = iterator;
318
322 virtual auto call(const utility::hashed_string& tag, const entity_type entity) -> void;
323
324 void swap_only(const basic_iterator iterator);
325
326 auto swap_and_pop(const basic_iterator iterator) -> void;
327
328 auto in_place_pop(const basic_iterator iterator) -> void;
329
330 virtual auto pop(basic_iterator first, basic_iterator last) -> void;
331
332 virtual auto pop_all() -> void;
333
334 virtual auto try_emplace(const entity_type entity, const bool force_back) -> basic_iterator;
335
336private:
337
338 [[nodiscard]] virtual auto get_at(const std::size_t) const -> const void*;
339
340 virtual auto _swap_or_move(const std::size_t from, const std::size_t to) -> void;
341
342 [[nodiscard]] auto _policy_to_head() const noexcept -> size_type;
343
344 [[nodiscard]] auto _entity_to_position(const entity_type entity) const noexcept;
345
346 [[nodiscard]] auto _position_to_page(const size_type position) const noexcept;
347
348 [[nodiscard]] auto _sparse_pointer(const entity_type entity) const -> pointer;
349
350 [[nodiscard]] auto _sparse_reference(const entity_type entity) const -> reference;
351
352 void _release_sparse_pages();
353
354 [[nodiscard]] auto _to_iterator(const entity_type entity) const noexcept -> iterator;
355
356 [[nodiscard]] auto _assure_at_least(const entity_type entity) -> reference;
357
358 auto _swap_at(const size_type lhs, const size_type rhs) -> void;
359
360 dense_storage_type _dense;
361 sparse_storage_type _sparse;
362 deletion_policy _policy;
363 size_type _head;
364
365}; // class basic_sparse_set
366
367} // namespace sbx::ecs
368
369#include <libsbx/ecs/sparse_set.ipp>
370
371#endif // LIBSBX_SPARSE_SET_HPP_
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