]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/any/test/any_test.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / any / test / any_test.cpp
1 // what: unit tests for variant type boost::any
2 // who: contributed by Kevlin Henney
3 // when: July 2001, 2013, 2014
4 // where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95
5
6 #include <cstdlib>
7 #include <string>
8 #include <vector>
9 #include <utility>
10
11 #include "boost/any.hpp"
12 #include "test.hpp"
13
14 namespace any_tests
15 {
16 typedef test<const char *, void (*)()> test_case;
17 typedef const test_case * test_case_iterator;
18
19 extern const test_case_iterator begin, end;
20 }
21
22 int main()
23 {
24 using namespace any_tests;
25 tester<test_case_iterator> test_suite(begin, end);
26 return test_suite() ? EXIT_SUCCESS : EXIT_FAILURE;
27 }
28
29 namespace any_tests // test suite
30 {
31 void test_default_ctor();
32 void test_converting_ctor();
33 void test_copy_ctor();
34 void test_copy_assign();
35 void test_converting_assign();
36 void test_bad_cast();
37 void test_swap();
38 void test_null_copying();
39 void test_cast_to_reference();
40 void test_with_array();
41 void test_with_func();
42 void test_clear();
43 void test_vectors();
44
45 const test_case test_cases[] =
46 {
47 { "default construction", test_default_ctor },
48 { "single argument construction", test_converting_ctor },
49 { "copy construction", test_copy_ctor },
50 { "copy assignment operator", test_copy_assign },
51 { "converting assignment operator", test_converting_assign },
52 { "failed custom keyword cast", test_bad_cast },
53 { "swap member function", test_swap },
54 { "copying operations on a null", test_null_copying },
55 { "cast to reference types", test_cast_to_reference },
56 { "storing an array inside", test_with_array },
57 { "implicit cast of returned value",test_with_func },
58 { "clear() methods", test_clear },
59 { "testing with vectors", test_vectors }
60 };
61
62 const test_case_iterator begin = test_cases;
63 const test_case_iterator end =
64 test_cases + (sizeof test_cases / sizeof *test_cases);
65
66
67
68 struct copy_counter
69 {
70
71 public:
72
73 copy_counter() {}
74 copy_counter(const copy_counter&) { ++count; }
75 copy_counter& operator=(const copy_counter&) { ++count; return *this; }
76 static int get_count() { return count; }
77
78 private:
79
80 static int count;
81
82 };
83
84 int copy_counter::count = 0;
85 }
86
87 namespace any_tests // test definitions
88 {
89 using namespace boost;
90
91 void test_default_ctor()
92 {
93 const any value;
94
95 check_true(value.empty(), "empty");
96 check_null(any_cast<int>(&value), "any_cast<int>");
97 check_equal(value.type(), boost::typeindex::type_id<void>(), "type");
98 }
99
100 void test_converting_ctor()
101 {
102 std::string text = "test message";
103 any value = text;
104
105 check_false(value.empty(), "empty");
106 check_equal(value.type(), boost::typeindex::type_id<std::string>(), "type");
107 check_null(any_cast<int>(&value), "any_cast<int>");
108 check_non_null(any_cast<std::string>(&value), "any_cast<std::string>");
109 check_equal(
110 any_cast<std::string>(value), text,
111 "comparing cast copy against original text");
112 check_unequal(
113 any_cast<std::string>(&value), &text,
114 "comparing address in copy against original text");
115 }
116
117 void test_copy_ctor()
118 {
119 std::string text = "test message";
120 any original = text, copy = original;
121
122 check_false(copy.empty(), "empty");
123 check_equal(boost::typeindex::type_index(original.type()), copy.type(), "type");
124 check_equal(
125 any_cast<std::string>(original), any_cast<std::string>(copy),
126 "comparing cast copy against original");
127 check_equal(
128 text, any_cast<std::string>(copy),
129 "comparing cast copy against original text");
130 check_unequal(
131 any_cast<std::string>(&original),
132 any_cast<std::string>(&copy),
133 "comparing address in copy against original");
134 }
135
136 void test_copy_assign()
137 {
138 std::string text = "test message";
139 any original = text, copy;
140 any * assign_result = &(copy = original);
141
142 check_false(copy.empty(), "empty");
143 check_equal(boost::typeindex::type_index(original.type()), copy.type(), "type");
144 check_equal(
145 any_cast<std::string>(original), any_cast<std::string>(copy),
146 "comparing cast copy against cast original");
147 check_equal(
148 text, any_cast<std::string>(copy),
149 "comparing cast copy against original text");
150 check_unequal(
151 any_cast<std::string>(&original),
152 any_cast<std::string>(&copy),
153 "comparing address in copy against original");
154 check_equal(assign_result, &copy, "address of assignment result");
155 }
156
157 void test_converting_assign()
158 {
159 std::string text = "test message";
160 any value;
161 any * assign_result = &(value = text);
162
163 check_false(value.empty(), "type");
164 check_equal(value.type(), boost::typeindex::type_id<std::string>(), "type");
165 check_null(any_cast<int>(&value), "any_cast<int>");
166 check_non_null(any_cast<std::string>(&value), "any_cast<std::string>");
167 check_equal(
168 any_cast<std::string>(value), text,
169 "comparing cast copy against original text");
170 check_unequal(
171 any_cast<std::string>(&value),
172 &text,
173 "comparing address in copy against original text");
174 check_equal(assign_result, &value, "address of assignment result");
175 }
176
177 void test_bad_cast()
178 {
179 std::string text = "test message";
180 any value = text;
181
182 TEST_CHECK_THROW(
183 any_cast<const char *>(value),
184 bad_any_cast,
185 "any_cast to incorrect type");
186 }
187
188 void test_swap()
189 {
190 std::string text = "test message";
191 any original = text, swapped;
192 std::string * original_ptr = any_cast<std::string>(&original);
193 any * swap_result = &original.swap(swapped);
194
195 check_true(original.empty(), "empty on original");
196 check_false(swapped.empty(), "empty on swapped");
197 check_equal(swapped.type(), boost::typeindex::type_id<std::string>(), "type");
198 check_equal(
199 text, any_cast<std::string>(swapped),
200 "comparing swapped copy against original text");
201 check_non_null(original_ptr, "address in pre-swapped original");
202 check_equal(
203 original_ptr,
204 any_cast<std::string>(&swapped),
205 "comparing address in swapped against original");
206 check_equal(swap_result, &original, "address of swap result");
207
208 any copy1 = copy_counter();
209 any copy2 = copy_counter();
210 int count = copy_counter::get_count();
211 swap(copy1, copy2);
212 check_equal(count, copy_counter::get_count(), "checking that free swap doesn't make any copies.");
213 }
214
215 void test_null_copying()
216 {
217 const any null;
218 any copied = null, assigned;
219 assigned = null;
220
221 check_true(null.empty(), "empty on null");
222 check_true(copied.empty(), "empty on copied");
223 check_true(assigned.empty(), "empty on copied");
224 }
225
226 void test_cast_to_reference()
227 {
228 any a(137);
229 const any b(a);
230
231 int & ra = any_cast<int &>(a);
232 int const & ra_c = any_cast<int const &>(a);
233 int volatile & ra_v = any_cast<int volatile &>(a);
234 int const volatile & ra_cv = any_cast<int const volatile&>(a);
235
236 check_true(
237 &ra == &ra_c && &ra == &ra_v && &ra == &ra_cv,
238 "cv references to same obj");
239
240 int const & rb_c = any_cast<int const &>(b);
241 int const volatile & rb_cv = any_cast<int const volatile &>(b);
242
243 check_true(&rb_c == &rb_cv, "cv references to copied const obj");
244 check_true(&ra != &rb_c, "copies hold different objects");
245
246 ++ra;
247 int incremented = any_cast<int>(a);
248 check_true(incremented == 138, "increment by reference changes value");
249
250 TEST_CHECK_THROW(
251 any_cast<char &>(a),
252 bad_any_cast,
253 "any_cast to incorrect reference type");
254
255 TEST_CHECK_THROW(
256 any_cast<const char &>(b),
257 bad_any_cast,
258 "any_cast to incorrect const reference type");
259 }
260
261 void test_with_array()
262 {
263 any value1("Char array");
264 any value2;
265 value2 = "Char array";
266
267 check_false(value1.empty(), "type");
268 check_false(value2.empty(), "type");
269
270 check_equal(value1.type(), boost::typeindex::type_id<const char*>(), "type");
271 check_equal(value2.type(), boost::typeindex::type_id<const char*>(), "type");
272
273 check_non_null(any_cast<const char*>(&value1), "any_cast<const char*>");
274 check_non_null(any_cast<const char*>(&value2), "any_cast<const char*>");
275 }
276
277 const std::string& returning_string1()
278 {
279 static const std::string ret("foo");
280 return ret;
281 }
282
283 std::string returning_string2()
284 {
285 static const std::string ret("foo");
286 return ret;
287 }
288
289 void test_with_func()
290 {
291 std::string s;
292 s = any_cast<std::string>(returning_string1());
293 s = any_cast<const std::string&>(returning_string1());
294
295 s = any_cast<std::string>(returning_string2());
296 s = any_cast<const std::string&>(returning_string2());
297
298 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
299 #if !defined(__INTEL_COMPILER) && !defined(__ICL) && (!defined(_MSC_VER) || _MSC_VER != 1600)
300 // Intel compiler thinks that it must choose the `any_cast(const any&)` function
301 // instead of the `any_cast(const any&&)`.
302 // Bug was not reported because of missing premier support account + annoying
303 // registrations requirements.
304
305 // MSVC-10 had a bug:
306 //
307 // any.hpp(291) : error C2440: 'return' : cannot convert.
308 // Conversion loses qualifiers
309 // any_test.cpp(304) : see reference to function template instantiation
310 //
311 // This issue was fixed in MSVC-11.
312
313 s = any_cast<std::string&&>(returning_string1());
314 #endif
315
316 s = any_cast<std::string&&>(returning_string2());
317 #endif
318 }
319
320
321 void test_clear()
322 {
323 std::string text = "test message";
324 any value = text;
325
326 check_false(value.empty(), "empty");
327
328 value.clear();
329 check_true(value.empty(), "non-empty after clear");
330
331 value.clear();
332 check_true(value.empty(), "non-empty after second clear");
333
334 value = text;
335 check_false(value.empty(), "empty");
336
337 value.clear();
338 check_true(value.empty(), "non-empty after clear");
339 }
340
341 // Following tests cover the case from #9462
342 // https://svn.boost.org/trac/boost/ticket/9462
343 boost::any makeVec()
344 {
345 return std::vector<int>(100 /*size*/, 7 /*value*/);
346 }
347
348 void test_vectors()
349 {
350 const std::vector<int>& vec = boost::any_cast<std::vector<int> >(makeVec());
351 check_equal(vec.size(), 100u, "size of vector extracted from boost::any");
352 check_equal(vec.back(), 7, "back value of vector extracted from boost::any");
353 check_equal(vec.front(), 7, "front value of vector extracted from boost::any");
354
355 std::vector<int> vec1 = boost::any_cast<std::vector<int> >(makeVec());
356 check_equal(vec1.size(), 100u, "size of second vector extracted from boost::any");
357 check_equal(vec1.back(), 7, "back value of second vector extracted from boost::any");
358 check_equal(vec1.front(), 7, "front value of second vector extracted from boost::any");
359
360 }
361
362 }
363
364 // Copyright Kevlin Henney, 2000, 2001. All rights reserved.
365 // Copyright Antony Polukhin, 2013-2014.
366 //
367 // Distributed under the Boost Software License, Version 1.0. (See
368 // accompanying file LICENSE_1_0.txt or copy at
369 // http://www.boost.org/LICENSE_1_0.txt)
370 //