xref: /minix3/external/bsd/libc++/dist/libcxx/test/support/any_helpers.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc #ifndef ANY_HELPERS_H
2*0a6a1f1dSLionel Sambuc #define ANY_HELPERS_H
3*0a6a1f1dSLionel Sambuc 
4*0a6a1f1dSLionel Sambuc #include <experimental/any>
5*0a6a1f1dSLionel Sambuc #include <typeinfo>
6*0a6a1f1dSLionel Sambuc #include <type_traits>
7*0a6a1f1dSLionel Sambuc #include <cassert>
8*0a6a1f1dSLionel Sambuc 
9*0a6a1f1dSLionel Sambuc #include "test_macros.h"
10*0a6a1f1dSLionel Sambuc 
11*0a6a1f1dSLionel Sambuc #if !defined(TEST_HAS_NO_RTTI)
12*0a6a1f1dSLionel Sambuc #define RTTI_ASSERT(X) assert(X)
13*0a6a1f1dSLionel Sambuc #else
14*0a6a1f1dSLionel Sambuc #define RTTI_ASSERT(X)
15*0a6a1f1dSLionel Sambuc #endif
16*0a6a1f1dSLionel Sambuc 
17*0a6a1f1dSLionel Sambuc template <class _Tp>
18*0a6a1f1dSLionel Sambuc   struct IsSmallObject
19*0a6a1f1dSLionel Sambuc     : public std::integral_constant<bool
20*0a6a1f1dSLionel Sambuc         , sizeof(_Tp) <= (sizeof(void*)*3)
21*0a6a1f1dSLionel Sambuc           && std::alignment_of<void*>::value
22*0a6a1f1dSLionel Sambuc              % std::alignment_of<_Tp>::value == 0
23*0a6a1f1dSLionel Sambuc           && std::is_nothrow_move_constructible<_Tp>::value
24*0a6a1f1dSLionel Sambuc         >
25*0a6a1f1dSLionel Sambuc   {};
26*0a6a1f1dSLionel Sambuc 
27*0a6a1f1dSLionel Sambuc 
28*0a6a1f1dSLionel Sambuc // Return 'true' if 'Type' will be considered a small type by 'any'
29*0a6a1f1dSLionel Sambuc template <class Type>
isSmallType()30*0a6a1f1dSLionel Sambuc bool isSmallType() {
31*0a6a1f1dSLionel Sambuc #if defined(_LIBCPP_VERSION)
32*0a6a1f1dSLionel Sambuc     return std::experimental::__any_imp::_IsSmallObject<Type>::value;
33*0a6a1f1dSLionel Sambuc #else
34*0a6a1f1dSLionel Sambuc     return IsSmallObject<Type>::value;
35*0a6a1f1dSLionel Sambuc #endif
36*0a6a1f1dSLionel Sambuc 
37*0a6a1f1dSLionel Sambuc }
38*0a6a1f1dSLionel Sambuc 
39*0a6a1f1dSLionel Sambuc // Assert that an object is empty. If the object used to contain an object
40*0a6a1f1dSLionel Sambuc // of type 'LastType' check that it can no longer be accessed.
41*0a6a1f1dSLionel Sambuc template <class LastType = int>
assertEmpty(std::experimental::any const & a)42*0a6a1f1dSLionel Sambuc void assertEmpty(std::experimental::any const& a) {
43*0a6a1f1dSLionel Sambuc     assert(a.empty());
44*0a6a1f1dSLionel Sambuc     RTTI_ASSERT(a.type() == typeid(void));
45*0a6a1f1dSLionel Sambuc     assert(std::experimental::any_cast<LastType const>(&a) == nullptr);
46*0a6a1f1dSLionel Sambuc }
47*0a6a1f1dSLionel Sambuc 
48*0a6a1f1dSLionel Sambuc // Assert that an 'any' object stores the specified 'Type' and 'value'.
49*0a6a1f1dSLionel Sambuc template <class Type>
50*0a6a1f1dSLionel Sambuc void assertContains(std::experimental::any const& a, int value = 1) {
51*0a6a1f1dSLionel Sambuc     assert(!a.empty());
52*0a6a1f1dSLionel Sambuc     RTTI_ASSERT(a.type() == typeid(Type));
53*0a6a1f1dSLionel Sambuc     assert(std::experimental::any_cast<Type const &>(a).value == value);
54*0a6a1f1dSLionel Sambuc }
55*0a6a1f1dSLionel Sambuc 
56*0a6a1f1dSLionel Sambuc // Modify the value of a "test type" stored within an any to the specified
57*0a6a1f1dSLionel Sambuc // 'value'.
58*0a6a1f1dSLionel Sambuc template <class Type>
modifyValue(std::experimental::any & a,int value)59*0a6a1f1dSLionel Sambuc void modifyValue(std::experimental::any& a, int value) {
60*0a6a1f1dSLionel Sambuc     assert(!a.empty());
61*0a6a1f1dSLionel Sambuc     RTTI_ASSERT(a.type() == typeid(Type));
62*0a6a1f1dSLionel Sambuc     std::experimental::any_cast<Type&>(a).value = value;
63*0a6a1f1dSLionel Sambuc }
64*0a6a1f1dSLionel Sambuc 
65*0a6a1f1dSLionel Sambuc // A test type that will trigger the small object optimization within 'any'.
66*0a6a1f1dSLionel Sambuc template <int Dummy = 0>
67*0a6a1f1dSLionel Sambuc struct small_type
68*0a6a1f1dSLionel Sambuc {
69*0a6a1f1dSLionel Sambuc     static int count;
70*0a6a1f1dSLionel Sambuc     static int copied;
71*0a6a1f1dSLionel Sambuc     static int moved;
72*0a6a1f1dSLionel Sambuc     static int const_copied;
73*0a6a1f1dSLionel Sambuc     static int non_const_copied;
74*0a6a1f1dSLionel Sambuc 
resetsmall_type75*0a6a1f1dSLionel Sambuc     static void reset() {
76*0a6a1f1dSLionel Sambuc         small_type::copied = 0;
77*0a6a1f1dSLionel Sambuc         small_type::moved = 0;
78*0a6a1f1dSLionel Sambuc         small_type::const_copied = 0;
79*0a6a1f1dSLionel Sambuc         small_type::non_const_copied = 0;
80*0a6a1f1dSLionel Sambuc     }
81*0a6a1f1dSLionel Sambuc 
82*0a6a1f1dSLionel Sambuc     int value;
83*0a6a1f1dSLionel Sambuc 
small_typesmall_type84*0a6a1f1dSLionel Sambuc     explicit small_type(int val) : value(val) {
85*0a6a1f1dSLionel Sambuc         ++count;
86*0a6a1f1dSLionel Sambuc     }
87*0a6a1f1dSLionel Sambuc 
throwsmall_type88*0a6a1f1dSLionel Sambuc     small_type(small_type const & other) throw() {
89*0a6a1f1dSLionel Sambuc         value = other.value;
90*0a6a1f1dSLionel Sambuc         ++count;
91*0a6a1f1dSLionel Sambuc         ++copied;
92*0a6a1f1dSLionel Sambuc         ++const_copied;
93*0a6a1f1dSLionel Sambuc     }
94*0a6a1f1dSLionel Sambuc 
throwsmall_type95*0a6a1f1dSLionel Sambuc     small_type(small_type& other) throw() {
96*0a6a1f1dSLionel Sambuc         value = other.value;
97*0a6a1f1dSLionel Sambuc         ++count;
98*0a6a1f1dSLionel Sambuc         ++copied;
99*0a6a1f1dSLionel Sambuc         ++non_const_copied;
100*0a6a1f1dSLionel Sambuc     }
101*0a6a1f1dSLionel Sambuc 
throwsmall_type102*0a6a1f1dSLionel Sambuc     small_type(small_type && other) throw() {
103*0a6a1f1dSLionel Sambuc         value = other.value;
104*0a6a1f1dSLionel Sambuc         other.value = 0;
105*0a6a1f1dSLionel Sambuc         ++count;
106*0a6a1f1dSLionel Sambuc         ++moved;
107*0a6a1f1dSLionel Sambuc     }
108*0a6a1f1dSLionel Sambuc 
~small_typesmall_type109*0a6a1f1dSLionel Sambuc     ~small_type() {
110*0a6a1f1dSLionel Sambuc         value = -1;
111*0a6a1f1dSLionel Sambuc         --count;
112*0a6a1f1dSLionel Sambuc     }
113*0a6a1f1dSLionel Sambuc 
114*0a6a1f1dSLionel Sambuc private:
115*0a6a1f1dSLionel Sambuc     small_type& operator=(small_type const&) = delete;
116*0a6a1f1dSLionel Sambuc     small_type& operator=(small_type&&) = delete;
117*0a6a1f1dSLionel Sambuc };
118*0a6a1f1dSLionel Sambuc 
119*0a6a1f1dSLionel Sambuc template <int Dummy>
120*0a6a1f1dSLionel Sambuc int small_type<Dummy>::count = 0;
121*0a6a1f1dSLionel Sambuc 
122*0a6a1f1dSLionel Sambuc template <int Dummy>
123*0a6a1f1dSLionel Sambuc int small_type<Dummy>::copied = 0;
124*0a6a1f1dSLionel Sambuc 
125*0a6a1f1dSLionel Sambuc template <int Dummy>
126*0a6a1f1dSLionel Sambuc int small_type<Dummy>::moved = 0;
127*0a6a1f1dSLionel Sambuc 
128*0a6a1f1dSLionel Sambuc template <int Dummy>
129*0a6a1f1dSLionel Sambuc int small_type<Dummy>::const_copied = 0;
130*0a6a1f1dSLionel Sambuc 
131*0a6a1f1dSLionel Sambuc template <int Dummy>
132*0a6a1f1dSLionel Sambuc int small_type<Dummy>::non_const_copied = 0;
133*0a6a1f1dSLionel Sambuc 
134*0a6a1f1dSLionel Sambuc typedef small_type<> small;
135*0a6a1f1dSLionel Sambuc typedef small_type<1> small1;
136*0a6a1f1dSLionel Sambuc typedef small_type<2> small2;
137*0a6a1f1dSLionel Sambuc 
138*0a6a1f1dSLionel Sambuc 
139*0a6a1f1dSLionel Sambuc // A test type that will NOT trigger the small object optimization in any.
140*0a6a1f1dSLionel Sambuc template <int Dummy = 0>
141*0a6a1f1dSLionel Sambuc struct large_type
142*0a6a1f1dSLionel Sambuc {
143*0a6a1f1dSLionel Sambuc     static int count;
144*0a6a1f1dSLionel Sambuc     static int copied;
145*0a6a1f1dSLionel Sambuc     static int moved;
146*0a6a1f1dSLionel Sambuc     static int const_copied;
147*0a6a1f1dSLionel Sambuc     static int non_const_copied;
148*0a6a1f1dSLionel Sambuc 
resetlarge_type149*0a6a1f1dSLionel Sambuc     static void reset() {
150*0a6a1f1dSLionel Sambuc         large_type::copied = 0;
151*0a6a1f1dSLionel Sambuc         large_type::moved  = 0;
152*0a6a1f1dSLionel Sambuc         large_type::const_copied = 0;
153*0a6a1f1dSLionel Sambuc         large_type::non_const_copied = 0;
154*0a6a1f1dSLionel Sambuc     }
155*0a6a1f1dSLionel Sambuc 
156*0a6a1f1dSLionel Sambuc     int value;
157*0a6a1f1dSLionel Sambuc 
large_typelarge_type158*0a6a1f1dSLionel Sambuc     large_type(int val) : value(val) {
159*0a6a1f1dSLionel Sambuc         ++count;
160*0a6a1f1dSLionel Sambuc         data[0] = 0;
161*0a6a1f1dSLionel Sambuc     }
162*0a6a1f1dSLionel Sambuc 
large_typelarge_type163*0a6a1f1dSLionel Sambuc     large_type(large_type const & other) {
164*0a6a1f1dSLionel Sambuc         value = other.value;
165*0a6a1f1dSLionel Sambuc         ++count;
166*0a6a1f1dSLionel Sambuc         ++copied;
167*0a6a1f1dSLionel Sambuc         ++const_copied;
168*0a6a1f1dSLionel Sambuc     }
169*0a6a1f1dSLionel Sambuc 
large_typelarge_type170*0a6a1f1dSLionel Sambuc     large_type(large_type & other) {
171*0a6a1f1dSLionel Sambuc         value = other.value;
172*0a6a1f1dSLionel Sambuc         ++count;
173*0a6a1f1dSLionel Sambuc         ++copied;
174*0a6a1f1dSLionel Sambuc         ++non_const_copied;
175*0a6a1f1dSLionel Sambuc     }
176*0a6a1f1dSLionel Sambuc 
large_typelarge_type177*0a6a1f1dSLionel Sambuc     large_type(large_type && other) {
178*0a6a1f1dSLionel Sambuc         value = other.value;
179*0a6a1f1dSLionel Sambuc         other.value = 0;
180*0a6a1f1dSLionel Sambuc         ++count;
181*0a6a1f1dSLionel Sambuc         ++moved;
182*0a6a1f1dSLionel Sambuc     }
183*0a6a1f1dSLionel Sambuc 
~large_typelarge_type184*0a6a1f1dSLionel Sambuc     ~large_type()  {
185*0a6a1f1dSLionel Sambuc         value = 0;
186*0a6a1f1dSLionel Sambuc         --count;
187*0a6a1f1dSLionel Sambuc     }
188*0a6a1f1dSLionel Sambuc 
189*0a6a1f1dSLionel Sambuc private:
190*0a6a1f1dSLionel Sambuc     large_type& operator=(large_type const&) = delete;
191*0a6a1f1dSLionel Sambuc     large_type& operator=(large_type &&) = delete;
192*0a6a1f1dSLionel Sambuc     int data[10];
193*0a6a1f1dSLionel Sambuc };
194*0a6a1f1dSLionel Sambuc 
195*0a6a1f1dSLionel Sambuc template <int Dummy>
196*0a6a1f1dSLionel Sambuc int large_type<Dummy>::count = 0;
197*0a6a1f1dSLionel Sambuc 
198*0a6a1f1dSLionel Sambuc template <int Dummy>
199*0a6a1f1dSLionel Sambuc int large_type<Dummy>::copied = 0;
200*0a6a1f1dSLionel Sambuc 
201*0a6a1f1dSLionel Sambuc template <int Dummy>
202*0a6a1f1dSLionel Sambuc int large_type<Dummy>::moved = 0;
203*0a6a1f1dSLionel Sambuc 
204*0a6a1f1dSLionel Sambuc template <int Dummy>
205*0a6a1f1dSLionel Sambuc int large_type<Dummy>::const_copied = 0;
206*0a6a1f1dSLionel Sambuc 
207*0a6a1f1dSLionel Sambuc template <int Dummy>
208*0a6a1f1dSLionel Sambuc int large_type<Dummy>::non_const_copied = 0;
209*0a6a1f1dSLionel Sambuc 
210*0a6a1f1dSLionel Sambuc typedef large_type<> large;
211*0a6a1f1dSLionel Sambuc typedef large_type<1> large1;
212*0a6a1f1dSLionel Sambuc typedef large_type<2> large2;
213*0a6a1f1dSLionel Sambuc 
214*0a6a1f1dSLionel Sambuc // The exception type thrown by 'small_throws_on_copy', 'large_throws_on_copy'
215*0a6a1f1dSLionel Sambuc // and 'throws_on_move'.
216*0a6a1f1dSLionel Sambuc struct my_any_exception {};
217*0a6a1f1dSLionel Sambuc 
throwMyAnyExpression()218*0a6a1f1dSLionel Sambuc void throwMyAnyExpression() {
219*0a6a1f1dSLionel Sambuc #if !defined(TEST_HAS_NO_EXCEPTIONS)
220*0a6a1f1dSLionel Sambuc         throw my_any_exception();
221*0a6a1f1dSLionel Sambuc #else
222*0a6a1f1dSLionel Sambuc         assert(false && "Exceptions are disabled");
223*0a6a1f1dSLionel Sambuc #endif
224*0a6a1f1dSLionel Sambuc }
225*0a6a1f1dSLionel Sambuc 
226*0a6a1f1dSLionel Sambuc // A test type that will trigger the small object optimization within 'any'.
227*0a6a1f1dSLionel Sambuc // this type throws if it is copied.
228*0a6a1f1dSLionel Sambuc struct small_throws_on_copy
229*0a6a1f1dSLionel Sambuc {
230*0a6a1f1dSLionel Sambuc     static int count;
231*0a6a1f1dSLionel Sambuc     int value;
232*0a6a1f1dSLionel Sambuc 
valuesmall_throws_on_copy233*0a6a1f1dSLionel Sambuc     explicit small_throws_on_copy(int val = 0) : value(val) {
234*0a6a1f1dSLionel Sambuc         ++count;
235*0a6a1f1dSLionel Sambuc     }
236*0a6a1f1dSLionel Sambuc 
small_throws_on_copysmall_throws_on_copy237*0a6a1f1dSLionel Sambuc     small_throws_on_copy(small_throws_on_copy const &) {
238*0a6a1f1dSLionel Sambuc         throwMyAnyExpression();
239*0a6a1f1dSLionel Sambuc     }
240*0a6a1f1dSLionel Sambuc 
throwsmall_throws_on_copy241*0a6a1f1dSLionel Sambuc     small_throws_on_copy(small_throws_on_copy && other) throw() {
242*0a6a1f1dSLionel Sambuc         value = other.value;
243*0a6a1f1dSLionel Sambuc         ++count;
244*0a6a1f1dSLionel Sambuc     }
245*0a6a1f1dSLionel Sambuc 
~small_throws_on_copysmall_throws_on_copy246*0a6a1f1dSLionel Sambuc     ~small_throws_on_copy() {
247*0a6a1f1dSLionel Sambuc         --count;
248*0a6a1f1dSLionel Sambuc     }
249*0a6a1f1dSLionel Sambuc private:
250*0a6a1f1dSLionel Sambuc     small_throws_on_copy& operator=(small_throws_on_copy const&) = delete;
251*0a6a1f1dSLionel Sambuc     small_throws_on_copy& operator=(small_throws_on_copy &&) = delete;
252*0a6a1f1dSLionel Sambuc };
253*0a6a1f1dSLionel Sambuc 
254*0a6a1f1dSLionel Sambuc int small_throws_on_copy::count = 0;
255*0a6a1f1dSLionel Sambuc 
256*0a6a1f1dSLionel Sambuc // A test type that will NOT trigger the small object optimization within 'any'.
257*0a6a1f1dSLionel Sambuc // this type throws if it is copied.
258*0a6a1f1dSLionel Sambuc struct large_throws_on_copy
259*0a6a1f1dSLionel Sambuc {
260*0a6a1f1dSLionel Sambuc     static int count;
261*0a6a1f1dSLionel Sambuc     int value = 0;
262*0a6a1f1dSLionel Sambuc 
valuelarge_throws_on_copy263*0a6a1f1dSLionel Sambuc     explicit large_throws_on_copy(int val = 0) : value(val) {
264*0a6a1f1dSLionel Sambuc         data[0] = 0;
265*0a6a1f1dSLionel Sambuc         ++count;
266*0a6a1f1dSLionel Sambuc     }
267*0a6a1f1dSLionel Sambuc 
large_throws_on_copylarge_throws_on_copy268*0a6a1f1dSLionel Sambuc     large_throws_on_copy(large_throws_on_copy const &) {
269*0a6a1f1dSLionel Sambuc          throwMyAnyExpression();
270*0a6a1f1dSLionel Sambuc     }
271*0a6a1f1dSLionel Sambuc 
throwlarge_throws_on_copy272*0a6a1f1dSLionel Sambuc     large_throws_on_copy(large_throws_on_copy && other) throw() {
273*0a6a1f1dSLionel Sambuc         value = other.value;
274*0a6a1f1dSLionel Sambuc         ++count;
275*0a6a1f1dSLionel Sambuc     }
276*0a6a1f1dSLionel Sambuc 
~large_throws_on_copylarge_throws_on_copy277*0a6a1f1dSLionel Sambuc     ~large_throws_on_copy() {
278*0a6a1f1dSLionel Sambuc         --count;
279*0a6a1f1dSLionel Sambuc     }
280*0a6a1f1dSLionel Sambuc 
281*0a6a1f1dSLionel Sambuc private:
282*0a6a1f1dSLionel Sambuc     large_throws_on_copy& operator=(large_throws_on_copy const&) = delete;
283*0a6a1f1dSLionel Sambuc     large_throws_on_copy& operator=(large_throws_on_copy &&) = delete;
284*0a6a1f1dSLionel Sambuc     int data[10];
285*0a6a1f1dSLionel Sambuc };
286*0a6a1f1dSLionel Sambuc 
287*0a6a1f1dSLionel Sambuc int large_throws_on_copy::count = 0;
288*0a6a1f1dSLionel Sambuc 
289*0a6a1f1dSLionel Sambuc // A test type that throws when it is moved. This object will NOT trigger
290*0a6a1f1dSLionel Sambuc // the small object optimization in 'any'.
291*0a6a1f1dSLionel Sambuc struct throws_on_move
292*0a6a1f1dSLionel Sambuc {
293*0a6a1f1dSLionel Sambuc     static int count;
294*0a6a1f1dSLionel Sambuc     int value;
295*0a6a1f1dSLionel Sambuc 
valuethrows_on_move296*0a6a1f1dSLionel Sambuc     explicit throws_on_move(int val = 0) : value(val) { ++count; }
297*0a6a1f1dSLionel Sambuc 
throws_on_movethrows_on_move298*0a6a1f1dSLionel Sambuc     throws_on_move(throws_on_move const & other) {
299*0a6a1f1dSLionel Sambuc         value = other.value;
300*0a6a1f1dSLionel Sambuc         ++count;
301*0a6a1f1dSLionel Sambuc     }
302*0a6a1f1dSLionel Sambuc 
throws_on_movethrows_on_move303*0a6a1f1dSLionel Sambuc     throws_on_move(throws_on_move &&) {
304*0a6a1f1dSLionel Sambuc         throwMyAnyExpression();
305*0a6a1f1dSLionel Sambuc     }
306*0a6a1f1dSLionel Sambuc 
~throws_on_movethrows_on_move307*0a6a1f1dSLionel Sambuc     ~throws_on_move() {
308*0a6a1f1dSLionel Sambuc         --count;
309*0a6a1f1dSLionel Sambuc     }
310*0a6a1f1dSLionel Sambuc private:
311*0a6a1f1dSLionel Sambuc     throws_on_move& operator=(throws_on_move const&) = delete;
312*0a6a1f1dSLionel Sambuc     throws_on_move& operator=(throws_on_move &&) = delete;
313*0a6a1f1dSLionel Sambuc };
314*0a6a1f1dSLionel Sambuc 
315*0a6a1f1dSLionel Sambuc int throws_on_move::count = 0;
316*0a6a1f1dSLionel Sambuc 
317*0a6a1f1dSLionel Sambuc 
318*0a6a1f1dSLionel Sambuc #endif
319