mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
98d44e93bf
commit
7d4f48b5b8
|
|
@ -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>
|
2016-07-04 François Dumont <fdumont@gcc.gnu.org>
|
||||||
|
|
||||||
* testsuite/23_containers/vector/modifiers/emplace/self_emplace.cc:
|
* testsuite/23_containers/vector/modifiers/emplace/self_emplace.cc:
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
/// Construct with a copy of @p __value as the contained object.
|
/// Construct with a copy of @p __value as the contained object.
|
||||||
template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
|
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)
|
any(_ValueType&& __value)
|
||||||
: _M_manager(&_Mgr::_S_manage)
|
: _M_manager(&_Mgr::_S_manage)
|
||||||
{
|
{
|
||||||
|
|
@ -167,6 +169,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
"The contained object must be CopyConstructible");
|
"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()
|
/// Destructor, calls @c clear()
|
||||||
~any() { clear(); }
|
~any() { clear(); }
|
||||||
|
|
||||||
|
|
@ -377,7 +392,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
__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)
|
inline _ValueType any_cast(any&& __any)
|
||||||
{
|
{
|
||||||
static_assert(any::__is_valid_cast<_ValueType>(),
|
static_assert(any::__is_valid_cast<_ValueType>(),
|
||||||
|
|
@ -387,6 +405,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
return *__p;
|
return *__p;
|
||||||
__throw_bad_any_cast();
|
__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>
|
template<typename _Tp>
|
||||||
|
|
|
||||||
|
|
@ -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()
|
int main()
|
||||||
{
|
{
|
||||||
test01();
|
test01();
|
||||||
test02();
|
test02();
|
||||||
|
test03();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,5 +26,5 @@ void test01()
|
||||||
using std::experimental::any_cast;
|
using std::experimental::any_cast;
|
||||||
|
|
||||||
const any y(1);
|
const any y(1);
|
||||||
any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 353 }
|
any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 368 }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue