1 #ifndef ENTT_RESOURCE_RESOURCE_CACHE_HPP
2 #define ENTT_RESOURCE_RESOURCE_CACHE_HPP
11 #include "../config/config.h"
12 #include "../container/dense_map.hpp"
13 #include "../core/compressed_pair.hpp"
14 #include "../core/fwd.hpp"
15 #include "../core/iterator.hpp"
16 #include "../core/utility.hpp"
19 #include "resource.hpp"
30 template<
typename Type,
typename It>
31 class resource_cache_iterator final {
32 template<
typename,
typename>
33 friend class resource_cache_iterator;
36 using value_type = std::pair<id_type, resource<Type>>;
37 using pointer = input_iterator_pointer<value_type>;
38 using reference = value_type;
39 using difference_type = std::ptrdiff_t;
40 using iterator_category = std::input_iterator_tag;
42 resource_cache_iterator() ENTT_NOEXCEPT = default;
44 resource_cache_iterator(const It iter) ENTT_NOEXCEPT
47 template<
typename Other,
typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
48 resource_cache_iterator(
const resource_cache_iterator<std::remove_const_t<Type>, Other> &other) ENTT_NOEXCEPT
51 resource_cache_iterator &operator++() ENTT_NOEXCEPT {
55 resource_cache_iterator operator++(
int) ENTT_NOEXCEPT {
56 resource_cache_iterator orig = *
this;
57 return ++(*this), orig;
60 resource_cache_iterator &operator--() ENTT_NOEXCEPT {
64 resource_cache_iterator operator--(
int) ENTT_NOEXCEPT {
65 resource_cache_iterator orig = *
this;
66 return operator--(), orig;
69 resource_cache_iterator &operator+=(
const difference_type value) ENTT_NOEXCEPT {
74 resource_cache_iterator
operator+(
const difference_type value)
const ENTT_NOEXCEPT {
75 resource_cache_iterator copy = *
this;
76 return (copy += value);
79 resource_cache_iterator &operator-=(
const difference_type value) ENTT_NOEXCEPT {
80 return (*
this += -value);
83 resource_cache_iterator operator-(
const difference_type value)
const ENTT_NOEXCEPT {
84 return (*
this + -value);
87 [[nodiscard]] reference operator[](
const difference_type value)
const ENTT_NOEXCEPT {
88 return {it[value].first, resource<Type>{it[value].second}};
91 [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
95 [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
99 template<
typename TLhs,
typename ILhs,
typename TRhs,
typename IRhs>
100 friend std::ptrdiff_t operator-(
const resource_cache_iterator<TLhs, ILhs> &,
const resource_cache_iterator<TRhs, IRhs> &) ENTT_NOEXCEPT;
102 template<
typename TLhs,
typename ILhs,
typename TRhs,
typename IRhs>
103 friend bool operator==(
const resource_cache_iterator<TLhs, ILhs> &,
const resource_cache_iterator<TRhs, IRhs> &) ENTT_NOEXCEPT;
105 template<
typename TLhs,
typename ILhs,
typename TRhs,
typename IRhs>
106 friend bool operator<(
const resource_cache_iterator<TLhs, ILhs> &,
const resource_cache_iterator<TRhs, IRhs> &) ENTT_NOEXCEPT;
112 template<
typename TLhs,
typename ILhs,
typename TRhs,
typename IRhs>
113 [[nodiscard]] std::ptrdiff_t operator-(
const resource_cache_iterator<TLhs, ILhs> &lhs,
const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
114 return lhs.it - rhs.it;
117 template<
typename TLhs,
typename ILhs,
typename TRhs,
typename IRhs>
118 [[nodiscard]]
bool operator==(
const resource_cache_iterator<TLhs, ILhs> &lhs,
const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
119 return lhs.it == rhs.it;
122 template<
typename TLhs,
typename ILhs,
typename TRhs,
typename IRhs>
123 [[nodiscard]]
bool operator!=(
const resource_cache_iterator<TLhs, ILhs> &lhs,
const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
124 return !(lhs == rhs);
127 template<
typename TLhs,
typename ILhs,
typename TRhs,
typename IRhs>
128 [[nodiscard]]
bool operator<(
const resource_cache_iterator<TLhs, ILhs> &lhs,
const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
129 return lhs.it < rhs.it;
132 template<
typename TLhs,
typename ILhs,
typename TRhs,
typename IRhs>
133 [[nodiscard]]
bool operator>(
const resource_cache_iterator<TLhs, ILhs> &lhs,
const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
137 template<
typename TLhs,
typename ILhs,
typename TRhs,
typename IRhs>
138 [[nodiscard]]
bool operator<=(
const resource_cache_iterator<TLhs, ILhs> &lhs,
const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
142 template<
typename TLhs,
typename ILhs,
typename TRhs,
typename IRhs>
143 [[nodiscard]]
bool operator>=(
const resource_cache_iterator<TLhs, ILhs> &lhs,
const resource_cache_iterator<TRhs, IRhs> &rhs) ENTT_NOEXCEPT {
160 template<
typename Type,
typename Loader,
typename Allocator>
162 using alloc_traits =
typename std::allocator_traits<Allocator>;
163 static_assert(std::is_same_v<typename alloc_traits::value_type, Type>,
"Invalid value type");
164 using container_allocator =
typename alloc_traits::template rebind_alloc<std::pair<const id_type, typename Loader::result_type>>;
177 using iterator = internal::resource_cache_iterator<Type, typename container_type::iterator>;
179 using const_iterator = internal::resource_cache_iterator<const Type, typename container_type::const_iterator>;
198 : pool{container_type{allocator}, callable} {}
209 : pool{std::piecewise_construct, std::forward_as_tuple(other.pool.first(), allocator), std::forward_as_tuple(other.pool.second())} {}
220 : pool{std::piecewise_construct, std::forward_as_tuple(std::move(other.pool.first()), allocator), std::forward_as_tuple(std::move(other.pool.second()))} {}
239 return pool.first().get_allocator();
251 return pool.first().begin();
261 return pool.first().begin();
275 return pool.first().end();
285 return pool.first().end();
292 [[nodiscard]]
bool empty() const ENTT_NOEXCEPT {
293 return pool.first().empty();
301 return pool.first().size();
306 pool.first().clear();
326 template<
typename... Args>
327 std::pair<iterator, bool>
load(
const id_type id, Args &&...args) {
328 if(
auto it = pool.first().find(
id); it != pool.first().end()) {
332 return pool.first().emplace(
id, pool.second()(std::forward<Args>(args)...));
339 template<
typename... Args>
341 return {pool.first().insert_or_assign(
id, pool.second()(std::forward<Args>(args)...)).first,
true};
355 if(
auto it = pool.first().find(
id); it != pool.first().cend()) {
364 if(
auto it = pool.first().find(
id); it != pool.first().end()) {
377 return pool.first().contains(
id);
386 const auto it = pool.first().begin();
397 const auto it = pool.first().begin();
407 return pool.first().erase(
id);
415 return pool.second();
Associative container for key-value pairs with unique keys.
Basic cache for resources of any type.
size_type erase(const id_type id)
Removes the given elements from a cache.
resource_cache()
Default constructor.
iterator end()
Returns an iterator to the end.
resource_cache(const resource_cache &other, const allocator_type &allocator)
Allocator-extended copy constructor.
const_iterator cend() const
Returns an iterator to the end.
loader_type loader() const
Returns the loader used to create resources.
std::pair< iterator, bool > force_load(const id_type id, Args &&...args)
Force loads a resource, if its identifier does not exist.
void clear()
Clears a cache.
const_iterator begin() const
Returns an iterator to the beginning.
iterator erase(const_iterator pos)
Removes an element from a given position.
size_type size() const
Number of resources managed by a cache.
Type value_type
Resource type.
bool empty() const
Returns true if a cache contains no resources, false otherwise.
constexpr allocator_type get_allocator() const
Returns the associated allocator.
Loader loader_type
Loader type.
resource_cache(resource_cache &&other, const allocator_type &allocator)
Allocator-extended move constructor.
resource_cache(const allocator_type &allocator)
Constructs an empty cache with a given allocator.
resource_cache(const loader_type &callable, const allocator_type &allocator=allocator_type{})
Constructs an empty cache with a given allocator and loader.
internal::resource_cache_iterator< const Type, typename container_type::const_iterator > const_iterator
Constant input iterator type.
std::pair< iterator, bool > load(const id_type id, Args &&...args)
Loads a resource, if its identifier does not exist.
resource_cache & operator=(resource_cache &&)=default
Default move assignment operator.
resource_cache(resource_cache &&)=default
Default move constructor.
internal::resource_cache_iterator< Type, typename container_type::iterator > iterator
Input iterator type.
Allocator allocator_type
Allocator type.
resource_cache(const resource_cache &)=default
Default copy constructor.
resource< const value_type > operator[](const id_type id) const
Returns a handle for a given resource identifier.
resource_cache & operator=(const resource_cache &)=default
Default copy assignment operator.
iterator begin()
Returns an iterator to the beginning.
const_iterator cbegin() const
Returns an iterator to the beginning.
const_iterator end() const
Returns an iterator to the end.
resource< value_type > operator[](const id_type id)
Returns a handle for a given resource identifier.
std::size_t size_type
Unsigned integer type.
iterator erase(const_iterator first, const_iterator last)
Removes the given elements from a cache.
bool contains(const id_type id) const
Checks if a cache contains a given identifier.
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs)
Compares two hashed strings.
std::uint32_t id_type
Alias declaration for type identifiers.
constexpr bool operator<=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs)
Compares two hashed strings.
constexpr bool operator>=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs)
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)
Compares two hashed strings.
bool operator!=(const basic_any< Len, Align > &lhs, const basic_any< Len, Align > &rhs)
Checks if two wrappers differ in their content.
constexpr bool operator>(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs)
Compares two hashed strings.