EnTT: src/entt/resource/cache.hpp Source File

EnTT 3.15.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
23namespace internal {
24
25template<typename Type, typename It>
26class resource_cache_iterator final {
27 template<typename, typename>
28 friend class resource_cache_iterator;
29
30public:
31 using value_type = std::pair<id_type, resource<Type>>;
32 using pointer = input_iterator_pointer<value_type>;
33 using reference = value_type;
34 using difference_type = std::ptrdiff_t;
35 using iterator_category = std::input_iterator_tag;
36 using iterator_concept = std::random_access_iterator_tag;
37
38 constexpr resource_cache_iterator() noexcept = default;
39
40 constexpr resource_cache_iterator(const It iter) noexcept
41 : it{iter} {}
42
43 template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
44 constexpr resource_cache_iterator(const resource_cache_iterator<std::remove_const_t<Type>, Other> &other) noexcept
45 : it{other.it} {}
46
47 constexpr resource_cache_iterator &operator++() noexcept {
48 return ++it, *this;
49 }
50
51 constexpr resource_cache_iterator operator++(int) noexcept {
52 const resource_cache_iterator orig = *this;
53 return ++(*this), orig;
54 }
55
56 constexpr resource_cache_iterator &operator--() noexcept {
57 return --it, *this;
58 }
59
60 constexpr resource_cache_iterator operator--(int) noexcept {
61 const resource_cache_iterator orig = *this;
62 return operator--(), orig;
63 }
64
65 constexpr resource_cache_iterator &operator+=(const difference_type value) noexcept {
66 it += value;
67 return *this;
68 }
69
70 constexpr resource_cache_iterator operator+(const difference_type value) const noexcept {
71 resource_cache_iterator copy = *this;
72 return (copy += value);
73 }
74
75 constexpr resource_cache_iterator &operator-=(const difference_type value) noexcept {
76 return (*this += -value);
77 }
78
79 constexpr resource_cache_iterator operator-(const difference_type value) const noexcept {
80 return (*this + -value);
81 }
82
83 [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
84 return {it[value].first, resource<Type>{it[value].second}};
85 }
86
87 [[nodiscard]] constexpr reference operator*() const noexcept {
88 return operator[](0);
89 }
90
91 [[nodiscard]] constexpr pointer operator->() const noexcept {
92 return operator*();
93 }
94
95 template<typename... Lhs, typename... Rhs>
96 friend constexpr std::ptrdiff_t operator-(const resource_cache_iterator<Lhs...> &, const resource_cache_iterator<Rhs...> &) noexcept;
97
98 template<typename... Lhs, typename... Rhs>
99 friend constexpr bool 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
104private:
105 It it;
106};
107
108template<typename... Lhs, typename... Rhs>
109[[nodiscard]] constexpr std::ptrdiff_t operator-(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
110 return lhs.it - rhs.it;
111}
112
113template<typename... Lhs, typename... Rhs>
114[[nodiscard]] constexpr bool operator==(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
115 return lhs.it == rhs.it;
116}
117
118template<typename... Lhs, typename... Rhs>
119[[nodiscard]] constexpr bool operator!=(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
120 return !(lhs == rhs);
121}
122
123template<typename... Lhs, typename... Rhs>
124[[nodiscard]] constexpr bool operator<(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
125 return lhs.it < rhs.it;
126}
127
128template<typename... Lhs, typename... Rhs>
129[[nodiscard]] constexpr bool operator>(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
130 return rhs < lhs;
131}
132
133template<typename... Lhs, typename... Rhs>
134[[nodiscard]] constexpr bool operator<=(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
135 return !(lhs > rhs);
136}
137
138template<typename... Lhs, typename... Rhs>
139[[nodiscard]] constexpr bool operator>=(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
140 return !(lhs < rhs);
141}
142
143} // namespace internal
145
152template<typename Type, typename Loader, typename Allocator>
153 class resource_cache {
154 using alloc_traits = std::allocator_traits<Allocator>;
155 static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
156 using container_allocator = typename alloc_traits::template rebind_alloc<std::pair<const id_type, typename Loader::result_type>>;
157 using container_type = dense_map<id_type, typename Loader::result_type, identity, std::equal_to<>, container_allocator>;
158
159public:
161 using allocator_type = Allocator;
163 using value_type = Type;
165 using size_type = std::size_t;
167 using loader_type = Loader;
169 using iterator = internal::resource_cache_iterator<Type, typename container_type::iterator>;
171 using const_iterator = internal::resource_cache_iterator<const Type, typename container_type::const_iterator>;
172
174 resource_cache()
175 : resource_cache{loader_type{}} {}
176
181 explicit resource_cache(const allocator_type &allocator)
182 : resource_cache{loader_type{}, allocator} {}
183
189 explicit resource_cache(const loader_type &callable, const allocator_type &allocator = allocator_type{})
190 : pool{container_type{allocator}, callable} {}
191
193 resource_cache(const resource_cache &) = default;
194
200 resource_cache(const resource_cache &other, const allocator_type &allocator)
201 : pool{std::piecewise_construct, std::forward_as_tuple(other.pool.first(), allocator), std::forward_as_tuple(other.pool.second())} {}
202
204 resource_cache(resource_cache &&) noexcept = default;
205
211 resource_cache(resource_cache &&other, const allocator_type &allocator)
212 : pool{std::piecewise_construct, std::forward_as_tuple(std::move(other.pool.first()), allocator), std::forward_as_tuple(std::move(other.pool.second()))} {}
213
215 ~resource_cache() = default;
216
221 resource_cache &operator=(const resource_cache &) = default;
222
227 resource_cache &operator=(resource_cache &&) noexcept = default;
228
233 [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
234 return pool.first().get_allocator();
235 }
236
244 [[nodiscard]] const_iterator cbegin() const noexcept {
245 return pool.first().begin();
246 }
247
249 [[nodiscard]] const_iterator begin() const noexcept {
250 return cbegin();
251 }
252
254 [[nodiscard]] iterator begin() noexcept {
255 return pool.first().begin();
256 }
257
263 [[nodiscard]] const_iterator cend() const noexcept {
264 return pool.first().end();
265 }
266
268 [[nodiscard]] const_iterator end() const noexcept {
269 return cend();
270 }
271
273 [[nodiscard]] iterator end() noexcept {
274 return pool.first().end();
275 }
276
281 [[nodiscard]] bool empty() const noexcept {
282 return pool.first().empty();
283 }
284
289 [[nodiscard]] size_type size() const noexcept {
290 return pool.first().size();
291 }
292
294 void clear() noexcept {
295 pool.first().clear();
296 }
297
315 template<typename... Args>
316 std::pair<iterator, bool> load(const id_type id, Args &&...args) {
317 if(auto it = pool.first().find(id); it != pool.first().end()) {
318 return {it, false};
319 }
320
321 return pool.first().emplace(id, pool.second()(std::forward<Args>(args)...));
322 }
323
328 template<typename... Args>
329 std::pair<iterator, bool> force_load(const id_type id, Args &&...args) {
330 return {pool.first().insert_or_assign(id, pool.second()(std::forward<Args>(args)...)).first, true};
331 }
332
343 [[nodiscard]] resource<const value_type> operator[](const id_type id) const {
344 if(auto it = pool.first().find(id); it != pool.first().cend()) {
345 return resource<const value_type>{it->second};
346 }
347
348 return {};
349 }
350
352 [[nodiscard]] resource<value_type> operator[](const id_type id) {
353 if(auto it = pool.first().find(id); it != pool.first().end()) {
354 return resource<value_type>{it->second};
355 }
356
357 return {};
358 }
359
365 [[nodiscard]] bool contains(const id_type id) const {
366 return pool.first().contains(id);
367 }
368
374 iterator erase(const_iterator pos) {
375 const auto it = pool.first().begin();
376 return pool.first().erase(it + (pos - const_iterator{it}));
377 }
378
385 iterator erase(const_iterator first, const_iterator last) {
386 const auto it = pool.first().begin();
387 return pool.first().erase(it + (first - const_iterator{it}), it + (last - const_iterator{it}));
388 }
389
395 size_type erase(const id_type id) {
396 return pool.first().erase(id);
397 }
398
403 [[nodiscard]] loader_type loader() const {
404 return pool.second();
405 }
406
407private:
408 compressed_pair<container_type, loader_type> pool;
409};
410
411} // namespace entt
412
413#endif
entt::compressed_pair
A compressed pair.
Definition compressed_pair.hpp:87
entt::dense_map
Associative container for key-value pairs with unique keys.
Definition dense_map.hpp:260
entt::resource_cache::erase
size_type erase(const id_type id)
Removes the given elements from a cache.
Definition cache.hpp:395
entt::resource_cache::resource_cache
resource_cache()
Default constructor.
Definition cache.hpp:174
entt::resource_cache::operator=
resource_cache & operator=(resource_cache &&) noexcept=default
Default move assignment operator.
entt::resource_cache::resource_cache
resource_cache(resource_cache &&) noexcept=default
Default move constructor.
entt::resource_cache::begin
iterator begin() noexcept
Returns an iterator to the beginning.
Definition cache.hpp:254
entt::resource_cache::resource_cache
resource_cache(const resource_cache &other, const allocator_type &allocator)
Allocator-extended copy constructor.
Definition cache.hpp:200
entt::resource_cache::loader
loader_type loader() const
Returns the loader used to create resources.
Definition cache.hpp:403
entt::resource_cache::operator[]
resource< value_type > operator[](const id_type id)
Returns a handle for a given resource identifier.
Definition cache.hpp:352
entt::resource_cache::cend
const_iterator cend() const noexcept
Returns an iterator to the end.
Definition cache.hpp:263
entt::resource_cache::load
std::pair< iterator, bool > load(const id_type id, Args &&...args)
Loads a resource, if its identifier does not exist.
Definition cache.hpp:316
entt::resource_cache::erase
iterator erase(const_iterator pos)
Removes an element from a given position.
Definition cache.hpp:374
entt::resource_cache::value_type
Type value_type
Resource type.
Definition cache.hpp:163
entt::resource_cache::loader_type
Loader loader_type
Loader type.
Definition cache.hpp:167
entt::resource_cache::resource_cache
resource_cache(const allocator_type &allocator)
Constructs an empty cache with a given allocator.
Definition cache.hpp:181
entt::resource_cache::cbegin
const_iterator cbegin() const noexcept
Returns an iterator to the beginning.
Definition cache.hpp:244
entt::resource_cache::resource_cache
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:189
entt::resource_cache::const_iterator
internal::resource_cache_iterator< const Type, typename container_type::const_iterator > const_iterator
Constant input iterator type.
Definition cache.hpp:171
entt::resource_cache::operator[]
resource< const value_type > operator[](const id_type id) const
Returns a handle for a given resource identifier.
Definition cache.hpp:343
entt::resource_cache::force_load
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:329
entt::resource_cache::iterator
internal::resource_cache_iterator< Type, typename container_type::iterator > iterator
Input iterator type.
Definition cache.hpp:169
entt::resource_cache::allocator_type
Allocator allocator_type
Allocator type.
Definition cache.hpp:161
entt::resource_cache::resource_cache
resource_cache(const resource_cache &)=default
Default copy constructor.
entt::resource_cache::empty
bool empty() const noexcept
Returns true if a cache contains no resources, false otherwise.
Definition cache.hpp:281
entt::resource_cache::operator=
resource_cache & operator=(const resource_cache &)=default
Default copy assignment operator.
entt::resource_cache::begin
const_iterator begin() const noexcept
Returns an iterator to the beginning.
Definition cache.hpp:249
entt::resource_cache::end
iterator end() noexcept
Returns an iterator to the end.
Definition cache.hpp:273
entt::resource_cache::get_allocator
constexpr allocator_type get_allocator() const noexcept
Returns the associated allocator.
Definition cache.hpp:233
entt::resource_cache::~resource_cache
~resource_cache()=default
Default destructor.
entt::resource_cache::size
size_type size() const noexcept
Number of resources managed by a cache.
Definition cache.hpp:289
entt::resource_cache::size_type
std::size_t size_type
Unsigned integer type.
Definition cache.hpp:165
entt::resource_cache::end
const_iterator end() const noexcept
Returns an iterator to the end.
Definition cache.hpp:268
entt::resource_cache::erase
iterator erase(const_iterator first, const_iterator last)
Removes the given elements from a cache.
Definition cache.hpp:385
entt::resource_cache::clear
void clear() noexcept
Clears a cache.
Definition cache.hpp:294
entt::resource_cache::contains
bool contains(const id_type id) const
Checks if a cache contains a given identifier.
Definition cache.hpp:365
entt::resource
Basic resource handle.
Definition resource.hpp:22
entt
EnTT default namespace.
Definition dense_map.hpp:22
entt::id_type
std::uint32_t id_type
Alias declaration for type identifiers.
Definition fwd.hpp:29
entt::operator<=
constexpr bool operator<=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
Definition hashed_string.hpp:257
entt::operator<
constexpr bool operator<(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
Definition hashed_string.hpp:244
entt::operator+
constexpr type_list< Type..., Other... > operator+(type_list< Type... >, type_list< Other... >)
Concatenates multiple type lists.
Definition type_traits.hpp:210
entt::operator!=
constexpr bool operator!=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
Definition hashed_string.hpp:232
entt::operator>=
constexpr bool operator>=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
Definition hashed_string.hpp:283
entt::operator>
constexpr bool operator>(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
Definition hashed_string.hpp:270
entt::operator==
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
Definition hashed_string.hpp:220