]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/variant/test/auto_visitors.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / variant / test / auto_visitors.cpp
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 //
6 // Copyright (c) 2014-2019 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/config.hpp"
13
14 #include "boost/core/lightweight_test.hpp"
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
22 namespace 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
49 void test_has_result_type_triat() {
50 using namespace has_result_type_tests;
51 using boost::detail::variant::has_result_type;
52
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);
62 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
63 BOOST_TEST(has_result_type<s10>::value);
64 #endif
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);
71 }
72
73 struct 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
86 void 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
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"));
96 }
97
98
99 // Most part of tests from this file require decltype(auto)
100
101 #ifdef BOOST_NO_CXX14_DECLTYPE_AUTO
102
103 void run()
104 {
105 BOOST_TEST(true);
106 }
107
108 void run2()
109 {
110 BOOST_TEST(true);
111 }
112
113
114 void run3()
115 {
116 BOOST_TEST(true);
117 }
118
119 #else
120
121 #include <iostream>
122
123 struct 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
130 struct 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
150 struct lex_streamer2 {
151 std::string res;
152
153 template <class T>
154 const char* operator()(const T& /*val*/) const {
155 return "fail";
156 }
157
158 template <class T1, class T2>
159 const char* operator()(const T1& /*v1*/, const T2& /*v2*/) const {
160 return "fail2";
161 }
162
163
164 template <class T1, class T2, class T3>
165 const char* operator()(const T1& /*v1*/, const T2& /*v2*/, const T3& /*v3*/) const {
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
192 # define BOOST_TEST_IF_HAS_VARIADIC(x) BOOST_TEST(x)
193 #else
194 # define BOOST_TEST_IF_HAS_VARIADIC(x) /**/
195 #endif
196
197 void 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
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");
207
208 #ifndef BOOST_NO_CXX14_GENERIC_LAMBDAS
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");
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);
214 //BOOST_TEST(boost::apply_visitor([](auto v) { return v; }, v_diff_types) == 1);
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;
221 BOOST_TEST(boost::apply_visitor(visitor_ref, v1) == "1");
222 BOOST_TEST(boost::apply_visitor(visitor_ref, v2) == "10");
223 #ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
224 std::string& ref_to_string = boost::apply_visitor(visitor_ref, v1);
225 BOOST_TEST(ref_to_string == "1");
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
238 struct 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
253 void 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
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");
262
263
264 #ifndef BOOST_NO_CXX14_GENERIC_LAMBDAS
265 BOOST_TEST(
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 );
275 BOOST_TEST(
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;
292 BOOST_TEST(boost::apply_visitor(visitor_ref, v1, v2) == "1+10");
293 BOOST_TEST(boost::apply_visitor(visitor_ref, v2, v1) == "10+1");
294 #ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
295 std::string& ref_to_string = boost::apply_visitor(visitor_ref)(v1, v2);
296 BOOST_TEST(ref_to_string == "1+10");
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
305 #undef BOOST_TEST_IF_HAS_VARIADIC
306
307 void 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
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");
317
318
319 #ifndef BOOST_NO_CXX14_GENERIC_LAMBDAS
320 BOOST_TEST(
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 );
332 BOOST_TEST(
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;
357 BOOST_TEST(boost::apply_visitor(visitor_ref, v1, v2) == "1+10");
358 BOOST_TEST(boost::apply_visitor(visitor_ref)(v2, v1) == "10+1");
359 std::string& ref_to_string = boost::apply_visitor(visitor_ref, v1, v2);
360 BOOST_TEST(ref_to_string == "1+10");
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
371 int main()
372 {
373 run_explicit();
374 run();
375 run2();
376 run3();
377 test_has_result_type_triat();
378
379 return boost::report_errors();
380 }