]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/variant/test/variant_get_test.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / variant / test / variant_get_test.cpp
1 //-----------------------------------------------------------------------------
2 // boost-libs variant/test/variant_get_test.cpp source file
3 // See http://www.boost.org for updates, documentation, and revision history.
4 //-----------------------------------------------------------------------------
5 //
6 // Copyright (c) 2014-2015 Antony Polukhin
7 //
8 // Distributed under the Boost Software License, Version 1.0. (See
9 // accompanying file LICENSE_1_0.txt or copy at
10 // http://www.boost.org/LICENSE_1_0.txt)
11
12 #include "boost/variant/get.hpp"
13 #include "boost/variant/variant.hpp"
14 #include "boost/variant/polymorphic_get.hpp"
15 #include "boost/variant/recursive_wrapper.hpp"
16 #include "boost/test/minimal.hpp"
17
18 struct base {
19 int trash;
20
21 base() : trash(123) {}
22 base(const base& b) : trash(b.trash) { int i = 100; (void)i; }
23 const base& operator=(const base& b) {
24 trash = b.trash;
25 int i = 100; (void)i;
26
27 return *this;
28 }
29
30 virtual ~base(){}
31 };
32
33 struct derived1 : base{};
34 struct derived2 : base{};
35
36 struct vbase { short trash; virtual ~vbase(){} virtual int foo() const { return 0; } };
37 struct vderived1 : virtual vbase{ virtual int foo() const { return 1; } };
38 struct vderived2 : virtual vbase{ virtual int foo() const { return 3; } };
39 struct vderived3 : vderived1, vderived2 { virtual int foo() const { return 3; } };
40
41 typedef boost::variant<int, base, derived1, derived2, std::string> var_t;
42 typedef boost::variant<int, derived1, derived2, std::string> var_t_shortened;
43 typedef boost::variant<base, derived1, derived2> var_t_no_fallback;
44 typedef boost::variant<int&, base&, derived1&, derived2&, std::string&> var_ref_t;
45 typedef boost::variant<const int&, const base&, const derived1&, const derived2&, const std::string&> var_cref_t;
46
47 struct recursive_structure;
48 typedef boost::variant<
49 int, base, derived1, derived2, std::string, boost::recursive_wrapper<recursive_structure>
50 > var_req_t;
51 struct recursive_structure { var_req_t var; };
52
53 template <class T, class V, class TestType>
54 inline void check_polymorphic_get_on_types_impl_single_type(V* v)
55 {
56 typedef typename boost::add_reference<TestType>::type ref_test_t;
57 typedef typename boost::add_reference<const TestType>::type cref_test_t;
58 const bool exact_same = !!boost::is_same<T, TestType>::value;
59 const bool ref_same = !!boost::is_same<T, ref_test_t>::value;
60
61 if (exact_same || ref_same) {
62 BOOST_CHECK(boost::polymorphic_get<TestType>(v));
63 BOOST_CHECK(boost::polymorphic_get<const TestType>(v));
64 BOOST_CHECK(boost::polymorphic_strict_get<TestType>(v));
65 BOOST_CHECK(boost::polymorphic_strict_get<const TestType>(v));
66 BOOST_CHECK(boost::polymorphic_relaxed_get<TestType>(v));
67 BOOST_CHECK(boost::polymorphic_relaxed_get<const TestType>(v));
68 } else {
69 if (ref_same) {
70 BOOST_CHECK(boost::polymorphic_get<ref_test_t>(v));
71 BOOST_CHECK(boost::polymorphic_get<cref_test_t>(v));
72 BOOST_CHECK(boost::polymorphic_strict_get<ref_test_t>(v));
73 BOOST_CHECK(boost::polymorphic_strict_get<cref_test_t>(v));
74 BOOST_CHECK(boost::polymorphic_relaxed_get<ref_test_t>(v));
75 BOOST_CHECK(boost::polymorphic_relaxed_get<cref_test_t>(v));
76 }
77
78 BOOST_CHECK(!boost::polymorphic_get<TestType>(v));
79 BOOST_CHECK(!boost::polymorphic_get<const TestType>(v));
80 BOOST_CHECK(!boost::polymorphic_strict_get<TestType>(v));
81 BOOST_CHECK(!boost::polymorphic_strict_get<const TestType>(v));
82 BOOST_CHECK(!boost::polymorphic_relaxed_get<TestType>(v));
83 BOOST_CHECK(!boost::polymorphic_relaxed_get<const TestType>(v));
84 }
85 }
86
87 template <class T, class V, class TestType>
88 inline void check_get_on_types_impl_single_type(V* v)
89 {
90 typedef typename boost::add_reference<TestType>::type ref_test_t;
91 typedef typename boost::add_reference<const TestType>::type cref_test_t;
92 const bool exact_same = !!boost::is_same<T, TestType>::value;
93 const bool ref_same = !!boost::is_same<T, ref_test_t>::value;
94
95 if (exact_same || ref_same) {
96 BOOST_CHECK(boost::get<TestType>(v));
97 BOOST_CHECK(boost::get<const TestType>(v));
98 BOOST_CHECK(boost::strict_get<TestType>(v));
99 BOOST_CHECK(boost::strict_get<const TestType>(v));
100 BOOST_CHECK(boost::relaxed_get<TestType>(v));
101 BOOST_CHECK(boost::relaxed_get<const TestType>(v));
102
103 BOOST_CHECK(boost::get<cref_test_t>(v));
104 BOOST_CHECK(boost::strict_get<cref_test_t>(v));
105 BOOST_CHECK(boost::relaxed_get<cref_test_t>(v));
106 } else {
107 if (ref_same) {
108 BOOST_CHECK(boost::get<ref_test_t>(v));
109 BOOST_CHECK(boost::get<cref_test_t>(v));
110 BOOST_CHECK(boost::strict_get<ref_test_t>(v));
111 BOOST_CHECK(boost::strict_get<cref_test_t>(v));
112 BOOST_CHECK(boost::relaxed_get<ref_test_t>(v));
113 BOOST_CHECK(boost::relaxed_get<cref_test_t>(v));
114 }
115
116 BOOST_CHECK(!boost::get<TestType>(v));
117 BOOST_CHECK(!boost::get<const TestType>(v));
118 BOOST_CHECK(!boost::strict_get<TestType>(v));
119 BOOST_CHECK(!boost::strict_get<const TestType>(v));
120 BOOST_CHECK(!boost::relaxed_get<TestType>(v));
121 BOOST_CHECK(!boost::relaxed_get<const TestType>(v));
122 }
123 }
124
125 template <class T, class V>
126 inline void check_get_on_types_impl(V* v)
127 {
128 check_get_on_types_impl_single_type<T, V, int>(v);
129 check_polymorphic_get_on_types_impl_single_type<T, V, int>(v);
130
131 check_get_on_types_impl_single_type<T, V, base>(v);
132
133 check_get_on_types_impl_single_type<T, V, derived1>(v);
134 check_polymorphic_get_on_types_impl_single_type<T, V, derived1>(v);
135
136 check_get_on_types_impl_single_type<T, V, derived2>(v);
137 check_polymorphic_get_on_types_impl_single_type<T, V, derived2>(v);
138
139 check_get_on_types_impl_single_type<T, V, std::string>(v);
140 check_polymorphic_get_on_types_impl_single_type<T, V, std::string>(v);
141
142 // Never exist in here
143 BOOST_CHECK(!boost::relaxed_get<short>(v));
144 BOOST_CHECK(!boost::relaxed_get<const short>(v));
145 BOOST_CHECK(!boost::relaxed_get<char>(v));
146 BOOST_CHECK(!boost::relaxed_get<char*>(v));
147 BOOST_CHECK(!boost::relaxed_get<bool>(v));
148 BOOST_CHECK(!boost::relaxed_get<const bool>(v));
149
150 BOOST_CHECK(!boost::polymorphic_relaxed_get<short>(v));
151 BOOST_CHECK(!boost::polymorphic_relaxed_get<const short>(v));
152 BOOST_CHECK(!boost::polymorphic_relaxed_get<char>(v));
153 BOOST_CHECK(!boost::polymorphic_relaxed_get<char*>(v));
154 BOOST_CHECK(!boost::polymorphic_relaxed_get<bool>(v));
155 BOOST_CHECK(!boost::polymorphic_relaxed_get<const bool>(v));
156
157 boost::get<T>(*v); // Must compile
158 boost::get<const T>(*v); // Must compile
159 boost::strict_get<T>(*v); // Must compile
160 boost::strict_get<const T>(*v); // Must compile
161
162 boost::polymorphic_get<T>(*v); // Must compile
163 boost::polymorphic_get<const T>(*v); // Must compile
164 boost::polymorphic_strict_get<T>(*v); // Must compile
165 boost::polymorphic_strict_get<const T>(*v); // Must compile
166 }
167
168 template <class T, class V>
169 inline void check_get_on_types(V* v)
170 {
171 check_get_on_types_impl<T, V>(v);
172 check_get_on_types_impl<T, const V>(v);
173 }
174
175 inline void get_test()
176 {
177 var_t v;
178 check_get_on_types<int>(&v);
179
180 var_t(base()).swap(v);
181 check_get_on_types<base>(&v);
182
183 var_t(derived1()).swap(v);
184 check_get_on_types<derived1>(&v);
185
186 var_t(derived2()).swap(v);
187 check_get_on_types<derived2>(&v);
188
189 var_t(std::string("Hello")).swap(v);
190 check_get_on_types<std::string>(&v);
191
192 var_t_shortened vs = derived2();
193 check_polymorphic_get_on_types_impl_single_type<derived2, var_t_shortened, int>(&vs);
194 check_polymorphic_get_on_types_impl_single_type<derived2, const var_t_shortened, int>(&vs);
195 // Checking that Base is really determinated
196 check_polymorphic_get_on_types_impl_single_type<base, var_t_shortened, base>(&vs);
197 check_polymorphic_get_on_types_impl_single_type<base, const var_t_shortened, base>(&vs);
198
199 vs = derived1();
200 check_polymorphic_get_on_types_impl_single_type<derived2, var_t_shortened, int>(&vs);
201 check_polymorphic_get_on_types_impl_single_type<derived2, const var_t_shortened, int>(&vs);
202 // Checking that Base is really determinated
203 check_polymorphic_get_on_types_impl_single_type<base, var_t_shortened, base>(&vs);
204 check_polymorphic_get_on_types_impl_single_type<base, const var_t_shortened, base>(&vs);
205 }
206
207 inline void get_test_no_fallback()
208 {
209 var_t_no_fallback v;
210 var_t_no_fallback(base()).swap(v);
211 check_polymorphic_get_on_types_impl_single_type<base, var_t_no_fallback, base>(&v);
212 check_polymorphic_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
213 check_get_on_types_impl_single_type<base, var_t_no_fallback, base>(&v);
214 check_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
215
216 var_t_no_fallback(derived1()).swap(v);
217 check_polymorphic_get_on_types_impl_single_type<base, var_t_no_fallback, base>(&v);
218 check_polymorphic_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
219 check_get_on_types_impl_single_type<derived1, var_t_no_fallback, derived1>(&v);
220 check_get_on_types_impl_single_type<derived1, const var_t_no_fallback, derived1>(&v);
221
222 var_t_no_fallback(derived2()).swap(v);
223 check_polymorphic_get_on_types_impl_single_type<base, var_t_no_fallback, base>(&v);
224 check_polymorphic_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
225 check_get_on_types_impl_single_type<derived2, var_t_no_fallback, derived2>(&v);
226 check_get_on_types_impl_single_type<derived2, const var_t_no_fallback, derived2>(&v);
227 }
228
229 inline void get_ref_test()
230 {
231 int i = 0;
232 var_ref_t v(i);
233 check_get_on_types<int>(&v);
234
235 base b;
236 var_ref_t v1(b);
237 check_get_on_types<base>(&v1);
238
239 derived1 d1;
240 var_ref_t v2(d1);
241 check_get_on_types<derived1>(&v2);
242
243 derived2 d2;
244 var_ref_t v3(d2);
245 check_get_on_types<derived2>(&v3);
246
247 std::string s("Hello");
248 var_ref_t v4(s);
249 check_get_on_types<std::string>(&v4);
250 }
251
252
253 inline void get_cref_test()
254 {
255 int i = 0;
256 var_cref_t v(i);
257 BOOST_CHECK(boost::get<const int>(&v));
258 BOOST_CHECK(!boost::get<const base>(&v));
259
260 base b;
261 var_cref_t v1(b);
262 BOOST_CHECK(boost::get<const base>(&v1));
263 BOOST_CHECK(!boost::get<const derived1>(&v1));
264 BOOST_CHECK(!boost::get<const int>(&v1));
265
266 std::string s("Hello");
267 const var_cref_t v4 = s;
268 BOOST_CHECK(boost::get<const std::string>(&v4));
269 BOOST_CHECK(!boost::get<const int>(&v4));
270 }
271
272 inline void get_recursive_test()
273 {
274 var_req_t v;
275 check_get_on_types<int>(&v);
276
277 var_req_t(base()).swap(v);
278 check_get_on_types<base>(&v);
279
280 var_req_t(derived1()).swap(v);
281 check_get_on_types<derived1>(&v);
282
283 var_req_t(derived2()).swap(v);
284 check_get_on_types<derived2>(&v);
285
286 var_req_t(std::string("Hello")).swap(v);
287 check_get_on_types<std::string>(&v);
288
289 recursive_structure s = { v }; // copying "v"
290 v = s;
291 check_get_on_types<recursive_structure>(&v);
292 }
293
294 template <class T>
295 inline void check_that_does_not_exist_impl()
296 {
297 using namespace boost::detail::variant;
298
299 BOOST_CHECK((holds_element<T, const int>::value));
300 BOOST_CHECK((!holds_element<T, short>::value));
301 BOOST_CHECK((!holds_element<T, short>::value));
302 BOOST_CHECK((!holds_element<T, const short>::value));
303 BOOST_CHECK((!holds_element<T, char*>::value));
304 BOOST_CHECK((!holds_element<T, const char*>::value));
305 BOOST_CHECK((!holds_element<T, char[5]>::value));
306 BOOST_CHECK((!holds_element<T, const char[5]>::value));
307 BOOST_CHECK((!holds_element<T, bool>::value));
308 BOOST_CHECK((!holds_element<T, const bool>::value));
309
310 BOOST_CHECK((!holds_element<T, boost::recursive_wrapper<int> >::value));
311 BOOST_CHECK((!holds_element<T, boost::recursive_wrapper<short> >::value));
312 BOOST_CHECK((!holds_element<T, boost::detail::reference_content<short> >::value));
313
314
315 BOOST_CHECK((holds_element_polymorphic<T, const int>::value));
316 BOOST_CHECK((!holds_element_polymorphic<T, short>::value));
317 BOOST_CHECK((!holds_element_polymorphic<T, short>::value));
318 BOOST_CHECK((!holds_element_polymorphic<T, const short>::value));
319 BOOST_CHECK((!holds_element_polymorphic<T, char*>::value));
320 BOOST_CHECK((!holds_element_polymorphic<T, const char*>::value));
321 BOOST_CHECK((!holds_element_polymorphic<T, char[5]>::value));
322 BOOST_CHECK((!holds_element_polymorphic<T, const char[5]>::value));
323 BOOST_CHECK((!holds_element_polymorphic<T, bool>::value));
324 BOOST_CHECK((!holds_element_polymorphic<T, const bool>::value));
325
326 BOOST_CHECK((!holds_element_polymorphic<T, boost::recursive_wrapper<int> >::value));
327 BOOST_CHECK((!holds_element_polymorphic<T, boost::recursive_wrapper<short> >::value));
328 BOOST_CHECK((!holds_element_polymorphic<T, boost::detail::reference_content<short> >::value));
329 }
330
331 inline void check_that_does_not_exist()
332 {
333 using namespace boost::detail::variant;
334
335 BOOST_CHECK((holds_element<var_t, int>::value));
336 BOOST_CHECK((holds_element<var_ref_t, int>::value));
337 BOOST_CHECK((!holds_element<var_cref_t, int>::value));
338
339 check_that_does_not_exist_impl<var_t>();
340 check_that_does_not_exist_impl<var_ref_t>();
341 check_that_does_not_exist_impl<var_cref_t>();
342 check_that_does_not_exist_impl<var_req_t>();
343 }
344
345 int test_main(int , char* [])
346 {
347 get_test();
348 get_test_no_fallback();
349 get_ref_test();
350 get_cref_test();
351 get_recursive_test();
352 check_that_does_not_exist();
353
354 return boost::exit_success;
355 }