1#ifndef ENTT_RESOURCE_RESOURCE_CACHE_HPP
2#define ENTT_RESOURCE_RESOURCE_CACHE_HPP
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"
19#include "resource.hpp"
26template<
typename Type,
typename It>
27class resource_cache_iterator final {
28 template<
typename,
typename>
29 friend class resource_cache_iterator;
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;
39 constexpr resource_cache_iterator() noexcept = default;
41 constexpr resource_cache_iterator(const It iter) noexcept
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
49 constexpr resource_cache_iterator &operator++() noexcept {
53 constexpr resource_cache_iterator operator++(
int)
noexcept {
54 const resource_cache_iterator orig = *
this;
55 return ++(*this), orig;
58 constexpr resource_cache_iterator &operator--() noexcept {
62 constexpr resource_cache_iterator operator--(
int)
noexcept {
63 const resource_cache_iterator orig = *
this;
64 return operator--(), orig;
67 constexpr resource_cache_iterator &operator+=(
const difference_type value)
noexcept {
72 constexpr resource_cache_iterator
operator+(
const difference_type value)
const noexcept {
73 resource_cache_iterator copy = *
this;
74 return (copy += value);
77 constexpr resource_cache_iterator &operator-=(
const difference_type value)
noexcept {
78 return (*
this += -value);
81 constexpr resource_cache_iterator operator-(
const difference_type value)
const noexcept {
82 return (*
this + -value);
85 [[nodiscard]]
constexpr reference operator[](
const difference_type value)
const noexcept {
86 return {it[value].first, resource<Type>{it[value].second}};
89 [[nodiscard]]
constexpr reference operator*() const noexcept {
93 [[nodiscard]]
constexpr pointer operator->() const noexcept {
97 template<
typename... Args>
98 [[nodiscard]]
constexpr stl::ptrdiff_t operator-(
const resource_cache_iterator<Args...> &other)
const noexcept {
102 template<
typename... Args>
103 [[nodiscard]]
constexpr bool operator==(
const resource_cache_iterator<Args...> &other)
const noexcept {
104 return it == other.it;
107 template<
typename... Args>
108 [[nodiscard]]
constexpr auto operator<=>(
const resource_cache_iterator<Args...> &other)
const noexcept {
109 return it <=> other.it;
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>>;
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>;
163 : pool{container_type{allocator}, callable} {}
174 : pool{
stl::piecewise_construct,
stl::forward_as_tuple(other.pool.first(), allocator),
stl::forward_as_tuple(other.pool.second())} {}
185 : pool{stl::piecewise_construct, stl::forward_as_tuple(stl::move(other.pool.first()), allocator), stl::forward_as_tuple(stl::move(other.pool.second()))} {}
218 return pool.first().begin();
228 return pool.first().begin();
237 return pool.first().end();
247 return pool.first().end();
254 [[nodiscard]]
bool empty() const noexcept {
255 return pool.first().empty();
263 return pool.first().size();
268 pool.first().clear();
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()) {
294 return pool.first().emplace(
id, pool.second()(stl::forward<Args>(args)...));
301 template<
typename... Args>
303 return {pool.first().insert_or_assign(
id, pool.second()(stl::forward<Args>(args)...)).first,
true};
317 if(
auto it = pool.first().find(
id); it != pool.first().cend()) {
326 if(
auto it = pool.first().find(
id); it != pool.first().end()) {
339 return pool.first().contains(
id);
348 const auto it = pool.first().begin();
359 const auto it = pool.first().begin();
369 return pool.first().erase(
id);
377 return pool.second();
Associative container for key-value pairs with unique keys.
size_type erase(const id_type id)
Removes the given elements from a cache.
resource_cache()
Default constructor.
stl::size_t size_type
Unsigned integer type.
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.
resource_cache(const resource_cache &other, const allocator_type &allocator)
Allocator-extended copy constructor.
loader_type loader() const
Returns the loader used to create resources.
resource< value_type > operator[](const id_type id)
Returns a handle for a given resource identifier.
const_iterator cend() const noexcept
Returns an iterator to the end.
iterator erase(const_iterator pos)
Removes an element from a given position.
Type value_type
Resource type.
Loader loader_type
Loader type.
resource_cache(const allocator_type &allocator)
Constructs an empty cache with a given allocator.
const_iterator cbegin() const noexcept
Returns an iterator to the beginning.
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.
stl::pair< iterator, bool > load(const id_type id, Args &&...args)
Loads a resource, if its identifier does not exist.
resource< const value_type > operator[](const id_type id) const
Returns a handle for a given resource identifier.
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.
bool empty() const noexcept
Returns true if a cache contains no resources, false otherwise.
resource_cache & operator=(const resource_cache &)=default
Default copy assignment operator.
const_iterator begin() const noexcept
Returns an iterator to the beginning.
iterator end() noexcept
Returns an iterator to the end.
stl::pair< iterator, bool > force_load(const id_type id, Args &&...args)
Force loads a resource, even if its identifier already exists.
constexpr allocator_type get_allocator() const noexcept
Returns the associated allocator.
~resource_cache()=default
Default destructor.
size_type size() const noexcept
Number of resources managed by a cache.
const_iterator end() const noexcept
Returns an iterator to the end.
iterator erase(const_iterator first, const_iterator last)
Removes the given elements from a cache.
void clear() noexcept
Clears a cache.
bool contains(const id_type id) const
Checks if a cache contains a given identifier.
Custom EnTT namespace for the standard template library.
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.