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

any/meta_any/poly: as_ref is a member function, no longer an in-class friend function exported in the global namespace

Michele Caini 5 лет назад
Родитель
Сommit
1249a4f8d3

+ 0 - 2
TODO

@@ -18,13 +18,11 @@
   - ...
 
 WIP:
-* HP: as_ref should be a qualified function, not a global one (no breaking change, ADL makes it work anyway)
 * HP: remove storage category and get_as_tuple, make storage classes return tuple (+ view generator detect shared storage in future)?
 * HP: remove non-const registry::storage function?
 * HP: review registry::get, registry::try_get
 * HP: weak reference wrapper example with custom storage.
 * HP: review ENTT_PAGE_SIZE, seems "wrong" (see sparse_set)
-* HP: virtual sparse_set::poly_storage (and sparse_set * only in the registry)
 * HP: merge view and view pack
 * HP: invalid view auto-refresh
 * HP: paginate pools

+ 1 - 1
docs/md/core.md

@@ -289,7 +289,7 @@ object:
 
 ```cpp
 // aliasing constructor
-entt::any ref = as_ref(other);
+entt::any ref = other.as_ref();
 ```
 
 In this case, it doesn't matter if the original container actually holds an

+ 11 - 11
docs/md/poly.md

@@ -302,11 +302,11 @@ struct square {
 
 // ...
 
-drawable d{circle{}};
-d->draw();
+drawable instance{circle{}};
+instance->draw();
 
-d = square{};
-d->draw();
+instance = square{};
+instance->draw();
 ```
 
 The `poly` class template offers a wide range of constructors, from the default
@@ -316,23 +316,23 @@ Among others, there is a constructor that allows users to wrap unmanaged objects
 in a `poly` instance (either const or non-const ones):
 
 ```cpp
-circle c;
-drawable d{std::ref(c)};
+circle shape;
+drawable instance{std::ref(shape)};
 ```
 
 Similarly, it's possible to create non-owning copies of `poly` from an existing
 object:
 
 ```cpp
-drawable other = as_ref(d);
+drawable other = instance.as_ref();
 ```
 
 In both cases, although the interface of the `poly` object doesn't change, it
 won't construct any element or take care of destroying the referenced objects.
 
 Note also how the underlying concept is accessed via a call to `operator->` and
-not directly as `d.draw()`.<br/>
+not directly as `instance.draw()`.<br/>
 This allows users to decouple the API of the wrapper from that of the concept.
-Therefore, where `d.data()` will invoke the `data` member function of the poly
-object, `d->data()` will map directly to the functionality exposed by the
-underlying concept.
+Therefore, where `instance.data()` will invoke the `data` member function of the
+poly object, `instance->data()` will map directly to the functionality exposed
+by the underlying concept.

+ 4 - 5
src/entt/core/any.hpp

@@ -306,19 +306,18 @@ public:
 
     /**
      * @brief Aliasing constructor.
-     * @param other A reference to an object that isn't necessarily initialized.
      * @return An any that shares a reference to an unmanaged object.
      */
-    [[nodiscard]] friend any as_ref(any &other) ENTT_NOEXCEPT {
+    [[nodiscard]] any as_ref() ENTT_NOEXCEPT {
         any ref{};
-        other.vtable(operation::REF, other, &ref);
+        vtable(operation::REF, *this, &ref);
         return ref;
     }
 
     /*! @copydoc as_ref */
-    [[nodiscard]] friend any as_ref(const any &other) ENTT_NOEXCEPT {
+    [[nodiscard]] any as_ref() const ENTT_NOEXCEPT {
         any ref{};
-        other.vtable(operation::CREF, other, &ref);
+        vtable(operation::CREF, *this, &ref);
         return ref;
     }
 

+ 11 - 12
src/entt/meta/meta.hpp

@@ -184,13 +184,13 @@ class meta_any {
         case operation::SEQ:
         case operation::CSEQ:
             if constexpr(has_meta_sequence_container_traits_v<Type>) {
-                *static_cast<meta_sequence_container *>(to) = { std::in_place_type<Type>, (op == operation::SEQ ? as_ref(const_cast<any &>(from)) : as_ref(from)) };
+                *static_cast<meta_sequence_container *>(to) = { std::in_place_type<Type>, (op == operation::SEQ ? const_cast<any &>(from).as_ref() : from.as_ref()) };
             }
             break;
         case operation::ASSOC:
         case operation::CASSOC:
             if constexpr(has_meta_associative_container_traits_v<Type>) {
-                *static_cast<meta_associative_container *>(to) = { std::in_place_type<Type>, (op == operation::ASSOC ? as_ref(const_cast<any &>(from)) : as_ref(from)) };
+                *static_cast<meta_associative_container *>(to) = { std::in_place_type<Type>, (op == operation::ASSOC ? const_cast<any &>(from).as_ref() : from.as_ref()) };
             }
             break;
         }
@@ -398,7 +398,7 @@ public:
     template<typename Type>
     [[nodiscard]] meta_any allow_cast() const {
         if(try_cast<std::remove_reference_t<Type>>() != nullptr) {
-            return as_ref(*this);
+            return as_ref();
         } else if(node) {
             if(const auto * const conv = internal::meta_visit<&internal::meta_type_node::conv>([info = type_id<Type>()](const auto *curr) { return curr->type()->info == info; }, node); conv) {
                 return conv->conv(storage.data());
@@ -526,21 +526,20 @@ public:
 
     /**
      * @brief Aliasing constructor.
-     * @param other A reference to an object that isn't necessarily initialized.
      * @return A meta any that shares a reference to an unmanaged object.
      */
-    [[nodiscard]] friend meta_any as_ref(meta_any &other) ENTT_NOEXCEPT {
-        meta_any ref = as_ref(std::as_const(other));
-        ref.storage = as_ref(other.storage);
+    [[nodiscard]] meta_any as_ref() ENTT_NOEXCEPT {
+        auto ref = std::as_const(*this).as_ref();
+        ref.storage = storage.as_ref();
         return ref;
     }
 
     /*! @copydoc as_ref */
-    [[nodiscard]] friend meta_any as_ref(const meta_any &other) ENTT_NOEXCEPT {
+    [[nodiscard]] meta_any as_ref() const ENTT_NOEXCEPT {
         meta_any ref{};
-        ref.node = other.node;
-        ref.storage = as_ref(other.storage);
-        ref.vtable = other.vtable;
+        ref.storage = storage.as_ref();
+        ref.vtable = vtable;
+        ref.node = node;
         return ref;
     }
 
@@ -602,7 +601,7 @@ struct meta_handle {
         : meta_handle{}
     {
         if constexpr(std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, meta_any>) {
-            any = as_ref(value);
+            any = value.as_ref();
         } else {
             any = std::reference_wrapper{value};
         }

+ 7 - 9
src/entt/poly/poly.hpp

@@ -319,21 +319,19 @@ public:
 
     /**
      * @brief Aliasing constructor.
-     * @param other A reference to an object that isn't necessarily initialized.
      * @return A poly that shares a reference to an unmanaged object.
      */
-    [[nodiscard]] friend poly as_ref(poly &other) ENTT_NOEXCEPT {
-        poly ref;
-        ref.storage = as_ref(other.storage);
-        ref.vtable = other.vtable;
+    [[nodiscard]] poly as_ref() ENTT_NOEXCEPT {
+        poly ref = std::as_const(*this).as_ref();
+        ref.storage = storage.as_ref();
         return ref;
     }
 
     /*! @copydoc as_ref */
-    [[nodiscard]] friend poly as_ref(const poly &other) ENTT_NOEXCEPT {
-        poly ref;
-        ref.storage = as_ref(other.storage);
-        ref.vtable = other.vtable;
+    [[nodiscard]] poly as_ref() const ENTT_NOEXCEPT {
+        poly ref{};
+        ref.storage = storage.as_ref();
+        ref.vtable = vtable;
         return ref;
     }
 

+ 10 - 10
test/entt/core/any.cpp

@@ -70,7 +70,7 @@ TEST(Any, SBOInPlaceTypeConstruction) {
     ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
     ASSERT_EQ(entt::any_cast<int>(any), 42);
 
-    auto other = as_ref(any);
+    auto other = any.as_ref();
 
     ASSERT_TRUE(other);
     ASSERT_EQ(other.type(), entt::type_id<int>());
@@ -97,7 +97,7 @@ TEST(Any, SBOAsRefConstruction) {
     ASSERT_EQ(any.data(), &value);
     ASSERT_EQ(std::as_const(any).data(), &value);
 
-    auto other = as_ref(any);
+    auto other = any.as_ref();
 
     ASSERT_TRUE(other);
     ASSERT_EQ(other.type(), entt::type_id<int>());
@@ -124,7 +124,7 @@ TEST(Any, SBOAsConstRefConstruction) {
     ASSERT_EQ(any.data(), nullptr);
     ASSERT_EQ(std::as_const(any).data(), &value);
 
-    auto other = as_ref(any);
+    auto other = any.as_ref();
 
     ASSERT_TRUE(other);
     ASSERT_EQ(other.type(), entt::type_id<int>());
@@ -203,7 +203,7 @@ TEST(Any, NoSBOInPlaceTypeConstruction) {
     ASSERT_EQ(entt::any_cast<double>(&any), nullptr);
     ASSERT_EQ(entt::any_cast<fat>(any), instance);
 
-    auto other = as_ref(any);
+    auto other = any.as_ref();
 
     ASSERT_TRUE(other);
     ASSERT_EQ(other.type(), entt::type_id<fat>());
@@ -230,7 +230,7 @@ TEST(Any, NoSBOAsRefConstruction) {
     ASSERT_EQ(any.data(), &instance);
     ASSERT_EQ(std::as_const(any).data(), &instance);
 
-    auto other = as_ref(any);
+    auto other = any.as_ref();
 
     ASSERT_TRUE(other);
     ASSERT_EQ(other.type(), entt::type_id<fat>());
@@ -257,7 +257,7 @@ TEST(Any, NoSBOAsConstRefConstruction) {
     ASSERT_EQ(any.data(), nullptr);
     ASSERT_EQ(std::as_const(any).data(), &instance);
 
-    auto other = as_ref(any);
+    auto other = any.as_ref();
 
     ASSERT_TRUE(other);
     ASSERT_EQ(other.type(), entt::type_id<fat>());
@@ -674,8 +674,8 @@ TEST(Any, NoSBOWithVoidSwap) {
 
 TEST(Any, AsRef) {
     entt::any any{42};
-    auto ref = as_ref(any);
-    auto cref = as_ref(std::as_const(any));
+    auto ref = any.as_ref();
+    auto cref = std::as_const(any).as_ref();
 
     ASSERT_EQ(entt::any_cast<int>(&any), any.data());
     ASSERT_EQ(entt::any_cast<int>(&ref), any.data());
@@ -711,8 +711,8 @@ TEST(Any, AsRef) {
     ASSERT_EQ(entt::any_cast<int>(&ref), nullptr);
     ASSERT_EQ(entt::any_cast<int>(&cref), any.data());
 
-    ref = as_ref(ref);
-    cref = as_ref(std::as_const(cref));
+    ref = ref.as_ref();
+    cref = std::as_const(cref).as_ref();
 
     ASSERT_EQ(entt::any_cast<int>(&ref), nullptr);
     ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);

+ 7 - 7
test/entt/meta/meta_any.cpp

@@ -576,8 +576,8 @@ TEST_F(MetaAny, NoSBOWithVoidSwap) {
 
 TEST_F(MetaAny, AsRef) {
     entt::meta_any any{42};
-    auto ref = as_ref(any);
-    auto cref = as_ref(std::as_const(any));
+    auto ref = any.as_ref();
+    auto cref = std::as_const(any).as_ref();
 
     ASSERT_EQ(any.try_cast<int>(), any.data());
     ASSERT_EQ(ref.try_cast<int>(), any.data());
@@ -613,8 +613,8 @@ TEST_F(MetaAny, AsRef) {
     ASSERT_EQ(ref.try_cast<int>(), nullptr);
     ASSERT_EQ(cref.try_cast<int>(), any.data());
 
-    ref = as_ref(ref);
-    cref = as_ref(std::as_const(cref));
+    ref = ref.as_ref();
+    cref = std::as_const(cref).as_ref();
 
     ASSERT_EQ(ref.try_cast<int>(), nullptr);
     ASSERT_EQ(cref.try_cast<int>(), nullptr);
@@ -746,7 +746,7 @@ TEST_F(MetaAny, ConstConvert) {
 TEST_F(MetaAny, UnmanageableType) {
     unmanageable_t instance;
     entt::meta_any any{std::ref(instance)};
-    entt::meta_any other = as_ref(any);
+    entt::meta_any other = any.as_ref();
 
     std::swap(any, other);
 
@@ -774,7 +774,7 @@ TEST_F(MetaAny, Invoke) {
     ASSERT_TRUE(any.invoke("func"_hs));
     ASSERT_TRUE(any.invoke("member"_hs, 42));
     ASSERT_FALSE(std::as_const(any).invoke("member"_hs, 42));
-    ASSERT_FALSE(as_ref(std::as_const(any)).invoke("member"_hs, 42));
+    ASSERT_FALSE(std::as_const(any).as_ref().invoke("member"_hs, 42));
     ASSERT_FALSE(any.invoke("non_existent"_hs, 42));
 
     ASSERT_EQ(clazz_t::c, 'd');
@@ -793,7 +793,7 @@ TEST_F(MetaAny, SetGet) {
 
     ASSERT_TRUE(value);
     ASSERT_EQ(value, any.get("value"_hs));
-    ASSERT_EQ(value, as_ref(std::as_const(any)).get("value"_hs));
+    ASSERT_EQ(value, std::as_const(any).as_ref().get("value"_hs));
     ASSERT_NE(value.try_cast<int>(), nullptr);
     ASSERT_EQ(value.cast<int>(), 42);
     ASSERT_EQ(instance.value, 42);

+ 1 - 1
test/entt/meta/meta_container.cpp

@@ -443,7 +443,7 @@ TEST_F(MetaContainer, StdVectorBool) {
 
     std::vector<bool> vec{};
     entt::meta_any any{std::ref(vec)};
-    auto cany = as_ref(std::as_const(any));
+    auto cany = std::as_const(any).as_ref();
 
     auto view = any.as_sequence_container();
     auto cview = cany.as_sequence_container();

+ 2 - 2
test/entt/meta/meta_data.cpp

@@ -292,7 +292,7 @@ TEST_F(MetaData, SetByRef) {
     value = 3;
     entt::meta_any wrapper{std::ref(value)};
 
-    ASSERT_TRUE(entt::resolve<clazz_t>().data("i"_hs).set(any, as_ref(wrapper)));
+    ASSERT_TRUE(entt::resolve<clazz_t>().data("i"_hs).set(any, wrapper.as_ref()));
     ASSERT_EQ(any.cast<clazz_t>().i, 3);
 }
 
@@ -309,7 +309,7 @@ TEST_F(MetaData, SetByConstRef) {
     value = 3;
     entt::meta_any wrapper{std::cref(value)};
 
-    ASSERT_TRUE(entt::resolve<clazz_t>().data("i"_hs).set(any, as_ref(wrapper)));
+    ASSERT_TRUE(entt::resolve<clazz_t>().data("i"_hs).set(any, wrapper.as_ref()));
     ASSERT_EQ(any.cast<clazz_t>().i, 3);
 }
 

+ 2 - 2
test/entt/meta/meta_func.cpp

@@ -316,7 +316,7 @@ TEST_F(MetaFunc, ArgsByRef) {
     int value = 4;
 
     ASSERT_EQ(func.invoke({}, std::ref(value)).cast<int>(), 8);
-    ASSERT_EQ(func.invoke({}, as_ref(any)).cast<int>(), 6);
+    ASSERT_EQ(func.invoke({}, any.as_ref()).cast<int>(), 6);
     ASSERT_EQ(any.cast<int>(), 6);
     ASSERT_EQ(value, 8);
 }
@@ -332,7 +332,7 @@ TEST_F(MetaFunc, ArgsByConstRef) {
     ASSERT_TRUE(func.invoke(instance, std::cref(value)));
     ASSERT_EQ(func_t::value, 9);
 
-    ASSERT_TRUE(func.invoke(instance, as_ref(std::as_const(any))));
+    ASSERT_TRUE(func.invoke(instance, std::as_const(any).as_ref()));
     ASSERT_EQ(func_t::value, 4);
 }
 

+ 5 - 5
test/entt/poly/poly_deduced.cpp

@@ -75,7 +75,7 @@ TEST(PolyDeduced, Functionalities) {
     ASSERT_TRUE(empty);
     ASSERT_EQ(empty->get(), 3);
 
-    entt::poly<Deduced> ref = as_ref(in_place);
+    entt::poly<Deduced> ref = in_place.as_ref();
 
     ASSERT_TRUE(ref);
     ASSERT_NE(ref.data(), nullptr);
@@ -180,8 +180,8 @@ TEST(PolyDeduced, ConstReference) {
 
 TEST(PolyDeduced, AsRef) {
     entt::poly<Deduced> poly{impl{}};
-    auto ref = as_ref(poly);
-    auto cref = as_ref(std::as_const(poly));
+    auto ref = poly.as_ref();
+    auto cref = std::as_const(poly).as_ref();
 
     ASSERT_NE(poly.data(), nullptr);
     ASSERT_NE(ref.data(), nullptr);
@@ -194,8 +194,8 @@ TEST(PolyDeduced, AsRef) {
     ASSERT_NE(std::as_const(ref).data(), nullptr);
     ASSERT_NE(cref.data(), nullptr);
 
-    ref = as_ref(ref);
-    cref = as_ref(std::as_const(cref));
+    ref = ref.as_ref();
+    cref = std::as_const(cref).as_ref();
 
     ASSERT_EQ(ref.data(), nullptr);
     ASSERT_NE(std::as_const(ref).data(), nullptr);

+ 5 - 5
test/entt/poly/poly_defined.cpp

@@ -81,7 +81,7 @@ TEST(PolyDefined, Functionalities) {
     ASSERT_TRUE(empty);
     ASSERT_EQ(empty->get(), 3);
 
-    entt::poly<Defined> ref = as_ref(in_place);
+    entt::poly<Defined> ref = in_place.as_ref();
 
     ASSERT_TRUE(ref);
     ASSERT_NE(ref.data(), nullptr);
@@ -186,8 +186,8 @@ TEST(PolyDefined, ConstReference) {
 
 TEST(PolyDefined, AsRef) {
     entt::poly<Defined> poly{impl{}};
-    auto ref = as_ref(poly);
-    auto cref = as_ref(std::as_const(poly));
+    auto ref = poly.as_ref();
+    auto cref = std::as_const(poly).as_ref();
 
     ASSERT_NE(poly.data(), nullptr);
     ASSERT_NE(ref.data(), nullptr);
@@ -200,8 +200,8 @@ TEST(PolyDefined, AsRef) {
     ASSERT_NE(std::as_const(ref).data(), nullptr);
     ASSERT_NE(cref.data(), nullptr);
 
-    ref = as_ref(ref);
-    cref = as_ref(std::as_const(cref));
+    ref = ref.as_ref();
+    cref = std::as_const(cref).as_ref();
 
     ASSERT_EQ(ref.data(), nullptr);
     ASSERT_NE(std::as_const(ref).data(), nullptr);