summaryrefslogtreecommitdiffstats
path: root/libcxx/test
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/test')
-rw-r--r--libcxx/test/libcxx/experimental/any/small_type.pass.cpp2
-rw-r--r--libcxx/test/libcxx/utilities/any/size_and_alignment.pass.cpp23
-rw-r--r--libcxx/test/libcxx/utilities/any/small_type.pass.cpp114
-rw-r--r--libcxx/test/libcxx/utilities/any/version.pass.cpp20
-rw-r--r--libcxx/test/std/experimental/any/any.class/any.assign/copy.pass.cpp2
-rw-r--r--libcxx/test/std/experimental/any/any.class/any.assign/move.pass.cpp2
-rw-r--r--libcxx/test/std/experimental/any/any.class/any.assign/value.pass.cpp2
-rw-r--r--libcxx/test/std/experimental/any/any.class/any.cons/copy.pass.cpp2
-rw-r--r--libcxx/test/std/experimental/any/any.class/any.cons/default.pass.cpp2
-rw-r--r--libcxx/test/std/experimental/any/any.class/any.cons/move.pass.cpp2
-rw-r--r--libcxx/test/std/experimental/any/any.class/any.cons/value.pass.cpp2
-rw-r--r--libcxx/test/std/experimental/any/any.class/any.modifiers/clear.pass.cpp2
-rw-r--r--libcxx/test/std/experimental/any/any.class/any.modifiers/swap.pass.cpp2
-rw-r--r--libcxx/test/std/experimental/any/any.class/any.observers/empty.pass.cpp2
-rw-r--r--libcxx/test/std/experimental/any/any.class/any.observers/type.pass.cpp2
-rw-r--r--libcxx/test/std/experimental/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp2
-rw-r--r--libcxx/test/std/experimental/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp2
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.assign/copy.pass.cpp197
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.assign/move.pass.cpp102
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.assign/value.pass.cpp205
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.cons/copy.pass.cpp100
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.cons/default.pass.cpp47
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.cons/in_place_type.pass.cpp152
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.cons/move.pass.cpp102
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.cons/value.pass.cpp184
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp255
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.modifiers/reset.pass.cpp63
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.modifiers/swap.pass.cpp101
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.observers/has_value.pass.cpp64
-rw-r--r--libcxx/test/std/utilities/any/any.class/any.observers/type.pass.cpp41
-rw-r--r--libcxx/test/std/utilities/any/any.class/not_literal_type.pass.cpp21
-rw-r--r--libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp158
-rw-r--r--libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp396
-rw-r--r--libcxx/test/std/utilities/any/any.nonmembers/any.cast/const_correctness.fail.cpp38
-rw-r--r--libcxx/test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.fail.cpp45
-rw-r--r--libcxx/test/std/utilities/any/any.nonmembers/any.cast/reference_types.fail.cpp37
-rw-r--r--libcxx/test/std/utilities/any/any.nonmembers/make_any.pass.cpp140
-rw-r--r--libcxx/test/std/utilities/any/any.nonmembers/swap.pass.cpp40
-rw-r--r--libcxx/test/support/any_helpers.h215
-rw-r--r--libcxx/test/support/experimental_any_helpers.h326
-rw-r--r--libcxx/test/support/test_macros.h7
41 files changed, 3178 insertions, 43 deletions
diff --git a/libcxx/test/libcxx/experimental/any/small_type.pass.cpp b/libcxx/test/libcxx/experimental/any/small_type.pass.cpp
index e6595d4a4ab..96754126c99 100644
--- a/libcxx/test/libcxx/experimental/any/small_type.pass.cpp
+++ b/libcxx/test/libcxx/experimental/any/small_type.pass.cpp
@@ -14,7 +14,7 @@
// Check that the size and alignment of any are what we expect.
#include <experimental/any>
-#include "any_helpers.h"
+#include "experimental_any_helpers.h"
constexpr std::size_t BufferSize = (sizeof(void*) * 3);
constexpr std::size_t BufferAlignment = alignof(void*);
diff --git a/libcxx/test/libcxx/utilities/any/size_and_alignment.pass.cpp b/libcxx/test/libcxx/utilities/any/size_and_alignment.pass.cpp
new file mode 100644
index 00000000000..55b6b38d0f0
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/any/size_and_alignment.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <any>
+
+// Check that the size and alignment of any are what we expect.
+
+#include <any>
+
+int main()
+{
+ using std::any;
+ static_assert(sizeof(any) == sizeof(void*)*4, "");
+ static_assert(alignof(any) == alignof(void*), "");
+}
diff --git a/libcxx/test/libcxx/utilities/any/small_type.pass.cpp b/libcxx/test/libcxx/utilities/any/small_type.pass.cpp
new file mode 100644
index 00000000000..34d57c70573
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/any/small_type.pass.cpp
@@ -0,0 +1,114 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <any>
+
+// Check that the size and alignment of any are what we expect.
+
+#include <any>
+#include "any_helpers.h"
+
+constexpr std::size_t BufferSize = (sizeof(void*) * 3);
+constexpr std::size_t BufferAlignment = alignof(void*);
+// Clang doesn't like "alignof(BufferAlignment * 2)" due to PR13986.
+// So we create "DoubleBufferAlignment" instead.
+constexpr std::size_t DoubleBufferAlignment = BufferAlignment * 2;
+
+class SmallThrowsDtor
+{
+public:
+ SmallThrowsDtor() {}
+ SmallThrowsDtor(SmallThrowsDtor const &) noexcept {}
+ SmallThrowsDtor(SmallThrowsDtor &&) noexcept {}
+ ~SmallThrowsDtor() noexcept(false) {}
+};
+
+
+struct alignas(1) MaxSizeType {
+ char buff[BufferSize];
+};
+
+struct alignas(BufferAlignment) MaxAlignType {
+};
+
+struct alignas(BufferAlignment) MaxSizeAndAlignType {
+ char buff[BufferSize];
+};
+
+
+struct alignas(1) OverSizeType {
+ char buff[BufferSize + 1];
+};
+
+struct alignas(DoubleBufferAlignment) OverAlignedType {
+};
+
+struct alignas(DoubleBufferAlignment) OverSizeAndAlignedType {
+ char buff[BufferSize + 1];
+};
+
+int main()
+{
+ using std::any;
+ using std::__any_imp::_IsSmallObject;
+ static_assert(_IsSmallObject<small>::value, "");
+ static_assert(_IsSmallObject<void*>::value, "");
+ static_assert(!_IsSmallObject<SmallThrowsDtor>::value, "");
+ static_assert(!_IsSmallObject<large>::value, "");
+ {
+ // Check a type that meets the size requirement *exactly* and has
+ // a lesser alignment requirement is considered small.
+ typedef MaxSizeType T;
+ static_assert(sizeof(T) == BufferSize, "");
+ static_assert(alignof(T) < BufferAlignment, "");
+ static_assert(_IsSmallObject<T>::value, "");
+ }
+ {
+ // Check a type that meets the alignment requirement *exactly* and has
+ // a lesser size is considered small.
+ typedef MaxAlignType T;
+ static_assert(sizeof(T) < BufferSize, "");
+ static_assert(alignof(T) == BufferAlignment, "");
+ static_assert(_IsSmallObject<T>::value, "");
+ }
+ {
+ // Check a type that meets the size and alignment requirements *exactly*
+ // is considered small.
+ typedef MaxSizeAndAlignType T;
+ static_assert(sizeof(T) == BufferSize, "");
+ static_assert(alignof(T) == BufferAlignment, "");
+ static_assert(_IsSmallObject<T>::value, "");
+ }
+ {
+ // Check a type that meets the alignment requirements but is over-sized
+ // is not considered small.
+ typedef OverSizeType T;
+ static_assert(sizeof(T) > BufferSize, "");
+ static_assert(alignof(T) < BufferAlignment, "");
+ static_assert(!_IsSmallObject<T>::value, "");
+ }
+ {
+ // Check a type that meets the size requirements but is over-aligned
+ // is not considered small.
+ typedef OverAlignedType T;
+ static_assert(sizeof(T) < BufferSize, "");
+ static_assert(alignof(T) > BufferAlignment, "");
+ static_assert(!_IsSmallObject<T>::value, "");
+ }
+ {
+ // Check a type that exceeds both the size an alignment requirements
+ // is not considered small.
+ typedef OverSizeAndAlignedType T;
+ static_assert(sizeof(T) > BufferSize, "");
+ static_assert(alignof(T) > BufferAlignment, "");
+ static_assert(!_IsSmallObject<T>::value, "");
+ }
+}
diff --git a/libcxx/test/libcxx/utilities/any/version.pass.cpp b/libcxx/test/libcxx/utilities/any/version.pass.cpp
new file mode 100644
index 00000000000..5edee710d58
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/any/version.pass.cpp
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <any>
+
+#include <any>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main()
+{
+}
diff --git a/libcxx/test/std/experimental/any/any.class/any.assign/copy.pass.cpp b/libcxx/test/std/experimental/any/any.class/any.assign/copy.pass.cpp
index 8ee575c408f..17b01fe630b 100644
--- a/libcxx/test/std/experimental/any/any.class/any.assign/copy.pass.cpp
+++ b/libcxx/test/std/experimental/any/any.class/any.assign/copy.pass.cpp
@@ -18,7 +18,7 @@
#include <experimental/any>
#include <cassert>
-#include "any_helpers.h"
+#include "experimental_any_helpers.h"
#include "count_new.hpp"
#include "test_macros.h"
diff --git a/libcxx/test/std/experimental/any/any.class/any.assign/move.pass.cpp b/libcxx/test/std/experimental/any/any.class/any.assign/move.pass.cpp
index 0a2d71967cd..49508febd94 100644
--- a/libcxx/test/std/experimental/any/any.class/any.assign/move.pass.cpp
+++ b/libcxx/test/std/experimental/any/any.class/any.assign/move.pass.cpp
@@ -18,7 +18,7 @@
#include <experimental/any>
#include <cassert>
-#include "any_helpers.h"
+#include "experimental_any_helpers.h"
#include "test_macros.h"
using std::experimental::any;
diff --git a/libcxx/test/std/experimental/any/any.class/any.assign/value.pass.cpp b/libcxx/test/std/experimental/any/any.class/any.assign/value.pass.cpp
index 8262990523c..b42a4ba2b05 100644
--- a/libcxx/test/std/experimental/any/any.class/any.assign/value.pass.cpp
+++ b/libcxx/test/std/experimental/any/any.class/any.assign/value.pass.cpp
@@ -18,7 +18,7 @@
#include <experimental/any>
#include <cassert>
-#include "any_helpers.h"
+#include "experimental_any_helpers.h"
#include "count_new.hpp"
#include "test_macros.h"
diff --git a/libcxx/test/std/experimental/any/any.class/any.cons/copy.pass.cpp b/libcxx/test/std/experimental/any/any.class/any.cons/copy.pass.cpp
index 3d0b34b2740..69341ca6b80 100644
--- a/libcxx/test/std/experimental/any/any.class/any.cons/copy.pass.cpp
+++ b/libcxx/test/std/experimental/any/any.class/any.cons/copy.pass.cpp
@@ -16,7 +16,7 @@
#include <experimental/any>
#include <cassert>
-#include "any_helpers.h"
+#include "experimental_any_helpers.h"
#include "count_new.hpp"
#include "test_macros.h"
diff --git a/libcxx/test/std/experimental/any/any.class/any.cons/default.pass.cpp b/libcxx/test/std/experimental/any/any.class/any.cons/default.pass.cpp
index b52c83fc388..3839e3afc81 100644
--- a/libcxx/test/std/experimental/any/any.class/any.cons/default.pass.cpp
+++ b/libcxx/test/std/experimental/any/any.class/any.cons/default.pass.cpp
@@ -17,7 +17,7 @@
#include <type_traits>
#include <cassert>
-#include "any_helpers.h"
+#include "experimental_any_helpers.h"
#include "count_new.hpp"
diff --git a/libcxx/test/std/experimental/any/any.class/any.cons/move.pass.cpp b/libcxx/test/std/experimental/any/any.class/any.cons/move.pass.cpp
index 40534cb5506..2a050946afa 100644
--- a/libcxx/test/std/experimental/any/any.class/any.cons/move.pass.cpp
+++ b/libcxx/test/std/experimental/any/any.class/any.cons/move.pass.cpp
@@ -18,7 +18,7 @@
#include <type_traits>
#include <cassert>
-#include "any_helpers.h"
+#include "experimental_any_helpers.h"
#include "count_new.hpp"
#include "test_macros.h"
diff --git a/libcxx/test/std/experimental/any/any.class/any.cons/value.pass.cpp b/libcxx/test/std/experimental/any/any.class/any.cons/value.pass.cpp
index 7bb134efd28..a3ab0edc8b6 100644
--- a/libcxx/test/std/experimental/any/any.class/any.cons/value.pass.cpp
+++ b/libcxx/test/std/experimental/any/any.class/any.cons/value.pass.cpp
@@ -23,7 +23,7 @@
#include <experimental/any>
#include <cassert>
-#include "any_helpers.h"
+#include "experimental_any_helpers.h"
#include "count_new.hpp"
#include "test_macros.h"
diff --git a/libcxx/test/std/experimental/any/any.class/any.modifiers/clear.pass.cpp b/libcxx/test/std/experimental/any/any.class/any.modifiers/clear.pass.cpp
index 603490cef43..781ed73f2b3 100644
--- a/libcxx/test/std/experimental/any/any.class/any.modifiers/clear.pass.cpp
+++ b/libcxx/test/std/experimental/any/any.class/any.modifiers/clear.pass.cpp
@@ -16,7 +16,7 @@
#include <experimental/any>
#include <cassert>
-#include "any_helpers.h"
+#include "experimental_any_helpers.h"
int main()
{
diff --git a/libcxx/test/std/experimental/any/any.class/any.modifiers/swap.pass.cpp b/libcxx/test/std/experimental/any/any.class/any.modifiers/swap.pass.cpp
index 064935167eb..b1d31546896 100644
--- a/libcxx/test/std/experimental/any/any.class/any.modifiers/swap.pass.cpp
+++ b/libcxx/test/std/experimental/any/any.class/any.modifiers/swap.pass.cpp
@@ -18,7 +18,7 @@
#include <experimental/any>
#include <cassert>
-#include "any_helpers.h"
+#include "experimental_any_helpers.h"
using std::experimental::any;
using std::experimental::any_cast;
diff --git a/libcxx/test/std/experimental/any/any.class/any.observers/empty.pass.cpp b/libcxx/test/std/experimental/any/any.class/any.observers/empty.pass.cpp
index 8c681f37017..bdf0d511b81 100644
--- a/libcxx/test/std/experimental/any/any.class/any.observers/empty.pass.cpp
+++ b/libcxx/test/std/experimental/any/any.class/any.observers/empty.pass.cpp
@@ -16,7 +16,7 @@
#include <experimental/any>
#include <cassert>
-#include "any_helpers.h"
+#include "experimental_any_helpers.h"
int main()
{
diff --git a/libcxx/test/std/experimental/any/any.class/any.observers/type.pass.cpp b/libcxx/test/std/experimental/any/any.class/any.observers/type.pass.cpp
index 682b73bc98c..6d004840367 100644
--- a/libcxx/test/std/experimental/any/any.class/any.observers/type.pass.cpp
+++ b/libcxx/test/std/experimental/any/any.class/any.observers/type.pass.cpp
@@ -17,7 +17,7 @@
#include <experimental/any>
#include <cassert>
-#include "any_helpers.h"
+#include "experimental_any_helpers.h"
int main()
{
diff --git a/libcxx/test/std/experimental/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp b/libcxx/test/std/experimental/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp
index 9d9a5cdb472..46ddbe5b05a 100644
--- a/libcxx/test/std/experimental/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp
+++ b/libcxx/test/std/experimental/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp
@@ -21,7 +21,7 @@
#include <type_traits>
#include <cassert>
-#include "any_helpers.h"
+#include "experimental_any_helpers.h"
using std::experimental::any;
using std::experimental::any_cast;
diff --git a/libcxx/test/std/experimental/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp b/libcxx/test/std/experimental/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp
index e97560937fb..7efbafff83c 100644
--- a/libcxx/test/std/experimental/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp
+++ b/libcxx/test/std/experimental/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp
@@ -24,7 +24,7 @@
#include <type_traits>
#include <cassert>
-#include "any_helpers.h"
+#include "experimental_any_helpers.h"
#include "count_new.hpp"
#include "test_macros.h"
diff --git a/libcxx/test/std/utilities/any/any.class/any.assign/copy.pass.cpp b/libcxx/test/std/utilities/any/any.class/any.assign/copy.pass.cpp
new file mode 100644
index 00000000000..fc76a2d8b95
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.class/any.assign/copy.pass.cpp
@@ -0,0 +1,197 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+
+// any& operator=(any const &);
+
+// Test copy assignment
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::any;
+using std::any_cast;
+
+template <class LHS, class RHS>
+void test_copy_assign() {
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+ LHS::reset();
+ RHS::reset();
+ {
+ any lhs(LHS(1));
+ any const rhs(RHS(2));
+
+ assert(LHS::count == 1);
+ assert(RHS::count == 1);
+ assert(RHS::copied == 0);
+
+ lhs = rhs;
+
+ assert(RHS::copied == 1);
+ assert(LHS::count == 0);
+ assert(RHS::count == 2);
+
+ assertContains<RHS>(lhs, 2);
+ assertContains<RHS>(rhs, 2);
+ }
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+}
+
+template <class LHS>
+void test_copy_assign_empty() {
+ assert(LHS::count == 0);
+ LHS::reset();
+ {
+ any lhs;
+ any const rhs(LHS(42));
+
+ assert(LHS::count == 1);
+ assert(LHS::copied == 0);
+
+ lhs = rhs;
+
+ assert(LHS::copied == 1);
+ assert(LHS::count == 2);
+
+ assertContains<LHS>(lhs, 42);
+ assertContains<LHS>(rhs, 42);
+ }
+ assert(LHS::count == 0);
+ LHS::reset();
+ {
+ any lhs(LHS(1));
+ any const rhs;
+
+ assert(LHS::count == 1);
+ assert(LHS::copied == 0);
+
+ lhs = rhs;
+
+ assert(LHS::copied == 0);
+ assert(LHS::count == 0);
+
+ assertEmpty<LHS>(lhs);
+ assertEmpty(rhs);
+ }
+ assert(LHS::count == 0);
+}
+
+void test_copy_assign_self() {
+ // empty
+ {
+ any a;
+ a = a;
+ assertEmpty(a);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ }
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ // small
+ {
+ any a((small(1)));
+ assert(small::count == 1);
+
+ a = a;
+
+ assert(small::count == 1);
+ assertContains<small>(a, 1);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ }
+ assert(small::count == 0);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ // large
+ {
+ any a(large(1));
+ assert(large::count == 1);
+
+ a = a;
+
+ assert(large::count == 1);
+ assertContains<large>(a, 1);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ }
+ assert(large::count == 0);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+}
+
+template <class Tp>
+void test_copy_assign_throws()
+{
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ auto try_throw =
+ [](any& lhs, any const& rhs) {
+ try {
+ lhs = rhs;
+ assert(false);
+ } catch (my_any_exception const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+ };
+ // const lvalue to empty
+ {
+ any lhs;
+ any const rhs((Tp(1)));
+ assert(Tp::count == 1);
+
+ try_throw(lhs, rhs);
+
+ assert(Tp::count == 1);
+ assertEmpty<Tp>(lhs);
+ assertContains<Tp>(rhs);
+ }
+ {
+ any lhs((small(2)));
+ any const rhs((Tp(1)));
+ assert(small::count == 1);
+ assert(Tp::count == 1);
+
+ try_throw(lhs, rhs);
+
+ assert(small::count == 1);
+ assert(Tp::count == 1);
+ assertContains<small>(lhs, 2);
+ assertContains<Tp>(rhs);
+ }
+ {
+ any lhs((large(2)));
+ any const rhs((Tp(1)));
+ assert(large::count == 1);
+ assert(Tp::count == 1);
+
+ try_throw(lhs, rhs);
+
+ assert(large::count == 1);
+ assert(Tp::count == 1);
+ assertContains<large>(lhs, 2);
+ assertContains<Tp>(rhs);
+ }
+#endif
+}
+
+int main() {
+ test_copy_assign<small1, small2>();
+ test_copy_assign<large1, large2>();
+ test_copy_assign<small, large>();
+ test_copy_assign<large, small>();
+ test_copy_assign_empty<small>();
+ test_copy_assign_empty<large>();
+ test_copy_assign_self();
+ test_copy_assign_throws<small_throws_on_copy>();
+ test_copy_assign_throws<large_throws_on_copy>();
+}
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
new file mode 100644
index 00000000000..bac3edb7cdb
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.class/any.assign/move.pass.cpp
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+
+// any& operator=(any &&);
+
+// Test move assignment.
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "test_macros.h"
+
+using std::any;
+using std::any_cast;
+
+template <class LHS, class RHS>
+void test_move_assign() {
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+ {
+ LHS const s1(1);
+ any a(s1);
+ RHS const s2(2);
+ any a2(s2);
+
+ assert(LHS::count == 2);
+ assert(RHS::count == 2);
+
+ a = std::move(a2);
+
+ assert(LHS::count == 1);
+ assert(RHS::count == 2);
+
+ assertContains<RHS>(a, 2);
+ assertEmpty<RHS>(a2);
+ }
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+}
+
+template <class LHS>
+void test_move_assign_empty() {
+ assert(LHS::count == 0);
+ {
+ any a;
+ any a2((LHS(1)));
+
+ assert(LHS::count == 1);
+
+ a = std::move(a2);
+
+ assert(LHS::count == 1);
+
+ assertContains<LHS>(a, 1);
+ assertEmpty<LHS>(a2);
+ }
+ assert(LHS::count == 0);
+ {
+ any a((LHS(1)));
+ any a2;
+
+ assert(LHS::count == 1);
+
+ a = std::move(a2);
+
+ assert(LHS::count == 0);
+
+ assertEmpty<LHS>(a);
+ assertEmpty(a2);
+ }
+ assert(LHS::count == 0);
+}
+
+void test_move_assign_noexcept() {
+ any a1;
+ any a2;
+ static_assert(
+ noexcept(a1 = std::move(a2))
+ , "any & operator=(any &&) must be noexcept"
+ );
+}
+
+int main() {
+ test_move_assign_noexcept();
+ test_move_assign<small1, small2>();
+ test_move_assign<large1, large2>();
+ test_move_assign<small, large>();
+ test_move_assign<large, small>();
+ test_move_assign_empty<small>();
+ test_move_assign_empty<large>();
+}
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
new file mode 100644
index 00000000000..d844fcfaa7c
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.class/any.assign/value.pass.cpp
@@ -0,0 +1,205 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+
+// any& operator=(any const &);
+
+// Test value copy and move assignment.
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::any;
+using std::any_cast;
+
+template <class LHS, class RHS>
+void test_assign_value() {
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+ LHS::reset();
+ RHS::reset();
+ {
+ any lhs(LHS(1));
+ any const rhs(RHS(2));
+
+ assert(LHS::count == 1);
+ assert(RHS::count == 1);
+ assert(RHS::copied == 0);
+
+ lhs = rhs;
+
+ assert(RHS::copied == 1);
+ assert(LHS::count == 0);
+ assert(RHS::count == 2);
+
+ assertContains<RHS>(lhs, 2);
+ assertContains<RHS>(rhs, 2);
+ }
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+ LHS::reset();
+ RHS::reset();
+ {
+ any lhs(LHS(1));
+ any rhs(RHS(2));
+
+ assert(LHS::count == 1);
+ assert(RHS::count == 1);
+ assert(RHS::moved == 1);
+
+ lhs = std::move(rhs);
+
+ assert(RHS::moved >= 1);
+ assert(RHS::copied == 0);
+ assert(LHS::count == 0);
+ assert(RHS::count == 1);
+
+ assertContains<RHS>(lhs, 2);
+ assertEmpty<RHS>(rhs);
+ }
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+}
+
+template <class RHS>
+void test_assign_value_empty() {
+ assert(RHS::count == 0);
+ RHS::reset();
+ {
+ any lhs;
+ RHS rhs(42);
+ assert(RHS::count == 1);
+ assert(RHS::copied == 0);
+
+ lhs = rhs;
+
+ assert(RHS::count == 2);
+ assert(RHS::copied == 1);
+ assert(RHS::moved >= 0);
+ assertContains<RHS>(lhs, 42);
+ }
+ assert(RHS::count == 0);
+ RHS::reset();
+ {
+ any lhs;
+ RHS rhs(42);
+ assert(RHS::count == 1);
+ assert(RHS::moved == 0);
+
+ lhs = std::move(rhs);
+
+ assert(RHS::count == 2);
+ assert(RHS::copied == 0);
+ assert(RHS::moved >= 1);
+ assertContains<RHS>(lhs, 42);
+ }
+ assert(RHS::count == 0);
+ RHS::reset();
+}
+
+
+template <class Tp, bool Move = false>
+void test_assign_throws() {
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ auto try_throw=
+ [](any& lhs, auto&& rhs) {
+ try {
+ Move ? lhs = std::move(rhs)
+ : lhs = rhs;
+ assert(false);
+ } catch (my_any_exception const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+ };
+ // const lvalue to empty
+ {
+ any lhs;
+ Tp rhs(1);
+ assert(Tp::count == 1);
+
+ try_throw(lhs, rhs);
+
+ assert(Tp::count == 1);
+ assertEmpty<Tp>(lhs);
+ }
+ {
+ any lhs((small(2)));
+ Tp rhs(1);
+ assert(small::count == 1);
+ assert(Tp::count == 1);
+
+ try_throw(lhs, rhs);
+
+ assert(small::count == 1);
+ assert(Tp::count == 1);
+ assertContains<small>(lhs, 2);
+ }
+ {
+ any lhs((large(2)));
+ Tp rhs(1);
+ assert(large::count == 1);
+ assert(Tp::count == 1);
+
+ try_throw(lhs, rhs);
+
+ assert(large::count == 1);
+ assert(Tp::count == 1);
+ assertContains<large>(lhs, 2);
+ }
+#endif
+}
+
+
+// Test that any& operator=(ValueType&&) is *never* selected for:
+// * std::in_place type.
+// * Non-copyable types
+void test_sfinae_constraints() {
+ {
+ using Tag = std::in_place_type_t<int>;
+ using RawTag = std::remove_reference_t<Tag>;
+ static_assert(!std::is_assignable<std::any, RawTag&&>::value, "");
+ }
+ {
+ struct Dummy { Dummy() = delete; };
+ using T = std::in_place_type_t<Dummy>;
+ static_assert(!std::is_assignable<std::any, T>::value, "");
+ }
+ {
+ // Test that the ValueType&& constructor SFINAE's away when the
+ // argument is non-copyable
+ struct NoCopy {
+ NoCopy() = default;
+ NoCopy(NoCopy const&) = delete;
+ NoCopy(NoCopy&&) = default;
+ };
+ static_assert(!std::is_assignable<std::any, NoCopy>::value, "");
+ }
+}
+
+int main() {
+ test_assign_value<small1, small2>();
+ test_assign_value<large1, large2>();
+ test_assign_value<small, large>();
+ test_assign_value<large, small>();
+ test_assign_value_empty<small>();
+ test_assign_value_empty<large>();
+ test_assign_throws<small_throws_on_copy>();
+ 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
new file mode 100644
index 00000000000..03870caa531
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.class/any.cons/copy.pass.cpp
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+
+// any(any const &);
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::any;
+using std::any_cast;
+
+template <class Type>
+void test_copy_throws() {
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ assert(Type::count == 0);
+ {
+ any const a((Type(42)));
+ assert(Type::count == 1);
+ try {
+ any const a2(a);
+ assert(false);
+ } catch (my_any_exception const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+ assert(Type::count == 1);
+ assertContains<Type>(a, 42);
+ }
+ assert(Type::count == 0);
+#endif
+}
+
+void test_copy_empty() {
+ DisableAllocationGuard g; ((void)g); // No allocations should occur.
+ any a1;
+ any a2(a1);
+
+ assertEmpty(a1);
+ assertEmpty(a2);
+}
+
+template <class Type>
+void test_copy()
+{
+ // Copying small types should not perform any allocations.
+ DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a((Type(42)));
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+
+ any a2(a);
+
+ assert(Type::copied == 1);
+ assert(Type::count == 2);
+ assertContains<Type>(a, 42);
+ assertContains<Type>(a, 42);
+
+ // Modify a and check that a2 is unchanged
+ modifyValue<Type>(a, -1);
+ assertContains<Type>(a, -1);
+ assertContains<Type>(a2, 42);
+
+ // modify a2 and check that a is unchanged
+ modifyValue<Type>(a2, 999);
+ assertContains<Type>(a, -1);
+ assertContains<Type>(a2, 999);
+
+ // clear a and check that a2 is unchanged
+ a.reset();
+ assertEmpty(a);
+ assertContains<Type>(a2, 999);
+ }
+ assert(Type::count == 0);
+}
+
+int main() {
+ test_copy<small>();
+ test_copy<large>();
+ test_copy_empty();
+ test_copy_throws<small_throws_on_copy>();
+ test_copy_throws<large_throws_on_copy>();
+}
diff --git a/libcxx/test/std/utilities/any/any.class/any.cons/default.pass.cpp b/libcxx/test/std/utilities/any/any.class/any.cons/default.pass.cpp
new file mode 100644
index 00000000000..9f9b826b612
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.class/any.cons/default.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+
+// any() noexcept;
+
+#include <any>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "any_helpers.h"
+#include "count_new.hpp"
+
+#if TEST_HAS_BUILTIN_IDENTIFIER(__has_constant_initializer)
+// std::any must have a constexpr default constructor, but it's a non-literal
+// type so we can't create a constexpr variable. This tests that we actually
+// get 'constant initialization'.
+std::any a;
+static_assert(__has_constant_initializer(a),
+ "any must be constant initializable");
+#endif
+
+int main()
+{
+ using std::any;
+ {
+ static_assert(
+ std::is_nothrow_default_constructible<any>::value
+ , "Must be default constructible"
+ );
+ }
+ {
+ DisableAllocationGuard g; ((void)g);
+ any const a;
+ assertEmpty(a);
+ }
+}
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
new file mode 100644
index 00000000000..949c105f988
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.class/any.cons/in_place_type.pass.cpp
@@ -0,0 +1,152 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 T, class ...Args> any(in_place_type_t<T>, Args&&...);
+// template <class T, class U, class ...Args>
+// any(in_place_type_t<T>, initializer_list<U>, Args&&...);
+
+// Test construction from a value.
+// Concerns:
+// ---------
+// 1. The value is properly move/copied depending on the value category.
+// 2. Both small and large values are properly handled.
+
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+#include "test_convertible.hpp"
+
+using std::any;
+using std::any_cast;
+
+template <class Type>
+void test_in_place_type() {
+ // constructing from a small type should perform no allocations.
+ DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ 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);
+
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 101);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a(std::in_place<Type>, -1, 42, -1);
+
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 42);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+}
+
+template <class Type>
+void test_in_place_type_tracked() {
+ // constructing from a small type should perform no allocations.
+ DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
+ {
+ any a(std::in_place<Type>);
+ assertArgsMatch<Type>(a);
+ }
+ {
+ any a(std::in_place<Type>, -1, 42, -1);
+ assertArgsMatch<Type, int, int, int>(a);
+ }
+ // initializer_list constructor tests
+ {
+ any a(std::in_place<Type>, {-1, 42, -1});
+ assertArgsMatch<Type, std::initializer_list<int>>(a);
+ }
+ {
+ int x = 42;
+ any a(std::in_place<Type>, {-1, 42, -1}, x);
+ assertArgsMatch<Type, std::initializer_list<int>, int&>(a);
+ }
+}
+
+void test_ctor_sfinae() {
+ {
+ // Test that the init-list ctor SFINAE's away properly when
+ // construction would be ill-formed.
+ using IL = std::initializer_list<int>;
+ static_assert(!std::is_constructible<std::any,
+ std::in_place_type_t<int>, IL>::value, "");
+ static_assert(std::is_constructible<std::any,
+ std::in_place_type_t<small_tracked_t>, IL>::value, "");
+ }
+ {
+ // Test that the tagged dispatch constructor SFINAE's away when the
+ // argument is non-copyable
+ struct NoCopy {
+ NoCopy() = default;
+ NoCopy(NoCopy const&) = delete;
+ NoCopy(int) {}
+ NoCopy(std::initializer_list<int>, int) {}
+ };
+ using Tag = 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, "");
+ }
+}
+
+struct Implicit {
+ Implicit(int) {}
+ Implicit(int, int, int) {}
+ Implicit(std::initializer_list<int>, int) {}
+};
+
+void test_constructor_explicit() {
+ using I = Implicit;
+ using IT = std::in_place_type_t<I>;
+ static_assert(!test_convertible<std::any, IT, int>(), "");
+ static_assert(std::is_constructible<std::any, IT, int>::value, "");
+ static_assert(!test_convertible<std::any, IT, int, int, int>(), "");
+ static_assert(std::is_constructible<std::any, IT, int, int, int>::value, "");
+ static_assert(!test_convertible<std::any, IT, std::initializer_list<int>&, int>(), "");
+ static_assert(std::is_constructible<std::any, IT, std::initializer_list<int>&, int>::value, "");
+}
+
+int main() {
+ test_in_place_type<small>();
+ test_in_place_type<large>();
+ test_in_place_type<small_throws_on_copy>();
+ test_in_place_type<large_throws_on_copy>();
+ test_in_place_type<throws_on_move>();
+ test_in_place_type_tracked<small_tracked_t>();
+ test_in_place_type_tracked<large_tracked_t>();
+ 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
new file mode 100644
index 00000000000..9a83e66ab8a
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.class/any.cons/move.pass.cpp
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+
+// any(any &&) noexcept;
+
+#include <any>
+#include <utility>
+#include <type_traits>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::any;
+using std::any_cast;
+
+// Moves are always noexcept. The throws_on_move object
+// must be stored dynamically so the pointer is moved and
+// not the stored object.
+void test_move_does_not_throw()
+{
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ assert(throws_on_move::count == 0);
+ {
+ throws_on_move v(42);
+ any a(v);
+ assert(throws_on_move::count == 2);
+ // No allocations should be performed after this point.
+ DisableAllocationGuard g; ((void)g);
+ try {
+ any const a2(std::move(a));
+ assertEmpty(a);
+ assertContains<throws_on_move>(a2, 42);
+ } catch (...) {
+ assert(false);
+ }
+ assert(throws_on_move::count == 1);
+ assertEmpty(a);
+ }
+ assert(throws_on_move::count == 0);
+#endif
+}
+
+void test_move_empty() {
+ DisableAllocationGuard g; ((void)g); // no allocations should be performed.
+
+ any a1;
+ any a2(std::move(a1));
+
+ assertEmpty(a1);
+ assertEmpty(a2);
+}
+
+template <class Type>
+void test_move() {
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a((Type(42)));
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+
+ // Moving should not perform allocations since it must be noexcept.
+ DisableAllocationGuard g; ((void)g);
+
+ any a2(std::move(a));
+
+ assert(Type::moved >= 1); // zero or more move operations can be performed.
+ assert(Type::copied == 0); // no copies can be performed.
+ assert(Type::count == 1);
+ assertEmpty(a); // Moves are always destructive.
+ assertContains<Type>(a2, 42);
+ }
+ assert(Type::count == 0);
+}
+
+int main()
+{
+ // noexcept test
+ {
+ static_assert(
+ std::is_nothrow_move_constructible<any>::value
+ , "any must be nothrow move constructible"
+ );
+ }
+ test_move<small>();
+ test_move<large>();
+ test_move_empty();
+ test_move_does_not_throw();
+}
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
new file mode 100644
index 00000000000..ba5419b1245
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.class/any.cons/value.pass.cpp
@@ -0,0 +1,184 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 Value> any(Value &&)
+
+// Test construction from a value.
+// Concerns:
+// ---------
+// 1. The value is properly move/copied depending on the value category.
+// 2. Both small and large values are properly handled.
+
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::any;
+using std::any_cast;
+
+
+template <class Type>
+void test_copy_value_throws()
+{
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ assert(Type::count == 0);
+ {
+ Type const t(42);
+ assert(Type::count == 1);
+ try {
+ any const a2(t);
+ assert(false);
+ } catch (my_any_exception const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+ assert(Type::count == 1);
+ assert(t.value == 42);
+ }
+ assert(Type::count == 0);
+#endif
+}
+
+void test_move_value_throws()
+{
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ assert(throws_on_move::count == 0);
+ {
+ throws_on_move v;
+ assert(throws_on_move::count == 1);
+ try {
+ any const a(std::move(v));
+ assert(false);
+ } catch (my_any_exception const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+ assert(throws_on_move::count == 1);
+ }
+ assert(throws_on_move::count == 0);
+#endif
+}
+
+template <class Type>
+void test_copy_move_value() {
+ // constructing from a small type should perform no allocations.
+ DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ Type t(42);
+ assert(Type::count == 1);
+
+ any a(t);
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 42);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ Type t(42);
+ assert(Type::count == 1);
+
+ any a(std::move(t));
+
+ assert(Type::count == 2);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+ assertContains<Type>(a, 42);
+ }
+}
+
+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>;
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wignored-qualifiers"
+#endif
+ static_assert(std::is_same<Tag, const Tag>::value, "");
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+ // Test that the tag type is properly handled in SFINAE
+ Tag t = std::in_place;
+ {
+ std::any a(t);
+ assertContains<int>(a, 0);
+ }
+ {
+ std::any a(std::move(t));
+ assertContains<int>(a, 0);
+ }
+ {
+ struct Dummy { Dummy() = delete; };
+ using T = std::in_place_type_t<Dummy>;
+ static_assert(!std::is_constructible<std::any, T>::value, "");
+ }
+ {
+ // Test that the ValueType&& constructor SFINAE's away when the
+ // argument is non-copyable
+ struct NoCopy {
+ NoCopy() = default;
+ NoCopy(NoCopy const&) = delete;
+ NoCopy(int) {}
+ };
+ static_assert(!std::is_constructible<std::any, NoCopy>::value, "");
+ static_assert(!std::is_convertible<NoCopy, std::any>::value, "");
+ }
+}
+
+int main() {
+ test_copy_move_value<small>();
+ test_copy_move_value<large>();
+ 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
new file mode 100644
index 00000000000..fa8b093d304
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.class/any.modifiers/emplace.pass.cpp
@@ -0,0 +1,255 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 T, class ...Args> emplace(Args&&...);
+// template <class T, class U, class ...Args>
+// void emplace(initializer_list<U>, Args&&...);
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::any;
+using std::any_cast;
+
+struct Tracked {
+ static int count;
+ Tracked() {++count;}
+ ~Tracked() { --count; }
+};
+int Tracked::count = 0;
+
+template <class Type>
+void test_emplace_type() {
+ // constructing from a small type should perform no allocations.
+ DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a(std::in_place<Tracked>);
+ assert(Tracked::count == 1);
+
+ a.emplace<Type>();
+
+ assert(Tracked::count == 0);
+ 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<Tracked>);
+ assert(Tracked::count == 1);
+
+ a.emplace<Type>(101);
+
+ assert(Tracked::count == 0);
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 101);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a(std::in_place<Tracked>);
+ assert(Tracked::count == 1);
+
+ a.emplace<Type>(-1, 42, -1);
+
+ assert(Tracked::count == 0);
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 42);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+}
+
+template <class Type>
+void test_emplace_type_tracked() {
+ // constructing from a small type should perform no allocations.
+ DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
+ {
+ any a(std::in_place<Tracked>);
+ assert(Tracked::count == 1);
+ a.emplace<Type>();
+ assert(Tracked::count == 0);
+ assertArgsMatch<Type>(a);
+ }
+ {
+ any a(std::in_place<Tracked>);
+ assert(Tracked::count == 1);
+ a.emplace<Type>(-1, 42, -1);
+ assert(Tracked::count == 0);
+ assertArgsMatch<Type, int, int, int>(a);
+ }
+ // initializer_list constructor tests
+ {
+ any a(std::in_place<Tracked>);
+ assert(Tracked::count == 1);
+ a.emplace<Type>({-1, 42, -1});
+ assert(Tracked::count == 0);
+ assertArgsMatch<Type, std::initializer_list<int>>(a);
+ }
+ {
+ int x = 42;
+ any a(std::in_place<Tracked>);
+ assert(Tracked::count == 1);
+ a.emplace<Type>({-1, 42, -1}, x);
+ assert(Tracked::count == 0);
+ assertArgsMatch<Type, std::initializer_list<int>, int&>(a);
+ }
+}
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+
+struct SmallThrows {
+ SmallThrows(int) { throw 42; }
+ SmallThrows(std::initializer_list<int>, int) { throw 42; }
+};
+static_assert(IsSmallObject<SmallThrows>::value, "");
+
+struct LargeThrows {
+ LargeThrows(int) { throw 42; }
+ LargeThrows(std::initializer_list<int>, int) { throw 42; }
+ int data[10];
+};
+static_assert(!IsSmallObject<LargeThrows>::value, "");
+
+template <class Type>
+void test_emplace_throws()
+{
+ // any stores small type
+ {
+ std::any a(small{42});
+ assert(small::count == 1);
+ try {
+ a.emplace<Type>(101);
+ assert(false);
+ } catch (int const&) {
+ }
+ assert(small::count == 0);
+ }
+ {
+ std::any a(small{42});
+ assert(small::count == 1);
+ try {
+ a.emplace<Type>({1, 2, 3}, 101);
+ assert(false);
+ } catch (int const&) {
+ }
+ assert(small::count == 0);
+ }
+ // any stores large type
+ {
+ std::any a(large{42});
+ assert(large::count == 1);
+ try {
+ a.emplace<Type>(101);
+ assert(false);
+ } catch (int const&) {
+ }
+ assert(large::count == 0);
+ }
+ {
+ std::any a(large{42});
+ assert(large::count == 1);
+ try {
+ a.emplace<Type>({1, 2, 3}, 101);
+ assert(false);
+ } catch (int const&) {
+ }
+ assert(large::count == 0);
+ }
+}
+
+#endif
+
+template <class T, class ...Args>
+constexpr auto has_emplace(int)
+ -> decltype(std::any{}.emplace<T>(std::declval<Args>()...), true) { return true; }
+
+template <class ...Args>
+constexpr bool has_emplace(long) { return false; }
+
+template <class ...Args>
+constexpr bool has_emplace() { return has_emplace<Args...>(0); }
+
+
+template <class T, class IT, class ...Args>
+constexpr auto has_emplace_init_list(int)
+ -> decltype(std::any{}.emplace<T>(
+ {std::declval<IT>(), std::declval<IT>(), std::declval<IT>()},
+ std::declval<Args>()...), true) { return true; }
+
+template <class ...Args>
+constexpr bool has_emplace_init_list(long) { return false; }
+
+template <class ...Args>
+constexpr bool has_emplace_init_list() { return has_emplace_init_list<Args...>(0); }
+
+
+void test_emplace_sfinae_constraints() {
+ {
+ static_assert(has_emplace<int>(), "");
+ static_assert(has_emplace<int, int>(), "");
+ static_assert(!has_emplace<int, int, int>(), "not constructible");
+ static_assert(!has_emplace_init_list<int, int>(), "not constructible from il");
+ }
+ {
+ static_assert(has_emplace<small>(), "");
+ static_assert(has_emplace<large>(), "");
+ static_assert(!has_emplace<small, void*>(), "");
+ static_assert(!has_emplace<large, void*>(), "");
+
+ static_assert(has_emplace_init_list<small, int>(), "");
+ static_assert(has_emplace_init_list<large, int>(), "");
+ static_assert(!has_emplace_init_list<small, void*>(), "");
+ static_assert(!has_emplace_init_list<large, void*>(), "");
+ }
+ {
+ // Test that the emplace SFINAE's away when the
+ // argument is non-copyable
+ struct NoCopy {
+ NoCopy() = default;
+ NoCopy(NoCopy const&) = delete;
+ NoCopy(int) {}
+ NoCopy(std::initializer_list<int>, int, int) {}
+ };
+ static_assert(!has_emplace<NoCopy>(), "");
+ static_assert(!has_emplace<NoCopy, int>(), "");
+ static_assert(!has_emplace_init_list<NoCopy, int, int, int>(), "");
+ }
+}
+
+int main() {
+ test_emplace_type<small>();
+ test_emplace_type<large>();
+ test_emplace_type<small_throws_on_copy>();
+ test_emplace_type<large_throws_on_copy>();
+ test_emplace_type<throws_on_move>();
+ test_emplace_type_tracked<small_tracked_t>();
+ test_emplace_type_tracked<large_tracked_t>();
+ test_emplace_sfinae_constraints();
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ 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/reset.pass.cpp b/libcxx/test/std/utilities/any/any.class/any.modifiers/reset.pass.cpp
new file mode 100644
index 00000000000..31648a04e1a
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.class/any.modifiers/reset.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+
+// any::reset() noexcept
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+
+int main()
+{
+ using std::any;
+ using std::any_cast;
+ // empty
+ {
+ any a;
+
+ // noexcept check
+ static_assert(
+ noexcept(a.reset())
+ , "any.reset() must be noexcept"
+ );
+
+ assertEmpty(a);
+
+ a.reset();
+
+ assertEmpty(a);
+ }
+ // small object
+ {
+ any a((small(1)));
+ assert(small::count == 1);
+ assertContains<small>(a, 1);
+
+ a.reset();
+
+ assertEmpty<small>(a);
+ assert(small::count == 0);
+ }
+ // large object
+ {
+ any a(large(1));
+ assert(large::count == 1);
+ assertContains<large>(a);
+
+ a.reset();
+
+ assertEmpty<large>(a);
+ assert(large::count == 0);
+ }
+}
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
new file mode 100644
index 00000000000..013982478ee
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.class/any.modifiers/swap.pass.cpp
@@ -0,0 +1,101 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+
+// any::swap(any &) noexcept
+
+// Test swap(large, small) and swap(small, large)
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+
+using std::any;
+using std::any_cast;
+
+template <class LHS, class RHS>
+void test_swap() {
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+ {
+ any a1((LHS(1)));
+ any a2(RHS{2});
+ assert(LHS::count == 1);
+ assert(RHS::count == 1);
+
+ a1.swap(a2);
+
+ assert(LHS::count == 1);
+ assert(RHS::count == 1);
+
+ assertContains<RHS>(a1, 2);
+ assertContains<LHS>(a2, 1);
+ }
+ assert(LHS::count == 0);
+ assert(RHS::count == 0);
+ assert(LHS::copied == 0);
+ assert(RHS::copied == 0);
+}
+
+template <class Tp>
+void test_swap_empty() {
+ assert(Tp::count == 0);
+ {
+ any a1((Tp(1)));
+ any a2;
+ assert(Tp::count == 1);
+
+ a1.swap(a2);
+
+ assert(Tp::count == 1);
+
+ assertContains<Tp>(a2, 1);
+ assertEmpty(a1);
+ }
+ assert(Tp::count == 0);
+ {
+ any a1((Tp(1)));
+ any a2;
+ assert(Tp::count == 1);
+
+ a2.swap(a1);
+
+ assert(Tp::count == 1);
+
+ assertContains<Tp>(a2, 1);
+ assertEmpty(a1);
+ }
+ assert(Tp::count == 0);
+ assert(Tp::copied == 0);
+}
+
+void test_noexcept()
+{
+ any a1;
+ any a2;
+ static_assert(
+ noexcept(a1.swap(a2))
+ , "any::swap(any&) must be noexcept"
+ );
+}
+
+int main()
+{
+ test_noexcept();
+ test_swap_empty<small>();
+ test_swap_empty<large>();
+ test_swap<small1, small2>();
+ test_swap<large1, large2>();
+ test_swap<small, large>();
+ test_swap<large, small>();
+}
diff --git a/libcxx/test/std/utilities/any/any.class/any.observers/has_value.pass.cpp b/libcxx/test/std/utilities/any/any.class/any.observers/has_value.pass.cpp
new file mode 100644
index 00000000000..072ac06776c
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.class/any.observers/has_value.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+
+// any::has_value() noexcept
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+
+int main()
+{
+ using std::any;
+ // noexcept test
+ {
+ any a;
+ static_assert(noexcept(a.has_value()), "any::has_value() must be noexcept");
+ }
+ // empty
+ {
+ any a;
+ assert(!a.has_value());
+
+ a.reset();
+ assert(!a.has_value());
+
+ a = 42;
+ assert(a.has_value());
+ }
+ // small object
+ {
+ small const s(1);
+ any a(s);
+ assert(a.has_value());
+
+ a.reset();
+ assert(!a.has_value());
+
+ a = s;
+ assert(a.has_value());
+ }
+ // large object
+ {
+ large const l(1);
+ any a(l);
+ assert(a.has_value());
+
+ a.reset();
+ assert(!a.has_value());
+
+ a = l;
+ assert(a.has_value());
+ }
+}
diff --git a/libcxx/test/std/utilities/any/any.class/any.observers/type.pass.cpp b/libcxx/test/std/utilities/any/any.class/any.observers/type.pass.cpp
new file mode 100644
index 00000000000..984c4137db0
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.class/any.observers/type.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// XFAIL: libcpp-no-rtti
+
+// <any>
+
+// any::type() noexcept
+
+#include <any>
+#include <cassert>
+#include "any_helpers.h"
+
+int main()
+{
+ using std::any;
+ {
+ any const a;
+ assert(a.type() == typeid(void));
+ static_assert(noexcept(a.type()), "any::type() must be noexcept");
+ }
+ {
+ small const s(1);
+ any const a(s);
+ assert(a.type() == typeid(small));
+
+ }
+ {
+ large const l(1);
+ any const a(l);
+ assert(a.type() == typeid(large));
+ }
+}
diff --git a/libcxx/test/std/utilities/any/any.class/not_literal_type.pass.cpp b/libcxx/test/std/utilities/any/any.class/not_literal_type.pass.cpp
new file mode 100644
index 00000000000..91ef5c970a2
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.class/not_literal_type.pass.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+
+// [Note any is a not a literal type --end note]
+
+#include <any>
+#include <type_traits>
+
+int main () {
+ static_assert(!std::is_literal_type<std::any>::value, "");
+}
diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp
new file mode 100644
index 00000000000..0f4fc6ab7eb
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp
@@ -0,0 +1,158 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 const* any_cast(any const *) noexcept;
+//
+// template <class ValueType>
+// ValueType * any_cast(any *) noexcept;
+
+#include <any>
+#include <type_traits>
+#include <cassert>
+
+#include "any_helpers.h"
+
+using std::any;
+using std::any_cast;
+
+// Test that the operators are properly noexcept.
+void test_cast_is_noexcept() {
+ any a;
+ static_assert(noexcept(any_cast<int>(&a)), "");
+
+ any const& ca = a;
+ static_assert(noexcept(any_cast<int>(&ca)), "");
+}
+
+// Test that the return type of any_cast is correct.
+void test_cast_return_type() {
+ any a;
+ static_assert(std::is_same<decltype(any_cast<int>(&a)), int*>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const>(&a)), int const*>::value, "");
+
+ any const& ca = a;
+ static_assert(std::is_same<decltype(any_cast<int>(&ca)), int const*>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const>(&ca)), int const*>::value, "");
+}
+
+// Test that any_cast handles null pointers.
+void test_cast_nullptr() {
+ any* a = nullptr;
+ assert(nullptr == any_cast<int>(a));
+ assert(nullptr == any_cast<int const>(a));
+
+ any const* ca = nullptr;
+ assert(nullptr == any_cast<int>(ca));
+ assert(nullptr == any_cast<int const>(ca));
+}
+
+// Test casting an empty object.
+void test_cast_empty() {
+ {
+ any a;
+ assert(nullptr == any_cast<int>(&a));
+ assert(nullptr == any_cast<int const>(&a));
+
+ any const& ca = a;
+ assert(nullptr == any_cast<int>(&ca));
+ assert(nullptr == any_cast<int const>(&ca));
+ }
+ // Create as non-empty, then make empty and run test.
+ {
+ any a(42);
+ a.reset();
+ assert(nullptr == any_cast<int>(&a));
+ assert(nullptr == any_cast<int const>(&a));
+
+ any const& ca = a;
+ assert(nullptr == any_cast<int>(&ca));
+ assert(nullptr == any_cast<int const>(&ca));
+ }
+}
+
+template <class Type>
+void test_cast() {
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a((Type(42)));
+ any const& ca = a;
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+
+ // Try a cast to a bad type.
+ // NOTE: Type cannot be an int.
+ assert(any_cast<int>(&a) == nullptr);
+ assert(any_cast<int const>(&a) == nullptr);
+ assert(any_cast<int const volatile>(&a) == nullptr);
+
+ // Try a cast to the right type, but as a pointer.
+ assert(any_cast<Type*>(&a) == nullptr);
+ assert(any_cast<Type const*>(&a) == nullptr);
+
+ // Check getting a unqualified type from a non-const any.
+ Type* v = any_cast<Type>(&a);
+ assert(v != nullptr);
+ assert(v->value == 42);
+
+ // change the stored value and later check for the new value.
+ v->value = 999;
+
+ // Check getting a const qualified type from a non-const any.
+ Type const* cv = any_cast<Type const>(&a);
+ assert(cv != nullptr);
+ assert(cv == v);
+ assert(cv->value == 999);
+
+ // Check getting a unqualified type from a const any.
+ cv = any_cast<Type>(&ca);
+ assert(cv != nullptr);
+ assert(cv == v);
+ assert(cv->value == 999);
+
+ // Check getting a const-qualified type from a const any.
+ cv = any_cast<Type const>(&ca);
+ assert(cv != nullptr);
+ assert(cv == v);
+ assert(cv->value == 999);
+
+ // Check that no more objects were created, copied or moved.
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+ }
+ assert(Type::count == 0);
+}
+
+void test_cast_non_copyable_type()
+{
+ // Even though 'any' never stores non-copyable types
+ // we still need to support any_cast<NoCopy>(ptr)
+ struct NoCopy { NoCopy(NoCopy const&) = delete; };
+ std::any a(42);
+ std::any const& ca = a;
+ assert(std::any_cast<NoCopy>(&a) == nullptr);
+ assert(std::any_cast<NoCopy>(&ca) == nullptr);
+}
+
+int main() {
+ test_cast_is_noexcept();
+ test_cast_return_type();
+ test_cast_nullptr();
+ test_cast_empty();
+ test_cast<small>();
+ test_cast<large>();
+ test_cast_non_copyable_type();
+}
diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp
new file mode 100644
index 00000000000..852e776ce2d
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp
@@ -0,0 +1,396 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 const any_cast(any const&);
+//
+// template <class ValueType>
+// ValueType any_cast(any &);
+//
+// template <class ValueType>
+// ValueType any_cast(any &&);
+
+#include <any>
+#include <type_traits>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::any;
+using std::any_cast;
+using std::bad_any_cast;
+
+
+// Test that the operators are NOT marked noexcept.
+void test_cast_is_not_noexcept() {
+ any a;
+ static_assert(!noexcept(any_cast<int>(static_cast<any&>(a))), "");
+ static_assert(!noexcept(any_cast<int>(static_cast<any const&>(a))), "");
+ static_assert(!noexcept(any_cast<int>(static_cast<any &&>(a))), "");
+}
+
+// Test that the return type of any_cast is correct.
+void test_cast_return_type() {
+ any a;
+ static_assert(std::is_same<decltype(any_cast<int>(a)), int>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const>(a)), int>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int&>(a)), int&>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const&>(a)), int const&>::value, "");
+
+ static_assert(std::is_same<decltype(any_cast<int&&>(a)), int&&>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const&&>(a)), int const&&>::value, "");
+
+ static_assert(std::is_same<decltype(any_cast<int>(std::move(a))), int>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const>(std::move(a))), int>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int&>(std::move(a))), int&>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const&>(std::move(a))), int const&>::value, "");
+
+ static_assert(std::is_same<decltype(any_cast<int&&>(std::move(a))), int&&>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const&&>(std::move(a))), int const&&>::value, "");
+
+ any const& ca = a;
+ static_assert(std::is_same<decltype(any_cast<int>(ca)), int>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const>(ca)), int>::value, "");
+ static_assert(std::is_same<decltype(any_cast<int const&>(ca)), int const&>::value, "");
+
+ static_assert(std::is_same<decltype(any_cast<int const&&>(ca)), int const&&>::value, "");
+}
+
+template <class Type, class ConstT = Type>
+void checkThrows(any& a)
+{
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ try {
+ any_cast<Type>(a);
+ assert(false);
+ } catch (bad_any_cast const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+
+ try {
+ any_cast<ConstT>(static_cast<any const&>(a));
+ assert(false);
+ } catch (bad_any_cast const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+
+ try {
+ any_cast<Type>(static_cast<any&&>(a));
+ assert(false);
+ } catch (bad_any_cast const &) {
+ // do nothing
+ } catch (...) {
+ assert(false);
+ }
+#endif
+}
+
+void test_cast_empty() {
+ // None of these operations should allocate.
+ DisableAllocationGuard g; ((void)g);
+ any a;
+ checkThrows<int>(a);
+}
+
+template <class Type>
+void test_cast_to_reference() {
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a((Type(42)));
+ any const& ca = a;
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+
+ // Try a cast to a bad type.
+ // NOTE: Type cannot be an int.
+ checkThrows<int>(a);
+ checkThrows<int&, int const&>(a);
+ checkThrows<Type*, Type const*>(a);
+ checkThrows<Type const*>(a);
+
+ // Check getting a type by reference from a non-const lvalue any.
+ {
+ Type& v = any_cast<Type&>(a);
+ assert(v.value == 42);
+
+ Type const &cv = any_cast<Type const&>(a);
+ assert(&cv == &v);
+ }
+ // Check getting a type by reference from a const lvalue any.
+ {
+ Type const& v = any_cast<Type const&>(ca);
+ assert(v.value == 42);
+
+ Type const &cv = any_cast<Type const&>(ca);
+ 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.
+ {
+ Type const& v = any_cast<Type const&>(std::move(ca));
+ assert(v.value == 42);
+
+ Type const &cv = any_cast<Type const&>(std::move(ca));
+ assert(&cv == &v);
+ }
+ // Check getting a type by reference from a const rvalue any.
+ {
+ Type&& v = any_cast<Type&&>(std::move(a));
+ assert(v.value == 42);
+ assert(any_cast<Type&>(a).value == 42);
+
+ Type&& cv = any_cast<Type&&>(std::move(a));
+ assert(&cv == &v);
+ assert(any_cast<Type&>(a).value == 42);
+ }
+ // Check getting a type by reference from a const rvalue any.
+ {
+ Type const&& v = any_cast<Type const&&>(std::move(a));
+ assert(v.value == 42);
+ assert(any_cast<Type&>(a).value == 42);
+
+ Type const&& cv = any_cast<Type const&&>(std::move(a));
+ assert(&cv == &v);
+ assert(any_cast<Type&>(a).value == 42);
+ }
+ // Check that the original object hasn't been changed.
+ assertContains<Type>(a, 42);
+
+ // Check that no objects have been created/copied/moved.
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+ }
+ assert(Type::count == 0);
+}
+
+template <class Type>
+void test_cast_to_value() {
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a((Type(42)));
+ any const& ca = a;
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 1);
+
+ // Try a cast to a bad type.
+ // NOTE: Type cannot be an int.
+ checkThrows<int>(a);
+ checkThrows<int&, int const&>(a);
+ checkThrows<Type*, Type const*>(a);
+ checkThrows<Type const*>(a);
+
+ Type::reset(); // NOTE: reset does not modify Type::count
+ // Check getting Type by value from a non-const lvalue any.
+ // This should cause the non-const copy constructor to be called.
+ {
+ Type t = any_cast<Type>(a);
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 0);
+ assert(Type::non_const_copied == 1);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
+ }
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting const Type by value from a non-const lvalue any.
+ // This should cause the const copy constructor to be called.
+ {
+ Type t = any_cast<Type const>(a);
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 1);
+ assert(Type::non_const_copied == 0);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
+ }
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting Type by value from a non-const lvalue any.
+ // This should cause the const copy constructor to be called.
+ {
+ Type t = any_cast<Type>(static_cast<any const&>(a));
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 1);
+ assert(Type::non_const_copied == 0);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
+ }
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting Type by value from a non-const rvalue any.
+ // This should cause the non-const copy constructor to be called.
+ {
+ Type t = any_cast<Type>(static_cast<any &&>(a));
+
+ assert(Type::count == 2);
+ assert(Type::moved == 1);
+ assert(Type::copied == 0);
+ assert(Type::const_copied == 0);
+ assert(Type::non_const_copied == 0);
+ assert(t.value == 42);
+ assert(any_cast<Type&>(a).value == 0);
+ any_cast<Type&>(a).value = 42; // reset the value
+ }
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting const Type by value from a non-const rvalue any.
+ // This should cause the const copy constructor to be called.
+ {
+ Type t = any_cast<Type const>(static_cast<any &&>(a));
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 1);
+ assert(Type::non_const_copied == 0);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
+ assert(any_cast<Type&>(a).value == 42);
+ }
+ assert(Type::count == 1);
+ Type::reset();
+ // Check getting Type by value from a const rvalue any.
+ // This should cause the const copy constructor to be called.
+ {
+ Type t = any_cast<Type>(static_cast<any const&&>(a));
+
+ assert(Type::count == 2);
+ assert(Type::copied == 1);
+ assert(Type::const_copied == 1);
+ assert(Type::non_const_copied == 0);
+ assert(Type::moved == 0);
+ assert(t.value == 42);
+ assert(any_cast<Type&>(a).value == 42);
+ }
+ // Ensure we still only have 1 Type object alive.
+ assert(Type::count == 1);
+
+ // Check that the original object hasn't been changed.
+ assertContains<Type>(a, 42);
+ }
+ 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() {
+ test_cast_is_not_noexcept();
+ test_cast_return_type();
+ test_cast_empty();
+ test_cast_to_reference<small>();
+ test_cast_to_reference<large>();
+ test_cast_to_value<small>();
+ test_cast_to_value<large>();
+ test_cast_to_value_deleted_move();
+ test_non_copyable_ref();
+}
diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/const_correctness.fail.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/const_correctness.fail.cpp
new file mode 100644
index 00000000000..a141b05ef7c
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/const_correctness.fail.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 const &);
+
+// Try and cast away const.
+
+#include <any>
+
+struct TestType {};
+struct TestType2 {};
+
+int main()
+{
+ using std::any;
+ using std::any_cast;
+
+ any a;
+
+ // expected-error@any:* 2 {{binding value of type '_Tp' (aka 'const TestType') to reference to type 'TestType' drops 'const' qualifier}}
+ 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}}
+ any_cast<TestType2 &>(static_cast<any const&&>(a)); // expected-note {{requested here}}
+ any_cast<TestType2 &&>(static_cast<any const&&>(a)); // expected-note {{requested here}}
+}
diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.fail.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.fail.cpp
new file mode 100644
index 00000000000..415da8396db
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/not_copy_constructible.fail.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 const any_cast(any const&);
+//
+// template <class ValueType>
+// ValueType any_cast(any &);
+//
+// template <class ValueType>
+// ValueType any_cast(any &&);
+
+// Test instantiating the any_cast with a non-copyable type.
+
+#include <any>
+
+using std::any;
+using std::any_cast;
+
+struct no_copy
+{
+ no_copy() {}
+ no_copy(no_copy &&) {}
+private:
+ no_copy(no_copy const &);
+};
+
+int main() {
+ any a;
+ any_cast<no_copy>(static_cast<any&>(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."}}
+ // expected-error@any:* 2 {{calling a private constructor of class 'no_copy'}}
+} \ No newline at end of file
diff --git a/libcxx/test/std/utilities/any/any.nonmembers/any.cast/reference_types.fail.cpp b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/reference_types.fail.cpp
new file mode 100644
index 00000000000..99cc029971a
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.nonmembers/any.cast/reference_types.fail.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 const* any_cast(any const *) noexcept;
+//
+// template <class ValueType>
+// ValueType * any_cast(any *) noexcept;
+
+#include <any>
+
+using std::any;
+using std::any_cast;
+
+int main()
+{
+ any a(1);
+ any_cast<int &>(&a); // expected-error@any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any_cast<int &&>(&a); // expected-error@any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any_cast<int const &>(&a); // expected-error@any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any_cast<int const&&>(&a); // expected-error@any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any const& a2 = a;
+ any_cast<int &>(&a2); // expected-error@any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any_cast<int &&>(&a2); // expected-error@any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any_cast<int const &>(&a2); // expected-error@any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+ any_cast<int const &&>(&a2); // expected-error@any:* 1 {{static_assert failed "_ValueType may not be a reference."}}
+}
diff --git a/libcxx/test/std/utilities/any/any.nonmembers/make_any.pass.cpp b/libcxx/test/std/utilities/any/any.nonmembers/make_any.pass.cpp
new file mode 100644
index 00000000000..143b60dd864
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.nonmembers/make_any.pass.cpp
@@ -0,0 +1,140 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 T, class ...Args> any make_any(Args&&...);
+// template <class T, class U, class ...Args>
+// any make_any(initializer_list<U>, Args&&...);
+
+#include <any>
+#include <cassert>
+
+#include "any_helpers.h"
+#include "count_new.hpp"
+#include "test_macros.h"
+
+using std::any;
+using std::any_cast;
+
+
+template <class Type>
+void test_make_any_type() {
+ // constructing from a small type should perform no allocations.
+ DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a = std::make_any<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::make_any<Type>(101);
+
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 101);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+ {
+ any a = std::make_any<Type>(-1, 42, -1);
+
+ assert(Type::count == 1);
+ assert(Type::copied == 0);
+ assert(Type::moved == 0);
+ assertContains<Type>(a, 42);
+ }
+ assert(Type::count == 0);
+ Type::reset();
+}
+
+template <class Type>
+void test_make_any_type_tracked() {
+ // constructing from a small type should perform no allocations.
+ DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
+ {
+ any a = std::make_any<Type>();
+ assertArgsMatch<Type>(a);
+ }
+ {
+ any a = std::make_any<Type>(-1, 42, -1);
+ assertArgsMatch<Type, int, int, int>(a);
+ }
+ // initializer_list constructor tests
+ {
+ any a = std::make_any<Type>({-1, 42, -1});
+ assertArgsMatch<Type, std::initializer_list<int>>(a);
+ }
+ {
+ int x = 42;
+ any a = std::make_any<Type>({-1, 42, -1}, x);
+ assertArgsMatch<Type, std::initializer_list<int>, int&>(a);
+ }
+}
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+
+struct SmallThrows {
+ SmallThrows(int) { throw 42; }
+ SmallThrows(std::initializer_list<int>, int) { throw 42; }
+};
+static_assert(IsSmallObject<SmallThrows>::value, "");
+
+struct LargeThrows {
+ LargeThrows(int) { throw 42; }
+ LargeThrows(std::initializer_list<int>, int) { throw 42; }
+ int data[10];
+};
+static_assert(!IsSmallObject<LargeThrows>::value, "");
+
+template <class Type>
+void test_make_any_throws()
+{
+ {
+ try {
+ std::make_any<Type>(101);
+ assert(false);
+ } catch (int const&) {
+ }
+ }
+ {
+ try {
+ std::make_any<Type>({1, 2, 3}, 101);
+ assert(false);
+ } catch (int const&) {
+ }
+ }
+}
+
+#endif
+
+int main() {
+ test_make_any_type<small>();
+ test_make_any_type<large>();
+ test_make_any_type<small_throws_on_copy>();
+ test_make_any_type<large_throws_on_copy>();
+ test_make_any_type<throws_on_move>();
+ test_make_any_type_tracked<small_tracked_t>();
+ test_make_any_type_tracked<large_tracked_t>();
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ test_make_any_throws<SmallThrows>();
+ test_make_any_throws<LargeThrows>();
+
+#endif
+} \ No newline at end of file
diff --git a/libcxx/test/std/utilities/any/any.nonmembers/swap.pass.cpp b/libcxx/test/std/utilities/any/any.nonmembers/swap.pass.cpp
new file mode 100644
index 00000000000..1b3785bb1c6
--- /dev/null
+++ b/libcxx/test/std/utilities/any/any.nonmembers/swap.pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+
+// void swap(any &, any &) noexcept
+
+// swap(...) just wraps any::swap(...). That function is tested elsewhere.
+
+#include <any>
+#include <cassert>
+
+using std::any;
+using std::any_cast;
+
+int main()
+{
+
+ { // test noexcept
+ any a;
+ static_assert(noexcept(swap(a, a)), "swap(any&, any&) must be noexcept");
+ }
+ {
+ any a1(1);
+ any a2(2);
+
+ swap(a1, a2);
+
+ assert(any_cast<int>(a1) == 2);
+ assert(any_cast<int>(a2) == 1);
+ }
+}
diff --git a/libcxx/test/support/any_helpers.h b/libcxx/test/support/any_helpers.h
index bb1ad175c1f..a0ff8dbc1f9 100644
--- a/libcxx/test/support/any_helpers.h
+++ b/libcxx/test/support/any_helpers.h
@@ -9,12 +9,14 @@
#ifndef ANY_HELPERS_H
#define ANY_HELPERS_H
-#include <experimental/any>
#include <typeinfo>
#include <type_traits>
#include <cassert>
+namespace std { namespace experimental {} }
+
#include "test_macros.h"
+#include "type_id.h"
#if !defined(TEST_HAS_NO_RTTI)
#define RTTI_ASSERT(X) assert(X)
@@ -32,42 +34,55 @@ template <class _Tp>
>
{};
+template <class T>
+bool containsType(std::any const& a) {
+#if !defined(TEST_HAS_NO_RTTI)
+ return a.type() == typeid(T);
+#else
+ return a.has_value() && std::any_cast<T>(&a) != nullptr;
+#endif
+}
// Return 'true' if 'Type' will be considered a small type by 'any'
template <class Type>
bool isSmallType() {
-#if defined(_LIBCPP_VERSION)
- return std::experimental::__any_imp::_IsSmallObject<Type>::value;
-#else
return IsSmallObject<Type>::value;
-#endif
-
}
// Assert that an object is empty. If the object used to contain an object
// of type 'LastType' check that it can no longer be accessed.
template <class LastType = int>
-void assertEmpty(std::experimental::any const& a) {
- assert(a.empty());
+void assertEmpty(std::any const& a) {
+ using namespace std;
+ assert(!a.has_value());
RTTI_ASSERT(a.type() == typeid(void));
- assert(std::experimental::any_cast<LastType const>(&a) == nullptr);
+ assert(any_cast<LastType const>(&a) == nullptr);
}
// Assert that an 'any' object stores the specified 'Type' and 'value'.
template <class Type>
-void assertContains(std::experimental::any const& a, int value = 1) {
- assert(!a.empty());
- RTTI_ASSERT(a.type() == typeid(Type));
- assert(std::experimental::any_cast<Type const &>(a).value == value);
+void assertContains(std::any const& a, int value = 1) {
+ assert(a.has_value());
+ assert(containsType<Type>(a));
+ assert(std::any_cast<Type const &>(a).value == value);
+}
+
+template <>
+void assertContains<int>(std::any const& a, int value) {
+ assert(a.has_value());
+ assert(containsType<int>(a));
+ assert(std::any_cast<int const &>(a) == value);
}
// Modify the value of a "test type" stored within an any to the specified
// 'value'.
template <class Type>
-void modifyValue(std::experimental::any& a, int value) {
- assert(!a.empty());
- RTTI_ASSERT(a.type() == typeid(Type));
- std::experimental::any_cast<Type&>(a).value = value;
+void modifyValue(std::any& a, int value) {
+ using namespace std;
+ using namespace std::experimental;
+ assert(a.has_value());
+ assert(containsType<Type>(a));
+ any_cast<Type&>(a).value = value;
}
// A test type that will trigger the small object optimization within 'any'.
@@ -89,25 +104,31 @@ struct small_type
int value;
- explicit small_type(int val) : value(val) {
+ explicit small_type(int val = 0) : value(val) {
+ ++count;
+ }
+ explicit small_type(int, int val, int) : value(val) {
+ ++count;
+ }
+ small_type(std::initializer_list<int> il) : value(*il.begin()) {
++count;
}
- small_type(small_type const & other) throw() {
+ small_type(small_type const & other) noexcept {
value = other.value;
++count;
++copied;
++const_copied;
}
- small_type(small_type& other) throw() {
+ small_type(small_type& other) noexcept {
value = other.value;
++count;
++copied;
++non_const_copied;
}
- small_type(small_type && other) throw() {
+ small_type(small_type && other) noexcept {
value = other.value;
other.value = 0;
++count;
@@ -163,11 +184,17 @@ struct large_type
int value;
- large_type(int val) : value(val) {
+ large_type(int val = 0) : value(val) {
++count;
data[0] = 0;
}
-
+ large_type(int, int val, int) : value(val) {
+ ++count;
+ data[0] = 0;
+ }
+ large_type(std::initializer_list<int> il) : value(*il.begin()) {
+ ++count;
+ }
large_type(large_type const & other) {
value = other.value;
++count;
@@ -219,6 +246,67 @@ typedef large_type<> large;
typedef large_type<1> large1;
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'
// and 'throws_on_move'.
struct my_any_exception {};
@@ -236,19 +324,24 @@ void throwMyAnyExpression() {
struct small_throws_on_copy
{
static int count;
+ static int copied;
+ static int moved;
+ static void reset() { count = copied = moved = 0; }
int value;
explicit small_throws_on_copy(int val = 0) : value(val) {
++count;
}
-
+ explicit small_throws_on_copy(int, int val, int) : value(val) {
+ ++count;
+ }
small_throws_on_copy(small_throws_on_copy const &) {
throwMyAnyExpression();
}
small_throws_on_copy(small_throws_on_copy && other) throw() {
value = other.value;
- ++count;
+ ++count; ++moved;
}
~small_throws_on_copy() {
@@ -260,26 +353,35 @@ private:
};
int small_throws_on_copy::count = 0;
+int small_throws_on_copy::copied = 0;
+int small_throws_on_copy::moved = 0;
+
// A test type that will NOT trigger the small object optimization within 'any'.
// this type throws if it is copied.
struct large_throws_on_copy
{
static int count;
+ static int copied;
+ static int moved;
+ static void reset() { count = copied = moved = 0; }
int value = 0;
explicit large_throws_on_copy(int val = 0) : value(val) {
data[0] = 0;
++count;
}
-
+ explicit large_throws_on_copy(int, int val, int) : value(val) {
+ data[0] = 0;
+ ++count;
+ }
large_throws_on_copy(large_throws_on_copy const &) {
throwMyAnyExpression();
}
large_throws_on_copy(large_throws_on_copy && other) throw() {
value = other.value;
- ++count;
+ ++count; ++moved;
}
~large_throws_on_copy() {
@@ -293,19 +395,24 @@ private:
};
int large_throws_on_copy::count = 0;
+int large_throws_on_copy::copied = 0;
+int large_throws_on_copy::moved = 0;
// A test type that throws when it is moved. This object will NOT trigger
// the small object optimization in 'any'.
struct throws_on_move
{
static int count;
+ static int copied;
+ static int moved;
+ static void reset() { count = copied = moved = 0; }
int value;
explicit throws_on_move(int val = 0) : value(val) { ++count; }
-
+ explicit throws_on_move(int, int val, int) : value(val) { ++count; }
throws_on_move(throws_on_move const & other) {
value = other.value;
- ++count;
+ ++count; ++copied;
}
throws_on_move(throws_on_move &&) {
@@ -321,6 +428,56 @@ private:
};
int throws_on_move::count = 0;
+int throws_on_move::copied = 0;
+int throws_on_move::moved = 0;
+
+struct small_tracked_t {
+ small_tracked_t()
+ : arg_types(&makeArgumentID<>()) {}
+ small_tracked_t(small_tracked_t const&) noexcept
+ : arg_types(&makeArgumentID<small_tracked_t const&>()) {}
+ small_tracked_t(small_tracked_t &&) noexcept
+ : arg_types(&makeArgumentID<small_tracked_t &&>()) {}
+ template <class ...Args>
+ explicit small_tracked_t(Args&&...)
+ : arg_types(&makeArgumentID<Args...>()) {}
+ template <class ...Args>
+ explicit small_tracked_t(std::initializer_list<int>, Args&&...)
+ : arg_types(&makeArgumentID<std::initializer_list<int>, Args...>()) {}
+
+ TypeID const* arg_types;
+};
+static_assert(IsSmallObject<small_tracked_t>::value, "must be small");
+
+struct large_tracked_t {
+ large_tracked_t()
+ : arg_types(&makeArgumentID<>()) { dummy[0] = 42; }
+ large_tracked_t(large_tracked_t const&) noexcept
+ : arg_types(&makeArgumentID<large_tracked_t const&>()) {}
+ large_tracked_t(large_tracked_t &&) noexcept
+ : arg_types(&makeArgumentID<large_tracked_t &&>()) {}
+ template <class ...Args>
+ explicit large_tracked_t(Args&&...)
+ : arg_types(&makeArgumentID<Args...>()) {}
+ template <class ...Args>
+ explicit large_tracked_t(std::initializer_list<int>, Args&&...)
+ : arg_types(&makeArgumentID<std::initializer_list<int>, Args...>()) {}
+
+ TypeID const* arg_types;
+ int dummy[10];
+};
+
+static_assert(!IsSmallObject<large_tracked_t>::value, "must be small");
+
+
+template <class Type, class ...Args>
+void assertArgsMatch(std::any const& a) {
+ using namespace std;
+ using namespace std::experimental;
+ assert(a.has_value());
+ assert(containsType<Type>(a));
+ assert(any_cast<Type const &>(a).arg_types == &makeArgumentID<Args...>());
+};
#endif
diff --git a/libcxx/test/support/experimental_any_helpers.h b/libcxx/test/support/experimental_any_helpers.h
new file mode 100644
index 00000000000..50bd6d68fba
--- /dev/null
+++ b/libcxx/test/support/experimental_any_helpers.h
@@ -0,0 +1,326 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+#ifndef EXPERIMENTAL_ANY_HELPERS_H
+#define EXPERIMENTAL_ANY_HELPERS_H
+
+#include <experimental/any>
+#include <typeinfo>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+
+#if !defined(TEST_HAS_NO_RTTI)
+#define RTTI_ASSERT(X) assert(X)
+#else
+#define RTTI_ASSERT(X)
+#endif
+
+template <class _Tp>
+ struct IsSmallObject
+ : public std::integral_constant<bool
+ , sizeof(_Tp) <= (sizeof(void*)*3)
+ && std::alignment_of<void*>::value
+ % std::alignment_of<_Tp>::value == 0
+ && std::is_nothrow_move_constructible<_Tp>::value
+ >
+ {};
+
+
+// Return 'true' if 'Type' will be considered a small type by 'any'
+template <class Type>
+bool isSmallType() {
+#if defined(_LIBCPP_VERSION)
+ return std::experimental::__any_imp::_IsSmallObject<Type>::value;
+#else
+ return IsSmallObject<Type>::value;
+#endif
+
+}
+
+// Assert that an object is empty. If the object used to contain an object
+// of type 'LastType' check that it can no longer be accessed.
+template <class LastType = int>
+void assertEmpty(std::experimental::any const& a) {
+ assert(a.empty());
+ RTTI_ASSERT(a.type() == typeid(void));
+ assert(std::experimental::any_cast<LastType const>(&a) == nullptr);
+}
+
+// Assert that an 'any' object stores the specified 'Type' and 'value'.
+template <class Type>
+void assertContains(std::experimental::any const& a, int value = 1) {
+ assert(!a.empty());
+ RTTI_ASSERT(a.type() == typeid(Type));
+ assert(std::experimental::any_cast<Type const &>(a).value == value);
+}
+
+// Modify the value of a "test type" stored within an any to the specified
+// 'value'.
+template <class Type>
+void modifyValue(std::experimental::any& a, int value) {
+ assert(!a.empty());
+ RTTI_ASSERT(a.type() == typeid(Type));
+ std::experimental::any_cast<Type&>(a).value = value;
+}
+
+// A test type that will trigger the small object optimization within 'any'.
+template <int Dummy = 0>
+struct small_type
+{
+ static int count;
+ static int copied;
+ static int moved;
+ static int const_copied;
+ static int non_const_copied;
+
+ static void reset() {
+ small_type::copied = 0;
+ small_type::moved = 0;
+ small_type::const_copied = 0;
+ small_type::non_const_copied = 0;
+ }
+
+ int value;
+
+ explicit small_type(int val) : value(val) {
+ ++count;
+ }
+
+ small_type(small_type const & other) throw() {
+ value = other.value;
+ ++count;
+ ++copied;
+ ++const_copied;
+ }
+
+ small_type(small_type& other) throw() {
+ value = other.value;
+ ++count;
+ ++copied;
+ ++non_const_copied;
+ }
+
+ small_type(small_type && other) throw() {
+ value = other.value;
+ other.value = 0;
+ ++count;
+ ++moved;
+ }
+
+ ~small_type() {
+ value = -1;
+ --count;
+ }
+
+private:
+ small_type& operator=(small_type const&) = delete;
+ small_type& operator=(small_type&&) = delete;
+};
+
+template <int Dummy>
+int small_type<Dummy>::count = 0;
+
+template <int Dummy>
+int small_type<Dummy>::copied = 0;
+
+template <int Dummy>
+int small_type<Dummy>::moved = 0;
+
+template <int Dummy>
+int small_type<Dummy>::const_copied = 0;
+
+template <int Dummy>
+int small_type<Dummy>::non_const_copied = 0;
+
+typedef small_type<> small;
+typedef small_type<1> small1;
+typedef small_type<2> small2;
+
+
+// A test type that will NOT trigger the small object optimization in any.
+template <int Dummy = 0>
+struct large_type
+{
+ static int count;
+ static int copied;
+ static int moved;
+ static int const_copied;
+ static int non_const_copied;
+
+ static void reset() {
+ large_type::copied = 0;
+ large_type::moved = 0;
+ large_type::const_copied = 0;
+ large_type::non_const_copied = 0;
+ }
+
+ int value;
+
+ large_type(int val) : value(val) {
+ ++count;
+ data[0] = 0;
+ }
+
+ large_type(large_type const & other) {
+ value = other.value;
+ ++count;
+ ++copied;
+ ++const_copied;
+ }
+
+ large_type(large_type & other) {
+ value = other.value;
+ ++count;
+ ++copied;
+ ++non_const_copied;
+ }
+
+ large_type(large_type && other) {
+ value = other.value;
+ other.value = 0;
+ ++count;
+ ++moved;
+ }
+
+ ~large_type() {
+ value = 0;
+ --count;
+ }
+
+private:
+ large_type& operator=(large_type const&) = delete;
+ large_type& operator=(large_type &&) = delete;
+ int data[10];
+};
+
+template <int Dummy>
+int large_type<Dummy>::count = 0;
+
+template <int Dummy>
+int large_type<Dummy>::copied = 0;
+
+template <int Dummy>
+int large_type<Dummy>::moved = 0;
+
+template <int Dummy>
+int large_type<Dummy>::const_copied = 0;
+
+template <int Dummy>
+int large_type<Dummy>::non_const_copied = 0;
+
+typedef large_type<> large;
+typedef large_type<1> large1;
+typedef large_type<2> large2;
+
+// The exception type thrown by 'small_throws_on_copy', 'large_throws_on_copy'
+// and 'throws_on_move'.
+struct my_any_exception {};
+
+void throwMyAnyExpression() {
+#if !defined(TEST_HAS_NO_EXCEPTIONS)
+ throw my_any_exception();
+#else
+ assert(false && "Exceptions are disabled");
+#endif
+}
+
+// A test type that will trigger the small object optimization within 'any'.
+// this type throws if it is copied.
+struct small_throws_on_copy
+{
+ static int count;
+ int value;
+
+ explicit small_throws_on_copy(int val = 0) : value(val) {
+ ++count;
+ }
+
+ small_throws_on_copy(small_throws_on_copy const &) {
+ throwMyAnyExpression();
+ }
+
+ small_throws_on_copy(small_throws_on_copy && other) throw() {
+ value = other.value;
+ ++count;
+ }
+
+ ~small_throws_on_copy() {
+ --count;
+ }
+private:
+ small_throws_on_copy& operator=(small_throws_on_copy const&) = delete;
+ small_throws_on_copy& operator=(small_throws_on_copy &&) = delete;
+};
+
+int small_throws_on_copy::count = 0;
+
+// A test type that will NOT trigger the small object optimization within 'any'.
+// this type throws if it is copied.
+struct large_throws_on_copy
+{
+ static int count;
+ int value = 0;
+
+ explicit large_throws_on_copy(int val = 0) : value(val) {
+ data[0] = 0;
+ ++count;
+ }
+
+ large_throws_on_copy(large_throws_on_copy const &) {
+ throwMyAnyExpression();
+ }
+
+ large_throws_on_copy(large_throws_on_copy && other) throw() {
+ value = other.value;
+ ++count;
+ }
+
+ ~large_throws_on_copy() {
+ --count;
+ }
+
+private:
+ large_throws_on_copy& operator=(large_throws_on_copy const&) = delete;
+ large_throws_on_copy& operator=(large_throws_on_copy &&) = delete;
+ int data[10];
+};
+
+int large_throws_on_copy::count = 0;
+
+// A test type that throws when it is moved. This object will NOT trigger
+// the small object optimization in 'any'.
+struct throws_on_move
+{
+ static int count;
+ int value;
+
+ explicit throws_on_move(int val = 0) : value(val) { ++count; }
+
+ throws_on_move(throws_on_move const & other) {
+ value = other.value;
+ ++count;
+ }
+
+ throws_on_move(throws_on_move &&) {
+ throwMyAnyExpression();
+ }
+
+ ~throws_on_move() {
+ --count;
+ }
+private:
+ throws_on_move& operator=(throws_on_move const&) = delete;
+ throws_on_move& operator=(throws_on_move &&) = delete;
+};
+
+int throws_on_move::count = 0;
+
+
+#endif
diff --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h
index 3e4400af00e..752bcdaecdd 100644
--- a/libcxx/test/support/test_macros.h
+++ b/libcxx/test/support/test_macros.h
@@ -33,6 +33,13 @@
#else
#define TEST_HAS_BUILTIN(X) 0
#endif
+#ifdef __is_identifier
+// '__is_identifier' returns '0' if '__x' is a reserved identifier provided by
+// the compiler and '1' otherwise.
+#define TEST_HAS_BUILTIN_IDENTIFIER(X) !__is_identifier(X)
+#else
+#define TEST_HAS_BUILTIN_IDENTIFIER(X) 0
+#endif
#if defined(__apple_build_version__)
#define TEST_APPLE_CLANG_VER (__clang_major__ * 100) + __clang_minor__
OpenPOWER on IntegriCloud