]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/variant/test/auto_visitors.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / variant / test / auto_visitors.cpp
CommitLineData
7c673cae
FG
1//-----------------------------------------------------------------------------
2// boost-libs variant/test/auto_visitors.cpp source file
3// See http://www.boost.org for updates, documentation, and revision history.
4//-----------------------------------------------------------------------------
5//
1e59de90 6// Copyright (c) 2014-2022 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
12#include "boost/config.hpp"
13
92f5a8d4 14#include "boost/core/lightweight_test.hpp"
7c673cae
FG
15#include "boost/variant.hpp"
16#include "boost/variant/multivisitors.hpp"
17#include "boost/lexical_cast.hpp"
18
19#include <boost/noncopyable.hpp>
20#include <boost/core/ignore_unused.hpp>
21
22namespace has_result_type_tests {
23 template <class T>
24 struct wrap {
25 typedef T result_type;
26 };
27
28 struct s1 : wrap<int> {};
29 struct s2 : wrap<int&> {};
30 struct s3 : wrap<const int&> {};
31 struct s4 {};
32 struct s5 : wrap<int*> {};
33 struct s6 : wrap<int**> {};
34 struct s7 : wrap<const int*> {};
35 struct s8 : wrap<boost::noncopyable> {};
36 struct s9 : wrap<boost::noncopyable&> {};
37#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
38 struct s10 : wrap<boost::noncopyable&&> {};
39#endif
40 struct s11 : wrap<const boost::noncopyable&> {};
41 struct s12 : wrap<const boost::noncopyable*> {};
42 struct s13 : wrap<boost::noncopyable*> {};
43 struct s14 { typedef int result_type; };
44 struct s15 { typedef int& result_type; };
45 struct s16 { typedef const int& result_type; };
46}
47
48
49void test_has_result_type_triat() {
50 using namespace has_result_type_tests;
51 using boost::detail::variant::has_result_type;
52
92f5a8d4
TL
53 BOOST_TEST(has_result_type<s1>::value);
54 BOOST_TEST(has_result_type<s2>::value);
55 BOOST_TEST(has_result_type<s3>::value);
56 BOOST_TEST(!has_result_type<s4>::value);
57 BOOST_TEST(has_result_type<s5>::value);
58 BOOST_TEST(has_result_type<s6>::value);
59 BOOST_TEST(has_result_type<s7>::value);
60 BOOST_TEST(has_result_type<s8>::value);
61 BOOST_TEST(has_result_type<s9>::value);
7c673cae 62#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
92f5a8d4 63 BOOST_TEST(has_result_type<s10>::value);
7c673cae 64#endif
92f5a8d4
TL
65 BOOST_TEST(has_result_type<s11>::value);
66 BOOST_TEST(has_result_type<s12>::value);
67 BOOST_TEST(has_result_type<s13>::value);
68 BOOST_TEST(has_result_type<s14>::value);
69 BOOST_TEST(has_result_type<s15>::value);
70 BOOST_TEST(has_result_type<s16>::value);
7c673cae
FG
71}
72
73struct lex_streamer_explicit: boost::static_visitor<std::string> {
74 template <class T>
75 const char* operator()(const T& ) {
76 return "10";
77 }
78
79 template <class T1, class T2>
80 const char* operator()(const T1& , const T2& ) {
81 return "100";
82 }
83};
84
85
86void run_explicit()
87{
88 typedef boost::variant<int, std::string, double> variant_type;
89 variant_type v2("10"), v1("100");
90
91 lex_streamer_explicit visitor_ref;
92
93 // Must return instance of std::string
92f5a8d4
TL
94 BOOST_TEST(boost::apply_visitor(visitor_ref, v2).c_str() == std::string("10"));
95 BOOST_TEST(boost::apply_visitor(visitor_ref, v2, v1).c_str() == std::string("100"));
7c673cae
FG
96}
97
98
99// Most part of tests from this file require decltype(auto)
100
101#ifdef BOOST_NO_CXX14_DECLTYPE_AUTO
102
103void run()
104{
92f5a8d4 105 BOOST_TEST(true);
7c673cae
FG
106}
107
108void run2()
109{
92f5a8d4 110 BOOST_TEST(true);
7c673cae
FG
111}
112
113
114void run3()
115{
92f5a8d4 116 BOOST_TEST(true);
7c673cae
FG
117}
118
119#else
120
121#include <iostream>
122
123struct lex_streamer {
124 template <class T>
125 std::string operator()(const T& val) const {
126 return boost::lexical_cast<std::string>(val);
127 }
128};
129
130struct lex_streamer_void {
131 template <class T>
132 void operator()(const T& val) const {
133 std::cout << val << std::endl;
134 }
135
136
137 template <class T1, class T2>
138 void operator()(const T1& val, const T2& val2) const {
139 std::cout << val << '+' << val2 << std::endl;
140 }
141
142
143 template <class T1, class T2, class T3>
144 void operator()(const T1& val, const T2& val2, const T3& val3) const {
145 std::cout << val << '+' << val2 << '+' << val3 << std::endl;
146 }
147};
148
149
150struct lex_streamer2 {
151 std::string res;
152
153 template <class T>
92f5a8d4 154 const char* operator()(const T& /*val*/) const {
7c673cae
FG
155 return "fail";
156 }
157
158 template <class T1, class T2>
92f5a8d4 159 const char* operator()(const T1& /*v1*/, const T2& /*v2*/) const {
7c673cae
FG
160 return "fail2";
161 }
162
163
164 template <class T1, class T2, class T3>
92f5a8d4 165 const char* operator()(const T1& /*v1*/, const T2& /*v2*/, const T3& /*v3*/) const {
7c673cae
FG
166 return "fail3";
167 }
168
169 template <class T>
170 std::string& operator()(const T& val) {
171 res = boost::lexical_cast<std::string>(val);
172 return res;
173 }
174
175
176 template <class T1, class T2>
177 std::string& operator()(const T1& v1, const T2& v2) {
178 res = boost::lexical_cast<std::string>(v1) + "+" + boost::lexical_cast<std::string>(v2);
179 return res;
180 }
181
182
183 template <class T1, class T2, class T3>
184 std::string& operator()(const T1& v1, const T2& v2, const T3& v3) {
185 res = boost::lexical_cast<std::string>(v1) + "+" + boost::lexical_cast<std::string>(v2)
186 + "+" + boost::lexical_cast<std::string>(v3);
187 return res;
188 }
189};
190
191#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
92f5a8d4 192# define BOOST_TEST_IF_HAS_VARIADIC(x) BOOST_TEST(x)
7c673cae 193#else
92f5a8d4 194# define BOOST_TEST_IF_HAS_VARIADIC(x) /**/
7c673cae
FG
195#endif
196
197void run()
198{
199 typedef boost::variant<int, std::string, double> variant_type;
200 variant_type v1(1), v2("10"), v3(100.0);
201 lex_streamer lex_streamer_visitor;
202
92f5a8d4
TL
203 BOOST_TEST(boost::apply_visitor(lex_streamer(), v1) == "1");
204 BOOST_TEST_IF_HAS_VARIADIC(boost::apply_visitor(lex_streamer_visitor)(v1) == "1");
205 BOOST_TEST(boost::apply_visitor(lex_streamer(), v2) == "10");
206 BOOST_TEST_IF_HAS_VARIADIC(boost::apply_visitor(lex_streamer_visitor)(v2) == "10");
7c673cae
FG
207
208 #ifndef BOOST_NO_CXX14_GENERIC_LAMBDAS
92f5a8d4
TL
209 BOOST_TEST(boost::apply_visitor([](auto v) { return boost::lexical_cast<std::string>(v); }, v1) == "1");
210 BOOST_TEST(boost::apply_visitor([](auto v) { return boost::lexical_cast<std::string>(v); }, v2) == "10");
7c673cae
FG
211
212 // Retun type must be the same in all instances, so this code does not compile
213 //boost::variant<int, short, unsigned> v_diff_types(1);
92f5a8d4 214 //BOOST_TEST(boost::apply_visitor([](auto v) { return v; }, v_diff_types) == 1);
7c673cae
FG
215
216 boost::apply_visitor([](auto v) { std::cout << v << std::endl; }, v1);
217 boost::apply_visitor([](auto v) { std::cout << v << std::endl; }, v2);
218 #endif
219
220 lex_streamer2 visitor_ref;
92f5a8d4
TL
221 BOOST_TEST(boost::apply_visitor(visitor_ref, v1) == "1");
222 BOOST_TEST(boost::apply_visitor(visitor_ref, v2) == "10");
7c673cae
FG
223#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
224 std::string& ref_to_string = boost::apply_visitor(visitor_ref, v1);
92f5a8d4 225 BOOST_TEST(ref_to_string == "1");
7c673cae
FG
226#endif
227 lex_streamer_void lex_streamer_void_visitor;
228 boost::apply_visitor(lex_streamer_void(), v1);
229 boost::apply_visitor(lex_streamer_void(), v2);
230#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
231 boost::apply_visitor(lex_streamer_void_visitor)(v2);
232#endif
233
234 boost::ignore_unused(lex_streamer_visitor, visitor_ref, lex_streamer_void_visitor);
235}
236
237
238struct lex_combine {
239 template <class T1, class T2>
240 std::string operator()(const T1& v1, const T2& v2) const {
241 return boost::lexical_cast<std::string>(v1) + "+" + boost::lexical_cast<std::string>(v2);
242 }
243
244
245 template <class T1, class T2, class T3>
246 std::string operator()(const T1& v1, const T2& v2, const T3& v3) const {
247 return boost::lexical_cast<std::string>(v1) + "+"
248 + boost::lexical_cast<std::string>(v2) + '+'
249 + boost::lexical_cast<std::string>(v3);
250 }
251};
252
253void run2()
254{
255 typedef boost::variant<int, std::string, double> variant_type;
256 variant_type v1(1), v2("10"), v3(100.0);
257 lex_combine lex_combine_visitor;
258
92f5a8d4
TL
259 BOOST_TEST(boost::apply_visitor(lex_combine(), v1, v2) == "1+10");
260 BOOST_TEST(boost::apply_visitor(lex_combine(), v2, v1) == "10+1");
261 BOOST_TEST_IF_HAS_VARIADIC(boost::apply_visitor(lex_combine_visitor)(v2, v1) == "10+1");
7c673cae
FG
262
263
264 #ifndef BOOST_NO_CXX14_GENERIC_LAMBDAS
92f5a8d4 265 BOOST_TEST(
7c673cae
FG
266 boost::apply_visitor(
267 [](auto v1, auto v2) {
268 return boost::lexical_cast<std::string>(v1) + "+"
269 + boost::lexical_cast<std::string>(v2);
270 }
271 , v1
272 , v2
273 ) == "1+10"
274 );
92f5a8d4 275 BOOST_TEST(
7c673cae
FG
276 boost::apply_visitor(
277 [](auto v1, auto v2) {
278 return boost::lexical_cast<std::string>(v1) + "+"
279 + boost::lexical_cast<std::string>(v2);
280 }
281 , v2
282 , v1
283 ) == "10+1"
284 );
285
286 boost::apply_visitor([](auto v1, auto v2) { std::cout << v1 << '+' << v2 << std::endl; }, v1, v2);
287 boost::apply_visitor([](auto v1, auto v2) { std::cout << v1 << '+' << v2 << std::endl; }, v2, v1);
288 #endif
289
290
291 lex_streamer2 visitor_ref;
92f5a8d4
TL
292 BOOST_TEST(boost::apply_visitor(visitor_ref, v1, v2) == "1+10");
293 BOOST_TEST(boost::apply_visitor(visitor_ref, v2, v1) == "10+1");
7c673cae
FG
294#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
295 std::string& ref_to_string = boost::apply_visitor(visitor_ref)(v1, v2);
92f5a8d4 296 BOOST_TEST(ref_to_string == "1+10");
7c673cae
FG
297#endif
298
299 boost::apply_visitor(lex_streamer_void(), v1, v2);
300 boost::apply_visitor(lex_streamer_void(), v2, v1);
301
302 boost::ignore_unused(lex_combine_visitor, visitor_ref);
303}
304
92f5a8d4 305#undef BOOST_TEST_IF_HAS_VARIADIC
7c673cae
FG
306
307void run3()
308{
309#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
310 typedef boost::variant<int, std::string, double> variant_type;
311 variant_type v1(1), v2("10"), v3(100);
312 lex_combine lex_combine_visitor;
313
92f5a8d4
TL
314 BOOST_TEST(boost::apply_visitor(lex_combine(), v1, v2, v3) == "1+10+100");
315 BOOST_TEST(boost::apply_visitor(lex_combine(), v2, v1, v3) == "10+1+100");
316 BOOST_TEST(boost::apply_visitor(lex_combine_visitor)(v2, v1, v3) == "10+1+100");
7c673cae
FG
317
318
319 #ifndef BOOST_NO_CXX14_GENERIC_LAMBDAS
92f5a8d4 320 BOOST_TEST(
7c673cae
FG
321 boost::apply_visitor(
322 [](auto v1, auto v2, auto v3) {
323 return boost::lexical_cast<std::string>(v1) + "+"
324 + boost::lexical_cast<std::string>(v2) + "+"
325 + boost::lexical_cast<std::string>(v3);
326 }
327 , v1
328 , v2
329 , v3
330 ) == "1+10+100"
331 );
92f5a8d4 332 BOOST_TEST(
7c673cae
FG
333 boost::apply_visitor(
334 [](auto v1, auto v2, auto v3) {
335 return boost::lexical_cast<std::string>(v1) + "+"
336 + boost::lexical_cast<std::string>(v2) + "+"
337 + boost::lexical_cast<std::string>(v3);
338 }
339 , v3
340 , v1
341 , v3
342 ) == "100+1+100"
343 );
344
345 boost::apply_visitor(
346 [](auto v1, auto v2, auto v3) { std::cout << v1 << '+' << v2 << '+' << v3 << std::endl; },
347 v1, v2, v3
348 );
349 boost::apply_visitor(
350 [](auto v1, auto v2, auto v3) { std::cout << v1 << '+' << v2 << '+' << v3 << std::endl; },
351 v2, v1, v3
352 );
353 #endif
354
355
356 lex_streamer2 visitor_ref;
92f5a8d4
TL
357 BOOST_TEST(boost::apply_visitor(visitor_ref, v1, v2) == "1+10");
358 BOOST_TEST(boost::apply_visitor(visitor_ref)(v2, v1) == "10+1");
7c673cae 359 std::string& ref_to_string = boost::apply_visitor(visitor_ref, v1, v2);
92f5a8d4 360 BOOST_TEST(ref_to_string == "1+10");
7c673cae
FG
361
362 lex_streamer_void lex_streamer_void_visitor;
363 boost::apply_visitor(lex_streamer_void(), v1, v2, v1);
364 boost::apply_visitor(lex_streamer_void(), v2, v1, v1);
365 boost::apply_visitor(lex_streamer_void_visitor)(v2, v1, v1);
366#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
367}
368#endif
369
370
92f5a8d4 371int main()
7c673cae
FG
372{
373 run_explicit();
374 run();
375 run2();
376 run3();
377 test_has_result_type_triat();
378
92f5a8d4 379 return boost::report_errors();
7c673cae 380}