EnTT 3.12.0
Loading...
Searching...
No Matches
cache.hpp
1#ifndef ENTT_RESOURCE_RESOURCE_CACHE_HPP
2#define ENTT_RESOURCE_RESOURCE_CACHE_HPP
3
4#include <cstddef>
5#include <functional>
6#include <iterator>
7#include <memory>
8#include <tuple>
9#include <type_traits>
10#include <utility>
11#include "../container/dense_map.hpp"
12#include "../core/compressed_pair.hpp"
13#include "../core/fwd.hpp"
14#include "../core/iterator.hpp"
15#include "../core/utility.hpp"
16#include "fwd.hpp"
17#include "loader.hpp"
18#include "resource.hpp"
19
20namespace entt {
21
27namespace internal {
28
29template<typename Type, typename It>
30class resource_cache_iterator final {
31 template<typename, typename>
32 friend class resource_cache_iterator;
33
34public:
35 using value_type = std::pair<id_type, resource<Type>>;
36 using pointer = input_iterator_pointer<value_type>;
37 using reference = value_type;
38 using difference_type = std::ptrdiff_t;
39 using iterator_category = std::input_iterator_tag;
40
41 constexpr resource_cache_iterator() noexcept = default;
42
43 constexpr resource_cache_iterator(const It iter) noexcept
44 : it{iter} {}
45
46 template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
47 constexpr resource_cache_iterator(const resource_cache_iterator<std::remove_const_t<Type>, Other> &other) noexcept
48 : it{other.it} {}
49
50 constexpr resource_cache_iterator &operator++() noexcept {
51 return ++it, *this;
52 }
53
54 constexpr resource_cache_iterator operator++(int) noexcept {
55 resource_cache_iterator orig = *this;
56 return ++(*this), orig;
57 }
58
59 constexpr resource_cache_iterator &operator--() noexcept {
60 return --it, *this;
61 }
62
63 constexpr resource_cache_iterator operator--(int) noexcept {
64 resource_cache_iterator orig = *this;
65 return operator--(), orig;
66 }
67
68 constexpr resource_cache_iterator &operator+=(const difference_type value) noexcept {
69 it += value;
70 return *this;
71 }
72
73 constexpr resource_cache_iterator operator+(const difference_type value) const noexcept {
74 resource_cache_iterator copy = *this;
75 return (copy += value);
76 }
77
78 constexpr resource_cache_iterator &operator-=(const difference_type value) noexcept {
79 return (*this += -value);
80 }
81
82 constexpr resource_cache_iterator operator-(const difference_type value) const noexcept {
83 return (*this + -value);
84 }
85
86 [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
87 return {it[value].first, resource<Type>{it[value].second}};
88 }
89
90 [[nodiscard]] constexpr reference operator*() const noexcept {
91 return (*this)[0];
92 }
93
94 [[nodiscard]] constexpr pointer operator->() const noexcept {
95 return operator*();
96 }
97
98 template<typename... Lhs, typename... Rhs>
99 friend constexpr std::ptrdiff_t operator-(const resource_cache_iterator<Lhs...> &, const resource_cache_iterator<Rhs...> &) noexcept;
100
101 template<typename... Lhs, typename... Rhs>
102 friend constexpr bool operator==(const resource_cache_iterator<Lhs...> &, const resource_cache_iterator<Rhs...> &) noexcept;
103
104 template<typename... Lhs, typename... Rhs>
105 friend constexpr bool operator<(const resource_cache_iterator<Lhs...> &, const resource_cache_iterator<Rhs...> &) noexcept;
106
107private:
108 It it;
109};
110
111template<typename... Lhs, typename... Rhs>
112[[nodiscard]] constexpr std::ptrdiff_t operator-(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
113 return lhs.it - rhs.it;
114}
115
116template<typename... Lhs, typename... Rhs>
117[[nodiscard]] constexpr bool operator==(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
118 return lhs.it == rhs.it;
119}
120
121template<typename... Lhs, typename... Rhs>
122[[nodiscard]] constexpr bool operator!=(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
123 return !(lhs == rhs);
124}
125
126template<typename... Lhs, typename... Rhs>
127[[nodiscard]] constexpr bool operator<(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
128 return lhs.it < rhs.it;
129}
130
131template<typename... Lhs, typename... Rhs>
132[[nodiscard]] constexpr bool operator>(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
133 return rhs < lhs;
134}
135
136template<typename... Lhs, typename... Rhs>
137[[nodiscard]] constexpr bool operator<=(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
138 return !(lhs > rhs);
139}
140
141template<typename... Lhs, typename... Rhs>
142[[nodiscard]] constexpr bool operator>=(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
143 return !(lhs < rhs);
144}
145
146} // namespace internal
147
159template<typename Type, typename Loader, typename Allocator>
161 using alloc_traits = std::allocator_traits<Allocator>;
162 static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
163 using container_allocator = typename alloc_traits::template rebind_alloc<std::pair<const id_type, typename Loader::result_type>>;
165
166public:
168 using value_type = Type;
170 using size_type = std::size_t;
172 using loader_type = Loader;
174 using allocator_type = Allocator;
176 using iterator = internal::resource_cache_iterator<Type, typename container_type::iterator>;
178 using const_iterator = internal::resource_cache_iterator<const Type, typename container_type::const_iterator>;
179
183
188 explicit resource_cache(const allocator_type &allocator)
189 : resource_cache{loader_type{}, allocator} {}
190
196 explicit resource_cache(const loader_type &callable, const allocator_type &allocator = allocator_type{})
197 : pool{container_type{allocator}, callable} {}
198
200 resource_cache(const resource_cache &) = default;
201
207 resource_cache(const resource_cache &other, const allocator_type &allocator)
208 : pool{std::piecewise_construct, std::forward_as_tuple(other.pool.first(), allocator), std::forward_as_tuple(other.pool.second())} {}
209
212
219 : pool{std::piecewise_construct, std::forward_as_tuple(std::move(other.pool.first()), allocator), std::forward_as_tuple(std::move(other.pool.second()))} {}
220
226
232
237 [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
238 return pool.first().get_allocator();
239 }
240
248 [[nodiscard]] const_iterator cbegin() const noexcept {
249 return pool.first().begin();
250 }
251
253 [[nodiscard]] const_iterator begin() const noexcept {
254 return cbegin();
255 }
256
258 [[nodiscard]] iterator begin() noexcept {
259 return pool.first().begin();
260 }
261
267 [[nodiscard]] const_iterator cend() const noexcept {
268 return pool.first().end();
269 }
270
272 [[nodiscard]] const_iterator end() const noexcept {
273 return cend();
274 }
275
277 [[nodiscard]] iterator end() noexcept {
278 return pool.first().end();
279 }
280
285 [[nodiscard]] bool empty() const noexcept {
286 return pool.first().empty();
287 }
288
293 [[nodiscard]] size_type size() const noexcept {
294 return pool.first().size();
295 }
296
298 void clear() noexcept {
299 pool.first().clear();
300 }
301
319 template<typename... Args>
320 std::pair<iterator, bool> load(const id_type id, Args &&...args) {
321 if(auto it = pool.first().find(id); it != pool.first().end()) {
322 return {it, false};
323 }
324
325 return pool.first().emplace(id, pool.second()(std::forward<Args>(args)...));
326 }
327
332 template<typename... Args>
333 std::pair<iterator, bool> force_load(const id_type id, Args &&...args) {
334 return {pool.first().insert_or_assign(id, pool.second()(std::forward<Args>(args)...)).first, true};
335 }
336
347 [[nodiscard]] resource<const value_type> operator[](const id_type id) const {
348 if(auto it = pool.first().find(id); it != pool.first().cend()) {
349 return resource<const value_type>{it->second};
350 }
351
352 return {};
353 }
354
356 [[nodiscard]] resource<value_type> operator[](const id_type id) {
357 if(auto it = pool.first().find(id); it != pool.first().end()) {
358 return resource<value_type>{it->second};
359 }
360
361 return {};
362 }
363
369 [[nodiscard]] bool contains(const id_type id) const {
370 return pool.first().contains(id);
371 }
372
379 const auto it = pool.first().begin();
380 return pool.first().erase(it + (pos - const_iterator{it}));
381 }
382
390 const auto it = pool.first().begin();
391 return pool.first().erase(it + (first - const_iterator{it}), it + (last - const_iterator{it}));
392 }
393
400 return pool.first().erase(id);
401 }
402
407 [[nodiscard]] loader_type loader() const {
408 return pool.second();
409 }
410
411private:
413};
414
415} // namespace entt
416
417#endif
A compressed pair.
Associative container for key-value pairs with unique keys.
Definition: dense_map.hpp:264
Basic cache for resources of any type.
Definition: cache.hpp:160
size_type erase(const id_type id)
Removes the given elements from a cache.
Definition: cache.hpp:399
resource_cache()
Default constructor.
Definition: cache.hpp:181
iterator begin() noexcept
Returns an iterator to the beginning.
Definition: cache.hpp:258
resource_cache(const resource_cache &other, const allocator_type &allocator)
Allocator-extended copy constructor.
Definition: cache.hpp:207
loader_type loader() const
Returns the loader used to create resources.
Definition: cache.hpp:407
resource< value_type > operator[](const id_type id)
Returns a handle for a given resource identifier.
Definition: cache.hpp:356
const_iterator cend() const noexcept
Returns an iterator to the end.
Definition: cache.hpp:267
std::pair< iterator, bool > load(const id_type id, Args &&...args)
Loads a resource, if its identifier does not exist.
Definition: cache.hpp:320
iterator erase(const_iterator pos)
Removes an element from a given position.
Definition: cache.hpp:378
Type value_type
Resource type.
Definition: cache.hpp:168
Loader loader_type
Loader type.
Definition: cache.hpp:172
resource_cache(resource_cache &&other, const allocator_type &allocator)
Allocator-extended move constructor.
Definition: cache.hpp:218
resource_cache(const allocator_type &allocator)
Constructs an empty cache with a given allocator.
Definition: cache.hpp:188
const_iterator cbegin() const noexcept
Returns an iterator to the beginning.
Definition: cache.hpp:248
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:196
internal::resource_cache_iterator< const Type, typename container_type::const_iterator > const_iterator
Constant input iterator type.
Definition: cache.hpp:178
resource< const value_type > operator[](const id_type id) const
Returns a handle for a given resource identifier.
Definition: cache.hpp:347
resource_cache(resource_cache &&)=default
Default move constructor.
std::pair< iterator, bool > force_load(const id_type id, Args &&...args)
Force loads a resource, if its identifier does not exist.
Definition: cache.hpp:333
internal::resource_cache_iterator< Type, typename container_type::iterator > iterator
Input iterator type.
Definition: cache.hpp:176
Allocator allocator_type
Allocator type.
Definition: cache.hpp:174
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:285
resource_cache & operator=(resource_cache &&)=default
Default move assignment operator.
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:253
iterator end() noexcept
Returns an iterator to the end.
Definition: cache.hpp:277
constexpr allocator_type get_allocator() const noexcept
Returns the associated allocator.
Definition: cache.hpp:237
size_type size() const noexcept
Number of resources managed by a cache.
Definition: cache.hpp:293
std::size_t size_type
Unsigned integer type.
Definition: cache.hpp:170
const_iterator end() const noexcept
Returns an iterator to the end.
Definition: cache.hpp:272
iterator erase(const_iterator first, const_iterator last)
Removes the given elements from a cache.
Definition: cache.hpp:389
void clear() noexcept
Clears a cache.
Definition: cache.hpp:298
bool contains(const id_type id) const
Checks if a cache contains a given identifier.
Definition: cache.hpp:369
Basic resource handle.
Definition: resource.hpp:22
EnTT default namespace.
Definition: dense_map.hpp:21
std::uint32_t id_type
Alias declaration for type identifiers.
Definition: fwd.hpp:13
constexpr bool operator<=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator<(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr type_list< Type..., Other... > operator+(type_list< Type... >, type_list< Other... >)
Concatenates multiple type lists.
constexpr bool operator!=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator>=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator>(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.