Fix various issues in std::any and the related tests.
* Fix self-swap. Patch from Casey Carter. * Remove workarounds and tests for types with deleted move constructors. This was originally added as part of a LWG proposed resolution that has since changed. * Re-apply most recent PR for LWG 2769. * Re-apply most recent PR for LWG 2754. Specifically fix the SFINAE checks to use the decayed type. * Fix tests to allow moved-from std::any's to have a non-empty state. This is the behavior of MSVC's std::any. * Various whitespace and test fixes. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@283606 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
108
include/any
108
include/any
@@ -197,30 +197,33 @@ public:
|
|||||||
|
|
||||||
template <
|
template <
|
||||||
class _ValueType
|
class _ValueType
|
||||||
|
, class _Tp = decay_t<_ValueType>
|
||||||
, class = enable_if_t<
|
, class = enable_if_t<
|
||||||
!is_same<decay_t<_ValueType>, any>::value &&
|
!is_same<_Tp, any>::value &&
|
||||||
!__is_inplace_type<_ValueType>::value &&
|
!__is_inplace_type<_ValueType>::value &&
|
||||||
is_copy_constructible<_ValueType>::value>
|
is_copy_constructible<_Tp>::value>
|
||||||
>
|
>
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
any(_ValueType && __value);
|
any(_ValueType && __value);
|
||||||
|
|
||||||
template <class _Tp, class ..._Args,
|
template <class _ValueType, class ..._Args,
|
||||||
|
class _Tp = decay_t<_ValueType>,
|
||||||
class = enable_if_t<
|
class = enable_if_t<
|
||||||
is_constructible<_Tp, _Args...>::value &&
|
is_constructible<_Tp, _Args...>::value &&
|
||||||
is_copy_constructible<_Tp>::value
|
is_copy_constructible<_Tp>::value
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
explicit any(in_place_type_t<_Tp>, _Args&&... __args);
|
explicit any(in_place_type_t<_ValueType>, _Args&&... __args);
|
||||||
|
|
||||||
template <class _Tp, class _Up, class ..._Args,
|
template <class _ValueType, class _Up, class ..._Args,
|
||||||
|
class _Tp = decay_t<_ValueType>,
|
||||||
class = enable_if_t<
|
class = enable_if_t<
|
||||||
is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
|
is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
|
||||||
is_copy_constructible<_Tp>::value>
|
is_copy_constructible<_Tp>::value>
|
||||||
>
|
>
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
explicit any(in_place_type_t<_Tp>, initializer_list<_Up>, _Args&&... __args);
|
explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args);
|
||||||
|
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
~any() { this->reset(); }
|
~any() { this->reset(); }
|
||||||
@@ -242,15 +245,17 @@ public:
|
|||||||
// ValueType constructor?
|
// ValueType constructor?
|
||||||
template <
|
template <
|
||||||
class _ValueType
|
class _ValueType
|
||||||
|
, class _Tp = decay_t<_ValueType>
|
||||||
, class = enable_if_t<
|
, class = enable_if_t<
|
||||||
!is_same<decay_t<_ValueType>, any>::value
|
!is_same<_Tp, any>::value
|
||||||
&& is_copy_constructible<_ValueType>::value
|
&& is_copy_constructible<_Tp>::value
|
||||||
&& !__is_inplace_type<_ValueType>::value>
|
&& !__is_inplace_type<_ValueType>::value>
|
||||||
>
|
>
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
any & operator=(_ValueType && __rhs);
|
any & operator=(_ValueType && __rhs);
|
||||||
|
|
||||||
template <class _Tp, class ..._Args,
|
template <class _ValueType, class ..._Args,
|
||||||
|
class _Tp = decay_t<_ValueType>,
|
||||||
class = enable_if_t<
|
class = enable_if_t<
|
||||||
is_constructible<_Tp, _Args...>::value &&
|
is_constructible<_Tp, _Args...>::value &&
|
||||||
is_copy_constructible<_Tp>::value>
|
is_copy_constructible<_Tp>::value>
|
||||||
@@ -258,7 +263,8 @@ public:
|
|||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
void emplace(_Args&&... args);
|
void emplace(_Args&&... args);
|
||||||
|
|
||||||
template <class _Tp, class _Up, class ..._Args,
|
template <class _ValueType, class _Up, class ..._Args,
|
||||||
|
class _Tp = decay_t<_ValueType>,
|
||||||
class = enable_if_t<
|
class = enable_if_t<
|
||||||
is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
|
is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value &&
|
||||||
is_copy_constructible<_Tp>::value>
|
is_copy_constructible<_Tp>::value>
|
||||||
@@ -490,60 +496,49 @@ namespace __any_imp
|
|||||||
} // namespace __any_imp
|
} // namespace __any_imp
|
||||||
|
|
||||||
|
|
||||||
template <class _ValueType, class>
|
template <class _ValueType, class _Tp, class>
|
||||||
any::any(_ValueType && __v) : __h(nullptr)
|
any::any(_ValueType && __v) : __h(nullptr)
|
||||||
{
|
{
|
||||||
typedef typename decay<_ValueType>::type _Tp;
|
__any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_ValueType>(__v));
|
||||||
static_assert(is_copy_constructible<_Tp>::value,
|
|
||||||
"_ValueType must be CopyConstructible.");
|
|
||||||
using _ForwardTp = conditional_t<
|
|
||||||
is_move_constructible<_Tp>::value, _ValueType, _ValueType&>;
|
|
||||||
typedef __any_imp::_Handler<_Tp> _HandlerType;
|
|
||||||
_HandlerType::__create(*this, _VSTD::forward<_ForwardTp>(__v));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp, class ..._Args, class>
|
template <class _ValueType, class ..._Args, class _Tp, class>
|
||||||
any::any(in_place_type_t<_Tp>, _Args&&... __args) {
|
any::any(in_place_type_t<_ValueType>, _Args&&... __args) {
|
||||||
using _Hp = __any_imp::_Handler<_Tp>;
|
__any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
|
||||||
_Hp::__create(*this, _VSTD::forward<_Args>(__args)...);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class _Tp, class _Up, class ..._Args, class>
|
template <class _ValueType, class _Up, class ..._Args, class _Tp, class>
|
||||||
any::any(in_place_type_t<_Tp>, initializer_list<_Up> __il, _Args&&... __args) {
|
any::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) {
|
||||||
using _Hp = __any_imp::_Handler<_Tp>;
|
__any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
|
||||||
_Hp::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _ValueType, class>
|
template <class _ValueType, class, class>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
inline _LIBCPP_INLINE_VISIBILITY
|
||||||
any & any::operator=(_ValueType && __v)
|
any & any::operator=(_ValueType && __v)
|
||||||
{
|
{
|
||||||
typedef typename decay<_ValueType>::type _Tp;
|
|
||||||
static_assert(is_copy_constructible<_Tp>::value,
|
|
||||||
"_ValueType must be CopyConstructible.");
|
|
||||||
any(_VSTD::forward<_ValueType>(__v)).swap(*this);
|
any(_VSTD::forward<_ValueType>(__v)).swap(*this);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp, class ..._Args, class>
|
template <class _ValueType, class ..._Args, class _Tp, class>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
inline _LIBCPP_INLINE_VISIBILITY
|
||||||
void any::emplace(_Args&&... __args) {
|
void any::emplace(_Args&&... __args) {
|
||||||
using _Hp = __any_imp::_Handler<_Tp>;
|
|
||||||
reset();
|
reset();
|
||||||
_Hp::__create(*this, _VSTD::forward<_Args>(__args)...);
|
__any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _Tp, class _Up, class ..._Args, class>
|
template <class _ValueType, class _Up, class ..._Args, class _Tp, class>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
inline _LIBCPP_INLINE_VISIBILITY
|
||||||
void any::emplace(initializer_list<_Up> __il, _Args&&... __args) {
|
void any::emplace(initializer_list<_Up> __il, _Args&&... __args) {
|
||||||
using _Hp = __any_imp::_Handler<_Tp>;
|
|
||||||
reset();
|
reset();
|
||||||
_Hp::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
|
__any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
inline _LIBCPP_INLINE_VISIBILITY
|
||||||
void any::swap(any & __rhs) _NOEXCEPT
|
void any::swap(any & __rhs) _NOEXCEPT
|
||||||
{
|
{
|
||||||
|
if (this == &__rhs)
|
||||||
|
return;
|
||||||
if (__h && __rhs.__h) {
|
if (__h && __rhs.__h) {
|
||||||
any __tmp;
|
any __tmp;
|
||||||
__rhs.__call(_Action::_Move, &__tmp);
|
__rhs.__call(_Action::_Move, &__tmp);
|
||||||
@@ -582,50 +577,39 @@ template <class _ValueType>
|
|||||||
inline _LIBCPP_INLINE_VISIBILITY
|
inline _LIBCPP_INLINE_VISIBILITY
|
||||||
_ValueType any_cast(any const & __v)
|
_ValueType any_cast(any const & __v)
|
||||||
{
|
{
|
||||||
static_assert(
|
using _RawValueType = __uncvref_t<_ValueType>;
|
||||||
is_reference<_ValueType>::value
|
static_assert(is_constructible<_ValueType, _RawValueType const &>::value,
|
||||||
|| is_copy_constructible<_ValueType>::value,
|
"ValueType is required to be a reference or a CopyConstructible type");
|
||||||
"_ValueType is required to be a reference or a CopyConstructible type.");
|
auto __tmp = _VSTD::any_cast<add_const_t<_RawValueType>>(&__v);
|
||||||
using _Tp = add_const_t<remove_reference_t<_ValueType>>;
|
|
||||||
_Tp * __tmp = _VSTD::any_cast<_Tp>(&__v);
|
|
||||||
if (__tmp == nullptr)
|
if (__tmp == nullptr)
|
||||||
__throw_bad_any_cast();
|
__throw_bad_any_cast();
|
||||||
return *__tmp;
|
return static_cast<_ValueType>(*__tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _ValueType>
|
template <class _ValueType>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
inline _LIBCPP_INLINE_VISIBILITY
|
||||||
_ValueType any_cast(any & __v)
|
_ValueType any_cast(any & __v)
|
||||||
{
|
{
|
||||||
static_assert(
|
using _RawValueType = __uncvref_t<_ValueType>;
|
||||||
is_reference<_ValueType>::value
|
static_assert(is_constructible<_ValueType, _RawValueType &>::value,
|
||||||
|| is_copy_constructible<_ValueType>::value,
|
"ValueType is required to be a reference or a CopyConstructible type");
|
||||||
"_ValueType is required to be a reference or a CopyConstructible type.");
|
auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
|
||||||
typedef typename remove_reference<_ValueType>::type _Tp;
|
|
||||||
_Tp * __tmp = _VSTD::any_cast<_Tp>(&__v);
|
|
||||||
if (__tmp == nullptr)
|
if (__tmp == nullptr)
|
||||||
__throw_bad_any_cast();
|
__throw_bad_any_cast();
|
||||||
return *__tmp;
|
return static_cast<_ValueType>(*__tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _ValueType>
|
template <class _ValueType>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
inline _LIBCPP_INLINE_VISIBILITY
|
||||||
_ValueType any_cast(any && __v)
|
_ValueType any_cast(any && __v)
|
||||||
{
|
{
|
||||||
static_assert(
|
using _RawValueType = __uncvref_t<_ValueType>;
|
||||||
is_reference<_ValueType>::value
|
static_assert(is_constructible<_ValueType, _RawValueType>::value,
|
||||||
|| is_copy_constructible<_ValueType>::value,
|
"ValueType is required to be an rvalue reference or a CopyConstructible type");
|
||||||
"_ValueType is required to be a reference or a CopyConstructible type.");
|
auto __tmp = _VSTD::any_cast<_RawValueType>(&__v);
|
||||||
typedef typename remove_reference<_ValueType>::type _Tp;
|
|
||||||
using _ForwardTp = conditional_t<
|
|
||||||
is_reference<_ValueType>::value,
|
|
||||||
_ValueType,
|
|
||||||
conditional_t<is_move_constructible<_Tp>::value, _Tp, _Tp&>
|
|
||||||
>;
|
|
||||||
_Tp * __tmp = _VSTD::any_cast<_Tp>(&__v);
|
|
||||||
if (__tmp == nullptr)
|
if (__tmp == nullptr)
|
||||||
__throw_bad_any_cast();
|
__throw_bad_any_cast();
|
||||||
return _VSTD::forward<_ForwardTp>(*__tmp);
|
return static_cast<_ValueType>(_VSTD::move(*__tmp));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _ValueType>
|
template <class _ValueType>
|
||||||
|
|||||||
@@ -1122,6 +1122,11 @@ struct __unconstref {
|
|||||||
typedef typename remove_const<typename remove_reference<_Tp>::type>::type type;
|
typedef typename remove_const<typename remove_reference<_Tp>::type>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef _LIBCPP_CXX03_LANG
|
||||||
|
template <class _Tp>
|
||||||
|
using __uncvref_t = typename __uncvref<_Tp>::type;
|
||||||
|
#endif
|
||||||
|
|
||||||
// __is_same_uncvref
|
// __is_same_uncvref
|
||||||
|
|
||||||
template <class _Tp, class _Up>
|
template <class _Tp, class _Up>
|
||||||
|
|||||||
@@ -40,10 +40,13 @@ void test_move_assign() {
|
|||||||
a = std::move(a2);
|
a = std::move(a2);
|
||||||
|
|
||||||
assert(LHS::count == 1);
|
assert(LHS::count == 1);
|
||||||
assert(RHS::count == 2);
|
assert(RHS::count == 2 + a2.has_value());
|
||||||
|
LIBCPP_ASSERT(RHS::count == 2); // libc++ leaves the object empty
|
||||||
|
|
||||||
assertContains<RHS>(a, 2);
|
assertContains<RHS>(a, 2);
|
||||||
assertEmpty<RHS>(a2);
|
if (a2.has_value())
|
||||||
|
assertContains<RHS>(a2, 0);
|
||||||
|
LIBCPP_ASSERT(!a2.has_value());
|
||||||
}
|
}
|
||||||
assert(LHS::count == 0);
|
assert(LHS::count == 0);
|
||||||
assert(RHS::count == 0);
|
assert(RHS::count == 0);
|
||||||
@@ -54,16 +57,19 @@ void test_move_assign_empty() {
|
|||||||
assert(LHS::count == 0);
|
assert(LHS::count == 0);
|
||||||
{
|
{
|
||||||
any a;
|
any a;
|
||||||
any a2((LHS(1)));
|
any a2((LHS(1)));
|
||||||
|
|
||||||
assert(LHS::count == 1);
|
assert(LHS::count == 1);
|
||||||
|
|
||||||
a = std::move(a2);
|
a = std::move(a2);
|
||||||
|
|
||||||
assert(LHS::count == 1);
|
assert(LHS::count == 1 + a2.has_value());
|
||||||
|
LIBCPP_ASSERT(LHS::count == 1);
|
||||||
|
|
||||||
assertContains<LHS>(a, 1);
|
assertContains<LHS>(a, 1);
|
||||||
assertEmpty<LHS>(a2);
|
if (a2.has_value())
|
||||||
|
assertContains<LHS>(a2, 0);
|
||||||
|
LIBCPP_ASSERT(!a2.has_value());
|
||||||
}
|
}
|
||||||
assert(LHS::count == 0);
|
assert(LHS::count == 0);
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
|
|
||||||
// <any>
|
// <any>
|
||||||
|
|
||||||
// any& operator=(any const &);
|
// template <class ValueType>
|
||||||
|
// any& operator=(ValueType&&);
|
||||||
|
|
||||||
// Test value copy and move assignment.
|
// Test value copy and move assignment.
|
||||||
|
|
||||||
@@ -65,10 +66,12 @@ void test_assign_value() {
|
|||||||
assert(RHS::moved >= 1);
|
assert(RHS::moved >= 1);
|
||||||
assert(RHS::copied == 0);
|
assert(RHS::copied == 0);
|
||||||
assert(LHS::count == 0);
|
assert(LHS::count == 0);
|
||||||
assert(RHS::count == 1);
|
assert(RHS::count == 1 + rhs.has_value());
|
||||||
|
LIBCPP_ASSERT(!rhs.has_value());
|
||||||
|
|
||||||
assertContains<RHS>(lhs, 2);
|
assertContains<RHS>(lhs, 2);
|
||||||
assertEmpty<RHS>(rhs);
|
if (rhs.has_value())
|
||||||
|
assertContains<RHS>(rhs, 0);
|
||||||
}
|
}
|
||||||
assert(LHS::count == 0);
|
assert(LHS::count == 0);
|
||||||
assert(RHS::count == 0);
|
assert(RHS::count == 0);
|
||||||
@@ -114,7 +117,7 @@ void test_assign_value_empty() {
|
|||||||
template <class Tp, bool Move = false>
|
template <class Tp, bool Move = false>
|
||||||
void test_assign_throws() {
|
void test_assign_throws() {
|
||||||
#if !defined(TEST_HAS_NO_EXCEPTIONS)
|
#if !defined(TEST_HAS_NO_EXCEPTIONS)
|
||||||
auto try_throw=
|
auto try_throw =
|
||||||
[](any& lhs, auto&& rhs) {
|
[](any& lhs, auto&& rhs) {
|
||||||
try {
|
try {
|
||||||
Move ? lhs = std::move(rhs)
|
Move ? lhs = std::move(rhs)
|
||||||
@@ -188,6 +191,7 @@ void test_sfinae_constraints() {
|
|||||||
NoCopy(NoCopy&&) = default;
|
NoCopy(NoCopy&&) = default;
|
||||||
};
|
};
|
||||||
static_assert(!std::is_assignable<std::any, NoCopy>::value, "");
|
static_assert(!std::is_assignable<std::any, NoCopy>::value, "");
|
||||||
|
static_assert(!std::is_assignable<std::any, NoCopy&>::value, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ void test_copy()
|
|||||||
assert(Type::copied == 1);
|
assert(Type::copied == 1);
|
||||||
assert(Type::count == 2);
|
assert(Type::count == 2);
|
||||||
assertContains<Type>(a, 42);
|
assertContains<Type>(a, 42);
|
||||||
assertContains<Type>(a, 42);
|
assertContains<Type>(a2, 42);
|
||||||
|
|
||||||
// Modify a and check that a2 is unchanged
|
// Modify a and check that a2 is unchanged
|
||||||
modifyValue<Type>(a, -1);
|
modifyValue<Type>(a, -1);
|
||||||
|
|||||||
@@ -49,6 +49,16 @@ void test_in_place_type() {
|
|||||||
}
|
}
|
||||||
assert(Type::count == 0);
|
assert(Type::count == 0);
|
||||||
Type::reset();
|
Type::reset();
|
||||||
|
{ // Test that the in_place argument is properly decayed
|
||||||
|
any a(std::in_place<Type&>);
|
||||||
|
|
||||||
|
assert(Type::count == 1);
|
||||||
|
assert(Type::copied == 0);
|
||||||
|
assert(Type::moved == 0);
|
||||||
|
assertContains<Type>(a, 0);
|
||||||
|
}
|
||||||
|
assert(Type::count == 0);
|
||||||
|
Type::reset();
|
||||||
{
|
{
|
||||||
any a(std::in_place<Type>, 101);
|
any a(std::in_place<Type>, 101);
|
||||||
|
|
||||||
@@ -90,11 +100,38 @@ void test_in_place_type_tracked() {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
int x = 42;
|
int x = 42;
|
||||||
any a(std::in_place<Type>, {-1, 42, -1}, x);
|
any a(std::in_place<Type&>, {-1, 42, -1}, x);
|
||||||
assertArgsMatch<Type, std::initializer_list<int>, int&>(a);
|
assertArgsMatch<Type, std::initializer_list<int>, int&>(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_func() {}
|
||||||
|
|
||||||
|
void test_in_place_type_decayed() {
|
||||||
|
{
|
||||||
|
using Type = decltype(test_func);
|
||||||
|
using DecayT = void(*)();
|
||||||
|
any a(std::in_place<Type>, test_func);
|
||||||
|
assert(containsType<DecayT>(a));
|
||||||
|
assert(any_cast<DecayT>(a) == test_func);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
int my_arr[5];
|
||||||
|
using Type = int(&)[5];
|
||||||
|
using DecayT = int*;
|
||||||
|
any a(std::in_place<Type>, my_arr);
|
||||||
|
assert(containsType<DecayT>(a));
|
||||||
|
assert(any_cast<DecayT>(a) == my_arr);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
using Type = int[5];
|
||||||
|
using DecayT = int*;
|
||||||
|
any a(std::in_place<Type>);
|
||||||
|
assert(containsType<DecayT>(a));
|
||||||
|
assert(any_cast<DecayT>(a) == nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void test_ctor_sfinae() {
|
void test_ctor_sfinae() {
|
||||||
{
|
{
|
||||||
// Test that the init-list ctor SFINAE's away properly when
|
// Test that the init-list ctor SFINAE's away properly when
|
||||||
@@ -115,10 +152,14 @@ void test_ctor_sfinae() {
|
|||||||
NoCopy(std::initializer_list<int>, int) {}
|
NoCopy(std::initializer_list<int>, int) {}
|
||||||
};
|
};
|
||||||
using Tag = std::in_place_type_t<NoCopy>;
|
using Tag = std::in_place_type_t<NoCopy>;
|
||||||
|
using RefTag = std::in_place_type_t<NoCopy&>;
|
||||||
using IL = std::initializer_list<int>;
|
using IL = std::initializer_list<int>;
|
||||||
static_assert(!std::is_constructible<std::any, Tag>::value, "");
|
static_assert(!std::is_constructible<std::any, Tag>::value, "");
|
||||||
static_assert(!std::is_constructible<std::any, Tag, int>::value, "");
|
static_assert(!std::is_constructible<std::any, Tag, int>::value, "");
|
||||||
static_assert(!std::is_constructible<std::any, Tag, IL, int>::value, "");
|
static_assert(!std::is_constructible<std::any, Tag, IL, int>::value, "");
|
||||||
|
static_assert(!std::is_constructible<std::any, RefTag>::value, "");
|
||||||
|
static_assert(!std::is_constructible<std::any, RefTag, int>::value, "");
|
||||||
|
static_assert(!std::is_constructible<std::any, RefTag, IL, int>::value, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,6 +188,7 @@ int main() {
|
|||||||
test_in_place_type<throws_on_move>();
|
test_in_place_type<throws_on_move>();
|
||||||
test_in_place_type_tracked<small_tracked_t>();
|
test_in_place_type_tracked<small_tracked_t>();
|
||||||
test_in_place_type_tracked<large_tracked_t>();
|
test_in_place_type_tracked<large_tracked_t>();
|
||||||
|
test_in_place_type_decayed();
|
||||||
test_ctor_sfinae();
|
test_ctor_sfinae();
|
||||||
test_constructor_explicit();
|
test_constructor_explicit();
|
||||||
}
|
}
|
||||||
@@ -77,11 +77,13 @@ void test_move() {
|
|||||||
|
|
||||||
any a2(std::move(a));
|
any a2(std::move(a));
|
||||||
|
|
||||||
assert(Type::moved >= 1); // zero or more move operations can be performed.
|
assert(Type::moved == 1 || Type::moved == 2); // zero or more move operations can be performed.
|
||||||
assert(Type::copied == 0); // no copies can be performed.
|
assert(Type::copied == 0); // no copies can be performed.
|
||||||
assert(Type::count == 1);
|
assert(Type::count == 1 + a.has_value());
|
||||||
assertEmpty(a); // Moves are always destructive.
|
assertEmpty(a); // Moves are always destructive.
|
||||||
assertContains<Type>(a2, 42);
|
assertContains<Type>(a2, 42);
|
||||||
|
if (a.has_value())
|
||||||
|
assertContains<Type>(a, 0);
|
||||||
}
|
}
|
||||||
assert(Type::count == 0);
|
assert(Type::count == 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,6 @@
|
|||||||
using std::any;
|
using std::any;
|
||||||
using std::any_cast;
|
using std::any_cast;
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
template <class Type>
|
||||||
void test_copy_value_throws()
|
void test_copy_value_throws()
|
||||||
{
|
{
|
||||||
@@ -107,33 +106,6 @@ void test_copy_move_value() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_non_moveable_type()
|
|
||||||
{
|
|
||||||
using Type = deleted_move;
|
|
||||||
{
|
|
||||||
deleted_move mv(42);
|
|
||||||
std::any a(mv);
|
|
||||||
assert(Type::count == 2);
|
|
||||||
assert(Type::copied == 1);
|
|
||||||
assert(Type::moved == 0);
|
|
||||||
assertContains<Type>(a, 42);
|
|
||||||
}
|
|
||||||
assert(Type::count == 0);
|
|
||||||
Type::reset();
|
|
||||||
{
|
|
||||||
deleted_move mv(42);
|
|
||||||
std::any a(std::move(mv));
|
|
||||||
assert(Type::count == 2);
|
|
||||||
assert(Type::copied == 1);
|
|
||||||
assert(Type::moved == 0);
|
|
||||||
assertContains<Type>(a, 42);
|
|
||||||
}
|
|
||||||
assert(Type::count == 0);
|
|
||||||
Type::reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Test that any(ValueType&&) is *never* selected for a std::in_place type.
|
// Test that any(ValueType&&) is *never* selected for a std::in_place type.
|
||||||
void test_sfinae_constraints() {
|
void test_sfinae_constraints() {
|
||||||
using Tag = std::in_place_type_t<int>;
|
using Tag = std::in_place_type_t<int>;
|
||||||
@@ -169,6 +141,7 @@ void test_sfinae_constraints() {
|
|||||||
NoCopy(int) {}
|
NoCopy(int) {}
|
||||||
};
|
};
|
||||||
static_assert(!std::is_constructible<std::any, NoCopy>::value, "");
|
static_assert(!std::is_constructible<std::any, NoCopy>::value, "");
|
||||||
|
static_assert(!std::is_constructible<std::any, NoCopy&>::value, "");
|
||||||
static_assert(!std::is_convertible<NoCopy, std::any>::value, "");
|
static_assert(!std::is_convertible<NoCopy, std::any>::value, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,6 +152,5 @@ int main() {
|
|||||||
test_copy_value_throws<small_throws_on_copy>();
|
test_copy_value_throws<small_throws_on_copy>();
|
||||||
test_copy_value_throws<large_throws_on_copy>();
|
test_copy_value_throws<large_throws_on_copy>();
|
||||||
test_move_value_throws();
|
test_move_value_throws();
|
||||||
test_non_moveable_type();
|
|
||||||
test_sfinae_constraints();
|
test_sfinae_constraints();
|
||||||
}
|
}
|
||||||
@@ -129,7 +129,7 @@ static_assert(IsSmallObject<SmallThrows>::value, "");
|
|||||||
struct LargeThrows {
|
struct LargeThrows {
|
||||||
LargeThrows(int) { throw 42; }
|
LargeThrows(int) { throw 42; }
|
||||||
LargeThrows(std::initializer_list<int>, int) { throw 42; }
|
LargeThrows(std::initializer_list<int>, int) { throw 42; }
|
||||||
int data[10];
|
int data[sizeof(std::any)];
|
||||||
};
|
};
|
||||||
static_assert(!IsSmallObject<LargeThrows>::value, "");
|
static_assert(!IsSmallObject<LargeThrows>::value, "");
|
||||||
|
|
||||||
@@ -236,6 +236,13 @@ void test_emplace_sfinae_constraints() {
|
|||||||
static_assert(!has_emplace<NoCopy>(), "");
|
static_assert(!has_emplace<NoCopy>(), "");
|
||||||
static_assert(!has_emplace<NoCopy, int>(), "");
|
static_assert(!has_emplace<NoCopy, int>(), "");
|
||||||
static_assert(!has_emplace_init_list<NoCopy, int, int, int>(), "");
|
static_assert(!has_emplace_init_list<NoCopy, int, int, int>(), "");
|
||||||
|
static_assert(!has_emplace<NoCopy&>(), "");
|
||||||
|
static_assert(!has_emplace<NoCopy&, int>(), "");
|
||||||
|
static_assert(!has_emplace_init_list<NoCopy&, int, int, int>(), "");
|
||||||
|
static_assert(!has_emplace<NoCopy&&>(), "");
|
||||||
|
static_assert(!has_emplace<NoCopy&&, int>(), "");
|
||||||
|
static_assert(!has_emplace_init_list<NoCopy&&, int, int, int>(), "");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,37 @@ void test_noexcept()
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_self_swap() {
|
||||||
|
{
|
||||||
|
// empty
|
||||||
|
any a;
|
||||||
|
a.swap(a);
|
||||||
|
assertEmpty(a);
|
||||||
|
}
|
||||||
|
{ // small
|
||||||
|
using T = small;
|
||||||
|
any a{T{42}};
|
||||||
|
T::reset();
|
||||||
|
a.swap(a);
|
||||||
|
assertContains<T>(a, 42);
|
||||||
|
assert(T::count == 1);
|
||||||
|
assert(T::copied == 0);
|
||||||
|
assert(T::moved == 0);
|
||||||
|
}
|
||||||
|
assert(small::count == 0);
|
||||||
|
{ // large
|
||||||
|
using T = large;
|
||||||
|
any a{T{42}};
|
||||||
|
T::reset();
|
||||||
|
a.swap(a);
|
||||||
|
assertContains<T>(a, 42);
|
||||||
|
assert(T::copied == 0);
|
||||||
|
assert(T::moved == 0);
|
||||||
|
assert(T::count == 1);
|
||||||
|
}
|
||||||
|
assert(large::count == 0);
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
test_noexcept();
|
test_noexcept();
|
||||||
@@ -98,4 +129,5 @@ int main()
|
|||||||
test_swap<large1, large2>();
|
test_swap<large1, large2>();
|
||||||
test_swap<small, large>();
|
test_swap<small, large>();
|
||||||
test_swap<large, small>();
|
test_swap<large, small>();
|
||||||
|
test_self_swap();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,12 @@ void checkThrows(any& a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
any_cast<Type>(static_cast<any&&>(a));
|
using RefType = typename std::conditional<
|
||||||
|
std::is_lvalue_reference<Type>::value,
|
||||||
|
typename std::remove_reference<Type>::type&&,
|
||||||
|
Type
|
||||||
|
>::type;
|
||||||
|
any_cast<RefType>(static_cast<any&&>(a));
|
||||||
assert(false);
|
assert(false);
|
||||||
} catch (bad_any_cast const &) {
|
} catch (bad_any_cast const &) {
|
||||||
// do nothing
|
// do nothing
|
||||||
@@ -142,14 +147,6 @@ void test_cast_to_reference() {
|
|||||||
Type const &cv = any_cast<Type const&>(ca);
|
Type const &cv = any_cast<Type const&>(ca);
|
||||||
assert(&cv == &v);
|
assert(&cv == &v);
|
||||||
}
|
}
|
||||||
// Check getting a type by reference from a non-const rvalue
|
|
||||||
{
|
|
||||||
Type& v = any_cast<Type&>(std::move(a));
|
|
||||||
assert(v.value == 42);
|
|
||||||
|
|
||||||
Type const &cv = any_cast<Type const&>(std::move(a));
|
|
||||||
assert(&cv == &v);
|
|
||||||
}
|
|
||||||
// Check getting a type by reference from a const rvalue any.
|
// Check getting a type by reference from a const rvalue any.
|
||||||
{
|
{
|
||||||
Type const& v = any_cast<Type const&>(std::move(ca));
|
Type const& v = any_cast<Type const&>(std::move(ca));
|
||||||
@@ -229,8 +226,8 @@ void test_cast_to_value() {
|
|||||||
|
|
||||||
assert(Type::count == 2);
|
assert(Type::count == 2);
|
||||||
assert(Type::copied == 1);
|
assert(Type::copied == 1);
|
||||||
assert(Type::const_copied == 1);
|
assert(Type::const_copied == 0);
|
||||||
assert(Type::non_const_copied == 0);
|
assert(Type::non_const_copied == 1);
|
||||||
assert(Type::moved == 0);
|
assert(Type::moved == 0);
|
||||||
assert(t.value == 42);
|
assert(t.value == 42);
|
||||||
}
|
}
|
||||||
@@ -272,12 +269,13 @@ void test_cast_to_value() {
|
|||||||
Type t = any_cast<Type const>(static_cast<any &&>(a));
|
Type t = any_cast<Type const>(static_cast<any &&>(a));
|
||||||
|
|
||||||
assert(Type::count == 2);
|
assert(Type::count == 2);
|
||||||
assert(Type::copied == 1);
|
assert(Type::copied == 0);
|
||||||
assert(Type::const_copied == 1);
|
assert(Type::const_copied == 0);
|
||||||
assert(Type::non_const_copied == 0);
|
assert(Type::non_const_copied == 0);
|
||||||
assert(Type::moved == 0);
|
assert(Type::moved == 1);
|
||||||
assert(t.value == 42);
|
assert(t.value == 42);
|
||||||
assert(any_cast<Type&>(a).value == 42);
|
assert(any_cast<Type&>(a).value == 0);
|
||||||
|
any_cast<Type&>(a).value = 42; // reset the value
|
||||||
}
|
}
|
||||||
assert(Type::count == 1);
|
assert(Type::count == 1);
|
||||||
Type::reset();
|
Type::reset();
|
||||||
@@ -303,86 +301,6 @@ void test_cast_to_value() {
|
|||||||
assert(Type::count == 0);
|
assert(Type::count == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_cast_to_value_deleted_move()
|
|
||||||
{
|
|
||||||
using Type = deleted_move;
|
|
||||||
{
|
|
||||||
std::any a(deleted_move(42));
|
|
||||||
assert(Type::count == 1);
|
|
||||||
assert(Type::copied == 1);
|
|
||||||
assert(Type::moved == 0);
|
|
||||||
|
|
||||||
Type const& t = any_cast<Type>(a);
|
|
||||||
assert(Type::count == 2);
|
|
||||||
assert(Type::copied == 2);
|
|
||||||
assert(Type::moved == 0);
|
|
||||||
assertContains<Type>(a, 42);
|
|
||||||
}
|
|
||||||
assert(Type::count == 0);
|
|
||||||
Type::reset();
|
|
||||||
{
|
|
||||||
std::any a(deleted_move(42));
|
|
||||||
std::any const& ca = a;
|
|
||||||
assert(Type::count == 1);
|
|
||||||
assert(Type::copied == 1);
|
|
||||||
assert(Type::moved == 0);
|
|
||||||
|
|
||||||
Type const& t = any_cast<Type>(ca);
|
|
||||||
assert(Type::count == 2);
|
|
||||||
assert(Type::copied == 2);
|
|
||||||
assert(Type::moved == 0);
|
|
||||||
assertContains<Type>(a, 42);
|
|
||||||
}
|
|
||||||
assert(Type::count == 0);
|
|
||||||
Type::reset();
|
|
||||||
{
|
|
||||||
std::any a(deleted_move(42));
|
|
||||||
assert(Type::count == 1);
|
|
||||||
assert(Type::copied == 1);
|
|
||||||
assert(Type::moved == 0);
|
|
||||||
|
|
||||||
Type&& t = any_cast<Type>(std::move(a));
|
|
||||||
assert(Type::count == 2);
|
|
||||||
assert(Type::copied == 2);
|
|
||||||
assert(Type::moved == 0);
|
|
||||||
assertContains<Type>(a, 42);
|
|
||||||
}
|
|
||||||
assert(Type::count == 0);
|
|
||||||
Type::reset();
|
|
||||||
{
|
|
||||||
std::any a(deleted_move(42));
|
|
||||||
std::any const& ca = a;
|
|
||||||
assert(Type::count == 1);
|
|
||||||
assert(Type::copied == 1);
|
|
||||||
assert(Type::moved == 0);
|
|
||||||
|
|
||||||
Type&& t = any_cast<Type>(std::move(ca));
|
|
||||||
assert(Type::count == 2);
|
|
||||||
assert(Type::copied == 2);
|
|
||||||
assert(Type::moved == 0);
|
|
||||||
assertContains<Type>(a, 42);
|
|
||||||
}
|
|
||||||
assert(Type::count == 0);
|
|
||||||
Type::reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Even though you can't get a non-copyable class into std::any
|
|
||||||
// the standard requires that these overloads compile and function.
|
|
||||||
void test_non_copyable_ref() {
|
|
||||||
struct no_copy
|
|
||||||
{
|
|
||||||
no_copy() {}
|
|
||||||
no_copy(no_copy &&) {}
|
|
||||||
private:
|
|
||||||
no_copy(no_copy const &);
|
|
||||||
};
|
|
||||||
|
|
||||||
any a;
|
|
||||||
checkThrows<no_copy &, no_copy const&>(a);
|
|
||||||
checkThrows<no_copy const&>(a);
|
|
||||||
assertEmpty(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
test_cast_is_not_noexcept();
|
test_cast_is_not_noexcept();
|
||||||
test_cast_return_type();
|
test_cast_return_type();
|
||||||
@@ -391,6 +309,4 @@ int main() {
|
|||||||
test_cast_to_reference<large>();
|
test_cast_to_reference<large>();
|
||||||
test_cast_to_value<small>();
|
test_cast_to_value<small>();
|
||||||
test_cast_to_value<large>();
|
test_cast_to_value<large>();
|
||||||
test_cast_to_value_deleted_move();
|
|
||||||
test_non_copyable_ref();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,11 +28,19 @@ int main()
|
|||||||
|
|
||||||
any a;
|
any a;
|
||||||
|
|
||||||
// expected-error@any:* 2 {{binding value of type '_Tp' (aka 'const TestType') to reference to type 'TestType' drops 'const' qualifier}}
|
// expected-error@any:* {{binding value of type 'const TestType' to reference to type 'TestType' drops 'const' qualifier}}
|
||||||
|
// expected-error@any:* {{static_assert failed "ValueType is required to be a reference or a CopyConstructible type"}}
|
||||||
any_cast<TestType &>(static_cast<any const&>(a)); // expected-note {{requested here}}
|
any_cast<TestType &>(static_cast<any const&>(a)); // expected-note {{requested here}}
|
||||||
|
|
||||||
|
// expected-error@any:* {{cannot cast from lvalue of type 'const TestType' to rvalue reference type 'TestType &&'; types are not compatible}}
|
||||||
|
// expected-error@any:* {{static_assert failed "ValueType is required to be a reference or a CopyConstructible type"}}
|
||||||
any_cast<TestType &&>(static_cast<any const&>(a)); // expected-note {{requested here}}
|
any_cast<TestType &&>(static_cast<any const&>(a)); // expected-note {{requested here}}
|
||||||
|
|
||||||
// expected-error@any:* 2 {{binding value of type '_Tp' (aka 'const TestType2') to reference to type 'TestType2' drops 'const' qualifier}}
|
// expected-error@any:* {{binding value of type 'const TestType2' to reference to type 'TestType2' drops 'const' qualifier}}
|
||||||
|
// expected-error@any:* {{static_assert failed "ValueType is required to be a reference or a CopyConstructible type"}}
|
||||||
any_cast<TestType2 &>(static_cast<any const&&>(a)); // expected-note {{requested here}}
|
any_cast<TestType2 &>(static_cast<any const&&>(a)); // expected-note {{requested here}}
|
||||||
|
|
||||||
|
// expected-error@any:* {{cannot cast from lvalue of type 'const TestType2' to rvalue reference type 'TestType2 &&'; types are not compatible}}
|
||||||
|
// expected-error@any:* {{static_assert failed "ValueType is required to be a reference or a CopyConstructible type"}}
|
||||||
any_cast<TestType2 &&>(static_cast<any const&&>(a)); // expected-note {{requested here}}
|
any_cast<TestType2 &&>(static_cast<any const&&>(a)); // expected-note {{requested here}}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,15 +31,28 @@ struct no_copy
|
|||||||
{
|
{
|
||||||
no_copy() {}
|
no_copy() {}
|
||||||
no_copy(no_copy &&) {}
|
no_copy(no_copy &&) {}
|
||||||
private:
|
no_copy(no_copy const &) = delete;
|
||||||
no_copy(no_copy const &);
|
};
|
||||||
|
|
||||||
|
struct no_move {
|
||||||
|
no_move() {}
|
||||||
|
no_move(no_move&&) = delete;
|
||||||
|
no_move(no_move const&) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
any a;
|
any a;
|
||||||
|
// expected-error@any:* {{static_assert failed "ValueType is required to be a reference or a CopyConstructible type"}}
|
||||||
|
// expected-error@any:* {{static_cast from 'no_copy' to 'no_copy' uses deleted function}}
|
||||||
any_cast<no_copy>(static_cast<any&>(a)); // expected-note {{requested here}}
|
any_cast<no_copy>(static_cast<any&>(a)); // expected-note {{requested here}}
|
||||||
|
|
||||||
|
// expected-error@any:* {{static_assert failed "ValueType is required to be a reference or a CopyConstructible type"}}
|
||||||
|
// expected-error@any:* {{static_cast from 'const no_copy' to 'no_copy' uses deleted function}}
|
||||||
any_cast<no_copy>(static_cast<any const&>(a)); // expected-note {{requested here}}
|
any_cast<no_copy>(static_cast<any const&>(a)); // expected-note {{requested here}}
|
||||||
any_cast<no_copy>(static_cast<any &&>(a)); // expected-note {{requested here}}
|
|
||||||
// expected-error@any:* 3 {{static_assert failed "_ValueType is required to be a reference or a CopyConstructible type."}}
|
any_cast<no_copy>(static_cast<any &&>(a)); // OK
|
||||||
// expected-error@any:* 2 {{calling a private constructor of class 'no_copy'}}
|
|
||||||
|
// expected-error@any:* {{static_assert failed "ValueType is required to be an rvalue reference or a CopyConstructible type"}}
|
||||||
|
// expected-error@any:* {{static_cast from 'typename remove_reference<no_move &>::type' (aka 'no_move') to 'no_move' uses deleted function}}
|
||||||
|
any_cast<no_move>(static_cast<any &&>(a));
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||||
|
// Source Licenses. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++98, c++03, c++11, c++14
|
||||||
|
|
||||||
|
// <any>
|
||||||
|
|
||||||
|
// template <class ValueType>
|
||||||
|
// ValueType any_cast(any &&);
|
||||||
|
|
||||||
|
// Try and use the rvalue any_cast to cast to an lvalue reference
|
||||||
|
|
||||||
|
#include <any>
|
||||||
|
|
||||||
|
struct TestType {};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
using std::any;
|
||||||
|
using std::any_cast;
|
||||||
|
|
||||||
|
any a;
|
||||||
|
// expected-error@any:* {{static_assert failed "ValueType is required to be an rvalue reference or a CopyConstructible type"}}
|
||||||
|
// expected-error@any:* {{non-const lvalue reference to type 'TestType' cannot bind to a temporary}}
|
||||||
|
any_cast<TestType &>(std::move(a)); // expected-note {{requested here}}
|
||||||
|
|
||||||
|
// expected-error@any:* {{static_assert failed "ValueType is required to be an rvalue reference or a CopyConstructible type"}}
|
||||||
|
// expected-error@any:* {{non-const lvalue reference to type 'int' cannot bind to a temporary}}
|
||||||
|
any_cast<int&>(42);
|
||||||
|
}
|
||||||
@@ -99,7 +99,7 @@ static_assert(IsSmallObject<SmallThrows>::value, "");
|
|||||||
struct LargeThrows {
|
struct LargeThrows {
|
||||||
LargeThrows(int) { throw 42; }
|
LargeThrows(int) { throw 42; }
|
||||||
LargeThrows(std::initializer_list<int>, int) { throw 42; }
|
LargeThrows(std::initializer_list<int>, int) { throw 42; }
|
||||||
int data[10];
|
int data[sizeof(std::any)];
|
||||||
};
|
};
|
||||||
static_assert(!IsSmallObject<LargeThrows>::value, "");
|
static_assert(!IsSmallObject<LargeThrows>::value, "");
|
||||||
|
|
||||||
|
|||||||
@@ -246,67 +246,6 @@ typedef large_type<> large;
|
|||||||
typedef large_type<1> large1;
|
typedef large_type<1> large1;
|
||||||
typedef large_type<2> large2;
|
typedef large_type<2> large2;
|
||||||
|
|
||||||
|
|
||||||
struct deleted_move
|
|
||||||
{
|
|
||||||
static int count;
|
|
||||||
static int copied;
|
|
||||||
static int moved;
|
|
||||||
static int const_copied;
|
|
||||||
static int non_const_copied;
|
|
||||||
|
|
||||||
static void reset() {
|
|
||||||
deleted_move::copied = 0;
|
|
||||||
deleted_move::moved = 0;
|
|
||||||
deleted_move::const_copied = 0;
|
|
||||||
deleted_move::non_const_copied = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int value;
|
|
||||||
|
|
||||||
explicit deleted_move(int val = 0) : value(val) {
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
explicit deleted_move(int, int val, int) : value(val) {
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
deleted_move(std::initializer_list<int> il) : value(*il.begin()) {
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
|
|
||||||
deleted_move(deleted_move const & other) noexcept {
|
|
||||||
value = other.value;
|
|
||||||
++count;
|
|
||||||
++copied;
|
|
||||||
++const_copied;
|
|
||||||
}
|
|
||||||
|
|
||||||
deleted_move(deleted_move& other) noexcept {
|
|
||||||
value = other.value;
|
|
||||||
++count;
|
|
||||||
++copied;
|
|
||||||
++non_const_copied;
|
|
||||||
}
|
|
||||||
|
|
||||||
deleted_move(deleted_move && other) = delete;
|
|
||||||
|
|
||||||
~deleted_move() {
|
|
||||||
value = -1;
|
|
||||||
--count;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
deleted_move& operator=(deleted_move const&) = delete;
|
|
||||||
deleted_move& operator=(deleted_move&&) = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
int deleted_move::count = 0;
|
|
||||||
int deleted_move::copied = 0;
|
|
||||||
int deleted_move::moved = 0;
|
|
||||||
int deleted_move::const_copied = 0;
|
|
||||||
int deleted_move::non_const_copied = 0;
|
|
||||||
|
|
||||||
|
|
||||||
// The exception type thrown by 'small_throws_on_copy', 'large_throws_on_copy'
|
// The exception type thrown by 'small_throws_on_copy', 'large_throws_on_copy'
|
||||||
// and 'throws_on_move'.
|
// and 'throws_on_move'.
|
||||||
struct my_any_exception {};
|
struct my_any_exception {};
|
||||||
|
|||||||
@@ -124,9 +124,11 @@
|
|||||||
#if defined(_LIBCPP_VERSION)
|
#if defined(_LIBCPP_VERSION)
|
||||||
#define LIBCPP_ASSERT(...) assert(__VA_ARGS__)
|
#define LIBCPP_ASSERT(...) assert(__VA_ARGS__)
|
||||||
#define LIBCPP_STATIC_ASSERT(...) static_assert(__VA_ARGS__)
|
#define LIBCPP_STATIC_ASSERT(...) static_assert(__VA_ARGS__)
|
||||||
|
#define LIBCPP_ONLY(...) __VA_ARGS__
|
||||||
#else
|
#else
|
||||||
#define LIBCPP_ASSERT(...) ((void)0)
|
#define LIBCPP_ASSERT(...) ((void)0)
|
||||||
#define LIBCPP_STATIC_ASSERT(...) ((void)0)
|
#define LIBCPP_STATIC_ASSERT(...) ((void)0)
|
||||||
|
#define LIBCPP_ONLY(...) ((void)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ASSERT_NOEXCEPT(...) \
|
#define ASSERT_NOEXCEPT(...) \
|
||||||
|
|||||||
Reference in New Issue
Block a user