From 62549523462ea288aebd4e476bb33169bbe0a293 Mon Sep 17 00:00:00 2001 From: Ville Voutilainen Date: Fri, 16 Dec 2016 13:34:45 +0200 Subject: [PATCH] Implement LWG 2769, Redundant const in the return type of any_cast(const any&). 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. From-SVN: r243739 --- libstdc++-v3/ChangeLog | 12 ++++++++++++ libstdc++-v3/include/std/any | 18 ++++++++++-------- .../testsuite/20_util/any/misc/any_cast.cc | 13 +++++++++++++ .../testsuite/20_util/any/misc/any_cast_neg.cc | 2 +- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index cbed9d881c7..a0804e7d920 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,15 @@ +2016-12-16 Ville Voutilainen + + 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. + 2016-12-15 Jonathan Wakely PR libstdc++/59170 diff --git a/libstdc++-v3/include/std/any b/libstdc++-v3/include/std/any index ded2bb27522..44546e18c0f 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 + using _AnyCast = remove_cv_t>; /** * @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>>(&__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>(&__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>(&__any); + auto __p = any_cast<_AnyCast<_ValueType>>(&__any); if (__p) - return *__p; + return static_cast<_ValueType>(*__p); __throw_bad_any_cast(); } @@ -499,9 +501,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>(&__any); + 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 96f9419e070..f3ae5927904 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(any(std::move(md))); } +void test04() +{ + struct ExplicitCopy + { + ExplicitCopy() = default; + explicit ExplicitCopy(const ExplicitCopy&) = default; + }; + any x = ExplicitCopy(); + ExplicitCopy ec{any_cast(x)}; + ExplicitCopy ec2{any_cast(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 4de400d717e..a8a1ca9fd0a 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(y); // { dg-error "qualifiers" "" { target { *-*-* } } 453 } + any_cast(y); // { dg-error "invalid static_cast" "" { target { *-*-* } } 455 } }