1 //===----------------------------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // UNSUPPORTED: c++98, c++03, c++11, c++14
11
12 // <any>
13
14 // template <class T, class ...Args> any make_any(Args&&...);
15 // template <class T, class U, class ...Args>
16 // any make_any(initializer_list<U>, Args&&...);
17
18 #include <any>
19 #include <cassert>
20
21 #include "any_helpers.h"
22 #include "count_new.hpp"
23 #include "test_macros.h"
24
25 using std::any;
26 using std::any_cast;
27
28
29 template <class Type>
test_make_any_type()30 void test_make_any_type() {
31 // constructing from a small type should perform no allocations.
32 DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
33 assert(Type::count == 0);
34 Type::reset();
35 {
36 any a = std::make_any<Type>();
37
38 assert(Type::count == 1);
39 assert(Type::copied == 0);
40 assert(Type::moved == 0);
41 assertContains<Type>(a, 0);
42 }
43 assert(Type::count == 0);
44 Type::reset();
45 {
46 any a = std::make_any<Type>(101);
47
48 assert(Type::count == 1);
49 assert(Type::copied == 0);
50 assert(Type::moved == 0);
51 assertContains<Type>(a, 101);
52 }
53 assert(Type::count == 0);
54 Type::reset();
55 {
56 any a = std::make_any<Type>(-1, 42, -1);
57
58 assert(Type::count == 1);
59 assert(Type::copied == 0);
60 assert(Type::moved == 0);
61 assertContains<Type>(a, 42);
62 }
63 assert(Type::count == 0);
64 Type::reset();
65 }
66
67 template <class Type>
test_make_any_type_tracked()68 void test_make_any_type_tracked() {
69 // constructing from a small type should perform no allocations.
70 DisableAllocationGuard g(isSmallType<Type>()); ((void)g);
71 {
72 any a = std::make_any<Type>();
73 assertArgsMatch<Type>(a);
74 }
75 {
76 any a = std::make_any<Type>(-1, 42, -1);
77 assertArgsMatch<Type, int, int, int>(a);
78 }
79 // initializer_list constructor tests
80 {
81 any a = std::make_any<Type>({-1, 42, -1});
82 assertArgsMatch<Type, std::initializer_list<int>>(a);
83 }
84 {
85 int x = 42;
86 any a = std::make_any<Type>({-1, 42, -1}, x);
87 assertArgsMatch<Type, std::initializer_list<int>, int&>(a);
88 }
89 }
90
91 #ifndef TEST_HAS_NO_EXCEPTIONS
92
93 struct SmallThrows {
SmallThrowsSmallThrows94 SmallThrows(int) { throw 42; }
SmallThrowsSmallThrows95 SmallThrows(std::initializer_list<int>, int) { throw 42; }
96 };
97 static_assert(IsSmallObject<SmallThrows>::value, "");
98
99 struct LargeThrows {
LargeThrowsLargeThrows100 LargeThrows(int) { throw 42; }
LargeThrowsLargeThrows101 LargeThrows(std::initializer_list<int>, int) { throw 42; }
102 int data[sizeof(std::any)];
103 };
104 static_assert(!IsSmallObject<LargeThrows>::value, "");
105
106 template <class Type>
test_make_any_throws()107 void test_make_any_throws()
108 {
109 {
110 try {
111 std::make_any<Type>(101);
112 assert(false);
113 } catch (int const&) {
114 }
115 }
116 {
117 try {
118 std::make_any<Type>({1, 2, 3}, 101);
119 assert(false);
120 } catch (int const&) {
121 }
122 }
123 }
124
125 #endif
126
main()127 int main() {
128 test_make_any_type<small>();
129 test_make_any_type<large>();
130 test_make_any_type<small_throws_on_copy>();
131 test_make_any_type<large_throws_on_copy>();
132 test_make_any_type<throws_on_move>();
133 test_make_any_type_tracked<small_tracked_t>();
134 test_make_any_type_tracked<large_tracked_t>();
135 #ifndef TEST_HAS_NO_EXCEPTIONS
136 test_make_any_throws<SmallThrows>();
137 test_make_any_throws<LargeThrows>();
138
139 #endif
140 }
141