Просмотр исходного кода

meta_any uses reference_wrapper instead of as_alias_t for aliasing

Michele Caini 6 лет назад
Родитель
Сommit
0e42a779e2
4 измененных файлов с 16 добавлено и 14 удалено
  1. 5 3
      docs/md/meta.md
  2. 2 2
      src/entt/meta/factory.hpp
  3. 3 4
      src/entt/meta/meta.hpp
  4. 6 5
      test/entt/meta/meta.cpp

+ 5 - 3
docs/md/meta.md

@@ -204,11 +204,13 @@ Moreover, it can be used as an opaque container for unmanaged objects if needed:
 
 ```cpp
 int value;
-entt::meta_any any{entt::as_alias, value};
+entt::meta_any any{std::ref(value)};
 ```
 
-In this case, the contained instance is never destroyed and users must ensure
-that the lifetime of the object exceeds that of the container.
+In other words, whenever `meta_any` intercepts a `reference_wrapper`, it acts as
+a reference to the original instance rather than making a copy of it. The
+contained object is never destroyed and users must ensure that its lifetime
+exceeds that of the container.
 
 A meta any object has a `type` member function that returns the meta type of the
 contained value, if any. The member functions `try_cast`, `cast` and `convert`

+ 2 - 2
src/entt/meta/factory.hpp

@@ -153,7 +153,7 @@ meta_any getter([[maybe_unused]] meta_handle handle, [[maybe_unused]] meta_any i
         if constexpr(std::is_same_v<Policy, as_void_t>) {
             return meta_any{std::in_place_type<void>};
         } else if constexpr(std::is_same_v<Policy, as_alias_t>) {
-            return meta_any{as_alias, std::forward<decltype(value)>(value)};
+            return meta_any{std::ref(std::forward<decltype(value)>(value))};
         } else {
             static_assert(std::is_same_v<Policy, as_is_t>);
             return meta_any{std::forward<decltype(value)>(value)};
@@ -197,7 +197,7 @@ meta_any invoke([[maybe_unused]] meta_handle handle, meta_any *args, std::index_
             std::invoke(Candidate, *args...);
             return meta_any{std::in_place_type<void>};
         } else if constexpr(std::is_same_v<Policy, as_alias_t>) {
-            return meta_any{as_alias, std::invoke(Candidate, *args...)};
+            return meta_any{std::ref(std::invoke(Candidate, *args...))};
         } else {
             static_assert(std::is_same_v<Policy, as_is_t>);
             return meta_any{std::invoke(Candidate, *args...)};

+ 3 - 4
src/entt/meta/meta.hpp

@@ -9,7 +9,6 @@
 #include <utility>
 #include <type_traits>
 #include "../config/config.h"
-#include "policy.hpp"
 
 
 namespace entt {
@@ -416,11 +415,11 @@ public:
      * @param type An instance of an object to use to initialize the container.
      */
     template<typename Type>
-    explicit meta_any(as_alias_t, Type &type)
+    explicit meta_any(std::reference_wrapper<Type> type)
         : meta_any{}
     {
         node = internal::meta_info<Type>::resolve();
-        instance = &type;
+        instance = &type.get();
 
         compare_fn = [](const void *lhs, const void *rhs) {
             return compare(0, *static_cast<const Type *>(lhs), *static_cast<const Type *>(rhs));
@@ -638,7 +637,7 @@ public:
      * otherwise.
      */
     bool operator==(const meta_any &other) const ENTT_NOEXCEPT {
-        return node == other.node && ((!compare_fn && !other.compare_fn) || compare_fn(instance, other.instance));
+        return node == other.node && (!compare_fn || compare_fn(instance, other.instance));
     }
 
     /**

+ 6 - 5
test/entt/meta/meta.cpp

@@ -1,4 +1,5 @@
 #include <utility>
+#include <functional>
 #include <type_traits>
 #include <gtest/gtest.h>
 #include <entt/core/hashed_string.hpp>
@@ -307,7 +308,7 @@ TEST_F(Meta, MetaAnySBOInPlaceTypeConstruction) {
 TEST_F(Meta, MetaAnySBOAsAliasConstruction) {
     int value = 3;
     int other = 42;
-    entt::meta_any any{entt::as_alias, value};
+    entt::meta_any any{std::ref(value)};
 
     ASSERT_TRUE(any);
     ASSERT_FALSE(any.try_cast<std::size_t>());
@@ -316,8 +317,8 @@ TEST_F(Meta, MetaAnySBOAsAliasConstruction) {
     ASSERT_EQ(std::as_const(any).cast<int>(), 3);
     ASSERT_NE(any.data(), nullptr);
     ASSERT_NE(std::as_const(any).data(), nullptr);
-    ASSERT_EQ(any, (entt::meta_any{entt::as_alias, value}));
-    ASSERT_NE(any, (entt::meta_any{entt::as_alias, other}));
+    ASSERT_EQ(any, (entt::meta_any{std::ref(value)}));
+    ASSERT_NE(any, (entt::meta_any{std::ref(other)}));
     ASSERT_NE(any, entt::meta_any{42});
     ASSERT_EQ(entt::meta_any{3}, any);
 }
@@ -414,7 +415,7 @@ TEST_F(Meta, MetaAnyNoSBOInPlaceTypeConstruction) {
 TEST_F(Meta, MetaAnyNoSBOAsAliasConstruction) {
     int value = 3;
     fat_type instance{&value};
-    entt::meta_any any{entt::as_alias, instance};
+    entt::meta_any any{std::ref(instance)};
 
     ASSERT_TRUE(any);
     ASSERT_FALSE(any.try_cast<std::size_t>());
@@ -423,7 +424,7 @@ TEST_F(Meta, MetaAnyNoSBOAsAliasConstruction) {
     ASSERT_EQ(std::as_const(any).cast<fat_type>(), instance);
     ASSERT_NE(any.data(), nullptr);
     ASSERT_NE(std::as_const(any).data(), nullptr);
-    ASSERT_EQ(any, (entt::meta_any{entt::as_alias, instance}));
+    ASSERT_EQ(any, (entt::meta_any{std::ref(instance)}));
     ASSERT_EQ(any, entt::meta_any{instance});
     ASSERT_NE(entt::meta_any{fat_type{}}, any);
 }