blob: 0571c7070926b730b6600d12e411388e655d29de [file] [log] [blame]
Brian Silvermanffbc3082018-08-04 23:35:15 -07001// Unit test for boost::any.
2//
3// See http://www.boost.org for most recent version, including documentation.
4//
5// Copyright Antony Polukhin, 2013-2014.
6//
7// Distributed under the Boost
8// Software License, Version 1.0. (See accompanying file
9// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
10
11#include <cstdlib>
12#include <string>
13#include <utility>
14
15#include <boost/any.hpp>
16#include "test.hpp"
17#include <boost/move/move.hpp>
18
19#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
20
21int main()
22{
23 return EXIT_SUCCESS;
24}
25
26#else
27
28namespace any_tests
29{
30 typedef test<const char *, void (*)()> test_case;
31 typedef const test_case * test_case_iterator;
32
33 extern const test_case_iterator begin, end;
34}
35
36int main()
37{
38 using namespace any_tests;
39 tester<test_case_iterator> test_suite(begin, end);
40 return test_suite() ? EXIT_SUCCESS : EXIT_FAILURE;
41}
42
43namespace any_tests // test suite
44{
45 void test_move_construction();
46 void test_move_assignment();
47 void test_copy_construction();
48 void test_copy_assignment();
49
50 void test_move_construction_from_value();
51 void test_move_assignment_from_value();
52 void test_copy_construction_from_value();
53 void test_copy_assignment_from_value();
54 void test_construction_from_const_any_rv();
55 void test_cast_to_rv();
56
57
58 const test_case test_cases[] =
59 {
60 { "move construction of any", test_move_construction },
61 { "move assignment of any", test_move_assignment },
62 { "copy construction of any", test_copy_construction },
63 { "copy assignment of any", test_copy_assignment },
64
65 { "move construction from value", test_move_construction_from_value },
66 { "move assignment from value", test_move_assignment_from_value },
67 { "copy construction from value", test_copy_construction_from_value },
68 { "copy assignment from value", test_copy_assignment_from_value },
69 { "constructing from const any&&", test_construction_from_const_any_rv },
70 { "casting to rvalue reference", test_cast_to_rv }
71 };
72
73 const test_case_iterator begin = test_cases;
74 const test_case_iterator end =
75 test_cases + (sizeof test_cases / sizeof *test_cases);
76
77
78 class move_copy_conting_class {
79 public:
80 static unsigned int moves_count;
81 static unsigned int copy_count;
82
83 move_copy_conting_class(){}
84 move_copy_conting_class(move_copy_conting_class&& /*param*/) {
85 ++ moves_count;
86 }
87
88 move_copy_conting_class& operator=(move_copy_conting_class&& /*param*/) {
89 ++ moves_count;
90 return *this;
91 }
92
93 move_copy_conting_class(const move_copy_conting_class&) {
94 ++ copy_count;
95 }
96 move_copy_conting_class& operator=(const move_copy_conting_class& /*param*/) {
97 ++ copy_count;
98 return *this;
99 }
100 };
101
102 unsigned int move_copy_conting_class::moves_count = 0;
103 unsigned int move_copy_conting_class::copy_count = 0;
104}
105
106namespace any_tests // test definitions
107{
108 using namespace boost;
109
110 void test_move_construction()
111 {
112 any value0 = move_copy_conting_class();
113 move_copy_conting_class::copy_count = 0;
114 move_copy_conting_class::moves_count = 0;
115 any value(boost::move(value0));
116
117 check(value0.empty(), "moved away value is empty");
118 check_false(value.empty(), "empty");
119 check_equal(value.type(), typeindex::type_id<move_copy_conting_class>(), "type");
120 check_non_null(any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>");
121 check_equal(
122 move_copy_conting_class::copy_count, 0u,
123 "checking copy counts");
124 check_equal(
125 move_copy_conting_class::moves_count, 0u,
126 "checking move counts");
127 }
128
129 void test_move_assignment()
130 {
131 any value0 = move_copy_conting_class();
132 any value = move_copy_conting_class();
133 move_copy_conting_class::copy_count = 0;
134 move_copy_conting_class::moves_count = 0;
135 value = boost::move(value0);
136
137 check(value0.empty(), "moved away is empty");
138 check_false(value.empty(), "empty");
139 check_equal(value.type(), typeindex::type_id<move_copy_conting_class>(), "type");
140 check_non_null(any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>");
141 check_equal(
142 move_copy_conting_class::copy_count, 0u,
143 "checking copy counts");
144 check_equal(
145 move_copy_conting_class::moves_count, 0u,
146 "checking move counts");
147 }
148
149 void test_copy_construction()
150 {
151 any value0 = move_copy_conting_class();
152 move_copy_conting_class::copy_count = 0;
153 move_copy_conting_class::moves_count = 0;
154 any value(value0);
155
156 check_false(value0.empty(), "copyed value is not empty");
157 check_false(value.empty(), "empty");
158 check_equal(value.type(), typeindex::type_id<move_copy_conting_class>(), "type");
159 check_non_null(any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>");
160 check_equal(
161 move_copy_conting_class::copy_count, 1u,
162 "checking copy counts");
163 check_equal(
164 move_copy_conting_class::moves_count, 0u,
165 "checking move counts");
166 }
167
168 void test_copy_assignment()
169 {
170 any value0 = move_copy_conting_class();
171 any value = move_copy_conting_class();
172 move_copy_conting_class::copy_count = 0;
173 move_copy_conting_class::moves_count = 0;
174 value = value0;
175
176 check_false(value0.empty(), "copyied value is not empty");
177 check_false(value.empty(), "empty");
178 check_equal(value.type(), typeindex::type_id<move_copy_conting_class>(), "type");
179 check_non_null(any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>");
180 check_equal(
181 move_copy_conting_class::copy_count, 1u,
182 "checking copy counts");
183 check_equal(
184 move_copy_conting_class::moves_count, 0u,
185 "checking move counts");
186 }
187
188 void test_move_construction_from_value()
189 {
190 move_copy_conting_class value0;
191 move_copy_conting_class::copy_count = 0;
192 move_copy_conting_class::moves_count = 0;
193#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
194 any value(boost::move(value0));
195#else
196 any value(value0);
197#endif
198
199 check_false(value.empty(), "empty");
200 check_equal(value.type(), typeindex::type_id<move_copy_conting_class>(), "type");
201 check_non_null(any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>");
202
203#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
204 check_equal(
205 move_copy_conting_class::copy_count, 0u,
206 "checking copy counts");
207 check_equal(
208 move_copy_conting_class::moves_count, 1u,
209 "checking move counts");
210#endif
211
212 }
213
214 void test_move_assignment_from_value()
215 {
216 move_copy_conting_class value0;
217 any value;
218 move_copy_conting_class::copy_count = 0;
219 move_copy_conting_class::moves_count = 0;
220#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
221 value = boost::move(value0);
222#else
223 value = value0;
224#endif
225
226 check_false(value.empty(), "empty");
227 check_equal(value.type(), typeindex::type_id<move_copy_conting_class>(), "type");
228 check_non_null(any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>");
229
230#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
231 check_equal(
232 move_copy_conting_class::copy_count, 0u,
233 "checking copy counts");
234 check_equal(
235 move_copy_conting_class::moves_count, 1u,
236 "checking move counts");
237#endif
238
239 }
240
241 void test_copy_construction_from_value()
242 {
243 move_copy_conting_class value0;
244 move_copy_conting_class::copy_count = 0;
245 move_copy_conting_class::moves_count = 0;
246 any value(value0);
247
248 check_false(value.empty(), "empty");
249 check_equal(value.type(), typeindex::type_id<move_copy_conting_class>(), "type");
250 check_non_null(any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>");
251
252 check_equal(
253 move_copy_conting_class::copy_count, 1u,
254 "checking copy counts");
255 check_equal(
256 move_copy_conting_class::moves_count, 0u,
257 "checking move counts");
258 }
259
260 void test_copy_assignment_from_value()
261 {
262 move_copy_conting_class value0;
263 any value;
264 move_copy_conting_class::copy_count = 0;
265 move_copy_conting_class::moves_count = 0;
266 value = value0;
267
268 check_false(value.empty(), "empty");
269 check_equal(value.type(), typeindex::type_id<move_copy_conting_class>(), "type");
270 check_non_null(any_cast<move_copy_conting_class>(&value), "any_cast<move_copy_conting_class>");
271
272 check_equal(
273 move_copy_conting_class::copy_count, 1u,
274 "checking copy counts");
275 check_equal(
276 move_copy_conting_class::moves_count, 0u,
277 "checking move counts");
278 }
279
280 const any helper_method() {
281 return true;
282 }
283
284 const bool helper_method1() {
285 return true;
286 }
287
288 void test_construction_from_const_any_rv()
289 {
290 any values[] = {helper_method(), helper_method1() };
291 (void)values;
292 }
293
294 void test_cast_to_rv()
295 {
296 move_copy_conting_class value0;
297 any value;
298 value = value0;
299 move_copy_conting_class::copy_count = 0;
300 move_copy_conting_class::moves_count = 0;
301
302 move_copy_conting_class value1 = any_cast<move_copy_conting_class&&>(value);
303
304 check_equal(
305 move_copy_conting_class::copy_count, 0u,
306 "checking copy counts");
307 check_equal(
308 move_copy_conting_class::moves_count, 1u,
309 "checking move counts");
310 (void)value1;
311/* Following code shall fail to compile
312 const any cvalue = value0;
313 move_copy_conting_class::copy_count = 0;
314 move_copy_conting_class::moves_count = 0;
315
316 move_copy_conting_class value2 = any_cast<move_copy_conting_class&&>(cvalue);
317
318 check_equal(
319 move_copy_conting_class::copy_count, 1u,
320 "checking copy counts");
321 check_equal(
322 move_copy_conting_class::moves_count, 0u,
323 "checking move counts");
324 (void)value2;
325*/
326 }
327
328}
329
330#endif
331