diff options
Diffstat (limited to 'deps/include/entt/resource')
| -rw-r--r-- | deps/include/entt/resource/cache.hpp | 413 | ||||
| -rw-r--r-- | deps/include/entt/resource/fwd.hpp | 19 | ||||
| -rw-r--r-- | deps/include/entt/resource/loader.hpp | 33 | ||||
| -rw-r--r-- | deps/include/entt/resource/resource.hpp | 259 |
4 files changed, 724 insertions, 0 deletions
diff --git a/deps/include/entt/resource/cache.hpp b/deps/include/entt/resource/cache.hpp new file mode 100644 index 0000000..e17260b --- /dev/null +++ b/deps/include/entt/resource/cache.hpp @@ -0,0 +1,413 @@ +#ifndef ENTT_RESOURCE_RESOURCE_CACHE_HPP
+#define ENTT_RESOURCE_RESOURCE_CACHE_HPP
+
+#include <cstddef>
+#include <functional>
+#include <iterator>
+#include <memory>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+#include "../container/dense_map.hpp"
+#include "../core/compressed_pair.hpp"
+#include "../core/fwd.hpp"
+#include "../core/iterator.hpp"
+#include "../core/utility.hpp"
+#include "fwd.hpp"
+#include "loader.hpp"
+#include "resource.hpp"
+
+namespace entt {
+
+/*! @cond TURN_OFF_DOXYGEN */
+namespace internal {
+
+template<typename Type, typename It>
+class resource_cache_iterator final {
+ template<typename, typename>
+ friend class resource_cache_iterator;
+
+public:
+ using value_type = std::pair<id_type, resource<Type>>;
+ using pointer = input_iterator_pointer<value_type>;
+ using reference = value_type;
+ using difference_type = std::ptrdiff_t;
+ using iterator_category = std::input_iterator_tag;
+ using iterator_concept = std::random_access_iterator_tag;
+
+ constexpr resource_cache_iterator() noexcept = default;
+
+ constexpr resource_cache_iterator(const It iter) noexcept
+ : it{iter} {}
+
+ template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
+ constexpr resource_cache_iterator(const resource_cache_iterator<std::remove_const_t<Type>, Other> &other) noexcept
+ : it{other.it} {}
+
+ constexpr resource_cache_iterator &operator++() noexcept {
+ return ++it, *this;
+ }
+
+ constexpr resource_cache_iterator operator++(int) noexcept {
+ resource_cache_iterator orig = *this;
+ return ++(*this), orig;
+ }
+
+ constexpr resource_cache_iterator &operator--() noexcept {
+ return --it, *this;
+ }
+
+ constexpr resource_cache_iterator operator--(int) noexcept {
+ resource_cache_iterator orig = *this;
+ return operator--(), orig;
+ }
+
+ constexpr resource_cache_iterator &operator+=(const difference_type value) noexcept {
+ it += value;
+ return *this;
+ }
+
+ constexpr resource_cache_iterator operator+(const difference_type value) const noexcept {
+ resource_cache_iterator copy = *this;
+ return (copy += value);
+ }
+
+ constexpr resource_cache_iterator &operator-=(const difference_type value) noexcept {
+ return (*this += -value);
+ }
+
+ constexpr resource_cache_iterator operator-(const difference_type value) const noexcept {
+ return (*this + -value);
+ }
+
+ [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
+ return {it[value].first, resource<Type>{it[value].second}};
+ }
+
+ [[nodiscard]] constexpr reference operator*() const noexcept {
+ return operator[](0);
+ }
+
+ [[nodiscard]] constexpr pointer operator->() const noexcept {
+ return operator*();
+ }
+
+ template<typename... Lhs, typename... Rhs>
+ friend constexpr std::ptrdiff_t operator-(const resource_cache_iterator<Lhs...> &, const resource_cache_iterator<Rhs...> &) noexcept;
+
+ template<typename... Lhs, typename... Rhs>
+ friend constexpr bool operator==(const resource_cache_iterator<Lhs...> &, const resource_cache_iterator<Rhs...> &) noexcept;
+
+ template<typename... Lhs, typename... Rhs>
+ friend constexpr bool operator<(const resource_cache_iterator<Lhs...> &, const resource_cache_iterator<Rhs...> &) noexcept;
+
+private:
+ It it;
+};
+
+template<typename... Lhs, typename... Rhs>
+[[nodiscard]] constexpr std::ptrdiff_t operator-(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
+ return lhs.it - rhs.it;
+}
+
+template<typename... Lhs, typename... Rhs>
+[[nodiscard]] constexpr bool operator==(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
+ return lhs.it == rhs.it;
+}
+
+template<typename... Lhs, typename... Rhs>
+[[nodiscard]] constexpr bool operator!=(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
+ return !(lhs == rhs);
+}
+
+template<typename... Lhs, typename... Rhs>
+[[nodiscard]] constexpr bool operator<(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
+ return lhs.it < rhs.it;
+}
+
+template<typename... Lhs, typename... Rhs>
+[[nodiscard]] constexpr bool operator>(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
+ return rhs < lhs;
+}
+
+template<typename... Lhs, typename... Rhs>
+[[nodiscard]] constexpr bool operator<=(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
+ return !(lhs > rhs);
+}
+
+template<typename... Lhs, typename... Rhs>
+[[nodiscard]] constexpr bool operator>=(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
+ return !(lhs < rhs);
+}
+
+} // namespace internal
+/*! @endcond */
+
+/**
+ * @brief Basic cache for resources of any type.
+ * @tparam Type Type of resources managed by a cache.
+ * @tparam Loader Type of loader used to create the resources.
+ * @tparam Allocator Type of allocator used to manage memory and elements.
+ */
+template<typename Type, typename Loader, typename Allocator>
+class resource_cache {
+ using alloc_traits = std::allocator_traits<Allocator>;
+ static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
+ using container_allocator = typename alloc_traits::template rebind_alloc<std::pair<const id_type, typename Loader::result_type>>;
+ using container_type = dense_map<id_type, typename Loader::result_type, identity, std::equal_to<>, container_allocator>;
+
+public:
+ /*! @brief Allocator type. */
+ using allocator_type = Allocator;
+ /*! @brief Resource type. */
+ using value_type = Type;
+ /*! @brief Unsigned integer type. */
+ using size_type = std::size_t;
+ /*! @brief Loader type. */
+ using loader_type = Loader;
+ /*! @brief Input iterator type. */
+ using iterator = internal::resource_cache_iterator<Type, typename container_type::iterator>;
+ /*! @brief Constant input iterator type. */
+ using const_iterator = internal::resource_cache_iterator<const Type, typename container_type::const_iterator>;
+
+ /*! @brief Default constructor. */
+ resource_cache()
+ : resource_cache{loader_type{}} {}
+
+ /**
+ * @brief Constructs an empty cache with a given allocator.
+ * @param allocator The allocator to use.
+ */
+ explicit resource_cache(const allocator_type &allocator)
+ : resource_cache{loader_type{}, allocator} {}
+
+ /**
+ * @brief Constructs an empty cache with a given allocator and loader.
+ * @param callable The loader to use.
+ * @param allocator The allocator to use.
+ */
+ explicit resource_cache(const loader_type &callable, const allocator_type &allocator = allocator_type{})
+ : pool{container_type{allocator}, callable} {}
+
+ /*! @brief Default copy constructor. */
+ resource_cache(const resource_cache &) = default;
+
+ /**
+ * @brief Allocator-extended copy constructor.
+ * @param other The instance to copy from.
+ * @param allocator The allocator to use.
+ */
+ resource_cache(const resource_cache &other, const allocator_type &allocator)
+ : pool{std::piecewise_construct, std::forward_as_tuple(other.pool.first(), allocator), std::forward_as_tuple(other.pool.second())} {}
+
+ /*! @brief Default move constructor. */
+ resource_cache(resource_cache &&) noexcept = default;
+
+ /**
+ * @brief Allocator-extended move constructor.
+ * @param other The instance to move from.
+ * @param allocator The allocator to use.
+ */
+ resource_cache(resource_cache &&other, const allocator_type &allocator)
+ : pool{std::piecewise_construct, std::forward_as_tuple(std::move(other.pool.first()), allocator), std::forward_as_tuple(std::move(other.pool.second()))} {}
+
+ /*! @brief Default destructor. */
+ ~resource_cache() noexcept = default;
+
+ /**
+ * @brief Default copy assignment operator.
+ * @return This cache.
+ */
+ resource_cache &operator=(const resource_cache &) = default;
+
+ /**
+ * @brief Default move assignment operator.
+ * @return This cache.
+ */
+ resource_cache &operator=(resource_cache &&) noexcept = default;
+
+ /**
+ * @brief Returns the associated allocator.
+ * @return The associated allocator.
+ */
+ [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
+ return pool.first().get_allocator();
+ }
+
+ /**
+ * @brief Returns an iterator to the beginning.
+ *
+ * If the cache is empty, the returned iterator will be equal to `end()`.
+ *
+ * @return An iterator to the first instance of the internal cache.
+ */
+ [[nodiscard]] const_iterator cbegin() const noexcept {
+ return pool.first().begin();
+ }
+
+ /*! @copydoc cbegin */
+ [[nodiscard]] const_iterator begin() const noexcept {
+ return cbegin();
+ }
+
+ /*! @copydoc begin */
+ [[nodiscard]] iterator begin() noexcept {
+ return pool.first().begin();
+ }
+
+ /**
+ * @brief Returns an iterator to the end.
+ * @return An iterator to the element following the last instance of the
+ * internal cache.
+ */
+ [[nodiscard]] const_iterator cend() const noexcept {
+ return pool.first().end();
+ }
+
+ /*! @copydoc cend */
+ [[nodiscard]] const_iterator end() const noexcept {
+ return cend();
+ }
+
+ /*! @copydoc end */
+ [[nodiscard]] iterator end() noexcept {
+ return pool.first().end();
+ }
+
+ /**
+ * @brief Returns true if a cache contains no resources, false otherwise.
+ * @return True if the cache contains no resources, false otherwise.
+ */
+ [[nodiscard]] bool empty() const noexcept {
+ return pool.first().empty();
+ }
+
+ /**
+ * @brief Number of resources managed by a cache.
+ * @return Number of resources currently stored.
+ */
+ [[nodiscard]] size_type size() const noexcept {
+ return pool.first().size();
+ }
+
+ /*! @brief Clears a cache. */
+ void clear() noexcept {
+ pool.first().clear();
+ }
+
+ /**
+ * @brief Loads a resource, if its identifier does not exist.
+ *
+ * Arguments are forwarded directly to the loader and _consumed_ only if the
+ * resource doesn't already exist.
+ *
+ * @warning
+ * If the resource isn't loaded correctly, the returned handle could be
+ * invalid and any use of it will result in undefined behavior.
+ *
+ * @tparam Args Types of arguments to use to load the resource if required.
+ * @param id Unique resource identifier.
+ * @param args Arguments to use to load the resource if required.
+ * @return A pair consisting of an iterator to the inserted element (or to
+ * the element that prevented the insertion) and a bool denoting whether the
+ * insertion took place.
+ */
+ template<typename... Args>
+ std::pair<iterator, bool> load(const id_type id, Args &&...args) {
+ if(auto it = pool.first().find(id); it != pool.first().end()) {
+ return {it, false};
+ }
+
+ return pool.first().emplace(id, pool.second()(std::forward<Args>(args)...));
+ }
+
+ /**
+ * @brief Force loads a resource, if its identifier does not exist.
+ * @copydetails load
+ */
+ template<typename... Args>
+ std::pair<iterator, bool> force_load(const id_type id, Args &&...args) {
+ return {pool.first().insert_or_assign(id, pool.second()(std::forward<Args>(args)...)).first, true};
+ }
+
+ /**
+ * @brief Returns a handle for a given resource identifier.
+ *
+ * @warning
+ * There is no guarantee that the returned handle is valid.<br/>
+ * If it is not, any use will result in indefinite behavior.
+ *
+ * @param id Unique resource identifier.
+ * @return A handle for the given resource.
+ */
+ [[nodiscard]] resource<const value_type> operator[](const id_type id) const {
+ if(auto it = pool.first().find(id); it != pool.first().cend()) {
+ return resource<const value_type>{it->second};
+ }
+
+ return {};
+ }
+
+ /*! @copydoc operator[] */
+ [[nodiscard]] resource<value_type> operator[](const id_type id) {
+ if(auto it = pool.first().find(id); it != pool.first().end()) {
+ return resource<value_type>{it->second};
+ }
+
+ return {};
+ }
+
+ /**
+ * @brief Checks if a cache contains a given identifier.
+ * @param id Unique resource identifier.
+ * @return True if the cache contains the resource, false otherwise.
+ */
+ [[nodiscard]] bool contains(const id_type id) const {
+ return pool.first().contains(id);
+ }
+
+ /**
+ * @brief Removes an element from a given position.
+ * @param pos An iterator to the element to remove.
+ * @return An iterator following the removed element.
+ */
+ iterator erase(const_iterator pos) {
+ const auto it = pool.first().begin();
+ return pool.first().erase(it + (pos - const_iterator{it}));
+ }
+
+ /**
+ * @brief Removes the given elements from a cache.
+ * @param first An iterator to the first element of the range of elements.
+ * @param last An iterator past the last element of the range of elements.
+ * @return An iterator following the last removed element.
+ */
+ iterator erase(const_iterator first, const_iterator last) {
+ const auto it = pool.first().begin();
+ return pool.first().erase(it + (first - const_iterator{it}), it + (last - const_iterator{it}));
+ }
+
+ /**
+ * @brief Removes the given elements from a cache.
+ * @param id Unique resource identifier.
+ * @return Number of resources erased (either 0 or 1).
+ */
+ size_type erase(const id_type id) {
+ return pool.first().erase(id);
+ }
+
+ /**
+ * @brief Returns the loader used to create resources.
+ * @return The loader used to create resources.
+ */
+ [[nodiscard]] loader_type loader() const {
+ return pool.second();
+ }
+
+private:
+ compressed_pair<container_type, loader_type> pool;
+};
+
+} // namespace entt
+
+#endif
diff --git a/deps/include/entt/resource/fwd.hpp b/deps/include/entt/resource/fwd.hpp new file mode 100644 index 0000000..fae65b1 --- /dev/null +++ b/deps/include/entt/resource/fwd.hpp @@ -0,0 +1,19 @@ +#ifndef ENTT_RESOURCE_FWD_HPP
+#define ENTT_RESOURCE_FWD_HPP
+
+#include <memory>
+
+namespace entt {
+
+template<typename>
+struct resource_loader;
+
+template<typename Type, typename = resource_loader<Type>, typename = std::allocator<Type>>
+class resource_cache;
+
+template<typename>
+class resource;
+
+} // namespace entt
+
+#endif
diff --git a/deps/include/entt/resource/loader.hpp b/deps/include/entt/resource/loader.hpp new file mode 100644 index 0000000..6e12ff1 --- /dev/null +++ b/deps/include/entt/resource/loader.hpp @@ -0,0 +1,33 @@ +#ifndef ENTT_RESOURCE_LOADER_HPP
+#define ENTT_RESOURCE_LOADER_HPP
+
+#include <memory>
+#include <utility>
+#include "fwd.hpp"
+
+namespace entt {
+
+/**
+ * @brief Transparent loader for shared resources.
+ * @tparam Type Type of resources created by the loader.
+ */
+template<typename Type>
+struct resource_loader {
+ /*! @brief Result type. */
+ using result_type = std::shared_ptr<Type>;
+
+ /**
+ * @brief Constructs a shared pointer to a resource from its arguments.
+ * @tparam Args Types of arguments to use to construct the resource.
+ * @param args Parameters to use to construct the resource.
+ * @return A shared pointer to a resource of the given type.
+ */
+ template<typename... Args>
+ result_type operator()(Args &&...args) const {
+ return std::make_shared<Type>(std::forward<Args>(args)...);
+ }
+};
+
+} // namespace entt
+
+#endif
diff --git a/deps/include/entt/resource/resource.hpp b/deps/include/entt/resource/resource.hpp new file mode 100644 index 0000000..8d73ace --- /dev/null +++ b/deps/include/entt/resource/resource.hpp @@ -0,0 +1,259 @@ +#ifndef ENTT_RESOURCE_RESOURCE_HPP
+#define ENTT_RESOURCE_RESOURCE_HPP
+
+#include <memory>
+#include <type_traits>
+#include <utility>
+#include "fwd.hpp"
+
+namespace entt {
+
+/**
+ * @brief Basic resource handle.
+ *
+ * A handle wraps a resource and extends its lifetime. It also shares the same
+ * resource with all other handles constructed from the same element.<br/>
+ * As a rule of thumb, resources should never be copied nor moved. Handles are
+ * the way to go to push references around.
+ *
+ * @tparam Type Type of resource managed by a handle.
+ */
+template<typename Type>
+class resource {
+ template<typename>
+ friend class resource;
+
+ template<typename Other>
+ static constexpr bool is_acceptable_v = !std::is_same_v<Type, Other> && std::is_constructible_v<Type &, Other &>;
+
+public:
+ /*! @brief Resource type. */
+ using element_type = Type;
+ /*! @brief Handle type. */
+ using handle_type = std::shared_ptr<element_type>;
+
+ /*! @brief Default constructor. */
+ resource() noexcept
+ : value{} {}
+
+ /**
+ * @brief Creates a new resource handle.
+ * @param res A handle to a resource.
+ */
+ explicit resource(handle_type res) noexcept
+ : value{std::move(res)} {}
+
+ /*! @brief Default copy constructor. */
+ resource(const resource &) noexcept = default;
+
+ /*! @brief Default move constructor. */
+ resource(resource &&) noexcept = default;
+
+ /**
+ * @brief Aliasing constructor.
+ * @tparam Other Type of resource managed by the received handle.
+ * @param other The handle with which to share ownership information.
+ * @param res Unrelated and unmanaged resources.
+ */
+ template<typename Other>
+ resource(const resource<Other> &other, element_type &res) noexcept
+ : value{other.value, std::addressof(res)} {}
+
+ /**
+ * @brief Copy constructs a handle which shares ownership of the resource.
+ * @tparam Other Type of resource managed by the received handle.
+ * @param other The handle to copy from.
+ */
+ template<typename Other, typename = std::enable_if_t<is_acceptable_v<Other>>>
+ resource(const resource<Other> &other) noexcept
+ : value{other.value} {}
+
+ /**
+ * @brief Move constructs a handle which takes ownership of the resource.
+ * @tparam Other Type of resource managed by the received handle.
+ * @param other The handle to move from.
+ */
+ template<typename Other, typename = std::enable_if_t<is_acceptable_v<Other>>>
+ resource(resource<Other> &&other) noexcept
+ : value{std::move(other.value)} {}
+
+ /*! @brief Default destructor. */
+ ~resource() noexcept = default;
+
+ /**
+ * @brief Default copy assignment operator.
+ * @return This resource handle.
+ */
+ resource &operator=(const resource &) noexcept = default;
+
+ /**
+ * @brief Default move assignment operator.
+ * @return This resource handle.
+ */
+ resource &operator=(resource &&) noexcept = default;
+
+ /**
+ * @brief Copy assignment operator from foreign handle.
+ * @tparam Other Type of resource managed by the received handle.
+ * @param other The handle to copy from.
+ * @return This resource handle.
+ */
+ template<typename Other, typename = std::enable_if_t<is_acceptable_v<Other>>>
+ resource &operator=(const resource<Other> &other) noexcept {
+ value = other.value;
+ return *this;
+ }
+
+ /**
+ * @brief Move assignment operator from foreign handle.
+ * @tparam Other Type of resource managed by the received handle.
+ * @param other The handle to move from.
+ * @return This resource handle.
+ */
+ template<typename Other, typename = std::enable_if_t<is_acceptable_v<Other>>>
+ resource &operator=(resource<Other> &&other) noexcept {
+ value = std::move(other.value);
+ return *this;
+ }
+
+ /**
+ * @brief Returns a reference to the managed resource.
+ *
+ * @warning
+ * The behavior is undefined if the handle doesn't contain a resource.
+ *
+ * @return A reference to the managed resource.
+ */
+ [[nodiscard]] element_type &operator*() const noexcept {
+ return *value;
+ }
+
+ /*! @copydoc operator* */
+ [[nodiscard]] operator element_type &() const noexcept {
+ return *value;
+ }
+
+ /**
+ * @brief Returns a pointer to the managed resource.
+ * @return A pointer to the managed resource.
+ */
+ [[nodiscard]] element_type *operator->() const noexcept {
+ return value.get();
+ }
+
+ /**
+ * @brief Returns true if a handle contains a resource, false otherwise.
+ * @return True if the handle contains a resource, false otherwise.
+ */
+ [[nodiscard]] explicit operator bool() const noexcept {
+ return static_cast<bool>(value);
+ }
+
+ /*! @brief Releases the ownership of the managed resource. */
+ void reset() {
+ value.reset();
+ }
+
+ /**
+ * @brief Replaces the managed resource.
+ * @param other A handle to a resource.
+ */
+ void reset(handle_type other) {
+ value = std::move(other);
+ }
+
+ /**
+ * @brief Returns the underlying resource handle.
+ * @return The underlying resource handle.
+ */
+ [[nodiscard]] const handle_type &handle() const noexcept {
+ return value;
+ }
+
+private:
+ handle_type value;
+};
+
+/**
+ * @brief Compares two handles.
+ * @tparam Lhs Type of resource managed by the first handle.
+ * @tparam Rhs Type of resource managed by the second handle.
+ * @param lhs A valid handle.
+ * @param rhs A valid handle.
+ * @return True if both handles refer to the same resource, false otherwise.
+ */
+template<typename Lhs, typename Rhs>
+[[nodiscard]] bool operator==(const resource<Lhs> &lhs, const resource<Rhs> &rhs) noexcept {
+ return (std::addressof(*lhs) == std::addressof(*rhs));
+}
+
+/**
+ * @brief Compares two handles.
+ * @tparam Lhs Type of resource managed by the first handle.
+ * @tparam Rhs Type of resource managed by the second handle.
+ * @param lhs A valid handle.
+ * @param rhs A valid handle.
+ * @return False if both handles refer to the same resource, true otherwise.
+ */
+template<typename Lhs, typename Rhs>
+[[nodiscard]] bool operator!=(const resource<Lhs> &lhs, const resource<Rhs> &rhs) noexcept {
+ return !(lhs == rhs);
+}
+
+/**
+ * @brief Compares two handles.
+ * @tparam Lhs Type of resource managed by the first handle.
+ * @tparam Rhs Type of resource managed by the second handle.
+ * @param lhs A valid handle.
+ * @param rhs A valid handle.
+ * @return True if the first handle is less than the second, false otherwise.
+ */
+template<typename Lhs, typename Rhs>
+[[nodiscard]] bool operator<(const resource<Lhs> &lhs, const resource<Rhs> &rhs) noexcept {
+ return (std::addressof(*lhs) < std::addressof(*rhs));
+}
+
+/**
+ * @brief Compares two handles.
+ * @tparam Lhs Type of resource managed by the first handle.
+ * @tparam Rhs Type of resource managed by the second handle.
+ * @param lhs A valid handle.
+ * @param rhs A valid handle.
+ * @return True if the first handle is greater than the second, false otherwise.
+ */
+template<typename Lhs, typename Rhs>
+[[nodiscard]] bool operator>(const resource<Lhs> &lhs, const resource<Rhs> &rhs) noexcept {
+ return rhs < lhs;
+}
+
+/**
+ * @brief Compares two handles.
+ * @tparam Lhs Type of resource managed by the first handle.
+ * @tparam Rhs Type of resource managed by the second handle.
+ * @param lhs A valid handle.
+ * @param rhs A valid handle.
+ * @return True if the first handle is less than or equal to the second, false
+ * otherwise.
+ */
+template<typename Lhs, typename Rhs>
+[[nodiscard]] bool operator<=(const resource<Lhs> &lhs, const resource<Rhs> &rhs) noexcept {
+ return !(lhs > rhs);
+}
+
+/**
+ * @brief Compares two handles.
+ * @tparam Lhs Type of resource managed by the first handle.
+ * @tparam Rhs Type of resource managed by the second handle.
+ * @param lhs A valid handle.
+ * @param rhs A valid handle.
+ * @return True if the first handle is greater than or equal to the second,
+ * false otherwise.
+ */
+template<typename Lhs, typename Rhs>
+[[nodiscard]] bool operator>=(const resource<Lhs> &lhs, const resource<Rhs> &rhs) noexcept {
+ return !(lhs < rhs);
+}
+
+} // namespace entt
+
+#endif
|
