aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVille Voutilainen <ville.voutilainen@gmail.com>2016-07-05 21:33:18 +0300
committerVille Voutilainen <ville@gcc.gnu.org>2016-07-05 21:33:18 +0300
commit7d4f48b5b85b20df4f1acc19a3f1326d37a8bf6a (patch)
treebac6ae817f1101d9ed774592f2b848b5c7ffea8f
parent98d44e93bfde113ced834cc65dd9d11231a94114 (diff)
downloadgcc-7d4f48b5b85b20df4f1acc19a3f1326d37a8bf6a.zip
gcc-7d4f48b5b85b20df4f1acc19a3f1326d37a8bf6a.tar.gz
gcc-7d4f48b5b85b20df4f1acc19a3f1326d37a8bf6a.tar.bz2
Implement LWG 2509,
any_cast doesn't work with rvalue reference targets and cannot move with a value target. * include/experimental/any (any(_ValueType&&)): Constrain and add an overload that doesn't forward. (any_cast(any&&)): Constrain and add an overload that moves. * testsuite/experimental/any/misc/any_cast.cc: Add tests for the functionality added by LWG 2509. From-SVN: r238022
-rw-r--r--libstdc++-v3/ChangeLog11
-rw-r--r--libstdc++-v3/include/experimental/any36
-rw-r--r--libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc30
-rw-r--r--libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc2
4 files changed, 76 insertions, 3 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 536e49f..d888864 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,14 @@
+2016-07-05 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Implement LWG 2509,
+ any_cast doesn't work with rvalue reference targets and cannot
+ move with a value target.
+ * include/experimental/any (any(_ValueType&&)): Constrain and
+ add an overload that doesn't forward.
+ (any_cast(any&&)): Constrain and add an overload that moves.
+ * testsuite/experimental/any/misc/any_cast.cc: Add tests for
+ the functionality added by LWG 2509.
+
2016-07-04 François Dumont <fdumont@gcc.gnu.org>
* testsuite/23_containers/vector/modifiers/emplace/self_emplace.cc:
diff --git a/libstdc++-v3/include/experimental/any b/libstdc++-v3/include/experimental/any
index ae40091..96ad576 100644
--- a/libstdc++-v3/include/experimental/any
+++ b/libstdc++-v3/include/experimental/any
@@ -158,7 +158,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Construct with a copy of @p __value as the contained object.
template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
- typename _Mgr = _Manager<_Tp>>
+ typename _Mgr = _Manager<_Tp>,
+ typename enable_if<is_constructible<_Tp, _ValueType&&>::value,
+ bool>::type = true>
any(_ValueType&& __value)
: _M_manager(&_Mgr::_S_manage)
{
@@ -167,6 +169,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
"The contained object must be CopyConstructible");
}
+ /// Construct with a copy of @p __value as the contained object.
+ template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
+ typename _Mgr = _Manager<_Tp>,
+ typename enable_if<!is_constructible<_Tp, _ValueType&&>::value,
+ bool>::type = false>
+ any(_ValueType&& __value)
+ : _M_manager(&_Mgr::_S_manage)
+ {
+ _Mgr::_S_create(_M_storage, __value);
+ static_assert(is_copy_constructible<_Tp>::value,
+ "The contained object must be CopyConstructible");
+ }
+
/// Destructor, calls @c clear()
~any() { clear(); }
@@ -377,7 +392,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__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>(),
@@ -387,6 +405,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *__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)
+ {
+ 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);
+ if (__p)
+ return std::move(*__p);
+ __throw_bad_any_cast();
+ }
// @}
template<typename _Tp>
diff --git a/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc b/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc
index ce3f213..bb0f754 100644
--- a/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc
+++ b/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc
@@ -77,8 +77,38 @@ void test02()
}
}
+static int move_count = 0;
+
+void test03()
+{
+ struct MoveEnabled
+ {
+ MoveEnabled(MoveEnabled&&)
+ {
+ ++move_count;
+ }
+ MoveEnabled() = default;
+ MoveEnabled(const MoveEnabled&) = default;
+ };
+ MoveEnabled m;
+ MoveEnabled m2 = any_cast<MoveEnabled>(any(m));
+ 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)));
+}
+
int main()
{
test01();
test02();
+ test03();
}
diff --git a/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc b/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc
index 1361db8..82957a1 100644
--- a/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc
+++ b/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc
@@ -26,5 +26,5 @@ void test01()
using std::experimental::any_cast;
const any y(1);
- any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 353 }
+ any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 368 }
}