stellarlib 0.1.0
Loading...
Searching...
No Matches
sparse_storage.hpp
1/* clang-format off */
2
3/*
4 stellarlib
5 Copyright (C) 2025-2026 Domán Zana
6
7 This software is provided 'as-is', without any express or implied
8 warranty. In no event will the authors be held liable for any damages
9 arising from the use of this software.
10
11 Permission is granted to anyone to use this software for any purpose,
12 including commercial applications, and to alter it and redistribute it
13 freely, subject to the following restrictions:
14
15 1. The origin of this software must not be misrepresented; you must not
16 claim that you wrote the original software. If you use this software
17 in a product, an acknowledgment in the product documentation would be
18 appreciated but is not required.
19 2. Altered source versions must be plainly marked as such, and must not be
20 misrepresented as being the original software.
21 3. This notice may not be removed or altered from any source distribution.
22*/
23
24#ifndef STELLARLIB_ECS_SPARSE_STORAGE_HPP
25#define STELLARLIB_ECS_SPARSE_STORAGE_HPP
26
27#include <stellarlib/ecs/any_set.hpp>
28#include <stellarlib/ecs/sparse_map.hpp>
29#include <stellarlib/ext/utility.hpp>
30
31#include <array>
32#include <cstdint>
33#include <memory>
34#include <type_traits>
35
36namespace stellarlib::ecs::internal
37{
38class sparse_storage final
39{
40public:
41 template <typename ...T>
42 [[nodiscard]]
43 static constexpr auto ids() noexcept
44 -> std::conditional_t<1 < sizeof...(T), const std::array<std::uint16_t, sizeof...(T)> &, std::array<std::uint16_t, sizeof...(T)>>
45 {
46 if constexpr (1 < sizeof...(T)) {
47 static const std::array<std::uint16_t, sizeof...(T)> cache{ext::scoped_typeid<sparse_storage, T, std::uint16_t>()...};
48 return cache;
49 }
50 else {
52 }
53 }
54
55 [[nodiscard]]
56 sparse_storage() noexcept;
57
58 [[nodiscard]]
59 constexpr sparse_storage(const sparse_storage &) noexcept = delete;
60
61 [[nodiscard]]
62 sparse_storage(sparse_storage &&) noexcept;
63
64 constexpr auto operator=(const sparse_storage &) noexcept
65 -> sparse_storage & = delete;
66
67 auto operator=(sparse_storage &&) noexcept
68 -> sparse_storage &;
69
70 ~sparse_storage() noexcept;
71
72 template <typename T>
73 [[nodiscard]]
74 constexpr auto at(const std::uint16_t id) const noexcept
75 -> const auto &
76 {
77 if (const auto map{_maps.at(id)}) {
78 return static_cast<const sparse_map<std::uint32_t, T> &>(**map);
79 }
80
81 static const sparse_map<std::uint32_t, T> map{};
82 return map;
83 }
84
85 template <typename T>
86 [[nodiscard]]
87 constexpr auto at(const std::uint16_t id) noexcept
88 -> auto &
89 {
90 if (const auto map{_maps.at(id)}) {
91 return static_cast<sparse_map<std::uint32_t, T> &>(**map);
92 }
93
94 _maps.insert(id, std::make_unique<sparse_map<std::uint32_t, T>>());
95 return static_cast<sparse_map<std::uint32_t, T> &>(*_maps.values().back());
96 }
97
98 template <typename T>
99 [[nodiscard]]
100 constexpr auto operator[](const std::uint16_t id) const noexcept
101 -> const auto &
102 {
103 return static_cast<const sparse_map<std::uint32_t, T> &>(*_maps[id]);
104 }
105
106 template <typename T>
107 [[nodiscard]]
108 constexpr auto operator[](const std::uint16_t id) noexcept
109 -> auto &
110 {
111 return static_cast<sparse_map<std::uint32_t, T> &>(*_maps[id]);
112 }
113
114 void erase(std::uint32_t key) const noexcept;
115
116 void clear() const noexcept;
117
118private:
119 sparse_map<std::uint16_t, std::unique_ptr<any_set<std::uint32_t>>> _maps;
120};
121}
122
123#endif
constexpr auto scoped_typeid() noexcept
Generates a unique ID per type within a scope.
Definition utility.hpp:59