]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/variant/test/variant_get_test.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / variant / test / variant_get_test.cpp
CommitLineData
7c673cae
FG
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//
b32b8144 6// Copyright (c) 2014-2017 Antony Polukhin
7c673cae
FG
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
b32b8144
FG
12#ifdef _MSC_VER
13#pragma warning(disable: 4127) // conditional expression is constant
14#endif
15
7c673cae
FG
16#include "boost/variant/get.hpp"
17#include "boost/variant/variant.hpp"
18#include "boost/variant/polymorphic_get.hpp"
19#include "boost/variant/recursive_wrapper.hpp"
20#include "boost/test/minimal.hpp"
21
22struct base {
23 int trash;
24
25 base() : trash(123) {}
26 base(const base& b) : trash(b.trash) { int i = 100; (void)i; }
27 const base& operator=(const base& b) {
28 trash = b.trash;
29 int i = 100; (void)i;
30
31 return *this;
32 }
33
34 virtual ~base(){}
35};
36
37struct derived1 : base{};
38struct derived2 : base{};
39
40struct vbase { short trash; virtual ~vbase(){} virtual int foo() const { return 0; } };
41struct vderived1 : virtual vbase{ virtual int foo() const { return 1; } };
42struct vderived2 : virtual vbase{ virtual int foo() const { return 3; } };
43struct vderived3 : vderived1, vderived2 { virtual int foo() const { return 3; } };
44
45typedef boost::variant<int, base, derived1, derived2, std::string> var_t;
46typedef boost::variant<int, derived1, derived2, std::string> var_t_shortened;
47typedef boost::variant<base, derived1, derived2> var_t_no_fallback;
48typedef boost::variant<int&, base&, derived1&, derived2&, std::string&> var_ref_t;
49typedef boost::variant<const int&, const base&, const derived1&, const derived2&, const std::string&> var_cref_t;
50
51struct recursive_structure;
52typedef boost::variant<
53 int, base, derived1, derived2, std::string, boost::recursive_wrapper<recursive_structure>
54> var_req_t;
55struct recursive_structure { var_req_t var; };
56
b32b8144 57template <class TypeInVariant, class V, class TestType>
7c673cae
FG
58inline void check_polymorphic_get_on_types_impl_single_type(V* v)
59{
60 typedef typename boost::add_reference<TestType>::type ref_test_t;
61 typedef typename boost::add_reference<const TestType>::type cref_test_t;
b32b8144
FG
62 const bool exact_same = !!boost::is_same<TypeInVariant, TestType>::value;
63 const bool ref_same = !!boost::is_same<TypeInVariant, ref_test_t>::value;
7c673cae
FG
64
65 if (exact_same || ref_same) {
66 BOOST_CHECK(boost::polymorphic_get<TestType>(v));
67 BOOST_CHECK(boost::polymorphic_get<const TestType>(v));
68 BOOST_CHECK(boost::polymorphic_strict_get<TestType>(v));
69 BOOST_CHECK(boost::polymorphic_strict_get<const TestType>(v));
70 BOOST_CHECK(boost::polymorphic_relaxed_get<TestType>(v));
71 BOOST_CHECK(boost::polymorphic_relaxed_get<const TestType>(v));
b32b8144
FG
72
73 BOOST_CHECK(boost::polymorphic_get<cref_test_t>(v));
74 BOOST_CHECK(boost::polymorphic_strict_get<cref_test_t>(v));
75 BOOST_CHECK(boost::polymorphic_relaxed_get<cref_test_t>(v));
76
7c673cae
FG
77 if (ref_same) {
78 BOOST_CHECK(boost::polymorphic_get<ref_test_t>(v));
79 BOOST_CHECK(boost::polymorphic_get<cref_test_t>(v));
80 BOOST_CHECK(boost::polymorphic_strict_get<ref_test_t>(v));
81 BOOST_CHECK(boost::polymorphic_strict_get<cref_test_t>(v));
82 BOOST_CHECK(boost::polymorphic_relaxed_get<ref_test_t>(v));
83 BOOST_CHECK(boost::polymorphic_relaxed_get<cref_test_t>(v));
84 }
b32b8144 85 } else {
7c673cae
FG
86 BOOST_CHECK(!boost::polymorphic_get<TestType>(v));
87 BOOST_CHECK(!boost::polymorphic_get<const TestType>(v));
88 BOOST_CHECK(!boost::polymorphic_strict_get<TestType>(v));
89 BOOST_CHECK(!boost::polymorphic_strict_get<const TestType>(v));
90 BOOST_CHECK(!boost::polymorphic_relaxed_get<TestType>(v));
91 BOOST_CHECK(!boost::polymorphic_relaxed_get<const TestType>(v));
92 }
93}
94
95template <class T, class V, class TestType>
96inline void check_get_on_types_impl_single_type(V* v)
97{
98 typedef typename boost::add_reference<TestType>::type ref_test_t;
99 typedef typename boost::add_reference<const TestType>::type cref_test_t;
100 const bool exact_same = !!boost::is_same<T, TestType>::value;
101 const bool ref_same = !!boost::is_same<T, ref_test_t>::value;
102
103 if (exact_same || ref_same) {
104 BOOST_CHECK(boost::get<TestType>(v));
105 BOOST_CHECK(boost::get<const TestType>(v));
106 BOOST_CHECK(boost::strict_get<TestType>(v));
107 BOOST_CHECK(boost::strict_get<const TestType>(v));
108 BOOST_CHECK(boost::relaxed_get<TestType>(v));
109 BOOST_CHECK(boost::relaxed_get<const TestType>(v));
110
111 BOOST_CHECK(boost::get<cref_test_t>(v));
112 BOOST_CHECK(boost::strict_get<cref_test_t>(v));
113 BOOST_CHECK(boost::relaxed_get<cref_test_t>(v));
b32b8144 114
7c673cae
FG
115 if (ref_same) {
116 BOOST_CHECK(boost::get<ref_test_t>(v));
117 BOOST_CHECK(boost::get<cref_test_t>(v));
118 BOOST_CHECK(boost::strict_get<ref_test_t>(v));
119 BOOST_CHECK(boost::strict_get<cref_test_t>(v));
120 BOOST_CHECK(boost::relaxed_get<ref_test_t>(v));
121 BOOST_CHECK(boost::relaxed_get<cref_test_t>(v));
122 }
b32b8144 123 } else {
7c673cae
FG
124 BOOST_CHECK(!boost::get<TestType>(v));
125 BOOST_CHECK(!boost::get<const TestType>(v));
126 BOOST_CHECK(!boost::strict_get<TestType>(v));
127 BOOST_CHECK(!boost::strict_get<const TestType>(v));
128 BOOST_CHECK(!boost::relaxed_get<TestType>(v));
129 BOOST_CHECK(!boost::relaxed_get<const TestType>(v));
130 }
131}
132
133template <class T, class V>
134inline void check_get_on_types_impl(V* v)
135{
136 check_get_on_types_impl_single_type<T, V, int>(v);
137 check_polymorphic_get_on_types_impl_single_type<T, V, int>(v);
138
139 check_get_on_types_impl_single_type<T, V, base>(v);
140
141 check_get_on_types_impl_single_type<T, V, derived1>(v);
142 check_polymorphic_get_on_types_impl_single_type<T, V, derived1>(v);
143
144 check_get_on_types_impl_single_type<T, V, derived2>(v);
145 check_polymorphic_get_on_types_impl_single_type<T, V, derived2>(v);
146
147 check_get_on_types_impl_single_type<T, V, std::string>(v);
148 check_polymorphic_get_on_types_impl_single_type<T, V, std::string>(v);
149
150 // Never exist in here
151 BOOST_CHECK(!boost::relaxed_get<short>(v));
152 BOOST_CHECK(!boost::relaxed_get<const short>(v));
153 BOOST_CHECK(!boost::relaxed_get<char>(v));
154 BOOST_CHECK(!boost::relaxed_get<char*>(v));
155 BOOST_CHECK(!boost::relaxed_get<bool>(v));
156 BOOST_CHECK(!boost::relaxed_get<const bool>(v));
157
158 BOOST_CHECK(!boost::polymorphic_relaxed_get<short>(v));
159 BOOST_CHECK(!boost::polymorphic_relaxed_get<const short>(v));
160 BOOST_CHECK(!boost::polymorphic_relaxed_get<char>(v));
161 BOOST_CHECK(!boost::polymorphic_relaxed_get<char*>(v));
162 BOOST_CHECK(!boost::polymorphic_relaxed_get<bool>(v));
163 BOOST_CHECK(!boost::polymorphic_relaxed_get<const bool>(v));
164
165 boost::get<T>(*v); // Must compile
166 boost::get<const T>(*v); // Must compile
167 boost::strict_get<T>(*v); // Must compile
168 boost::strict_get<const T>(*v); // Must compile
169
b32b8144
FG
170 bool is_ref = boost::is_lvalue_reference<T>::value;
171 (void)is_ref;
172 if (!is_ref) {
173 boost::polymorphic_get<T>(*v); // Must compile
174 boost::polymorphic_get<const T>(*v); // Must compile
175 boost::polymorphic_strict_get<T>(*v); // Must compile
176 boost::polymorphic_strict_get<const T>(*v); // Must compile
177 }
7c673cae
FG
178}
179
180template <class T, class V>
181inline void check_get_on_types(V* v)
182{
183 check_get_on_types_impl<T, V>(v);
184 check_get_on_types_impl<T, const V>(v);
185}
186
187inline void get_test()
188{
189 var_t v;
190 check_get_on_types<int>(&v);
191
192 var_t(base()).swap(v);
193 check_get_on_types<base>(&v);
194
195 var_t(derived1()).swap(v);
196 check_get_on_types<derived1>(&v);
197
198 var_t(derived2()).swap(v);
199 check_get_on_types<derived2>(&v);
200
201 var_t(std::string("Hello")).swap(v);
202 check_get_on_types<std::string>(&v);
203
204 var_t_shortened vs = derived2();
205 check_polymorphic_get_on_types_impl_single_type<derived2, var_t_shortened, int>(&vs);
206 check_polymorphic_get_on_types_impl_single_type<derived2, const var_t_shortened, int>(&vs);
207 // Checking that Base is really determinated
208 check_polymorphic_get_on_types_impl_single_type<base, var_t_shortened, base>(&vs);
209 check_polymorphic_get_on_types_impl_single_type<base, const var_t_shortened, base>(&vs);
210
211 vs = derived1();
212 check_polymorphic_get_on_types_impl_single_type<derived2, var_t_shortened, int>(&vs);
213 check_polymorphic_get_on_types_impl_single_type<derived2, const var_t_shortened, int>(&vs);
214 // Checking that Base is really determinated
215 check_polymorphic_get_on_types_impl_single_type<base, var_t_shortened, base>(&vs);
216 check_polymorphic_get_on_types_impl_single_type<base, const var_t_shortened, base>(&vs);
217}
218
219inline void get_test_no_fallback()
220{
221 var_t_no_fallback v;
222 var_t_no_fallback(base()).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<base, var_t_no_fallback, base>(&v);
226 check_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
227
228 var_t_no_fallback(derived1()).swap(v);
229 check_polymorphic_get_on_types_impl_single_type<base, var_t_no_fallback, base>(&v);
230 check_polymorphic_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
231 check_get_on_types_impl_single_type<derived1, var_t_no_fallback, derived1>(&v);
232 check_get_on_types_impl_single_type<derived1, const var_t_no_fallback, derived1>(&v);
233
234 var_t_no_fallback(derived2()).swap(v);
235 check_polymorphic_get_on_types_impl_single_type<base, var_t_no_fallback, base>(&v);
236 check_polymorphic_get_on_types_impl_single_type<base, const var_t_no_fallback, base>(&v);
237 check_get_on_types_impl_single_type<derived2, var_t_no_fallback, derived2>(&v);
238 check_get_on_types_impl_single_type<derived2, const var_t_no_fallback, derived2>(&v);
239}
240
241inline void get_ref_test()
242{
243 int i = 0;
244 var_ref_t v(i);
245 check_get_on_types<int>(&v);
b32b8144 246 check_get_on_types<int&>(&v);
7c673cae
FG
247
248 base b;
249 var_ref_t v1(b);
250 check_get_on_types<base>(&v1);
b32b8144 251 check_get_on_types<base&>(&v1);
7c673cae
FG
252
253 derived1 d1;
254 var_ref_t v2(d1);
255 check_get_on_types<derived1>(&v2);
b32b8144 256 check_get_on_types<derived1&>(&v2);
7c673cae
FG
257
258 derived2 d2;
259 var_ref_t v3(d2);
260 check_get_on_types<derived2>(&v3);
b32b8144 261 check_get_on_types<derived2&>(&v3);
7c673cae
FG
262
263 std::string s("Hello");
264 var_ref_t v4(s);
265 check_get_on_types<std::string>(&v4);
b32b8144 266 check_get_on_types<std::string&>(&v4);
7c673cae
FG
267}
268
269
270inline void get_cref_test()
271{
272 int i = 0;
273 var_cref_t v(i);
274 BOOST_CHECK(boost::get<const int>(&v));
b32b8144 275 BOOST_CHECK(boost::get<const int&>(&v));
7c673cae
FG
276 BOOST_CHECK(!boost::get<const base>(&v));
277
278 base b;
279 var_cref_t v1(b);
280 BOOST_CHECK(boost::get<const base>(&v1));
281 BOOST_CHECK(!boost::get<const derived1>(&v1));
282 BOOST_CHECK(!boost::get<const int>(&v1));
283
284 std::string s("Hello");
285 const var_cref_t v4 = s;
286 BOOST_CHECK(boost::get<const std::string>(&v4));
287 BOOST_CHECK(!boost::get<const int>(&v4));
288}
289
290inline void get_recursive_test()
291{
292 var_req_t v;
293 check_get_on_types<int>(&v);
294
295 var_req_t(base()).swap(v);
296 check_get_on_types<base>(&v);
297
298 var_req_t(derived1()).swap(v);
299 check_get_on_types<derived1>(&v);
300
301 var_req_t(derived2()).swap(v);
302 check_get_on_types<derived2>(&v);
303
304 var_req_t(std::string("Hello")).swap(v);
305 check_get_on_types<std::string>(&v);
306
307 recursive_structure s = { v }; // copying "v"
308 v = s;
309 check_get_on_types<recursive_structure>(&v);
310}
311
312template <class T>
313inline void check_that_does_not_exist_impl()
314{
315 using namespace boost::detail::variant;
316
317 BOOST_CHECK((holds_element<T, const int>::value));
318 BOOST_CHECK((!holds_element<T, short>::value));
319 BOOST_CHECK((!holds_element<T, short>::value));
320 BOOST_CHECK((!holds_element<T, const short>::value));
321 BOOST_CHECK((!holds_element<T, char*>::value));
322 BOOST_CHECK((!holds_element<T, const char*>::value));
323 BOOST_CHECK((!holds_element<T, char[5]>::value));
324 BOOST_CHECK((!holds_element<T, const char[5]>::value));
325 BOOST_CHECK((!holds_element<T, bool>::value));
326 BOOST_CHECK((!holds_element<T, const bool>::value));
327
328 BOOST_CHECK((!holds_element<T, boost::recursive_wrapper<int> >::value));
329 BOOST_CHECK((!holds_element<T, boost::recursive_wrapper<short> >::value));
330 BOOST_CHECK((!holds_element<T, boost::detail::reference_content<short> >::value));
331
332
333 BOOST_CHECK((holds_element_polymorphic<T, const int>::value));
334 BOOST_CHECK((!holds_element_polymorphic<T, short>::value));
335 BOOST_CHECK((!holds_element_polymorphic<T, short>::value));
336 BOOST_CHECK((!holds_element_polymorphic<T, const short>::value));
337 BOOST_CHECK((!holds_element_polymorphic<T, char*>::value));
338 BOOST_CHECK((!holds_element_polymorphic<T, const char*>::value));
339 BOOST_CHECK((!holds_element_polymorphic<T, char[5]>::value));
340 BOOST_CHECK((!holds_element_polymorphic<T, const char[5]>::value));
341 BOOST_CHECK((!holds_element_polymorphic<T, bool>::value));
342 BOOST_CHECK((!holds_element_polymorphic<T, const bool>::value));
343
344 BOOST_CHECK((!holds_element_polymorphic<T, boost::recursive_wrapper<int> >::value));
345 BOOST_CHECK((!holds_element_polymorphic<T, boost::recursive_wrapper<short> >::value));
346 BOOST_CHECK((!holds_element_polymorphic<T, boost::detail::reference_content<short> >::value));
347}
348
349inline void check_that_does_not_exist()
350{
351 using namespace boost::detail::variant;
352
353 BOOST_CHECK((holds_element<var_t, int>::value));
354 BOOST_CHECK((holds_element<var_ref_t, int>::value));
355 BOOST_CHECK((!holds_element<var_cref_t, int>::value));
356
357 check_that_does_not_exist_impl<var_t>();
358 check_that_does_not_exist_impl<var_ref_t>();
359 check_that_does_not_exist_impl<var_cref_t>();
360 check_that_does_not_exist_impl<var_req_t>();
361}
362
b32b8144
FG
363#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
364class MoveonlyType {
365public:
366 MoveonlyType() {}
367 ~MoveonlyType() {}
368
369 MoveonlyType(MoveonlyType&&) {}
370 void operator=(MoveonlyType&&) {}
371
372private:
373 MoveonlyType(const MoveonlyType&);
374 void operator=(const MoveonlyType&);
375};
376
377const boost::variant<int, std::string> foo1() { return ""; }
378boost::variant<int, std::string> foo2() { return ""; }
379
380inline void get_rvref_test()
381{
382 boost::get<std::string>(foo1());
383 boost::get<std::string>(foo2());
384
385 boost::variant<MoveonlyType, int> v;
386
387 v = MoveonlyType();
388 boost::get<MoveonlyType>(boost::move(v));
389
390 v = 3;
391
392 v = MoveonlyType();
393 boost::get<MoveonlyType>(v);
394
395 boost::relaxed_get<MoveonlyType&>(boost::variant<MoveonlyType, int>());
396
397 v = MoveonlyType();
398 MoveonlyType moved_from_variant(boost::get<MoveonlyType>(boost::move(v)));
399}
400#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
401
7c673cae
FG
402int test_main(int , char* [])
403{
404 get_test();
405 get_test_no_fallback();
406 get_ref_test();
407 get_cref_test();
408 get_recursive_test();
409 check_that_does_not_exist();
410
b32b8144
FG
411#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
412 get_rvref_test();
413#endif
414
7c673cae
FG
415 return boost::exit_success;
416}