diff mbox

[v3] Implement LWG 2769, Redundant const in the return type of any_cast(const any&).

Message ID CAFk2RUZfq4rZN+8ui1Nmww0thw9HdXERuh5uFXXnYJxq04+vJg@mail.gmail.com
State New
Headers show

Commit Message

Ville Voutilainen Dec. 15, 2016, 8:33 p.m. UTC
Tested on Linux-x64.

2016-12-15  Ville Voutilainen  <ville.voutilainen@gmail.com>

    Implement LWG 2769, Redundant const in the return type of
    any_cast(const any&).
    * include/std/any (_AnyCast): New.
    (any_cast(const any&)): Use it and add an explicit cast for return.
    (any_cast(any&)): Likewise.
    (any_cast(any&&)): Likewise.
    * testsuite/20_util/any/misc/any_cast.cc: Add a test for a type
    that has an explicit copy constructor.
    *testsuite/20_util/any/misc/any_cast_neg.cc: Adjust.

Comments

Jonathan Wakely Dec. 16, 2016, 11:30 a.m. UTC | #1
On 15/12/16 22:33 +0200, Ville Voutilainen wrote:
>@@ -499,9 +501,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>     {
>       static_assert(any::__is_valid_cast<_ValueType>(),
> 	  "Template argument must be a reference or CopyConstructible type");
>-      auto __p = any_cast<remove_reference_t<_ValueType>>(&__any);
>+      using _Up = remove_cv_t<remove_reference_t<_ValueType>>;

This typedef is unused and should be removed.

OK with that change, thanks.
diff mbox

Patch

diff --git a/libstdc++-v3/include/std/any b/libstdc++-v3/include/std/any
index ded2bb2..820427c 100644
--- a/libstdc++-v3/include/std/any
+++ b/libstdc++-v3/include/std/any
@@ -433,6 +433,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return any(in_place_type<_Tp>, __il, std::forward<_Args>(__args)...);
     }
 
+  template <typename _Tp>
+    using _AnyCast = remove_cv_t<remove_reference_t<_Tp>>;
   /**
    * @brief Access the contained object.
    *
@@ -448,9 +450,9 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       static_assert(any::__is_valid_cast<_ValueType>(),
 	  "Template argument must be a reference or CopyConstructible type");
-      auto __p = any_cast<add_const_t<remove_reference_t<_ValueType>>>(&__any);
+      auto __p = any_cast<_AnyCast<_ValueType>>(&__any);
       if (__p)
-	return *__p;
+	return static_cast<_ValueType>(*__p);
       __throw_bad_any_cast();
     }
 
@@ -471,9 +473,9 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       static_assert(any::__is_valid_cast<_ValueType>(),
 	  "Template argument must be a reference or CopyConstructible type");
-      auto __p = any_cast<remove_reference_t<_ValueType>>(&__any);
+      auto __p = any_cast<_AnyCast<_ValueType>>(&__any);
       if (__p)
-	return *__p;
+	return static_cast<_ValueType>(*__p);
       __throw_bad_any_cast();
     }
 
@@ -485,9 +487,9 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       static_assert(any::__is_valid_cast<_ValueType>(),
 	  "Template argument must be a reference or CopyConstructible type");
-      auto __p = any_cast<remove_reference_t<_ValueType>>(&__any);
+      auto __p = any_cast<_AnyCast<_ValueType>>(&__any);
       if (__p)
-	return *__p;
+	return static_cast<_ValueType>(*__p);
       __throw_bad_any_cast();
     }
 
@@ -499,9 +501,10 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       static_assert(any::__is_valid_cast<_ValueType>(),
 	  "Template argument must be a reference or CopyConstructible type");
-      auto __p = any_cast<remove_reference_t<_ValueType>>(&__any);
+      using _Up = remove_cv_t<remove_reference_t<_ValueType>>;
+      auto __p = any_cast<_AnyCast<_ValueType>>(&__any);
       if (__p)
-	return std::move(*__p);
+	return static_cast<_ValueType>(std::move(*__p));
       __throw_bad_any_cast();
     }
   // @}
diff --git a/libstdc++-v3/testsuite/20_util/any/misc/any_cast.cc b/libstdc++-v3/testsuite/20_util/any/misc/any_cast.cc
index 96f9419..f3ae592 100644
--- a/libstdc++-v3/testsuite/20_util/any/misc/any_cast.cc
+++ b/libstdc++-v3/testsuite/20_util/any/misc/any_cast.cc
@@ -106,9 +106,22 @@  void test03()
   MoveDeleted&& md3 = any_cast<MoveDeleted&&>(any(std::move(md)));
 }
 
+void test04()
+{
+  struct ExplicitCopy
+  {
+    ExplicitCopy() = default;
+    explicit ExplicitCopy(const ExplicitCopy&) = default;
+  };
+  any x = ExplicitCopy();
+  ExplicitCopy ec{any_cast<ExplicitCopy>(x)};
+  ExplicitCopy ec2{any_cast<ExplicitCopy>(std::move(x))};
+}
+
 int main()
 {
   test01();
   test02();
   test03();
+  test04();
 }
diff --git a/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc b/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc
index 4de400d..a8a1ca9 100644
--- a/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc
@@ -26,5 +26,5 @@  void test01()
   using std::any_cast;
 
   const any y(1);
-  any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 453 }
+  any_cast<int&>(y); // { dg-error "invalid static_cast" "" { target { *-*-* } } 455 }
 }