]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/beast/test/beast/core/detail/variant.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / beast / test / beast / core / detail / variant.cpp
1 //
2 // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7
8 // Test that header file is self-contained.
9 #include <boost/beast/core/detail/variant.hpp>
10
11 #include <boost/beast/unit_test/suite.hpp>
12 #include <exception>
13 #include <string>
14
15 namespace boost {
16 namespace beast {
17 namespace detail {
18
19 class variant_test : public beast::unit_test::suite
20 {
21 public:
22 template<unsigned char I>
23 struct Q
24 {
25 static
26 unsigned char&
27 count()
28 {
29 static unsigned char n = 0;
30 return n;
31 }
32
33 int value = 0;
34 bool move = false;
35 bool copy = false;
36
37 Q& operator=(Q&& q) = delete;
38 Q& operator=(Q const& q) = delete;
39
40 ~Q()
41 {
42 --count();
43 }
44
45 Q()
46 {
47 ++count();
48 }
49
50 Q(Q&& q)
51 {
52 if(q.value < 0)
53 throw std::exception{};
54 ++count();
55 move = true;
56 }
57
58 Q(Q const& q)
59 {
60 if(q.value < 0)
61 throw std::exception{};
62 ++count();
63 copy = true;
64 }
65
66 explicit Q(int value_)
67 : value(value_)
68 {
69 ++count();
70 }
71 };
72
73 void
74 testVariant()
75 {
76 // Default Constructor
77 // Destructor
78 {
79 variant<int> v;
80 BEAST_EXPECT(v.index() == 0);
81 }
82 // emplace
83 {
84 variant<int> v;
85 BEAST_EXPECT(v.index() == 0);
86 v.emplace<1>(10);
87 BEAST_EXPECT(v.index() == 1);
88 BEAST_EXPECT(v.get<1>() == 10);
89 v.emplace<1>(20);
90 BEAST_EXPECT(v.index() == 1);
91 BEAST_EXPECT(v.get<1>() == 20);
92 }
93 {
94 variant<std::string> v;
95 v.emplace<1>("Hello, world!");
96 BEAST_EXPECT(v.index() == 1);
97 BEAST_EXPECT(v.get<1>() == "Hello, world!");
98 }
99 {
100 variant<Q<1>> v;
101 BEAST_EXPECT(Q<1>::count() == 0);
102 v.emplace<1>();
103 BEAST_EXPECT(Q<1>::count() == 1);
104 BEAST_EXPECT(v.get<1>().value == 0);
105 v.emplace<1>(42);
106 BEAST_EXPECT(Q<1>::count() == 1);
107 BEAST_EXPECT(v.get<1>().value == 42);
108 v.reset();
109 BEAST_EXPECT(Q<1>::count() == 0);
110 }
111 BEAST_EXPECT(Q<1>::count() == 0);
112 {
113 variant<Q<1>, Q<2>, Q<3>> v;
114 BEAST_EXPECT(Q<1>::count() == 0);
115 BEAST_EXPECT(Q<2>::count() == 0);
116 BEAST_EXPECT(Q<3>::count() == 0);
117 v.emplace<1>();
118 BEAST_EXPECT(Q<1>::count() == 1);
119 BEAST_EXPECT(Q<2>::count() == 0);
120 BEAST_EXPECT(Q<3>::count() == 0);
121 v.emplace<2>();
122 BEAST_EXPECT(Q<1>::count() == 0);
123 BEAST_EXPECT(Q<2>::count() == 1);
124 BEAST_EXPECT(Q<3>::count() == 0);
125 v.emplace<3>();
126 BEAST_EXPECT(Q<1>::count() == 0);
127 BEAST_EXPECT(Q<2>::count() == 0);
128 BEAST_EXPECT(Q<3>::count() == 1);
129 v.reset();
130 BEAST_EXPECT(Q<1>::count() == 0);
131 BEAST_EXPECT(Q<2>::count() == 0);
132 BEAST_EXPECT(Q<3>::count() == 0);
133 }
134 BEAST_EXPECT(Q<1>::count() == 0);
135 BEAST_EXPECT(Q<2>::count() == 0);
136 BEAST_EXPECT(Q<3>::count() == 0);
137 // move
138 {
139 variant<std::string> v1;
140 BEAST_EXPECT(v1.index() == 0);
141 variant<std::string> v2{std::move(v1)};
142 BEAST_EXPECT(v1.index() == 0);
143 BEAST_EXPECT(v2.index() == 0);
144 v2.emplace<1>("Hello");
145 BEAST_EXPECT(v2.get<1>() == "Hello");
146 variant<std::string> v3{std::move(v2)};
147 BEAST_EXPECT(v2.index() == 0);
148 BEAST_EXPECT(v3.get<1>() == "Hello");
149 }
150 {
151 variant<Q<1>> v1;
152 BEAST_EXPECT(Q<1>::count() == 0);
153 v1.emplace<1>();
154 BEAST_EXPECT(Q<1>::count() == 1);
155 BEAST_EXPECT(! v1.get<1>().move);
156 variant<Q<1>> v2{std::move(v1)};
157 BEAST_EXPECT(v1.index() == 0);
158 BEAST_EXPECT(Q<1>::count() == 1);
159 BEAST_EXPECT(v2.get<1>().move);
160 }
161 BEAST_EXPECT(Q<1>::count() == 0);
162 {
163 variant<Q<1>, Q<2>, Q<3>> v1;
164 BEAST_EXPECT(Q<1>::count() == 0);
165 BEAST_EXPECT(Q<2>::count() == 0);
166 BEAST_EXPECT(Q<3>::count() == 0);
167 v1.emplace<2>();
168 BEAST_EXPECT(Q<1>::count() == 0);
169 BEAST_EXPECT(Q<2>::count() == 1);
170 BEAST_EXPECT(Q<3>::count() == 0);
171 variant<Q<1>, Q<2>, Q<3>> v2{std::move(v1)};
172 BEAST_EXPECT(Q<1>::count() == 0);
173 BEAST_EXPECT(Q<2>::count() == 1);
174 BEAST_EXPECT(Q<3>::count() == 0);
175 BEAST_EXPECT(v2.get<2>().move);
176 }
177 BEAST_EXPECT(Q<1>::count() == 0);
178 BEAST_EXPECT(Q<2>::count() == 0);
179 BEAST_EXPECT(Q<3>::count() == 0);
180 // copy
181 {
182 variant<std::string> v1;
183 BEAST_EXPECT(v1.index() == 0);
184 variant<std::string> v2{v1};
185 BEAST_EXPECT(v1.index() == 0);
186 BEAST_EXPECT(v2.index() == 0);
187 v2.emplace<1>("Hello");
188 BEAST_EXPECT(v2.get<1>() == "Hello");
189 variant<std::string> v3{v2};
190 BEAST_EXPECT(v2.get<1>() == "Hello");
191 BEAST_EXPECT(v3.get<1>() == "Hello");
192 }
193 {
194 variant<Q<1>> v1;
195 BEAST_EXPECT(Q<1>::count() == 0);
196 v1.emplace<1>();
197 BEAST_EXPECT(Q<1>::count() == 1);
198 BEAST_EXPECT(! v1.get<1>().copy);
199 variant<Q<1>> v2{v1};
200 BEAST_EXPECT(v1.index() == 1);
201 BEAST_EXPECT(Q<1>::count() == 2);
202 BEAST_EXPECT(v2.get<1>().copy);
203 }
204 BEAST_EXPECT(Q<1>::count() == 0);
205 {
206 variant<Q<1>, Q<2>, Q<3>> v1;
207 BEAST_EXPECT(Q<1>::count() == 0);
208 BEAST_EXPECT(Q<2>::count() == 0);
209 BEAST_EXPECT(Q<3>::count() == 0);
210 v1.emplace<2>();
211 BEAST_EXPECT(Q<1>::count() == 0);
212 BEAST_EXPECT(Q<2>::count() == 1);
213 BEAST_EXPECT(Q<3>::count() == 0);
214 variant<Q<1>, Q<2>, Q<3>> v2{v1};
215 BEAST_EXPECT(Q<1>::count() == 0);
216 BEAST_EXPECT(Q<2>::count() == 2);
217 BEAST_EXPECT(Q<3>::count() == 0);
218 BEAST_EXPECT(v2.get<2>().copy);
219 }
220 BEAST_EXPECT(Q<1>::count() == 0);
221 BEAST_EXPECT(Q<2>::count() == 0);
222 BEAST_EXPECT(Q<3>::count() == 0);
223 // move assign
224 {
225 variant<std::string> v1;
226 BEAST_EXPECT(v1.index() == 0);
227 variant<std::string> v2;
228 v2 = std::move(v1);
229 BEAST_EXPECT(v1.index() == 0);
230 BEAST_EXPECT(v2.index() == 0);
231 v2.emplace<1>("Hello");
232 BEAST_EXPECT(v2.get<1>() == "Hello");
233 variant<std::string> v3;
234 v3 = std::move(v2);
235 BEAST_EXPECT(v2.index() == 0);
236 BEAST_EXPECT(v3.get<1>() == "Hello");
237 }
238 {
239 variant<Q<1>, Q<2>> v1;
240 variant<Q<1>, Q<2>> v2;
241 v1.emplace<1>();
242 BEAST_EXPECT(v1.index() == 1);
243 BEAST_EXPECT(Q<1>::count() == 1);
244 v2.emplace<2>();
245 BEAST_EXPECT(v2.index() == 2);
246 BEAST_EXPECT(Q<2>::count() == 1);
247 v2 = std::move(v1);
248 BEAST_EXPECT(v1.index() == 0);
249 BEAST_EXPECT(v2.index() == 1);
250 BEAST_EXPECT(Q<1>::count() == 1);
251 BEAST_EXPECT(Q<2>::count() == 0);
252 }
253 BEAST_EXPECT(Q<1>::count() == 0);
254 BEAST_EXPECT(Q<2>::count() == 0);
255 {
256 variant<Q<1>> v1;
257 v1.emplace<1>();
258 BEAST_EXPECT(Q<1>::count() == 1);
259 variant<Q<1>> v2;
260 v2.emplace<1>();
261 BEAST_EXPECT(Q<1>::count() == 2);
262 v2 = std::move(v1);
263 BEAST_EXPECT(v1.index() == 0);
264 BEAST_EXPECT(v2.index() == 1);
265 BEAST_EXPECT(v2.get<1>().move);
266 BEAST_EXPECT(Q<1>::count() == 1);
267 }
268 BEAST_EXPECT(Q<1>::count() == 0);
269 {
270 variant<Q<1>, Q<2>, Q<3>> v1;
271 v1.emplace<2>();
272 BEAST_EXPECT(Q<1>::count() == 0);
273 BEAST_EXPECT(Q<2>::count() == 1);
274 BEAST_EXPECT(Q<3>::count() == 0);
275 variant<Q<1>, Q<2>, Q<3>> v2;
276 v2.emplace<2>();
277 BEAST_EXPECT(Q<1>::count() == 0);
278 BEAST_EXPECT(Q<2>::count() == 2);
279 BEAST_EXPECT(Q<3>::count() == 0);
280 v2 = std::move(v1);
281 BEAST_EXPECT(v1.index() == 0);
282 BEAST_EXPECT(v2.index() == 2);
283 BEAST_EXPECT(v2.get<2>().move);
284 BEAST_EXPECT(Q<1>::count() == 0);
285 BEAST_EXPECT(Q<2>::count() == 1);
286 BEAST_EXPECT(Q<3>::count() == 0);
287 }
288 BEAST_EXPECT(Q<1>::count() == 0);
289 BEAST_EXPECT(Q<2>::count() == 0);
290 BEAST_EXPECT(Q<3>::count() == 0);
291 // copy assign
292 {
293 variant<std::string> v1;
294 BEAST_EXPECT(v1.index() == 0);
295 variant<std::string> v2;
296 v2 = v1;
297 BEAST_EXPECT(v1.index() == 0);
298 BEAST_EXPECT(v2.index() == 0);
299 v2.emplace<1>("Hello");
300 BEAST_EXPECT(v2.get<1>() == "Hello");
301 variant<std::string> v3;
302 v3 = v2;
303 BEAST_EXPECT(v2.get<1>() == "Hello");
304 BEAST_EXPECT(v3.get<1>() == "Hello");
305 }
306 {
307 variant<Q<1>, Q<2>> v1;
308 variant<Q<1>, Q<2>> v2;
309 v1.emplace<1>();
310 BEAST_EXPECT(v1.index() == 1);
311 BEAST_EXPECT(Q<1>::count() == 1);
312 v2.emplace<2>();
313 BEAST_EXPECT(v2.index() == 2);
314 BEAST_EXPECT(Q<2>::count() == 1);
315 v2 = v1;
316 BEAST_EXPECT(v1.index() == 1);
317 BEAST_EXPECT(v2.index() == 1);
318 BEAST_EXPECT(Q<1>::count() == 2);
319 BEAST_EXPECT(Q<2>::count() == 0);
320 }
321 {
322 variant<Q<1>> v1;
323 v1.emplace<1>();
324 BEAST_EXPECT(Q<1>::count() == 1);
325 variant<Q<1>> v2;
326 v2.emplace<1>();
327 BEAST_EXPECT(Q<1>::count() == 2);
328 v2 = v1;
329 BEAST_EXPECT(v1.index() == 1);
330 BEAST_EXPECT(v2.index() == 1);
331 BEAST_EXPECT(v2.get<1>().copy);
332 BEAST_EXPECT(Q<1>::count() == 2);
333 }
334 BEAST_EXPECT(Q<1>::count() == 0);
335 {
336 variant<Q<1>, Q<2>, Q<3>> v1;
337 v1.emplace<2>();
338 BEAST_EXPECT(Q<1>::count() == 0);
339 BEAST_EXPECT(Q<2>::count() == 1);
340 BEAST_EXPECT(Q<3>::count() == 0);
341 variant<Q<1>, Q<2>, Q<3>> v2;
342 v2.emplace<2>();
343 BEAST_EXPECT(Q<1>::count() == 0);
344 BEAST_EXPECT(Q<2>::count() == 2);
345 BEAST_EXPECT(Q<3>::count() == 0);
346 v2 = v1;
347 BEAST_EXPECT(v1.index() == 2);
348 BEAST_EXPECT(v2.index() == 2);
349 BEAST_EXPECT(v2.get<2>().copy);
350 BEAST_EXPECT(Q<1>::count() == 0);
351 BEAST_EXPECT(Q<2>::count() == 2);
352 BEAST_EXPECT(Q<3>::count() == 0);
353 }
354 BEAST_EXPECT(Q<1>::count() == 0);
355 BEAST_EXPECT(Q<2>::count() == 0);
356 BEAST_EXPECT(Q<3>::count() == 0);
357 // get
358 {
359 variant<std::string> v;
360 v.emplace<1>("Hello");
361 v.get<1>() = "World!";
362 BEAST_EXPECT(v.get<1>() == "World!");
363 }
364 // reset
365 {
366 variant<std::string> v;
367 v.emplace<1>("Hello");
368 v.reset();
369 BEAST_EXPECT(v.index() == 0);
370 }
371 {
372 variant<Q<1>> v;
373 BEAST_EXPECT(Q<1>::count() == 0);
374 v.emplace<1>();
375 BEAST_EXPECT(Q<1>::count() == 1);
376 v.reset();
377 BEAST_EXPECT(Q<1>::count() == 0);
378 BEAST_EXPECT(v.index() == 0);
379 }
380 {
381 variant<Q<1>, Q<2>, Q<3>> v;
382 BEAST_EXPECT(Q<1>::count() == 0);
383 BEAST_EXPECT(Q<2>::count() == 0);
384 BEAST_EXPECT(Q<3>::count() == 0);
385 v.emplace<2>();
386 BEAST_EXPECT(Q<1>::count() == 0);
387 BEAST_EXPECT(Q<2>::count() == 1);
388 BEAST_EXPECT(Q<3>::count() == 0);
389 v.reset();
390 BEAST_EXPECT(Q<1>::count() == 0);
391 BEAST_EXPECT(Q<2>::count() == 0);
392 BEAST_EXPECT(Q<3>::count() == 0);
393 BEAST_EXPECT(v.index() == 0);
394 }
395 BEAST_EXPECT(Q<1>::count() == 0);
396 BEAST_EXPECT(Q<2>::count() == 0);
397 BEAST_EXPECT(Q<3>::count() == 0);
398
399 // basic guarantee
400 {
401 // move
402 variant<Q<1>> v1;
403 v1.emplace<1>();
404 BEAST_EXPECT(Q<1>::count() == 1);
405 variant<Q<1>> v2;
406 v2.emplace<1>(-1);
407 BEAST_EXPECT(Q<1>::count() == 2);
408 try
409 {
410 v1 = std::move(v2);
411 fail();
412 }
413 catch(std::exception const&)
414 {
415 BEAST_EXPECT(v1.index() == 0);
416 BEAST_EXPECT(Q<1>::count() == 1);
417 }
418 }
419 BEAST_EXPECT(Q<1>::count() == 0);
420 {
421 // copy
422 variant<Q<1>> v1;
423 v1.emplace<1>();
424 BEAST_EXPECT(Q<1>::count() == 1);
425 variant<Q<1>> v2;
426 v2.emplace<1>(-1);
427 BEAST_EXPECT(Q<1>::count() == 2);
428 try
429 {
430 v1 = v2;
431 fail();
432 }
433 catch(std::exception const&)
434 {
435 BEAST_EXPECT(v1.index() == 0);
436 BEAST_EXPECT(Q<1>::count() == 1);
437 }
438 }
439 BEAST_EXPECT(Q<1>::count() == 0);
440 }
441
442 void
443 run()
444 {
445 testVariant();
446 }
447 };
448
449 BEAST_DEFINE_TESTSUITE(beast,core,variant);
450
451 } // detail
452 } // beast
453 } // boost