Commit 23c3a059 by Ville Voutilainen Committed by Ville Voutilainen

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.

From-SVN: r258031
parent 2be4b342
2018-02-27 Ville Voutilainen <ville.voutilainen@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.
2018-02-23 Jonathan Wakely <jwakely@redhat.com> 2018-02-23 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/84532 PR libstdc++/84532
......
...@@ -438,8 +438,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -438,8 +438,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return any(in_place_type<_Tp>, __il, std::forward<_Args>(__args)...); 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. * @brief Access the contained object.
* *
...@@ -453,9 +451,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -453,9 +451,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _ValueType> template<typename _ValueType>
inline _ValueType any_cast(const any& __any) inline _ValueType any_cast(const any& __any)
{ {
using _Up = remove_cv_t<remove_reference_t<_ValueType>>;
static_assert(any::__is_valid_cast<_ValueType>(), static_assert(any::__is_valid_cast<_ValueType>(),
"Template argument must be a reference or CopyConstructible type"); "Template argument must be a reference or CopyConstructible type");
auto __p = any_cast<_AnyCast<_ValueType>>(&__any); static_assert(is_constructible_v<_ValueType, const _Up&>,
"Template argument must be constructible from a const value.");
auto __p = any_cast<_Up>(&__any);
if (__p) if (__p)
return static_cast<_ValueType>(*__p); return static_cast<_ValueType>(*__p);
__throw_bad_any_cast(); __throw_bad_any_cast();
...@@ -476,37 +477,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -476,37 +477,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _ValueType> template<typename _ValueType>
inline _ValueType any_cast(any& __any) inline _ValueType any_cast(any& __any)
{ {
using _Up = remove_cv_t<remove_reference_t<_ValueType>>;
static_assert(any::__is_valid_cast<_ValueType>(), static_assert(any::__is_valid_cast<_ValueType>(),
"Template argument must be a reference or CopyConstructible type"); "Template argument must be a reference or CopyConstructible type");
auto __p = any_cast<_AnyCast<_ValueType>>(&__any); static_assert(is_constructible_v<_ValueType, _Up&>,
"Template argument must be constructible from an lvalue.");
auto __p = any_cast<_Up>(&__any);
if (__p) if (__p)
return static_cast<_ValueType>(*__p); return static_cast<_ValueType>(*__p);
__throw_bad_any_cast(); __throw_bad_any_cast();
} }
template<typename _ValueType, 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>
inline _ValueType any_cast(any&& __any) inline _ValueType any_cast(any&& __any)
{ {
using _Up = remove_cv_t<remove_reference_t<_ValueType>>;
static_assert(any::__is_valid_cast<_ValueType>(), static_assert(any::__is_valid_cast<_ValueType>(),
"Template argument must be a reference or CopyConstructible type"); "Template argument must be a reference or CopyConstructible type");
auto __p = any_cast<_AnyCast<_ValueType>>(&__any); static_assert(is_constructible_v<_ValueType, _Up>,
"Template argument must be constructible from an rvalue.");
auto __p = any_cast<_Up>(&__any);
if (__p) if (__p)
return static_cast<_ValueType>(std::move(*__p)); return static_cast<_ValueType>(std::move(*__p));
__throw_bad_any_cast(); __throw_bad_any_cast();
......
...@@ -95,15 +95,6 @@ void test03() ...@@ -95,15 +95,6 @@ void test03()
VERIFY(move_count == 1); VERIFY(move_count == 1);
MoveEnabled&& m3 = any_cast<MoveEnabled&&>(any(m)); MoveEnabled&& m3 = any_cast<MoveEnabled&&>(any(m));
VERIFY(move_count == 1); 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() void test04()
......
...@@ -20,11 +20,26 @@ ...@@ -20,11 +20,26 @@
#include <any> #include <any>
using std::any;
using std::any_cast;
void test01() void test01()
{ {
using std::any;
using std::any_cast;
const any y(1); 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 { *-*-* } } 461 }
// { dg-error "Template argument must be constructible from a const value" "" { target { *-*-* } } 457 }
}
void test02()
{
any y(1);
any_cast<int&&>(y);
// { dg-error "Template argument must be constructible from an lvalue" "" { target { *-*-* } } 483 }
}
void test03()
{
any y(1);
any_cast<int&>(std::move(y)); // { dg-error "invalid static_cast" "" { target { *-*-* } } 501 }
// { dg-error "Template argument must be constructible from an rvalue" "" { target { *-*-* } } 497 }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment