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
11
12 // <experimental/any>
13
14 // template <class ValueType>
15 // ValueType const any_cast(any const&);
16 //
17 // template <class ValueType>
18 // ValueType any_cast(any &);
19 //
20 // template <class ValueType>
21 // ValueType any_cast(any &&);
22
23 #include <experimental/any>
24 #include <type_traits>
25 #include <cassert>
26
27 #include "experimental_any_helpers.h"
28 #include "count_new.hpp"
29 #include "test_macros.h"
30
31 using std::experimental::any;
32 using std::experimental::any_cast;
33 using std::experimental::bad_any_cast;
34
35
36 // Test that the operators are NOT marked noexcept.
test_cast_is_not_noexcept()37 void test_cast_is_not_noexcept() {
38 any a;
39 static_assert(!noexcept(any_cast<int>(static_cast<any&>(a))), "");
40 static_assert(!noexcept(any_cast<int>(static_cast<any const&>(a))), "");
41 static_assert(!noexcept(any_cast<int>(static_cast<any &&>(a))), "");
42 }
43
44 // Test that the return type of any_cast is correct.
test_cast_return_type()45 void test_cast_return_type() {
46 any a;
47 static_assert(std::is_same<decltype(any_cast<int>(a)), int>::value, "");
48 static_assert(std::is_same<decltype(any_cast<int const>(a)), int>::value, "");
49 static_assert(std::is_same<decltype(any_cast<int&>(a)), int&>::value, "");
50 static_assert(std::is_same<decltype(any_cast<int const&>(a)), int const&>::value, "");
51
52 //static_assert(std::is_same<decltype(any_cast<int&&>(a)), int&&>::value, "");
53 //static_assert(std::is_same<decltype(any_cast<int const&&>(a)), int const&&>::value, "");
54
55 static_assert(std::is_same<decltype(any_cast<int>(std::move(a))), int>::value, "");
56 static_assert(std::is_same<decltype(any_cast<int const>(std::move(a))), int>::value, "");
57 static_assert(std::is_same<decltype(any_cast<int&>(std::move(a))), int&>::value, "");
58 static_assert(std::is_same<decltype(any_cast<int const&>(std::move(a))), int const&>::value, "");
59
60 //static_assert(std::is_same<decltype(any_cast<int&&>(std::move(a))), int&&>::value, "");
61 //static_assert(std::is_same<decltype(any_cast<int const&&>(std::move(a))), int const&&>::value, "");
62
63 any const& ca = a;
64 static_assert(std::is_same<decltype(any_cast<int>(ca)), int>::value, "");
65 static_assert(std::is_same<decltype(any_cast<int const>(ca)), int>::value, "");
66 static_assert(std::is_same<decltype(any_cast<int const&>(ca)), int const&>::value, "");
67
68 //static_assert(std::is_same<decltype(any_cast<int const&&>(ca)), int const&&>::value, "");
69 }
70
71 template <class Type, class ConstT = Type>
checkThrows(any & a)72 void checkThrows(any& a)
73 {
74 #if !defined(TEST_HAS_NO_EXCEPTIONS)
75 try {
76 any_cast<Type>(a);
77 assert(false);
78 } catch (bad_any_cast const &) {
79 // do nothing
80 } catch (...) {
81 assert(false);
82 }
83
84 try {
85 any_cast<ConstT>(static_cast<any const&>(a));
86 assert(false);
87 } catch (bad_any_cast const &) {
88 // do nothing
89 } catch (...) {
90 assert(false);
91 }
92
93 try {
94 any_cast<Type>(static_cast<any&&>(a));
95 assert(false);
96 } catch (bad_any_cast const &) {
97 // do nothing
98 } catch (...) {
99 assert(false);
100 }
101 #else
102 ((void)a);
103 #endif
104 }
105
test_cast_empty()106 void test_cast_empty() {
107 // None of these operations should allocate.
108 DisableAllocationGuard g; ((void)g);
109 any a;
110 checkThrows<int>(a);
111 }
112
113 template <class Type>
test_cast_to_reference()114 void test_cast_to_reference() {
115 assert(Type::count == 0);
116 Type::reset();
117 {
118 any a((Type(42)));
119 any const& ca = a;
120 assert(Type::count == 1);
121 assert(Type::copied == 0);
122 assert(Type::moved == 1);
123
124 // Try a cast to a bad type.
125 // NOTE: Type cannot be an int.
126 checkThrows<int>(a);
127 checkThrows<int&, int const&>(a);
128 checkThrows<Type*, Type const*>(a);
129 checkThrows<Type const*>(a);
130
131 // Check getting a type by reference from a non-const lvalue any.
132 {
133 Type& v = any_cast<Type&>(a);
134 assert(v.value == 42);
135
136 Type const &cv = any_cast<Type const&>(a);
137 assert(&cv == &v);
138 }
139 // Check getting a type by reference from a const lvalue any.
140 {
141 Type const& v = any_cast<Type const&>(ca);
142 assert(v.value == 42);
143
144 Type const &cv = any_cast<Type const&>(ca);
145 assert(&cv == &v);
146 }
147 // Check getting a type by reference from a non-const rvalue
148 {
149 Type& v = any_cast<Type&>(std::move(a));
150 assert(v.value == 42);
151
152 Type const &cv = any_cast<Type const&>(std::move(a));
153 assert(&cv == &v);
154 }
155 // Check getting a type by reference from a const rvalue any.
156 {
157 Type const& v = any_cast<Type const&>(std::move(ca));
158 assert(v.value == 42);
159
160 Type const &cv = any_cast<Type const&>(std::move(ca));
161 assert(&cv == &v);
162 }
163
164 // Check that the original object hasn't been changed.
165 assertContains<Type>(a, 42);
166
167 // Check that no objects have been created/copied/moved.
168 assert(Type::count == 1);
169 assert(Type::copied == 0);
170 assert(Type::moved == 1);
171 }
172 assert(Type::count == 0);
173 }
174
175 template <class Type>
test_cast_to_value()176 void test_cast_to_value() {
177 assert(Type::count == 0);
178 Type::reset();
179 {
180 any a((Type(42)));
181 assert(Type::count == 1);
182 assert(Type::copied == 0);
183 assert(Type::moved == 1);
184
185 // Try a cast to a bad type.
186 // NOTE: Type cannot be an int.
187 checkThrows<int>(a);
188 checkThrows<int&, int const&>(a);
189 checkThrows<Type*, Type const*>(a);
190 checkThrows<Type const*>(a);
191
192 Type::reset(); // NOTE: reset does not modify Type::count
193 // Check getting Type by value from a non-const lvalue any.
194 // This should cause the non-const copy constructor to be called.
195 {
196 Type t = any_cast<Type>(a);
197
198 assert(Type::count == 2);
199 assert(Type::copied == 1);
200 assert(Type::const_copied == 0);
201 assert(Type::non_const_copied == 1);
202 assert(Type::moved == 0);
203 assert(t.value == 42);
204 }
205 assert(Type::count == 1);
206 Type::reset();
207 // Check getting const Type by value from a non-const lvalue any.
208 // This should cause the const copy constructor to be called.
209 {
210 Type t = any_cast<Type const>(a);
211
212 assert(Type::count == 2);
213 assert(Type::copied == 1);
214 assert(Type::const_copied == 1);
215 assert(Type::non_const_copied == 0);
216 assert(Type::moved == 0);
217 assert(t.value == 42);
218 }
219 assert(Type::count == 1);
220 Type::reset();
221 // Check getting Type by value from a non-const lvalue any.
222 // This should cause the const copy constructor to be called.
223 {
224 Type t = any_cast<Type>(static_cast<any const&>(a));
225
226 assert(Type::count == 2);
227 assert(Type::copied == 1);
228 assert(Type::const_copied == 1);
229 assert(Type::non_const_copied == 0);
230 assert(Type::moved == 0);
231 assert(t.value == 42);
232 }
233 assert(Type::count == 1);
234 Type::reset();
235 // Check getting Type by value from a non-const rvalue any.
236 // This should cause the non-const copy constructor to be called.
237 {
238 Type t = any_cast<Type>(static_cast<any &&>(a));
239
240 assert(Type::count == 2);
241 assert(Type::copied == 1);
242 assert(Type::const_copied == 0);
243 assert(Type::non_const_copied == 1);
244 assert(Type::moved == 0);
245 assert(t.value == 42);
246 }
247 assert(Type::count == 1);
248 Type::reset();
249 // Check getting const Type by value from a non-const rvalue any.
250 // This should cause the const copy constructor to be called.
251 {
252 Type t = any_cast<Type const>(static_cast<any &&>(a));
253
254 assert(Type::count == 2);
255 assert(Type::copied == 1);
256 assert(Type::const_copied == 1);
257 assert(Type::non_const_copied == 0);
258 assert(Type::moved == 0);
259 assert(t.value == 42);
260 }
261 assert(Type::count == 1);
262 Type::reset();
263 // Check getting Type by value from a const rvalue any.
264 // This should cause the const copy constructor to be called.
265 {
266 Type t = any_cast<Type>(static_cast<any const&&>(a));
267
268 assert(Type::count == 2);
269 assert(Type::copied == 1);
270 assert(Type::const_copied == 1);
271 assert(Type::non_const_copied == 0);
272 assert(Type::moved == 0);
273 assert(t.value == 42);
274 }
275 // Ensure we still only have 1 Type object alive.
276 assert(Type::count == 1);
277
278 // Check that the original object hasn't been changed.
279 assertContains<Type>(a, 42);
280 }
281 assert(Type::count == 0);
282 }
283
284 // Even though you can't get a non-copyable class into std::any
285 // the standard requires that these overloads compile and function.
test_non_copyable_ref()286 void test_non_copyable_ref() {
287 struct no_copy
288 {
289 no_copy() {}
290 no_copy(no_copy &&) {}
291 private:
292 no_copy(no_copy const &);
293 };
294
295 any a;
296 checkThrows<no_copy &, no_copy const&>(a);
297 checkThrows<no_copy const&>(a);
298 assertEmpty(a);
299 }
300
main()301 int main() {
302 test_cast_is_not_noexcept();
303 test_cast_return_type();
304 test_cast_empty();
305 test_cast_to_reference<small>();
306 test_cast_to_reference<large>();
307 test_cast_to_value<small>();
308 test_cast_to_value<large>();
309 test_non_copyable_ref();
310 }
311