Browse Source

test: any::as_ref for const references

Michele Caini 5 years ago
parent
commit
f55004d1e4
2 changed files with 52 additions and 3 deletions
  1. 5 3
      src/entt/core/any.hpp
  2. 47 0
      test/entt/core/any.cpp

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

@@ -37,10 +37,12 @@ class any {
         if constexpr(std::is_void_v<Type>) {
             return nullptr;
         } else if constexpr(std::is_lvalue_reference_v<Type>) {
+            using base_type = std::remove_reference_t<Type>;
+
             switch(op) {
             case operation::REF:
             case operation::CREF:
-                as_any(to).vtable = (op == operation::REF) ? basic_vtable<Type &> : basic_vtable<const Type &>;
+                as_any(to).vtable = (op == operation::REF) ? basic_vtable<base_type &> : basic_vtable<const base_type &>;
                 [[fallthrough]];
             case operation::COPY:
             case operation::MOVE:
@@ -49,11 +51,11 @@ class any {
             case operation::DTOR:
                 break;
             case operation::ADDR:
-                return std::is_const_v<std::remove_reference_t<Type>> ? nullptr : from.instance;
+                return std::is_const_v<base_type> ? nullptr : from.instance;
             case operation::CADDR:
                 return from.instance;
             case operation::TYPE:
-                as_type_info(to) = type_id<std::remove_reference_t<Type>>();
+                as_type_info(to) = type_id<base_type>();
                 break;
             }
         } else if constexpr(in_situ<Type>) {

+ 47 - 0
test/entt/core/any.cpp

@@ -646,6 +646,53 @@ TEST(Any, NoSBOWithVoidSwap) {
     ASSERT_EQ(entt::any_cast<fat>(lhs), (fat{{.1, .2, .3, .4}}));
 }
 
+TEST(Any, AsRef) {
+    entt::any any{42};
+    auto ref = as_ref(any);
+    auto cref = as_ref(std::as_const(any));
+
+    ASSERT_EQ(entt::any_cast<int>(&any), any.data());
+    ASSERT_EQ(entt::any_cast<int>(&ref), any.data());
+    ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
+
+    ASSERT_EQ(entt::any_cast<const int>(&any), any.data());
+    ASSERT_EQ(entt::any_cast<const int>(&ref), any.data());
+    ASSERT_EQ(entt::any_cast<const int>(&cref), any.data());
+
+    ASSERT_EQ(entt::any_cast<int>(any), 42);
+    ASSERT_EQ(entt::any_cast<int>(ref), 42);
+    ASSERT_EQ(entt::any_cast<const int>(cref), 42);
+
+    ASSERT_EQ(entt::any_cast<int &>(any), 42);
+    ASSERT_EQ(entt::any_cast<int &>(ref), 42);
+    ASSERT_EQ(entt::any_cast<const int &>(cref), 42);
+
+    entt::any_cast<int &>(any) = 3;
+
+    ASSERT_EQ(entt::any_cast<int>(any), 3);
+    ASSERT_EQ(entt::any_cast<int>(ref), 3);
+    ASSERT_EQ(entt::any_cast<const int>(cref), 3);
+
+    std::swap(ref, cref);
+
+    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));
+
+    ASSERT_EQ(entt::any_cast<int>(&ref), nullptr);
+    ASSERT_EQ(entt::any_cast<int>(&cref), nullptr);
+
+    ref = 42;
+    cref = 42;
+
+    ASSERT_NE(entt::any_cast<int>(&ref), nullptr);
+    ASSERT_NE(entt::any_cast<int>(&cref), nullptr);
+    ASSERT_NE(entt::any_cast<int>(&ref), any.data());
+    ASSERT_NE(entt::any_cast<int>(&cref), any.data());
+}
+
 TEST(Any, AnyCast) {
     entt::any any{42};
     const auto &cany = any;