• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  Unit test for boost::any.
2 //
3 //  See http://www.boost.org for most recent version, including documentation.
4 //
5 //  Copyright Antony Polukhin, 2013-2019.
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 
main()21 int main()
22 {
23     return EXIT_SUCCESS;
24 }
25 
26 #else
27 
28 namespace 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 
main()36 int 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 
43 namespace 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 
move_copy_conting_class()83         move_copy_conting_class(){}
move_copy_conting_class(move_copy_conting_class &&)84         move_copy_conting_class(move_copy_conting_class&& /*param*/) {
85             ++ moves_count;
86         }
87 
operator =(move_copy_conting_class &&)88         move_copy_conting_class& operator=(move_copy_conting_class&& /*param*/) {
89             ++ moves_count;
90             return *this;
91         }
92 
move_copy_conting_class(const move_copy_conting_class &)93         move_copy_conting_class(const move_copy_conting_class&) {
94             ++ copy_count;
95         }
operator =(const move_copy_conting_class &)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 
106 namespace any_tests // test definitions
107 {
108     using namespace boost;
109 
test_move_construction()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 
test_move_assignment()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 
test_copy_construction()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(), "copied 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 
test_copy_assignment()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(), "copied 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 
test_move_construction_from_value()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 
test_move_assignment_from_value()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 
test_copy_construction_from_value()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 
test_copy_assignment_from_value()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 
helper_method()280     const any helper_method() {
281         return true;
282     }
283 
helper_method1()284     const bool helper_method1() {
285         return true;
286     }
287 
test_construction_from_const_any_rv()288     void test_construction_from_const_any_rv()
289     {
290         any values[] = {helper_method(), helper_method1() };
291         (void)values;
292     }
293 
test_cast_to_rv()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 
332