1 //===----------------------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // UNSUPPORTED: c++98, c++03, c++11
12 // XFAIL: availability=macosx
16 // template <class ValueType>
17 // ValueType const any_cast(any const&);
19 // template <class ValueType>
20 // ValueType any_cast(any &);
22 // template <class ValueType>
23 // ValueType any_cast(any &&);
25 #include <experimental/any>
26 #include <type_traits>
29 #include "experimental_any_helpers.h"
30 #include "count_new.hpp"
31 #include "test_macros.h"
33 using std::experimental::any;
34 using std::experimental::any_cast;
35 using std::experimental::bad_any_cast;
38 // Test that the operators are NOT marked noexcept.
39 void test_cast_is_not_noexcept() {
41 static_assert(!noexcept(any_cast<int>(static_cast<any&>(a))), "");
42 static_assert(!noexcept(any_cast<int>(static_cast<any const&>(a))), "");
43 static_assert(!noexcept(any_cast<int>(static_cast<any &&>(a))), "");
46 // Test that the return type of any_cast is correct.
47 void test_cast_return_type() {
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>::value, "");
51 static_assert(std::is_same<decltype(any_cast<int&>(a)), int&>::value, "");
52 static_assert(std::is_same<decltype(any_cast<int const&>(a)), int const&>::value, "");
54 //static_assert(std::is_same<decltype(any_cast<int&&>(a)), int&&>::value, "");
55 //static_assert(std::is_same<decltype(any_cast<int const&&>(a)), int const&&>::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>::value, "");
59 static_assert(std::is_same<decltype(any_cast<int&>(std::move(a))), int&>::value, "");
60 static_assert(std::is_same<decltype(any_cast<int const&>(std::move(a))), int const&>::value, "");
62 //static_assert(std::is_same<decltype(any_cast<int&&>(std::move(a))), int&&>::value, "");
63 //static_assert(std::is_same<decltype(any_cast<int const&&>(std::move(a))), int const&&>::value, "");
66 static_assert(std::is_same<decltype(any_cast<int>(ca)), int>::value, "");
67 static_assert(std::is_same<decltype(any_cast<int const>(ca)), int>::value, "");
68 static_assert(std::is_same<decltype(any_cast<int const&>(ca)), int const&>::value, "");
70 //static_assert(std::is_same<decltype(any_cast<int const&&>(ca)), int const&&>::value, "");
73 template <class Type, class ConstT = Type>
74 void checkThrows(any& a)
76 #if !defined(TEST_HAS_NO_EXCEPTIONS)
80 } catch (bad_any_cast const &) {
87 any_cast<ConstT>(static_cast<any const&>(a));
89 } catch (bad_any_cast const &) {
96 any_cast<Type>(static_cast<any&&>(a));
98 } catch (bad_any_cast const &) {
108 void test_cast_empty() {
109 // None of these operations should allocate.
110 DisableAllocationGuard g; ((void)g);
115 template <class Type>
116 void test_cast_to_reference() {
117 assert(Type::count == 0);
122 assert(Type::count == 1);
123 assert(Type::copied == 0);
124 assert(Type::moved == 1);
126 // Try a cast to a bad type.
127 // NOTE: Type cannot be an int.
129 checkThrows<int&, int const&>(a);
130 checkThrows<Type*, Type const*>(a);
131 checkThrows<Type const*>(a);
133 // Check getting a type by reference from a non-const lvalue any.
135 Type& v = any_cast<Type&>(a);
136 assert(v.value == 42);
138 Type const &cv = any_cast<Type const&>(a);
141 // Check getting a type by reference from a const lvalue any.
143 Type const& v = any_cast<Type const&>(ca);
144 assert(v.value == 42);
146 Type const &cv = any_cast<Type const&>(ca);
149 // Check getting a type by reference from a non-const rvalue
151 Type& v = any_cast<Type&>(std::move(a));
152 assert(v.value == 42);
154 Type const &cv = any_cast<Type const&>(std::move(a));
157 // Check getting a type by reference from a const rvalue any.
159 Type const& v = any_cast<Type const&>(std::move(ca));
160 assert(v.value == 42);
162 Type const &cv = any_cast<Type const&>(std::move(ca));
166 // Check that the original object hasn't been changed.
167 assertContains<Type>(a, 42);
169 // Check that no objects have been created/copied/moved.
170 assert(Type::count == 1);
171 assert(Type::copied == 0);
172 assert(Type::moved == 1);
174 assert(Type::count == 0);
177 template <class Type>
178 void test_cast_to_value() {
179 assert(Type::count == 0);
183 assert(Type::count == 1);
184 assert(Type::copied == 0);
185 assert(Type::moved == 1);
187 // Try a cast to a bad type.
188 // NOTE: Type cannot be an int.
190 checkThrows<int&, int const&>(a);
191 checkThrows<Type*, Type const*>(a);
192 checkThrows<Type const*>(a);
194 Type::reset(); // NOTE: reset does not modify Type::count
195 // Check getting Type by value from a non-const lvalue any.
196 // This should cause the non-const copy constructor to be called.
198 Type t = any_cast<Type>(a);
200 assert(Type::count == 2);
201 assert(Type::copied == 1);
202 assert(Type::const_copied == 0);
203 assert(Type::non_const_copied == 1);
204 assert(Type::moved == 0);
205 assert(t.value == 42);
207 assert(Type::count == 1);
209 // Check getting const Type by value from a non-const lvalue any.
210 // This should cause the const copy constructor to be called.
212 Type t = any_cast<Type const>(a);
214 assert(Type::count == 2);
215 assert(Type::copied == 1);
216 assert(Type::const_copied == 1);
217 assert(Type::non_const_copied == 0);
218 assert(Type::moved == 0);
219 assert(t.value == 42);
221 assert(Type::count == 1);
223 // Check getting Type by value from a non-const lvalue any.
224 // This should cause the const copy constructor to be called.
226 Type t = any_cast<Type>(static_cast<any const&>(a));
228 assert(Type::count == 2);
229 assert(Type::copied == 1);
230 assert(Type::const_copied == 1);
231 assert(Type::non_const_copied == 0);
232 assert(Type::moved == 0);
233 assert(t.value == 42);
235 assert(Type::count == 1);
237 // Check getting Type by value from a non-const rvalue any.
238 // This should cause the non-const copy constructor to be called.
240 Type t = any_cast<Type>(static_cast<any &&>(a));
242 assert(Type::count == 2);
243 assert(Type::copied == 1);
244 assert(Type::const_copied == 0);
245 assert(Type::non_const_copied == 1);
246 assert(Type::moved == 0);
247 assert(t.value == 42);
249 assert(Type::count == 1);
251 // Check getting const Type by value from a non-const rvalue any.
252 // This should cause the const copy constructor to be called.
254 Type t = any_cast<Type const>(static_cast<any &&>(a));
256 assert(Type::count == 2);
257 assert(Type::copied == 1);
258 assert(Type::const_copied == 1);
259 assert(Type::non_const_copied == 0);
260 assert(Type::moved == 0);
261 assert(t.value == 42);
263 assert(Type::count == 1);
265 // Check getting Type by value from a const rvalue any.
266 // This should cause the const copy constructor to be called.
268 Type t = any_cast<Type>(static_cast<any const&&>(a));
270 assert(Type::count == 2);
271 assert(Type::copied == 1);
272 assert(Type::const_copied == 1);
273 assert(Type::non_const_copied == 0);
274 assert(Type::moved == 0);
275 assert(t.value == 42);
277 // Ensure we still only have 1 Type object alive.
278 assert(Type::count == 1);
280 // Check that the original object hasn't been changed.
281 assertContains<Type>(a, 42);
283 assert(Type::count == 0);
286 // Even though you can't get a non-copyable class into std::any
287 // the standard requires that these overloads compile and function.
288 void test_non_copyable_ref() {
292 no_copy(no_copy &&) {}
294 no_copy(no_copy const &);
298 checkThrows<no_copy &, no_copy const&>(a);
299 checkThrows<no_copy const&>(a);
304 test_cast_is_not_noexcept();
305 test_cast_return_type();
307 test_cast_to_reference<small>();
308 test_cast_to_reference<large>();
309 test_cast_to_value<small>();
310 test_cast_to_value<large>();
311 test_non_copyable_ref();