1#ifndef ENTT_RESOURCE_RESOURCE_CACHE_HPP
2#define ENTT_RESOURCE_RESOURCE_CACHE_HPP
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"
18#include "resource.hpp"
25template<
typename Type,
typename It>
26class resource_cache_iterator final {
27 template<
typename,
typename>
28 friend class resource_cache_iterator;
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;
38 constexpr resource_cache_iterator() noexcept = default;
40 constexpr resource_cache_iterator(const It iter) noexcept
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
47 constexpr resource_cache_iterator &operator++() noexcept {
51 constexpr resource_cache_iterator operator++(
int)
noexcept {
52 resource_cache_iterator orig = *
this;
53 return ++(*this), orig;
56 constexpr resource_cache_iterator &operator--() noexcept {
60 constexpr resource_cache_iterator operator--(
int)
noexcept {
61 resource_cache_iterator orig = *
this;
62 return operator--(), orig;
65 constexpr resource_cache_iterator &operator+=(
const difference_type value)
noexcept {
70 constexpr resource_cache_iterator
operator+(
const difference_type value)
const noexcept {
71 resource_cache_iterator copy = *
this;
72 return (copy += value);
75 constexpr resource_cache_iterator &operator-=(
const difference_type value)
noexcept {
76 return (*
this += -value);
79 constexpr resource_cache_iterator operator-(
const difference_type value)
const noexcept {
80 return (*
this + -value);
83 [[nodiscard]]
constexpr reference operator[](
const difference_type value)
const noexcept {
84 return {it[value].first, resource<Type>{it[value].second}};
87 [[nodiscard]]
constexpr reference operator*() const noexcept {
91 [[nodiscard]]
constexpr pointer operator->() const noexcept {
95 template<
typename... Lhs,
typename... Rhs>
96 friend constexpr std::ptrdiff_t operator-(
const resource_cache_iterator<Lhs...> &,
const resource_cache_iterator<Rhs...> &)
noexcept;
98 template<
typename... Lhs,
typename... Rhs>
99 friend constexpr bool operator==(
const resource_cache_iterator<Lhs...> &,
const resource_cache_iterator<Rhs...> &)
noexcept;
101 template<
typename... Lhs,
typename... Rhs>
102 friend constexpr bool operator<(
const resource_cache_iterator<Lhs...> &,
const resource_cache_iterator<Rhs...> &)
noexcept;
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;
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;
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);
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;
128template<
typename... Lhs,
typename... Rhs>
129[[nodiscard]]
constexpr bool operator>(
const resource_cache_iterator<Lhs...> &lhs,
const resource_cache_iterator<Rhs...> &rhs)
noexcept {
133template<
typename... Lhs,
typename... Rhs>
134[[nodiscard]]
constexpr bool operator<=(
const resource_cache_iterator<Lhs...> &lhs,
const resource_cache_iterator<Rhs...> &rhs)
noexcept {
138template<
typename... Lhs,
typename... Rhs>
139[[nodiscard]]
constexpr bool operator>=(
const resource_cache_iterator<Lhs...> &lhs,
const resource_cache_iterator<Rhs...> &rhs)
noexcept {
152template<
typename Type,
typename Loader,
typename Allocator>
154 using alloc_traits = std::allocator_traits<Allocator>;
155 static_assert(std::is_same_v<typename alloc_traits::value_type, Type>,
"Invalid value type");
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>;
212 : pool{std::piecewise_construct, std::forward_as_tuple(std::move(
other.pool.first()),
allocator), std::forward_as_tuple(std::move(
other.pool.second()))} {}
234 return pool.first().get_allocator();
245 return pool.first().begin();
255 return pool.first().begin();
264 return pool.first().end();
274 return pool.first().end();
282 return pool.first().empty();
290 return pool.first().size();
295 pool.first().clear();
315 template<
typename...
Args>
317 if(
auto it = pool.first().find(
id);
it != pool.first().end()) {
321 return pool.first().emplace(
id, pool.second()(std::forward<Args>(
args)...));
328 template<
typename...
Args>
330 return {pool.first().insert_or_assign(
id, pool.second()(std::forward<Args>(
args)...)).first,
true};
344 if(
auto it = pool.first().find(
id);
it != pool.first().cend()) {
353 if(
auto it = pool.first().find(
id);
it != pool.first().end()) {
366 return pool.first().contains(
id);
375 const auto it = pool.first().begin();
386 const auto it = pool.first().begin();
396 return pool.first().erase(
id);
404 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.
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.
std::pair< iterator, bool > load(const id_type id, Args &&...args)
Loads a resource, if its identifier does not exist.
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.
resource< const value_type > operator[](const id_type id) const
Returns a handle for a given resource identifier.
std::pair< iterator, bool > force_load(const id_type id, Args &&...args)
Force loads a resource, if its identifier does not exist.
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.
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.
std::size_t size_type
Unsigned integer type.
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.
constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args)
Uses-allocator construction utility (waiting for C++20).
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) 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.