* [v3 PATCH] Implement LWG 2769, Redundant const in the return type of any_cast(const any&).
@ 2016-12-15 20:41 Ville Voutilainen
2016-12-16 11:49 ` Jonathan Wakely
0 siblings, 1 reply; 2+ messages in thread
From: Ville Voutilainen @ 2016-12-15 20:41 UTC (permalink / raw)
To: libstdc++, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 516 bytes --]
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.
[-- Attachment #2: lwg2769.diff --]
[-- Type: text/plain, Size: 3516 bytes --]
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 }
}
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [v3 PATCH] Implement LWG 2769, Redundant const in the return type of any_cast(const any&).
2016-12-15 20:41 [v3 PATCH] Implement LWG 2769, Redundant const in the return type of any_cast(const any&) Ville Voutilainen
@ 2016-12-16 11:49 ` Jonathan Wakely
0 siblings, 0 replies; 2+ messages in thread
From: Jonathan Wakely @ 2016-12-16 11:49 UTC (permalink / raw)
To: Ville Voutilainen; +Cc: libstdc++, gcc-patches
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.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-12-16 11:30 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-15 20:41 [v3 PATCH] Implement LWG 2769, Redundant const in the return type of any_cast(const any&) Ville Voutilainen
2016-12-16 11:49 ` Jonathan Wakely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).