Tested partially on Linux-x64, will test with the full suite on Linux-PPC64.
Ok for trunk and the gcc-7 branch? This is theoretically a breaking change
for the branch, but the committee has decided that they don't want
the support for copyable-but-not-movable types.

2018-02-25  Ville Voutilainen  <ville.voutilai...@gmail.com>

    Implement the missing bits of LWG 2769
    * include/std/any (any_cast(const any&)): Add static_assert.
    (any_cast(any&)): Likewise.
    (any_cast(any&&)): Likewise, and remove the handling
    for copyable-but-not-movable type.
    * testsuite/20_util/any/misc/any_cast.cc: Adjust.
    * testsuite/20_util/any/misc/any_cast_neg.cc: Likewise, and
    add new tests.
diff --git a/libstdc++-v3/include/std/any b/libstdc++-v3/include/std/any
index 466b7ca..e0aba3c 100644
--- a/libstdc++-v3/include/std/any
+++ b/libstdc++-v3/include/std/any
@@ -455,6 +455,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       static_assert(any::__is_valid_cast<_ValueType>(),
          "Template argument must be a reference or CopyConstructible type");
+      static_assert(is_constructible_v<_ValueType,
+                   const _AnyCast<_ValueType>&>,
+         "Template argument must be constructible from a const value.");
       auto __p = any_cast<_AnyCast<_ValueType>>(&__any);
       if (__p)
        return static_cast<_ValueType>(*__p);
@@ -478,34 +481,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       static_assert(any::__is_valid_cast<_ValueType>(),
          "Template argument must be a reference or CopyConstructible type");
+      static_assert(is_constructible_v<_ValueType,
+                   _AnyCast<_ValueType>&>,
+         "Template argument must be constructible from an lvalue.");
       auto __p = any_cast<_AnyCast<_ValueType>>(&__any);
       if (__p)
        return static_cast<_ValueType>(*__p);
       __throw_bad_any_cast();
     }
 
-  template<typename _ValueType,
-           typename enable_if<!is_move_constructible<_ValueType>::value
-                              || is_lvalue_reference<_ValueType>::value,
-                              bool>::type = true>
-    inline _ValueType any_cast(any&& __any)
-    {
-      static_assert(any::__is_valid_cast<_ValueType>(),
-         "Template argument must be a reference or CopyConstructible type");
-      auto __p = any_cast<_AnyCast<_ValueType>>(&__any);
-      if (__p)
-       return static_cast<_ValueType>(*__p);
-      __throw_bad_any_cast();
-    }
-
-  template<typename _ValueType,
-           typename enable_if<is_move_constructible<_ValueType>::value
-                              && !is_lvalue_reference<_ValueType>::value,
-                              bool>::type = false>
+  template<typename _ValueType>
     inline _ValueType any_cast(any&& __any)
     {
       static_assert(any::__is_valid_cast<_ValueType>(),
          "Template argument must be a reference or CopyConstructible type");
+      static_assert(is_constructible_v<_ValueType,
+                   _AnyCast<_ValueType>>,
+         "Template argument must be constructible from an rvalue.");
       auto __p = any_cast<_AnyCast<_ValueType>>(&__any);
       if (__p)
        return static_cast<_ValueType>(std::move(*__p));
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 45d8b63..37a24d7 100644
--- a/libstdc++-v3/testsuite/20_util/any/misc/any_cast.cc
+++ b/libstdc++-v3/testsuite/20_util/any/misc/any_cast.cc
@@ -95,15 +95,6 @@ void test03()
   VERIFY(move_count == 1);
   MoveEnabled&& m3 = any_cast<MoveEnabled&&>(any(m));
   VERIFY(move_count == 1);
-  struct MoveDeleted
-  {
-    MoveDeleted(MoveDeleted&&) = delete;
-    MoveDeleted() = default;
-    MoveDeleted(const MoveDeleted&) = default;
-  };
-  MoveDeleted md;
-  MoveDeleted&& md2 = any_cast<MoveDeleted>(any(std::move(md)));
-  MoveDeleted&& md3 = any_cast<MoveDeleted&&>(any(std::move(md)));
 }
 
 void 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 50a9a67..08da07d 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
@@ -20,11 +20,26 @@
 
 #include <any>
 
+using std::any;
+using std::any_cast;
+
 void test01()
 {
-  using std::any;
-  using std::any_cast;
-
   const any y(1);
-  any_cast<int&>(y); // { dg-error "invalid static_cast" "" { target { *-*-* } 
} 460 }
+  any_cast<int&>(y); // { dg-error "invalid static_cast" "" { target { *-*-* } 
} 463 }
+  // { dg-error "Template argument must be constructible from a const value" 
"" { target { *-*-* } } 458 }
+}
+
+void test02()
+{
+  any y(1);
+  any_cast<int&&>(y);
+  // { dg-error "Template argument must be constructible from an lvalue" "" { 
target { *-*-* } } 484 }
+}
+
+void test03()
+{
+  any y(1);
+  any_cast<int&>(std::move(y));  // { dg-error "invalid static_cast" "" { 
target { *-*-* } } 503 }
+  // { dg-error "Template argument must be constructible from an rvalue" "" { 
target { *-*-* } } 498 }
 }

Reply via email to