Uranus  1.0.1.0
Uranus is a GameEngine written in C++
Loading...
Searching...
No Matches
SparseArray.hpp
1/*
2** EPITECH PROJECT, 2023
3** SparseArray.hpp
4** File description:
5** SparseArray.hpp
6*/
7
8#ifndef URANUS_SPARSEARRAY_HPP
9#define URANUS_SPARSEARRAY_HPP
10
11#include <memory>
12#include <optional>
13#include <vector>
14
15namespace uranus::ecs {
16
21 template<typename Component>
23 public:
24 using ValueType = std::shared_ptr<std::optional<Component>>;
25 using ReferenceType = ValueType &;
26 using ConstReferenceType = const ValueType &;
27 using Container = std::vector<ValueType>;
28 using SizeType = typename Container::size_type;
29 using Iterator = typename Container::iterator;
30 using ConstIterator = typename Container::const_iterator;
31
35 SparseArray() = default;
36
41 SparseArray(const SparseArray &) = default;
42
47 SparseArray(SparseArray &&) noexcept = default;
48
52 ~SparseArray() = default;
53
60 SparseArray &operator=(const SparseArray &);
61
68 SparseArray &operator=(SparseArray &&) noexcept;
69
76 ReferenceType operator[](std::size_t idx);
77
84 ConstReferenceType operator[](std::size_t idx) const;
85
91 Iterator begin();
92
98 ConstIterator begin() const;
99
105 ConstIterator cbegin() const;
106
112 Iterator end();
113
119 ConstIterator end() const;
120
126 ConstIterator cend() const;
127
133 SizeType size() const;
134
142 ReferenceType insertAt(SizeType pos, const Component &);
143
152 ReferenceType insertAt(SizeType pos, Component &&);
153
162 template<class... Params>
163 ReferenceType emplaceAt(SizeType pos, Params &&...params);
164
170 void erase(SizeType pos);
171
178 std::optional<SizeType> getIndex(const ValueType &) const;
179
184 Container &getData() const;
185
186 private:
187 Container _data;
188 };
189
190 template<typename Component>
191 SparseArray<Component> &SparseArray<Component>::operator=(const SparseArray<Component> &other)
192 {
193 _data = other._data;
194 return *this;
195 }
196
197 template<typename Component>
199 {
200 _data = std::move(other._data);
201 return *this;
202 }
203
204 template<typename Component>
205 typename SparseArray<Component>::ReferenceType SparseArray<Component>::operator[](std::size_t idx)
206 {
207 if (idx >= _data.size()) _data.resize(idx + 1);
208 return _data[idx];
209 }
210
211 template<typename Component>
212 typename SparseArray<Component>::ConstReferenceType SparseArray<Component>::operator[](std::size_t idx) const
213 {
214 if (idx >= _data.size()) return nullptr;
215 return _data[idx];
216 }
217
218 template<typename Component>
219 typename SparseArray<Component>::Iterator SparseArray<Component>::begin()
220 {
221 return _data.begin();
222 }
223
224 template<typename Component>
225 typename SparseArray<Component>::ConstIterator SparseArray<Component>::begin() const
226 {
227 return _data.begin();
228 }
229
230 template<typename Component>
231 typename SparseArray<Component>::ConstIterator SparseArray<Component>::cbegin() const
232 {
233 return _data.cbegin();
234 }
235
236 template<typename Component>
237 typename SparseArray<Component>::Iterator SparseArray<Component>::end()
238 {
239 return _data.end();
240 }
241
242 template<typename Component>
243 typename SparseArray<Component>::ConstIterator SparseArray<Component>::end() const
244 {
245 return _data.end();
246 }
247
248 template<typename Component>
249 typename SparseArray<Component>::ConstIterator SparseArray<Component>::cend() const
250 {
251 return _data.cend();
252 }
253
254 template<typename Component>
255 typename SparseArray<Component>::SizeType SparseArray<Component>::size() const
256 {
257 return _data.size();
258 }
259
260 template<typename Component>
261 typename SparseArray<Component>::ReferenceType SparseArray<Component>::insertAt(SizeType pos, const Component &component)
262 {
263 if (pos >= _data.size()) _data.resize(pos + 1);
264 _data[pos] = std::make_shared<std::optional<Component>>(std::make_optional<Component>(component));
265 return _data[pos];
266 }
267
268 template<typename Component>
269 typename SparseArray<Component>::ReferenceType SparseArray<Component>::insertAt(SizeType pos, Component &&component)
270 {
271 if (pos >= _data.size()) _data.resize(pos + 1);
272 _data[pos] = std::move(std::make_shared<std::optional<Component>>(std::make_optional<Component>(component)));
273 return _data[pos];
274 }
275
276 // TODO test this function
277 template<typename Component>
278 template<class... Params>
279 typename SparseArray<Component>::ReferenceType SparseArray<Component>::emplaceAt(SizeType pos, Params &&...params)
280 {
281 if (pos >= _data.size()) _data.resize(pos + 1);
282 _data[pos] = std::make_shared<std::optional<Component>>(std::make_optional<Component>(std::forward<Params>(params)...));
283 return _data[pos];
284 }
285
286 template<typename Component>
288 {
289 if (pos >= _data.size()) return;
290 _data[pos] = nullptr;
291 }
292
293 template<typename Component>
294 std::optional<typename SparseArray<Component>::SizeType> SparseArray<Component>::getIndex(const ValueType &ptr) const
295 {
296 for (SizeType i = 0; i < _data.size(); i++) {
297 if (_data[i] && _data[i]->has_value() && ptr->has_value()) {
298 if (std::addressof(_data[i]->value()) == std::addressof(ptr->value())) return i;
299 }
300 }
301 return std::nullopt;
302 }
303
304 template<typename Component>
305 typename SparseArray<Component>::Container &SparseArray<Component>::getData() const
306 {
307 return _data;
308 }
309} // namespace uranus::ecs
310#endif // URANUS_SPARSEARRAY_HPP
SparseArray class, used to store components in a sparse way.
Definition: SparseArray.hpp:22
void erase(SizeType pos)
Erase the component at the given index.
Definition: SparseArray.hpp:287
Container & getData() const
Get the _data container.
Definition: SparseArray.hpp:305
SizeType size() const
Return the size of the SparseArray.
Definition: SparseArray.hpp:255
SparseArray(const SparseArray &)=default
Default copy constructor.
Iterator end()
Return the iterator pointing to the end of the SparseArray.
Definition: SparseArray.hpp:237
ReferenceType insertAt(SizeType pos, const Component &)
Insert a component at the given index.
Definition: SparseArray.hpp:261
std::optional< SizeType > getIndex(const ValueType &) const
Get the index of the entity possessing the given component.
Definition: SparseArray.hpp:294
SparseArray()=default
Default constructor.
ConstIterator cbegin() const
Return the const_iterator pointing to the beginning of the SparseArray.
Definition: SparseArray.hpp:231
SparseArray(SparseArray &&) noexcept=default
Default move constructor.
Container _data
Container of the components.
Definition: SparseArray.hpp:187
ReferenceType emplaceAt(SizeType pos, Params &&...params)
Emplace a component at the given index.
Definition: SparseArray.hpp:279
Iterator begin()
Return the iterator pointing to the beginning of the SparseArray.
Definition: SparseArray.hpp:219
SparseArray & operator=(const SparseArray &)
Copy assignment operator.
Definition: SparseArray.hpp:191
ConstIterator cend() const
Return the const_iterator pointing to the end of the SparseArray.
Definition: SparseArray.hpp:249
ReferenceType operator[](std::size_t idx)
Access the component at the given index, if it exists, otherwise resize the SparseArray.
Definition: SparseArray.hpp:205