summaryrefslogtreecommitdiffstats
path: root/libcxx/test/std/utilities/any/any.class
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2016-10-07 21:27:45 +0000
committerEric Fiselier <eric@efcs.ca>2016-10-07 21:27:45 +0000
commitb18fd9654f67876d366dc7d5577a5c91287d8353 (patch)
tree19539be19870ba70f2fe9c75d55ef4aaa9e28f4d /libcxx/test/std/utilities/any/any.class
parentc50b1a263bcb7edd1d6f2e08cb47a6dcc0562eb7 (diff)
downloadbcm5719-llvm-b18fd9654f67876d366dc7d5577a5c91287d8353.tar.gz
bcm5719-llvm-b18fd9654f67876d366dc7d5577a5c91287d8353.zip
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. llvm-svn: 283606
Diffstat (limited to 'libcxx/test/std/utilities/any/any.class')
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.assign/move.pass.cpp16
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.assign/value.pass.cpp14
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.cons/copy.pass.cpp2
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.cons/in_place_type.pass.cpp46
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.cons/move.pass.cpp6
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.cons/value.pass.cpp30
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp11
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.modifiers/swap.pass.cpp32
8 files changed, 111 insertions, 46 deletions
diff --git a/libcxx/test/std/utilities/any/any.class/any.assign/move.pass.cpp b/libcxx/test/std/utilities/any/any.class/any.assign/move.pass.cpp
index bac3edb7cdb..2063e4f1e9f 100644
--- a/libcxx/test/std/utilities/any/any.class/any.assign/move.pass.cpp
+++ b/libcxx/test/std/utilities/any/any.class/any.assign/move.pass.cpp
@@ -40,10 +40,13 @@ void test_move_assign() {
a = std::move(a2);
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);
- assertEmpty<RHS>(a2);
+ if (a2.has_value())
+ assertContains<RHS>(a2, 0);
+ LIBCPP_ASSERT(!a2.has_value());
}
assert(LHS::count == 0);
assert(RHS::count == 0);
@@ -54,16 +57,19 @@ void test_move_assign_empty() {
assert(LHS::count == 0);
{
any a;
- any a2((LHS(1)));
+ any a2((LHS(1)));
assert(LHS::count == 1);
a = std::move(a2);
- assert(LHS::count == 1);
+ assert(LHS::count == 1 + a2.has_value());
+ LIBCPP_ASSERT(LHS::count == 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);
{
diff --git a/libcxx/test/std/utilities/any/any.class/any.assign/value.pass.cpp b/libcxx/test/std/utilities/any/any.class/any.assign/value.pass.cpp
index d844fcfaa7c..cb8dd4ca964 100644
--- a/libcxx/test/std/utilities/any/any.class/any.assign/value.pass.cpp
+++ b/libcxx/test/std/utilities/any/any.class/any.assign/value.pass.cpp
@@ -11,7 +11,8 @@
// <any>
-// any& operator=(any const &);
+// template <class ValueType>
+// any& operator=(ValueType&&);
// Test value copy and move assignment.
@@ -65,10 +66,12 @@ void test_assign_value() {
assert(RHS::moved >= 1);
assert(RHS::copied == 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);
- assertEmpty<RHS>(rhs);
+ if (rhs.has_value())
+ assertContains<RHS>(rhs, 0);
}
assert(LHS::count == 0);
assert(RHS::count == 0);
@@ -114,7 +117,7 @@ void test_assign_value_empty() {
template <class Tp, bool Move = false>
void test_assign_throws() {
#if !defined(TEST_HAS_NO_EXCEPTIONS)
- auto try_throw=
+ auto try_throw =
[](any& lhs, auto&& rhs) {
try {
Move ? lhs = std::move(rhs)
@@ -188,6 +191,7 @@ void test_sfinae_constraints() {
NoCopy(NoCopy&&) = default;
};
static_assert(!std::is_assignable<std::any, NoCopy>::value, "");
+ static_assert(!std::is_assignable<std::any, NoCopy&>::value, "");
}
}
@@ -202,4 +206,4 @@ int main() {
test_assign_throws<large_throws_on_copy>();
test_assign_throws<throws_on_move, /* Move = */ true>();
test_sfinae_constraints();
-} \ No newline at end of file
+}
diff --git a/libcxx/test/std/utilities/any/any.class/any.cons/copy.pass.cpp b/libcxx/test/std/utilities/any/any.class/any.cons/copy.pass.cpp
index 03870caa531..021c9e45284 100644
--- a/libcxx/test/std/utilities/any/any.class/any.cons/copy.pass.cpp
+++ b/libcxx/test/std/utilities/any/any.class/any.cons/copy.pass.cpp
@@ -71,7 +71,7 @@ void test_copy()
assert(Type::copied == 1);
assert(Type::count == 2);
assertContains<Type>(a, 42);
- assertContains<Type>(a, 42);
+ assertContains<Type>(a2, 42);
// Modify a and check that a2 is unchanged
modifyValue<Type>(a, -1);
diff --git a/libcxx/test/std/utilities/any/any.class/any.cons/in_place_type.pass.cpp b/libcxx/test/std/utilities/any/any.class/any.cons/in_place_type.pass.cpp
index 949c105f988..98b8c870162 100644
--- a/libcxx/test/std/utilities/any/any.class/any.cons/in_place_type.pass.cpp
+++ b/libcxx/test/std/utilities/any/any.class/any.cons/in_place_type.pass.cpp
@@ -49,6 +49,16 @@ void test_in_place_type() {
}
assert(Type::count == 0);
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);
@@ -90,11 +100,38 @@ void test_in_place_type_tracked() {
}
{
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);
}
}
+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() {
{
// 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) {}
};
using Tag = std::in_place_type_t<NoCopy>;
+ using RefTag = std::in_place_type_t<NoCopy&>;
using IL = std::initializer_list<int>;
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, 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_tracked<small_tracked_t>();
test_in_place_type_tracked<large_tracked_t>();
+ test_in_place_type_decayed();
test_ctor_sfinae();
test_constructor_explicit();
-} \ No newline at end of file
+}
diff --git a/libcxx/test/std/utilities/any/any.class/any.cons/move.pass.cpp b/libcxx/test/std/utilities/any/any.class/any.cons/move.pass.cpp
index 9a83e66ab8a..ebd49ccdcbd 100644
--- a/libcxx/test/std/utilities/any/any.class/any.cons/move.pass.cpp
+++ b/libcxx/test/std/utilities/any/any.class/any.cons/move.pass.cpp
@@ -77,11 +77,13 @@ void test_move() {
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::count == 1);
+ assert(Type::count == 1 + a.has_value());
assertEmpty(a); // Moves are always destructive.
assertContains<Type>(a2, 42);
+ if (a.has_value())
+ assertContains<Type>(a, 0);
}
assert(Type::count == 0);
}
diff --git a/libcxx/test/std/utilities/any/any.class/any.cons/value.pass.cpp b/libcxx/test/std/utilities/any/any.class/any.cons/value.pass.cpp
index ba5419b1245..e39f139dadc 100644
--- a/libcxx/test/std/utilities/any/any.class/any.cons/value.pass.cpp
+++ b/libcxx/test/std/utilities/any/any.class/any.cons/value.pass.cpp
@@ -30,7 +30,6 @@
using std::any;
using std::any_cast;
-
template <class Type>
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.
void test_sfinae_constraints() {
using Tag = std::in_place_type_t<int>;
@@ -169,6 +141,7 @@ void test_sfinae_constraints() {
NoCopy(int) {}
};
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, "");
}
}
@@ -179,6 +152,5 @@ int main() {
test_copy_value_throws<small_throws_on_copy>();
test_copy_value_throws<large_throws_on_copy>();
test_move_value_throws();
- test_non_moveable_type();
test_sfinae_constraints();
} \ No newline at end of file
diff --git a/libcxx/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp b/libcxx/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp
index fa8b093d304..2afb41e02ba 100644
--- a/libcxx/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp
+++ b/libcxx/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp
@@ -129,7 +129,7 @@ static_assert(IsSmallObject<SmallThrows>::value, "");
struct LargeThrows {
LargeThrows(int) { throw 42; }
LargeThrows(std::initializer_list<int>, int) { throw 42; }
- int data[10];
+ int data[sizeof(std::any)];
};
static_assert(!IsSmallObject<LargeThrows>::value, "");
@@ -236,6 +236,13 @@ void test_emplace_sfinae_constraints() {
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>(), "");
+ static_assert(!has_emplace<NoCopy&&>(), "");
+ static_assert(!has_emplace<NoCopy&&, int>(), "");
+ static_assert(!has_emplace_init_list<NoCopy&&, int, int, int>(), "");
+
}
}
@@ -252,4 +259,4 @@ int main() {
test_emplace_throws<SmallThrows>();
test_emplace_throws<LargeThrows>();
#endif
-} \ No newline at end of file
+}
diff --git a/libcxx/test/std/utilities/any/any.class/any.modifiers/swap.pass.cpp b/libcxx/test/std/utilities/any/any.class/any.modifiers/swap.pass.cpp
index 013982478ee..1fef43fc585 100644
--- a/libcxx/test/std/utilities/any/any.class/any.modifiers/swap.pass.cpp
+++ b/libcxx/test/std/utilities/any/any.class/any.modifiers/swap.pass.cpp
@@ -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()
{
test_noexcept();
@@ -98,4 +129,5 @@ int main()
test_swap<large1, large2>();
test_swap<small, large>();
test_swap<large, small>();
+ test_self_swap();
}
OpenPOWER on IntegriCloud