]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/std/experimental/any/any.nonmembers/any.cast/any_cast_reference.pass.cpp
Vendor import of libc++ trunk r302418:
[FreeBSD/FreeBSD.git] / test / std / experimental / any / any.nonmembers / any.cast / any_cast_reference.pass.cpp
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 // XFAIL: availability=macosx
13
14 // <experimental/any>
15
16 // template <class ValueType>
17 // ValueType const any_cast(any const&);
18 //
19 // template <class ValueType>
20 // ValueType any_cast(any &);
21 //
22 // template <class ValueType>
23 // ValueType any_cast(any &&);
24
25 #include <experimental/any>
26 #include <type_traits>
27 #include <cassert>
28
29 #include "experimental_any_helpers.h"
30 #include "count_new.hpp"
31 #include "test_macros.h"
32
33 using std::experimental::any;
34 using std::experimental::any_cast;
35 using std::experimental::bad_any_cast;
36
37
38 // Test that the operators are NOT marked noexcept.
39 void test_cast_is_not_noexcept() {
40     any a;
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))), "");
44 }
45
46 // Test that the return type of any_cast is correct.
47 void test_cast_return_type() {
48     any a;
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, "");
53
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, "");
56
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, "");
61
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, "");
64
65     any const& ca = a;
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, "");
69
70     //static_assert(std::is_same<decltype(any_cast<int const&&>(ca)), int const&&>::value, "");
71 }
72
73 template <class Type, class ConstT = Type>
74 void checkThrows(any& a)
75 {
76 #if !defined(TEST_HAS_NO_EXCEPTIONS)
77     try {
78         any_cast<Type>(a);
79         assert(false);
80     } catch (bad_any_cast const &) {
81             // do nothing
82     } catch (...) {
83         assert(false);
84     }
85
86     try {
87         any_cast<ConstT>(static_cast<any const&>(a));
88         assert(false);
89     } catch (bad_any_cast const &) {
90             // do nothing
91     } catch (...) {
92         assert(false);
93     }
94
95     try {
96         any_cast<Type>(static_cast<any&&>(a));
97         assert(false);
98     } catch (bad_any_cast const &) {
99             // do nothing
100     } catch (...) {
101         assert(false);
102     }
103 #else
104   ((void)a);
105 #endif
106 }
107
108 void test_cast_empty() {
109     // None of these operations should allocate.
110     DisableAllocationGuard g; ((void)g);
111     any a;
112     checkThrows<int>(a);
113 }
114
115 template <class Type>
116 void test_cast_to_reference() {
117     assert(Type::count == 0);
118     Type::reset();
119     {
120         any a((Type(42)));
121         any const& ca = a;
122         assert(Type::count == 1);
123         assert(Type::copied == 0);
124         assert(Type::moved == 1);
125
126         // Try a cast to a bad type.
127         // NOTE: Type cannot be an int.
128         checkThrows<int>(a);
129         checkThrows<int&, int const&>(a);
130         checkThrows<Type*, Type const*>(a);
131         checkThrows<Type const*>(a);
132
133         // Check getting a type by reference from a non-const lvalue any.
134         {
135             Type& v = any_cast<Type&>(a);
136             assert(v.value == 42);
137
138             Type const &cv = any_cast<Type const&>(a);
139             assert(&cv == &v);
140         }
141         // Check getting a type by reference from a const lvalue any.
142         {
143             Type const& v = any_cast<Type const&>(ca);
144             assert(v.value == 42);
145
146             Type const &cv = any_cast<Type const&>(ca);
147             assert(&cv == &v);
148         }
149         // Check getting a type by reference from a non-const rvalue
150         {
151             Type& v = any_cast<Type&>(std::move(a));
152             assert(v.value == 42);
153
154             Type const &cv = any_cast<Type const&>(std::move(a));
155             assert(&cv == &v);
156         }
157         // Check getting a type by reference from a const rvalue any.
158         {
159             Type const& v = any_cast<Type const&>(std::move(ca));
160             assert(v.value == 42);
161
162             Type const &cv = any_cast<Type const&>(std::move(ca));
163             assert(&cv == &v);
164         }
165
166         // Check that the original object hasn't been changed.
167         assertContains<Type>(a, 42);
168
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);
173     }
174     assert(Type::count == 0);
175 }
176
177 template <class Type>
178 void test_cast_to_value() {
179     assert(Type::count == 0);
180     Type::reset();
181     {
182         any a((Type(42)));
183         assert(Type::count == 1);
184         assert(Type::copied == 0);
185         assert(Type::moved == 1);
186
187         // Try a cast to a bad type.
188         // NOTE: Type cannot be an int.
189         checkThrows<int>(a);
190         checkThrows<int&, int const&>(a);
191         checkThrows<Type*, Type const*>(a);
192         checkThrows<Type const*>(a);
193
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.
197         {
198             Type t = any_cast<Type>(a);
199
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);
206         }
207         assert(Type::count == 1);
208         Type::reset();
209         // Check getting const Type by value from a non-const lvalue any.
210         // This should cause the const copy constructor to be called.
211         {
212             Type t = any_cast<Type const>(a);
213
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);
220         }
221         assert(Type::count == 1);
222         Type::reset();
223         // Check getting Type by value from a non-const lvalue any.
224         // This should cause the const copy constructor to be called.
225         {
226             Type t = any_cast<Type>(static_cast<any const&>(a));
227
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);
234         }
235         assert(Type::count == 1);
236         Type::reset();
237         // Check getting Type by value from a non-const rvalue any.
238         // This should cause the non-const copy constructor to be called.
239         {
240             Type t = any_cast<Type>(static_cast<any &&>(a));
241
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);
248         }
249         assert(Type::count == 1);
250         Type::reset();
251         // Check getting const Type by value from a non-const rvalue any.
252         // This should cause the const copy constructor to be called.
253         {
254             Type t = any_cast<Type const>(static_cast<any &&>(a));
255
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);
262         }
263         assert(Type::count == 1);
264         Type::reset();
265         // Check getting Type by value from a const rvalue any.
266         // This should cause the const copy constructor to be called.
267         {
268             Type t = any_cast<Type>(static_cast<any const&&>(a));
269
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);
276         }
277         // Ensure we still only have 1 Type object alive.
278         assert(Type::count == 1);
279
280         // Check that the original object hasn't been changed.
281         assertContains<Type>(a, 42);
282     }
283     assert(Type::count == 0);
284 }
285
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() {
289     struct no_copy
290     {
291         no_copy() {}
292         no_copy(no_copy &&) {}
293     private:
294         no_copy(no_copy const &);
295     };
296
297     any a;
298     checkThrows<no_copy &, no_copy const&>(a);
299     checkThrows<no_copy const&>(a);
300     assertEmpty(a);
301 }
302
303 int main() {
304     test_cast_is_not_noexcept();
305     test_cast_return_type();
306     test_cast_empty();
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();
312 }