EnTT 4.0.0
Loading...
Searching...
No Matches
cache.hpp
1#ifndef ENTT_RESOURCE_RESOURCE_CACHE_HPP
2#define ENTT_RESOURCE_RESOURCE_CACHE_HPP
3
4#include <compare>
5#include "../container/dense_map.hpp"
6#include "../core/compressed_pair.hpp"
7#include "../core/fwd.hpp"
8#include "../core/iterator.hpp"
9#include "../stl/concepts.hpp"
10#include "../stl/cstddef.hpp"
11#include "../stl/functional.hpp"
12#include "../stl/iterator.hpp"
13#include "../stl/memory.hpp"
14#include "../stl/tuple.hpp"
15#include "../stl/type_traits.hpp"
16#include "../stl/utility.hpp"
17#include "fwd.hpp"
18#include "loader.hpp"
19#include "resource.hpp"
20
21namespace entt {
22
24namespace internal {
25
26template<typename Type, typename It>
27class resource_cache_iterator final {
28 template<typename, typename>
29 friend class resource_cache_iterator;
30
31public:
32 using value_type = stl::pair<id_type, resource<Type>>;
33 using pointer = input_iterator_pointer<value_type>;
34 using reference = value_type;
35 using difference_type = stl::ptrdiff_t;
36 using iterator_category = stl::input_iterator_tag;
37 using iterator_concept = stl::random_access_iterator_tag;
38
39 constexpr resource_cache_iterator() noexcept = default;
40
41 constexpr resource_cache_iterator(const It iter) noexcept
42 : it{iter} {}
43
44 template<typename Other>
45 requires (!stl::same_as<It, Other> && stl::constructible_from<It, Other>)
46 constexpr resource_cache_iterator(const resource_cache_iterator<stl::remove_const_t<Type>, Other> &other) noexcept
47 : it{other.it} {}
48
49 constexpr resource_cache_iterator &operator++() noexcept {
50 return ++it, *this;
51 }
52
53 constexpr resource_cache_iterator operator++(int) noexcept {
54 const resource_cache_iterator orig = *this;
55 return ++(*this), orig;
56 }
57
58 constexpr resource_cache_iterator &operator--() noexcept {
59 return --it, *this;
60 }
61
62 constexpr resource_cache_iterator operator--(int) noexcept {
63 const resource_cache_iterator orig = *this;
64 return operator--(), orig;
65 }
66
67 constexpr resource_cache_iterator &operator+=(const difference_type value) noexcept {
68 it += value;
69 return *this;
70 }
71
72 constexpr resource_cache_iterator operator+(const difference_type value) const noexcept {
73 resource_cache_iterator copy = *this;
74 return (copy += value);
75 }
76
77 constexpr resource_cache_iterator &operator-=(const difference_type value) noexcept {
78 return (*this += -value);
79 }
80
81 constexpr resource_cache_iterator operator-(const difference_type value) const noexcept {
82 return (*this + -value);
83 }
84
85 [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
86 return {it[value].first, resource<Type>{it[value].second}};
87 }
88
89 [[nodiscard]] constexpr reference operator*() const noexcept {
90 return operator[](0);
91 }
92
93 [[nodiscard]] constexpr pointer operator->() const noexcept {
94 return operator*();
95 }
96
97 template<typename... Args>
98 [[nodiscard]] constexpr stl::ptrdiff_t operator-(const resource_cache_iterator<Args...> &other) const noexcept {
99 return it - other.it;
100 }
101
102 template<typename... Args>
103 [[nodiscard]] constexpr bool operator==(const resource_cache_iterator<Args...> &other) const noexcept {
104 return it == other.it;
105 }
106
107 template<typename... Args>
108 [[nodiscard]] constexpr auto operator<=>(const resource_cache_iterator<Args...> &other) const noexcept {
109 return it <=> other.it;
110 }
111
112private:
113 It it;
114};
115
116} // namespace internal
118
125template<typename Type, typename Loader, typename Allocator>
127 using alloc_traits = stl::allocator_traits<Allocator>;
128 static_assert(stl::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
129 using container_allocator = alloc_traits::template rebind_alloc<stl::pair<const id_type, typename Loader::result_type>>;
131
132public:
134 using allocator_type = Allocator;
136 using value_type = Type;
138 using size_type = stl::size_t;
140 using loader_type = Loader;
142 using iterator = internal::resource_cache_iterator<Type, typename container_type::iterator>;
144 using const_iterator = internal::resource_cache_iterator<const Type, typename container_type::const_iterator>;
145
149
154 explicit resource_cache(const allocator_type &allocator)
155 : resource_cache{loader_type{}, allocator} {}
156
162 explicit resource_cache(const loader_type &callable, const allocator_type &allocator = allocator_type{})
163 : pool{container_type{allocator}, callable} {}
164
166 resource_cache(const resource_cache &) = default;
167
173 resource_cache(const resource_cache &other, const allocator_type &allocator)
174 : pool{stl::piecewise_construct, stl::forward_as_tuple(other.pool.first(), allocator), stl::forward_as_tuple(other.pool.second())} {}
175
177 resource_cache(resource_cache &&) noexcept = default;
178
185 : pool{stl::piecewise_construct, stl::forward_as_tuple(stl::move(other.pool.first()), allocator), stl::forward_as_tuple(stl::move(other.pool.second()))} {}
186
188 ~resource_cache() = default;
189
195
200 resource_cache &operator=(resource_cache &&) noexcept = default;
201
206 [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
207 return pool.first().get_allocator();
208 }
209
217 [[nodiscard]] const_iterator cbegin() const noexcept {
218 return pool.first().begin();
219 }
220
222 [[nodiscard]] const_iterator begin() const noexcept {
223 return cbegin();
224 }
225
227 [[nodiscard]] iterator begin() noexcept {
228 return pool.first().begin();
229 }
230
236 [[nodiscard]] const_iterator cend() const noexcept {
237 return pool.first().end();
238 }
239
241 [[nodiscard]] const_iterator end() const noexcept {
242 return cend();
243 }
244
246 [[nodiscard]] iterator end() noexcept {
247 return pool.first().end();
248 }
249
254 [[nodiscard]] bool empty() const noexcept {
255 return pool.first().empty();
256 }
257
262 [[nodiscard]] size_type size() const noexcept {
263 return pool.first().size();
264 }
265
267 void clear() noexcept {
268 pool.first().clear();
269 }
270
288 template<typename... Args>
289 stl::pair<iterator, bool> load(const id_type id, Args &&...args) {
290 if(auto it = pool.first().find(id); it != pool.first().end()) {
291 return {it, false};
292 }
293
294 return pool.first().emplace(id, pool.second()(stl::forward<Args>(args)...));
295 }
296
301 template<typename... Args>
302 stl::pair<iterator, bool> force_load(const id_type id, Args &&...args) {
303 return {pool.first().insert_or_assign(id, pool.second()(stl::forward<Args>(args)...)).first, true};
304 }
305
316 [[nodiscard]] resource<const value_type> operator[](const id_type id) const {
317 if(auto it = pool.first().find(id); it != pool.first().cend()) {
318 return resource<const value_type>{it->second};
319 }
320
321 return {};
322 }
323
325 [[nodiscard]] resource<value_type> operator[](const id_type id) {
326 if(auto it = pool.first().find(id); it != pool.first().end()) {
327 return resource<value_type>{it->second};
328 }
329
330 return {};
331 }
332
338 [[nodiscard]] bool contains(const id_type id) const {
339 return pool.first().contains(id);
340 }
341
348 const auto it = pool.first().begin();
349 return pool.first().erase(it + (pos - const_iterator{it}));
350 }
351
359 const auto it = pool.first().begin();
360 return pool.first().erase(it + (first - const_iterator{it}), it + (last - const_iterator{it}));
361 }
362
369 return pool.first().erase(id);
370 }
371
376 [[nodiscard]] loader_type loader() const {
377 return pool.second();
378 }
379
380private:
382};
383
384} // namespace entt
385
386#endif
A compressed pair.
Associative container for key-value pairs with unique keys.
size_type erase(const id_type id)
Removes the given elements from a cache.
Definition cache.hpp:368
resource_cache()
Default constructor.
Definition cache.hpp:147
stl::size_t size_type
Unsigned integer type.
Definition cache.hpp:138
resource_cache & operator=(resource_cache &&) noexcept=default
Default move assignment operator.
resource_cache(resource_cache &&) noexcept=default
Default move constructor.
iterator begin() noexcept
Returns an iterator to the beginning.
Definition cache.hpp:227
resource_cache(const resource_cache &other, const allocator_type &allocator)
Allocator-extended copy constructor.
Definition cache.hpp:173
loader_type loader() const
Returns the loader used to create resources.
Definition cache.hpp:376
resource< value_type > operator[](const id_type id)
Returns a handle for a given resource identifier.
Definition cache.hpp:325
const_iterator cend() const noexcept
Returns an iterator to the end.
Definition cache.hpp:236
iterator erase(const_iterator pos)
Removes an element from a given position.
Definition cache.hpp:347
Type value_type
Resource type.
Definition cache.hpp:136
Loader loader_type
Loader type.
Definition cache.hpp:140
resource_cache(const allocator_type &allocator)
Constructs an empty cache with a given allocator.
Definition cache.hpp:154
const_iterator cbegin() const noexcept
Returns an iterator to the beginning.
Definition cache.hpp:217
resource_cache(const loader_type &callable, const allocator_type &allocator=allocator_type{})
Constructs an empty cache with a given allocator and loader.
Definition cache.hpp:162
internal::resource_cache_iterator< const Type, typename container_type::const_iterator > const_iterator
Constant input iterator type.
Definition cache.hpp:144
stl::pair< iterator, bool > load(const id_type id, Args &&...args)
Loads a resource, if its identifier does not exist.
Definition cache.hpp:289
resource< const value_type > operator[](const id_type id) const
Returns a handle for a given resource identifier.
Definition cache.hpp:316
internal::resource_cache_iterator< Type, typename container_type::iterator > iterator
Input iterator type.
Definition cache.hpp:142
Allocator allocator_type
Allocator type.
Definition cache.hpp:134
resource_cache(const resource_cache &)=default
Default copy constructor.
bool empty() const noexcept
Returns true if a cache contains no resources, false otherwise.
Definition cache.hpp:254
resource_cache & operator=(const resource_cache &)=default
Default copy assignment operator.
const_iterator begin() const noexcept
Returns an iterator to the beginning.
Definition cache.hpp:222
iterator end() noexcept
Returns an iterator to the end.
Definition cache.hpp:246
stl::pair< iterator, bool > force_load(const id_type id, Args &&...args)
Force loads a resource, even if its identifier already exists.
Definition cache.hpp:302
constexpr allocator_type get_allocator() const noexcept
Returns the associated allocator.
Definition cache.hpp:206
~resource_cache()=default
Default destructor.
size_type size() const noexcept
Number of resources managed by a cache.
Definition cache.hpp:262
const_iterator end() const noexcept
Returns an iterator to the end.
Definition cache.hpp:241
iterator erase(const_iterator first, const_iterator last)
Removes the given elements from a cache.
Definition cache.hpp:358
void clear() noexcept
Clears a cache.
Definition cache.hpp:267
bool contains(const id_type id) const
Checks if a cache contains a given identifier.
Definition cache.hpp:338
Basic resource handle.
Definition resource.hpp:23
Custom EnTT namespace for the standard template library.
Definition entt.hpp:5
EnTT default namespace.
Definition dense_map.hpp:25
constexpr type_list< Type..., Other... > operator+(type_list< Type... >, type_list< Other... >)
Concatenates multiple type lists.
stl::uint32_t id_type
Alias declaration for type identifiers.
Definition fwd.hpp:29