1// Copyright 2017, 2021 Peter Dimov.
2// Distributed under the Boost Software License, Version 1.0.
3// https://www.boost.org/LICENSE_1_0.txt
4
5#include <boost/system/result.hpp>
6#include <boost/core/lightweight_test.hpp>
7#include <boost/core/lightweight_test_trait.hpp>
8#include <iosfwd>
9#include <cerrno>
10
11using namespace boost::system;
12
13struct X
14{
15 static int instances;
16
17 int v_;
18
19 explicit X( int v = 0 ): v_( v ) { ++instances; }
20
21 X( X const& r ) = delete;
22 X( X&& r ): v_( r.v_ ) { r.v_ = 0; ++instances; }
23
24 X& operator=( X const& ) = delete;
25
26 X& operator=( X&& r )
27 {
28 v_ = r.v_;
29 r.v_ = 0;
30
31 return *this;
32 }
33
34 ~X() { --instances; }
35};
36
37bool operator==( X const & x1, X const & x2 )
38{
39 return x1.v_ == x2.v_;
40}
41
42std::ostream& operator<<( std::ostream& os, X const & x )
43{
44 os << "X:" << x.v_;
45 return os;
46}
47
48int X::instances = 0;
49
50struct Y
51{
52 static int instances;
53
54 int v_;
55
56 explicit Y( int v = 0 ): v_( v ) { ++instances; }
57
58 Y( Y const& r ) noexcept: v_( r.v_ ) { ++instances; }
59 Y( Y&& r ) noexcept: v_( r.v_ ) { r.v_ = 0; ++instances; }
60
61 Y& operator=( Y const& ) = default;
62
63 Y& operator=( Y&& r )
64 {
65 v_ = r.v_;
66 r.v_ = 0;
67
68 return *this;
69 }
70
71 ~Y() { --instances; }
72};
73
74bool operator==( Y const & y1, Y const & y2 )
75{
76 return y1.v_ == y2.v_;
77}
78
79std::ostream& operator<<( std::ostream& os, Y const & y )
80{
81 os << "Y:" << y.v_;
82 return os;
83}
84
85int Y::instances = 0;
86
87int main()
88{
89 // default-initialized lhs
90
91 {
92 result<int> r;
93 result<int> r2;
94
95 r2 = std::move( r );
96
97 BOOST_TEST( r2.has_value() );
98 BOOST_TEST( !r2.has_error() );
99
100 BOOST_TEST_EQ( r2.value(), 0 );
101 }
102
103 {
104 result<int> r2;
105
106 r2 = result<int>();
107
108 BOOST_TEST( r2.has_value() );
109 BOOST_TEST( !r2.has_error() );
110
111 BOOST_TEST_EQ( r2.value(), 0 );
112 }
113
114 {
115 result<int> r;
116 result<int> r2( 1 );
117
118 r2 = std::move( r );
119
120 BOOST_TEST( r2.has_value() );
121 BOOST_TEST( !r2.has_error() );
122
123 BOOST_TEST_EQ( r2.value(), 0 );
124 }
125
126 {
127 result<int> r2( 1 );
128
129 r2 = result<int>();
130
131 BOOST_TEST( r2.has_value() );
132 BOOST_TEST( !r2.has_error() );
133
134 BOOST_TEST_EQ( r2.value(), 0 );
135 }
136
137 {
138 result<int> r;
139 result<int> r2( ENOENT, generic_category() );
140
141 r2 = std::move( r );
142
143 BOOST_TEST( r2.has_value() );
144 BOOST_TEST( !r2.has_error() );
145
146 BOOST_TEST_EQ( r2.value(), 0 );
147 }
148
149 {
150 result<int> r2( ENOENT, generic_category() );
151
152 r2 = result<int>();
153
154 BOOST_TEST( r2.has_value() );
155 BOOST_TEST( !r2.has_error() );
156
157 BOOST_TEST_EQ( r2.value(), 0 );
158 }
159
160 BOOST_TEST_EQ( X::instances, 0 );
161
162 {
163 result<X> r;
164 result<X> r2;
165
166 BOOST_TEST_EQ( X::instances, 2 );
167
168 r2 = std::move( r );
169
170 BOOST_TEST_EQ( X::instances, 2 );
171
172 BOOST_TEST( r2.has_value() );
173 BOOST_TEST( !r2.has_error() );
174
175 BOOST_TEST_EQ( r2.value(), X() );
176 }
177
178 BOOST_TEST_EQ( X::instances, 0 );
179
180 {
181 result<X> r;
182 result<X> r2( 1 );
183
184 BOOST_TEST_EQ( X::instances, 2 );
185
186 r2 = std::move( r );
187
188 BOOST_TEST_EQ( X::instances, 2 );
189
190 BOOST_TEST( r2.has_value() );
191 BOOST_TEST( !r2.has_error() );
192
193 BOOST_TEST_EQ( r2.value(), X() );
194 }
195
196 BOOST_TEST_EQ( X::instances, 0 );
197
198 {
199 result<X> r;
200 result<X> r2( ENOENT, generic_category() );
201
202 BOOST_TEST_EQ( X::instances, 1 );
203
204 r2 = std::move( r );
205
206 BOOST_TEST_EQ( X::instances, 2 );
207
208 BOOST_TEST( r2.has_value() );
209 BOOST_TEST( !r2.has_error() );
210
211 BOOST_TEST_EQ( r2.value(), X() );
212 }
213
214 BOOST_TEST_EQ( X::instances, 0 );
215
216 // value lhs
217
218 {
219 result<int> r( 1 );
220 result<int> r2;
221
222 r2 = std::move( r );
223
224 BOOST_TEST( r2.has_value() );
225 BOOST_TEST( !r2.has_error() );
226
227 BOOST_TEST_EQ( r2.value(), 1 );
228
229 BOOST_TEST_EQ( r, r2 );
230 }
231
232 {
233 result<int> r( 1 );
234 result<int> r2( 2 );
235
236 r2 = std::move( r );
237
238 BOOST_TEST( r2.has_value() );
239 BOOST_TEST( !r2.has_error() );
240
241 BOOST_TEST_EQ( r2.value(), 1 );
242
243 BOOST_TEST_EQ( r, r2 );
244 }
245
246 {
247 result<int> r( 1 );
248 result<int> r2( ENOENT, generic_category() );
249
250 r2 = std::move( r );
251
252 BOOST_TEST( r2.has_value() );
253 BOOST_TEST( !r2.has_error() );
254
255 BOOST_TEST_EQ( r2.value(), 1 );
256
257 BOOST_TEST_EQ( r, r2 );
258 }
259
260 BOOST_TEST_EQ( X::instances, 0 );
261
262 {
263 result<X> r( 1 );
264 result<X> r2;
265
266 BOOST_TEST_EQ( X::instances, 2 );
267
268 r2 = std::move( r );
269
270 BOOST_TEST_EQ( X::instances, 2 );
271
272 BOOST_TEST( r2.has_value() );
273 BOOST_TEST( !r2.has_error() );
274
275 BOOST_TEST_EQ( r2.value().v_, 1 );
276
277 BOOST_TEST_EQ( r.value().v_, 0 );
278 }
279
280 BOOST_TEST_EQ( X::instances, 0 );
281
282 {
283 result<X> r( 1 );
284 result<X> r2( 2 );
285
286 BOOST_TEST_EQ( X::instances, 2 );
287
288 r2 = std::move( r );
289
290 BOOST_TEST_EQ( X::instances, 2 );
291
292 BOOST_TEST( r2.has_value() );
293 BOOST_TEST( !r2.has_error() );
294
295 BOOST_TEST_EQ( r2.value().v_, 1 );
296
297 BOOST_TEST_EQ( r.value().v_, 0 );
298 }
299
300 BOOST_TEST_EQ( X::instances, 0 );
301
302 {
303 result<X> r( 1 );
304 result<X> r2( ENOENT, generic_category() );
305
306 BOOST_TEST_EQ( X::instances, 1 );
307
308 r2 = std::move( r );
309
310 BOOST_TEST_EQ( X::instances, 2 );
311
312 BOOST_TEST( r2.has_value() );
313 BOOST_TEST( !r2.has_error() );
314
315 BOOST_TEST_EQ( r2.value().v_, 1 );
316
317 BOOST_TEST_EQ( r.value().v_, 0 );
318 }
319
320 BOOST_TEST_EQ( X::instances, 0 );
321
322 // error lhs
323
324 {
325 auto ec = make_error_code( e: errc::invalid_argument );
326
327 result<int> r( ec );
328 result<int> r2;
329
330 r2 = std::move( r );
331
332 BOOST_TEST( !r2.has_value() );
333 BOOST_TEST( r2.has_error() );
334
335 BOOST_TEST_EQ( r2.error(), ec );
336 }
337
338 {
339 auto ec = make_error_code( e: errc::invalid_argument );
340
341 result<int> r2;
342
343 r2 = result<int>( ec );
344
345 BOOST_TEST( !r2.has_value() );
346 BOOST_TEST( r2.has_error() );
347
348 BOOST_TEST_EQ( r2.error(), ec );
349 }
350
351 {
352 auto ec = make_error_code( e: errc::invalid_argument );
353
354 result<int> r( ec );
355 result<int> r2( 1 );
356
357 r2 = std::move( r );
358
359 BOOST_TEST( !r2.has_value() );
360 BOOST_TEST( r2.has_error() );
361
362 BOOST_TEST_EQ( r2.error(), ec );
363 }
364
365 {
366 auto ec = make_error_code( e: errc::invalid_argument );
367
368 result<int> r2( 1 );
369
370 r2 = result<int>( ec );
371
372 BOOST_TEST( !r2.has_value() );
373 BOOST_TEST( r2.has_error() );
374
375 BOOST_TEST_EQ( r2.error(), ec );
376 }
377
378 {
379 auto ec = make_error_code( e: errc::invalid_argument );
380
381 result<int> r( ec );
382 result<int> r2( ENOENT, generic_category() );
383
384 r2 = std::move( r );
385
386 BOOST_TEST( !r2.has_value() );
387 BOOST_TEST( r2.has_error() );
388
389 BOOST_TEST_EQ( r2.error(), ec );
390 }
391
392 {
393 auto ec = make_error_code( e: errc::invalid_argument );
394
395 result<int> r2( ENOENT, generic_category() );
396
397 r2 = result<int>( ec );
398
399 BOOST_TEST( !r2.has_value() );
400 BOOST_TEST( r2.has_error() );
401
402 BOOST_TEST_EQ( r2.error(), ec );
403 }
404
405 BOOST_TEST_EQ( X::instances, 0 );
406
407 {
408 auto ec = make_error_code( e: errc::invalid_argument );
409
410 result<X> r( ec );
411 result<X> r2;
412
413 BOOST_TEST_EQ( X::instances, 1 );
414
415 r2 = std::move( r );
416
417 BOOST_TEST_EQ( X::instances, 0 );
418
419 BOOST_TEST( !r2.has_value() );
420 BOOST_TEST( r2.has_error() );
421
422 BOOST_TEST_EQ( r2.error(), ec );
423 }
424
425 BOOST_TEST_EQ( X::instances, 0 );
426
427 {
428 auto ec = make_error_code( e: errc::invalid_argument );
429
430 result<X> r( ec );
431 result<X> r2( 1 );
432
433 BOOST_TEST_EQ( X::instances, 1 );
434
435 r2 = std::move( r );
436
437 BOOST_TEST_EQ( X::instances, 0 );
438
439 BOOST_TEST( !r2.has_value() );
440 BOOST_TEST( r2.has_error() );
441
442 BOOST_TEST_EQ( r2.error(), ec );
443 }
444
445 BOOST_TEST_EQ( X::instances, 0 );
446
447 {
448 auto ec = make_error_code( e: errc::invalid_argument );
449
450 result<X> r( ec );
451 result<X> r2( ENOENT, generic_category() );
452
453 BOOST_TEST_EQ( X::instances, 0 );
454
455 r2 = std::move( r );
456
457 BOOST_TEST_EQ( X::instances, 0 );
458
459 BOOST_TEST( !r2.has_value() );
460 BOOST_TEST( r2.has_error() );
461
462 BOOST_TEST_EQ( r2.error(), ec );
463 }
464
465 BOOST_TEST_EQ( X::instances, 0 );
466
467 //
468
469 BOOST_TEST_EQ( Y::instances, 0 );
470
471 {
472 result<std::string, Y> r( 1 );
473 result<std::string, Y> r2( 2 );
474
475 BOOST_TEST_EQ( Y::instances, 2 );
476
477 r2 = std::move( r );
478
479 BOOST_TEST_EQ( Y::instances, 2 );
480
481 BOOST_TEST( !r2.has_value() );
482 BOOST_TEST( r2.has_error() );
483
484 BOOST_TEST_EQ( r2.error().v_, 1 );
485
486 BOOST_TEST_EQ( r.error().v_, 0 );
487 }
488
489 BOOST_TEST_EQ( Y::instances, 0 );
490
491 {
492 result<std::string, Y> r( 1 );
493 result<std::string, Y> r2( "str" );
494
495 BOOST_TEST_EQ( Y::instances, 1 );
496
497 r2 = std::move( r );
498
499 BOOST_TEST_EQ( Y::instances, 2 );
500
501 BOOST_TEST( !r2.has_value() );
502 BOOST_TEST( r2.has_error() );
503
504 BOOST_TEST_EQ( r2.error().v_, 1 );
505
506 BOOST_TEST_EQ( r.error().v_, 0 );
507 }
508
509 BOOST_TEST_EQ( Y::instances, 0 );
510
511 //
512
513 {
514 result<void> r;
515 result<void> r2;
516
517 r2 = std::move( r );
518
519 BOOST_TEST( r2.has_value() );
520 BOOST_TEST( !r2.has_error() );
521 }
522
523 {
524 result<void> r2;
525
526 r2 = result<void>();
527
528 BOOST_TEST( r2.has_value() );
529 BOOST_TEST( !r2.has_error() );
530 }
531
532 {
533 result<void> r;
534 result<void> r2( ENOENT, generic_category() );
535
536 r2 = std::move( r );
537
538 BOOST_TEST( r2.has_value() );
539 BOOST_TEST( !r2.has_error() );
540 }
541
542 {
543 result<void> r2( ENOENT, generic_category() );
544
545 r2 = result<void>();
546
547 BOOST_TEST( r2.has_value() );
548 BOOST_TEST( !r2.has_error() );
549 }
550
551 {
552 auto ec = make_error_code( e: errc::invalid_argument );
553
554 result<void> r( ec );
555 result<void> r2;
556
557 r2 = std::move( r );
558
559 BOOST_TEST( !r2.has_value() );
560 BOOST_TEST( r2.has_error() );
561
562 BOOST_TEST_EQ( r2.error(), ec );
563 }
564
565 {
566 auto ec = make_error_code( e: errc::invalid_argument );
567
568 result<void> r2;
569
570 r2 = result<void>( ec );
571
572 BOOST_TEST( !r2.has_value() );
573 BOOST_TEST( r2.has_error() );
574
575 BOOST_TEST_EQ( r2.error(), ec );
576 }
577
578 {
579 auto ec = make_error_code( e: errc::invalid_argument );
580
581 result<void> r( ec );
582 result<void> r2( ENOENT, generic_category() );
583
584 r2 = std::move( r );
585
586 BOOST_TEST( !r2.has_value() );
587 BOOST_TEST( r2.has_error() );
588
589 BOOST_TEST_EQ( r2.error(), ec );
590 }
591
592 {
593 auto ec = make_error_code( e: errc::invalid_argument );
594
595 result<void> r2( ENOENT, generic_category() );
596
597 r2 = result<void>( ec );
598
599 BOOST_TEST( !r2.has_value() );
600 BOOST_TEST( r2.has_error() );
601
602 BOOST_TEST_EQ( r2.error(), ec );
603 }
604
605 //
606
607 {
608 int x1 = 1;
609 int x2 = 2;
610
611 result<int&> r1( x1 );
612 result<int&> r2( x2 );
613
614 r2 = std::move( r1 );
615
616 BOOST_TEST_EQ( x1, 1 );
617 BOOST_TEST_EQ( x2, 2 );
618
619 BOOST_TEST( r2.has_value() );
620 BOOST_TEST( !r2.has_error() );
621
622 BOOST_TEST_EQ( r2.value(), 1 );
623
624 BOOST_TEST_EQ( r1, r2 );
625 BOOST_TEST_EQ( &*r1, &*r2 );
626 }
627
628 {
629 int x1 = 1;
630
631 result<int&> r1( x1 );
632 result<int&> r2( ENOENT, generic_category() );
633
634 r2 = std::move( r1 );
635
636 BOOST_TEST_EQ( x1, 1 );
637
638 BOOST_TEST( r2.has_value() );
639 BOOST_TEST( !r2.has_error() );
640
641 BOOST_TEST_EQ( r2.value(), 1 );
642
643 BOOST_TEST_EQ( r1, r2 );
644 }
645
646 {
647 int x1 = 1;
648
649 auto ec = make_error_code( e: errc::invalid_argument );
650
651 result<int&> r1( ec );
652 result<int&> r2( x1 );
653
654 r2 = std::move( r1 );
655
656 BOOST_TEST_EQ( x1, 1 );
657
658 BOOST_TEST( !r2.has_value() );
659 BOOST_TEST( r2.has_error() );
660
661 BOOST_TEST_EQ( r2.error(), ec );
662 }
663
664 {
665 int x1 = 1;
666
667 auto ec = make_error_code( e: errc::invalid_argument );
668
669 result<int&> r2( x1 );
670
671 r2 = result<int&>( ec );
672
673 BOOST_TEST_EQ( x1, 1 );
674
675 BOOST_TEST( !r2.has_value() );
676 BOOST_TEST( r2.has_error() );
677
678 BOOST_TEST_EQ( r2.error(), ec );
679 }
680
681 {
682 auto ec = make_error_code( e: errc::invalid_argument );
683
684 result<int&> r1( ec );
685 result<int&> r2( ENOENT, generic_category() );
686
687 r2 = std::move( r1 );
688
689 BOOST_TEST( !r2.has_value() );
690 BOOST_TEST( r2.has_error() );
691
692 BOOST_TEST_EQ( r2.error(), ec );
693 }
694
695 {
696 auto ec = make_error_code( e: errc::invalid_argument );
697
698 result<int&> r2( ENOENT, generic_category() );
699
700 r2 = result<int&>( ec );
701
702 BOOST_TEST( !r2.has_value() );
703 BOOST_TEST( r2.has_error() );
704
705 BOOST_TEST_EQ( r2.error(), ec );
706 }
707
708 //
709
710 return boost::report_errors();
711}
712

source code of boost/libs/system/test/result_move_assign.cpp