Browse Source

resource: cache const correctness review

Michele Caini 4 years ago
parent
commit
c7a3e9d4ac
2 changed files with 56 additions and 9 deletions
  1. 46 2
      src/entt/resource/cache.hpp
  2. 10 7
      test/entt/resource/resource.cpp

+ 46 - 2
src/entt/resource/cache.hpp

@@ -160,7 +160,7 @@ public:
      * @param id Unique resource identifier.
      * @return A handle for the given resource.
      */
-    [[nodiscard]] resource_handle<resource_type> handle(const id_type id) const {
+    [[nodiscard]] resource_handle<const resource_type> handle(const id_type id) const {
         if(auto it = resources.find(id); it != resources.cend()) {
             return it->second;
         }
@@ -168,6 +168,15 @@ public:
         return {};
     }
 
+    /*! @copydoc handle */
+    [[nodiscard]] resource_handle<resource_type> handle(const id_type id) {
+        if(auto it = resources.find(id); it != resources.end()) {
+            return it->second;
+        }
+
+        return {};
+    }
+
     /**
      * @brief Checks if a cache contains a given identifier.
      * @param id Unique resource identifier.
@@ -201,6 +210,41 @@ public:
      *
      * @code{.cpp}
      * void(const entt::id_type);
+     * void(entt::resource_handle<const resource_type>);
+     * void(const entt::id_type, entt::resource_handle<const resource_type>);
+     * @endcode
+     *
+     * @tparam Func Type of the function object to invoke.
+     * @param func A valid function object.
+     */
+    template<typename Func>
+    void each(Func func) const {
+        auto begin = resources.begin();
+        auto end = resources.end();
+
+        while(begin != end) {
+            auto curr = begin++;
+
+            if constexpr(std::is_invocable_v<Func, id_type>) {
+                func(curr->first);
+            } else if constexpr(std::is_invocable_v<Func, resource_handle<const resource_type>>) {
+                func(resource_handle<const resource_type>{curr->second});
+            } else {
+                func(curr->first, resource_handle<const resource_type>{curr->second});
+            }
+        }
+    }
+
+    /**
+     * @copybrief each
+     *
+     * The function object is invoked for each element. It is provided with
+     * either the resource identifier, the resource handle or both of them.<br/>
+     * The signature of the function must be equivalent to one of the following
+     * forms:
+     *
+     * @code{.cpp}
+     * void(const entt::id_type);
      * void(entt::resource_handle<resource_type>);
      * void(const entt::id_type, entt::resource_handle<resource_type>);
      * @endcode
@@ -209,7 +253,7 @@ public:
      * @param func A valid function object.
      */
     template<typename Func>
-    void each(Func func) const {
+    void each(Func func) {
         auto begin = resources.begin();
         auto end = resources.end();
 

+ 10 - 7
test/entt/resource/resource.cpp

@@ -51,7 +51,7 @@ TEST(Resource, Functionalities) {
 
     auto tmp = cache.handle(hs1);
 
-    ASSERT_EQ(cache.handle(hs1).use_count(), 3);
+    ASSERT_EQ(std::as_const(cache).handle(hs1).use_count(), 3);
     ASSERT_TRUE(static_cast<bool>(tmp));
 
     tmp = {};
@@ -63,7 +63,7 @@ TEST(Resource, Functionalities) {
     ASSERT_FALSE(cache.empty());
     ASSERT_TRUE(cache.contains(hs1));
     ASSERT_FALSE(cache.contains(hs2));
-    ASSERT_EQ((*cache.handle(hs1)).value, 42);
+    ASSERT_EQ((*std::as_const(cache).handle(hs1)).value, 42);
 
     ASSERT_TRUE(cache.load<loader<resource>>(hs1, 42));
     ASSERT_TRUE(cache.load<loader<resource>>(hs2, 42));
@@ -73,7 +73,7 @@ TEST(Resource, Functionalities) {
     ASSERT_TRUE(cache.contains(hs1));
     ASSERT_TRUE(cache.contains(hs2));
     ASSERT_EQ((*cache.handle(hs1)).value, 42);
-    ASSERT_EQ(cache.handle(hs2)->value, 42);
+    ASSERT_EQ(std::as_const(cache).handle(hs2)->value, 42);
 
     ASSERT_NO_FATAL_FAILURE(cache.discard(hs1));
 
@@ -93,10 +93,10 @@ TEST(Resource, Functionalities) {
 
     ASSERT_NE(cache.size(), 0u);
     ASSERT_FALSE(cache.empty());
-    ASSERT_TRUE(cache.handle(hs1));
+    ASSERT_TRUE(std::as_const(cache).handle(hs1));
     ASSERT_FALSE(cache.handle(hs2));
 
-    ASSERT_TRUE(cache.handle(hs1));
+    ASSERT_TRUE(std::as_const(cache).handle(hs1));
     ASSERT_EQ(&cache.handle(hs1).get(), &static_cast<const resource &>(cache.handle(hs1)));
     ASSERT_NO_FATAL_FAILURE(cache.clear());
 
@@ -201,13 +201,16 @@ TEST(Resource, Each) {
     ASSERT_FALSE(cache.empty());
     ASSERT_EQ(cache.handle("resource"_hs)->value, 1);
 
-    cache.each([](auto id, auto res) {
+    cache.each([](entt::id_type id, entt::resource_handle<resource> res) {
         ASSERT_EQ(id, "resource"_hs);
         ++res->value;
     });
 
     ASSERT_FALSE(cache.empty());
-    ASSERT_EQ(cache.handle("resource"_hs)->value, 2);
+
+    std::as_const(cache).each([](entt::id_type id, entt::resource_handle<const resource> res) {
+        ASSERT_EQ(res->value, 2);
+    });
 
     cache.each([&cache](entt::id_type id) {
         cache.discard(id);