1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "android-base/expected.h"
18
19 #include <cstdio>
20 #include <memory>
21 #include <string>
22
23 #include <gtest/gtest.h>
24
25 using android::base::expected;
26 using android::base::unexpected;
27
28 typedef expected<int, int> exp_int;
29 typedef expected<double, double> exp_double;
30 typedef expected<std::string, std::string> exp_string;
31 typedef expected<std::pair<std::string, int>, int> exp_pair;
32 typedef expected<void, int> exp_void;
33
34 struct T {
35 int a;
36 int b;
37 T() = default;
TT38 T(int a, int b) noexcept : a(a), b(b) {}
39 };
operator ==(const T & x,const T & y)40 bool operator==(const T& x, const T& y) {
41 return x.a == y.a && x.b == y.b;
42 }
operator !=(const T & x,const T & y)43 bool operator!=(const T& x, const T& y) {
44 return x.a != y.a || x.b != y.b;
45 }
46
47 struct E {
48 std::string message;
49 int cause;
EE50 E(const std::string& message, int cause) : message(message), cause(cause) {}
51 };
52
53 typedef expected<T,E> exp_complex;
54
TEST(Expected,testDefaultConstructible)55 TEST(Expected, testDefaultConstructible) {
56 exp_int e;
57 EXPECT_TRUE(e.has_value());
58 EXPECT_EQ(0, e.value());
59
60 exp_complex e2;
61 EXPECT_TRUE(e2.has_value());
62 EXPECT_EQ(T(0,0), e2.value());
63
64 exp_void e3;
65 EXPECT_TRUE(e3.has_value());
66 }
67
TEST(Expected,testCopyConstructible)68 TEST(Expected, testCopyConstructible) {
69 exp_int e;
70 exp_int e2 = e;
71
72 EXPECT_TRUE(e.has_value());
73 EXPECT_TRUE(e2.has_value());
74 EXPECT_EQ(0, e.value());
75 EXPECT_EQ(0, e2.value());
76
77 exp_void e3;
78 exp_void e4 = e3;
79 EXPECT_TRUE(e3.has_value());
80 EXPECT_TRUE(e4.has_value());
81 }
82
TEST(Expected,testMoveConstructible)83 TEST(Expected, testMoveConstructible) {
84 exp_int e;
85 exp_int e2 = std::move(e);
86
87 EXPECT_TRUE(e.has_value());
88 EXPECT_TRUE(e2.has_value());
89 EXPECT_EQ(0, e.value());
90 EXPECT_EQ(0, e2.value());
91
92 exp_string e3(std::string("hello"));
93 exp_string e4 = std::move(e3);
94
95 EXPECT_TRUE(e3.has_value());
96 EXPECT_TRUE(e4.has_value());
97 EXPECT_EQ("", e3.value()); // e3 is moved
98 EXPECT_EQ("hello", e4.value());
99
100 exp_void e5;
101 exp_void e6 = std::move(e5);
102 EXPECT_TRUE(e5.has_value());
103 EXPECT_TRUE(e6.has_value());
104 }
105
TEST(Expected,testCopyConstructibleFromConvertibleType)106 TEST(Expected, testCopyConstructibleFromConvertibleType) {
107 exp_double e = 3.3f;
108 exp_int e2 = e;
109
110 EXPECT_TRUE(e.has_value());
111 EXPECT_TRUE(e2.has_value());
112 EXPECT_EQ(3.3f, e.value());
113 EXPECT_EQ(3, e2.value());
114 }
115
TEST(Expected,testMoveConstructibleFromConvertibleType)116 TEST(Expected, testMoveConstructibleFromConvertibleType) {
117 exp_double e = 3.3f;
118 exp_int e2 = std::move(e);
119
120 EXPECT_TRUE(e.has_value());
121 EXPECT_TRUE(e2.has_value());
122 EXPECT_EQ(3.3f, e.value());
123 EXPECT_EQ(3, e2.value());
124 }
125
TEST(Expected,testConstructibleFromValue)126 TEST(Expected, testConstructibleFromValue) {
127 exp_int e = 3;
128 exp_double e2 = 5.5f;
129 exp_string e3 = std::string("hello");
130 exp_complex e4 = T(10, 20);
131 exp_void e5 = {};
132
133 EXPECT_TRUE(e.has_value());
134 EXPECT_TRUE(e2.has_value());
135 EXPECT_TRUE(e3.has_value());
136 EXPECT_TRUE(e4.has_value());
137 EXPECT_TRUE(e5.has_value());
138 EXPECT_EQ(3, e.value());
139 EXPECT_EQ(5.5f, e2.value());
140 EXPECT_EQ("hello", e3.value());
141 EXPECT_EQ(T(10,20), e4.value());
142 }
143
TEST(Expected,testConstructibleFromMovedValue)144 TEST(Expected, testConstructibleFromMovedValue) {
145 std::string hello = "hello";
146 exp_string e = std::move(hello);
147
148 EXPECT_TRUE(e.has_value());
149 EXPECT_EQ("hello", e.value());
150 EXPECT_EQ("", hello);
151 }
152
TEST(Expected,testConstructibleFromConvertibleValue)153 TEST(Expected, testConstructibleFromConvertibleValue) {
154 exp_int e = 3.3f; // double to int
155 exp_string e2 = "hello"; // char* to std::string
156 EXPECT_TRUE(e.has_value());
157 EXPECT_EQ(3, e.value());
158
159 EXPECT_TRUE(e2.has_value());
160 EXPECT_EQ("hello", e2.value());
161 }
162
TEST(Expected,testConstructibleFromUnexpected)163 TEST(Expected, testConstructibleFromUnexpected) {
164 exp_int::unexpected_type unexp = unexpected(10);
165 exp_int e = unexp;
166
167 exp_double::unexpected_type unexp2 = unexpected(10.5f);
168 exp_double e2 = unexp2;
169
170 exp_string::unexpected_type unexp3 = unexpected(std::string("error"));
171 exp_string e3 = unexp3;
172
173 exp_void::unexpected_type unexp4 = unexpected(10);
174 exp_void e4 = unexp4;
175
176 EXPECT_FALSE(e.has_value());
177 EXPECT_FALSE(e2.has_value());
178 EXPECT_FALSE(e3.has_value());
179 EXPECT_FALSE(e4.has_value());
180 EXPECT_EQ(10, e.error());
181 EXPECT_EQ(10.5f, e2.error());
182 EXPECT_EQ("error", e3.error());
183 EXPECT_EQ(10, e4.error());
184 }
185
TEST(Expected,testMoveConstructibleFromUnexpected)186 TEST(Expected, testMoveConstructibleFromUnexpected) {
187 exp_int e = unexpected(10);
188 exp_double e2 = unexpected(10.5f);
189 exp_string e3 = unexpected(std::string("error"));
190 exp_void e4 = unexpected(10);
191
192 EXPECT_FALSE(e.has_value());
193 EXPECT_FALSE(e2.has_value());
194 EXPECT_FALSE(e3.has_value());
195 EXPECT_FALSE(e4.has_value());
196 EXPECT_EQ(10, e.error());
197 EXPECT_EQ(10.5f, e2.error());
198 EXPECT_EQ("error", e3.error());
199 EXPECT_EQ(10, e4.error());
200 }
201
TEST(Expected,testConstructibleByForwarding)202 TEST(Expected, testConstructibleByForwarding) {
203 exp_string e(std::in_place, 5, 'a');
204 EXPECT_TRUE(e.has_value());
205 EXPECT_EQ("aaaaa", e.value());
206
207 exp_string e2({'a', 'b', 'c'});
208 EXPECT_TRUE(e2.has_value());
209 EXPECT_EQ("abc", e2.value());
210
211 exp_pair e3({"hello", 30});
212 EXPECT_TRUE(e3.has_value());
213 EXPECT_EQ("hello",e3->first);
214 EXPECT_EQ(30,e3->second);
215
216 exp_void e4({});
217 EXPECT_TRUE(e4.has_value());
218 }
219
TEST(Expected,testDestructible)220 TEST(Expected, testDestructible) {
221 bool destroyed = false;
222 struct T {
223 bool* flag_;
224 T(bool* flag) : flag_(flag) {}
225 ~T() { *flag_ = true; }
226 };
227 {
228 expected<T, int> exp = T(&destroyed);
229 }
230 EXPECT_TRUE(destroyed);
231 }
232
TEST(Expected,testAssignable)233 TEST(Expected, testAssignable) {
234 exp_int e = 10;
235 exp_int e2 = 20;
236 e = e2;
237
238 EXPECT_EQ(20, e.value());
239 EXPECT_EQ(20, e2.value());
240
241 exp_int e3 = 10;
242 exp_int e4 = 20;
243 e3 = std::move(e4);
244
245 EXPECT_EQ(20, e3.value());
246 EXPECT_EQ(20, e4.value());
247
248 exp_void e5 = unexpected(10);
249 ASSERT_FALSE(e5.has_value());
250 exp_void e6;
251 e5 = e6;
252
253 EXPECT_TRUE(e5.has_value());
254 EXPECT_TRUE(e6.has_value());
255 }
256
TEST(Expected,testAssignableFromValue)257 TEST(Expected, testAssignableFromValue) {
258 exp_int e = 10;
259 e = 20;
260 EXPECT_EQ(20, e.value());
261
262 exp_double e2 = 3.5f;
263 e2 = 10.5f;
264 EXPECT_EQ(10.5f, e2.value());
265
266 exp_string e3 = "hello";
267 e3 = "world";
268 EXPECT_EQ("world", e3.value());
269
270 exp_void e4 = unexpected(10);
271 ASSERT_FALSE(e4.has_value());
272 e4 = {};
273 EXPECT_TRUE(e4.has_value());
274 }
275
TEST(Expected,testAssignableFromUnexpected)276 TEST(Expected, testAssignableFromUnexpected) {
277 exp_int e = 10;
278 e = unexpected(30);
279 EXPECT_FALSE(e.has_value());
280 EXPECT_EQ(30, e.error());
281
282 exp_double e2 = 3.5f;
283 e2 = unexpected(10.5f);
284 EXPECT_FALSE(e2.has_value());
285 EXPECT_EQ(10.5f, e2.error());
286
287 exp_string e3 = "hello";
288 e3 = unexpected("world");
289 EXPECT_FALSE(e3.has_value());
290 EXPECT_EQ("world", e3.error());
291
292 exp_void e4 = {};
293 e4 = unexpected(10);
294 EXPECT_FALSE(e4.has_value());
295 EXPECT_EQ(10, e4.error());
296 }
297
TEST(Expected,testAssignableFromMovedValue)298 TEST(Expected, testAssignableFromMovedValue) {
299 std::string world = "world";
300 exp_string e = "hello";
301 e = std::move(world);
302
303 EXPECT_TRUE(e.has_value());
304 EXPECT_EQ("world", e.value());
305 EXPECT_EQ("", world);
306 }
307
TEST(Expected,testAssignableFromMovedUnexpected)308 TEST(Expected, testAssignableFromMovedUnexpected) {
309 std::string world = "world";
310 exp_string e = "hello";
311 e = unexpected(std::move(world));
312
313 EXPECT_FALSE(e.has_value());
314 EXPECT_EQ("world", e.error());
315 EXPECT_EQ("", world);
316 }
317
TEST(Expected,testEmplace)318 TEST(Expected, testEmplace) {
319 struct T {
320 int a;
321 double b;
322 T() {}
323 T(int a, double b) noexcept : a(a), b(b) {}
324 };
325 expected<T, int> exp;
326 T& t = exp.emplace(3, 10.5f);
327
328 EXPECT_TRUE(exp.has_value());
329 EXPECT_EQ(3, t.a);
330 EXPECT_EQ(10.5f, t.b);
331 EXPECT_EQ(3, exp.value().a);
332 EXPECT_EQ(10.5, exp.value().b);
333
334 exp_void e = unexpected(10);
335 ASSERT_FALSE(e.has_value());
336 e.emplace();
337 EXPECT_TRUE(e.has_value());
338 }
339
TEST(Expected,testSwapExpectedExpected)340 TEST(Expected, testSwapExpectedExpected) {
341 exp_int e = 10;
342 exp_int e2 = 20;
343 e.swap(e2);
344
345 EXPECT_TRUE(e.has_value());
346 EXPECT_TRUE(e2.has_value());
347 EXPECT_EQ(20, e.value());
348 EXPECT_EQ(10, e2.value());
349
350 exp_void e3;
351 exp_void e4;
352 e3.swap(e4);
353
354 EXPECT_TRUE(e3.has_value());
355 EXPECT_TRUE(e4.has_value());
356 }
357
TEST(Expected,testSwapUnexpectedUnexpected)358 TEST(Expected, testSwapUnexpectedUnexpected) {
359 exp_int e = unexpected(10);
360 exp_int e2 = unexpected(20);
361 e.swap(e2);
362 EXPECT_FALSE(e.has_value());
363 EXPECT_FALSE(e2.has_value());
364 EXPECT_EQ(20, e.error());
365 EXPECT_EQ(10, e2.error());
366
367 exp_void e3 = unexpected(10);
368 exp_void e4 = unexpected(20);
369 e3.swap(e4);
370 EXPECT_FALSE(e3.has_value());
371 EXPECT_FALSE(e4.has_value());
372 EXPECT_EQ(20, e3.error());
373 EXPECT_EQ(10, e4.error());
374 }
375
TEST(Expected,testSwapExpectedUnepected)376 TEST(Expected, testSwapExpectedUnepected) {
377 exp_int e = 10;
378 exp_int e2 = unexpected(30);
379 e.swap(e2);
380 EXPECT_FALSE(e.has_value());
381 EXPECT_TRUE(e2.has_value());
382 EXPECT_EQ(30, e.error());
383 EXPECT_EQ(10, e2.value());
384
385 exp_void e3;
386 exp_void e4 = unexpected(10);
387 e3.swap(e4);
388 EXPECT_FALSE(e3.has_value());
389 EXPECT_TRUE(e4.has_value());
390 EXPECT_EQ(10, e3.error());
391 }
392
TEST(Expected,testDereference)393 TEST(Expected, testDereference) {
394 struct T {
395 int a;
396 double b;
397 T() {}
398 T(int a, double b) : a(a), b(b) {}
399 };
400 expected<T, int> exp = T(3, 10.5f);
401
402 EXPECT_EQ(3, exp->a);
403 EXPECT_EQ(10.5f, exp->b);
404
405 EXPECT_EQ(3, (*exp).a);
406 EXPECT_EQ(10.5f, (*exp).b);
407 }
408
TEST(Expected,testTest)409 TEST(Expected, testTest) {
410 exp_int e = 10;
411 EXPECT_TRUE(e.ok());
412 EXPECT_TRUE(e.has_value());
413
414 exp_int e2 = unexpected(10);
415 EXPECT_FALSE(e2.ok());
416 EXPECT_FALSE(e2.has_value());
417 }
418
TEST(Expected,testGetValue)419 TEST(Expected, testGetValue) {
420 exp_int e = 10;
421 EXPECT_EQ(10, e.value());
422 EXPECT_EQ(10, e.value_or(20));
423
424 exp_int e2 = unexpected(10);
425 EXPECT_EQ(10, e2.error());
426 EXPECT_EQ(20, e2.value_or(20));
427 }
428
TEST(Expected,testSameValues)429 TEST(Expected, testSameValues) {
430 exp_int e = 10;
431 exp_int e2 = 10;
432 EXPECT_TRUE(e == e2);
433 EXPECT_TRUE(e2 == e);
434 EXPECT_FALSE(e != e2);
435 EXPECT_FALSE(e2 != e);
436
437 exp_void e3;
438 exp_void e4;
439 EXPECT_TRUE(e3 == e4);
440 EXPECT_TRUE(e4 == e3);
441 EXPECT_FALSE(e3 != e4);
442 EXPECT_FALSE(e4 != e3);
443 }
444
TEST(Expected,testDifferentValues)445 TEST(Expected, testDifferentValues) {
446 exp_int e = 10;
447 exp_int e2 = 20;
448 EXPECT_FALSE(e == e2);
449 EXPECT_FALSE(e2 == e);
450 EXPECT_TRUE(e != e2);
451 EXPECT_TRUE(e2 != e);
452 }
453
TEST(Expected,testValueWithError)454 TEST(Expected, testValueWithError) {
455 exp_int e = 10;
456 exp_int e2 = unexpected(10);
457 EXPECT_FALSE(e == e2);
458 EXPECT_FALSE(e2 == e);
459 EXPECT_TRUE(e != e2);
460 EXPECT_TRUE(e2 != e);
461
462 exp_void e3;
463 exp_void e4 = unexpected(10);
464 EXPECT_FALSE(e3 == e4);
465 EXPECT_FALSE(e4 == e3);
466 EXPECT_TRUE(e3 != e4);
467 EXPECT_TRUE(e4 != e3);
468 }
469
TEST(Expected,testSameErrors)470 TEST(Expected, testSameErrors) {
471 exp_int e = unexpected(10);
472 exp_int e2 = unexpected(10);
473 EXPECT_TRUE(e == e2);
474 EXPECT_TRUE(e2 == e);
475 EXPECT_FALSE(e != e2);
476 EXPECT_FALSE(e2 != e);
477
478 exp_void e3 = unexpected(10);
479 exp_void e4 = unexpected(10);
480 EXPECT_TRUE(e3 == e4);
481 EXPECT_TRUE(e4 == e3);
482 EXPECT_FALSE(e3 != e4);
483 EXPECT_FALSE(e4 != e3);
484 }
485
TEST(Expected,testDifferentErrors)486 TEST(Expected, testDifferentErrors) {
487 exp_int e = unexpected(10);
488 exp_int e2 = unexpected(20);
489 EXPECT_FALSE(e == e2);
490 EXPECT_FALSE(e2 == e);
491 EXPECT_TRUE(e != e2);
492 EXPECT_TRUE(e2 != e);
493
494 exp_void e3 = unexpected(10);
495 exp_void e4 = unexpected(20);
496 EXPECT_FALSE(e3 == e4);
497 EXPECT_FALSE(e4 == e3);
498 EXPECT_TRUE(e3 != e4);
499 EXPECT_TRUE(e4 != e3);
500 }
501
TEST(Expected,testCompareWithSameError)502 TEST(Expected, testCompareWithSameError) {
503 exp_int e = unexpected(10);
504 exp_int::unexpected_type error = 10;
505 EXPECT_TRUE(e == error);
506 EXPECT_TRUE(error == e);
507 EXPECT_FALSE(e != error);
508 EXPECT_FALSE(error != e);
509
510 exp_void e2 = unexpected(10);
511 exp_void::unexpected_type error2 = 10;
512 EXPECT_TRUE(e2 == error2);
513 EXPECT_TRUE(error2 == e2);
514 EXPECT_FALSE(e2 != error2);
515 EXPECT_FALSE(error2 != e2);
516 }
517
TEST(Expected,testCompareWithDifferentError)518 TEST(Expected, testCompareWithDifferentError) {
519 exp_int e = unexpected(10);
520 exp_int::unexpected_type error = 20;
521 EXPECT_FALSE(e == error);
522 EXPECT_FALSE(error == e);
523 EXPECT_TRUE(e != error);
524 EXPECT_TRUE(error != e);
525
526 exp_void e2 = unexpected(10);
527 exp_void::unexpected_type error2 = 20;
528 EXPECT_FALSE(e2 == error2);
529 EXPECT_FALSE(error2 == e2);
530 EXPECT_TRUE(e2 != error2);
531 EXPECT_TRUE(error2 != e2);
532 }
533
TEST(Expected,testCompareDifferentType)534 TEST(Expected, testCompareDifferentType) {
535 expected<int,int> e = 10;
536 expected<int32_t, int> e2 = 10;
537 EXPECT_TRUE(e == e2);
538 e2 = 20;
539 EXPECT_FALSE(e == e2);
540
541 expected<std::string_view,int> e3 = "hello";
542 expected<std::string,int> e4 = "hello";
543 EXPECT_TRUE(e3 == e4);
544 e4 = "world";
545 EXPECT_FALSE(e3 == e4);
546
547 expected<void,int> e5;
548 expected<int,int> e6 = 10;
549 EXPECT_FALSE(e5 == e6);
550 EXPECT_FALSE(e6 == e5);
551 }
552
TEST(Expected,testDivideExample)553 TEST(Expected, testDivideExample) {
554 struct QR {
555 int quotient;
556 int remainder;
557 QR(int q, int r) noexcept : quotient(q), remainder(r) {}
558 bool operator==(const QR& rhs) const {
559 return quotient == rhs.quotient && remainder == rhs.remainder;
560 }
561 bool operator!=(const QR& rhs) const {
562 return quotient != rhs.quotient || remainder == rhs.remainder;
563 }
564 };
565
566 auto divide = [](int x, int y) -> expected<QR,E> {
567 if (y == 0) {
568 return unexpected(E("divide by zero", -1));
569 } else {
570 return QR(x / y, x % y);
571 }
572 };
573
574 EXPECT_FALSE(divide(10, 0).ok());
575 EXPECT_EQ("divide by zero", divide(10, 0).error().message);
576 EXPECT_EQ(-1, divide(10, 0).error().cause);
577
578 EXPECT_TRUE(divide(10, 3).ok());
579 EXPECT_EQ(QR(3, 1), *divide(10, 3));
580 }
581
TEST(Expected,testPair)582 TEST(Expected, testPair) {
583 auto test = [](bool yes) -> exp_pair {
584 if (yes) {
585 return exp_pair({"yes", 42});
586 } else {
587 return unexpected(42);
588 }
589 };
590
591 auto r = test(true);
592 EXPECT_TRUE(r.ok());
593 EXPECT_EQ("yes", r->first);
594 }
595
TEST(Expected,testVoid)596 TEST(Expected, testVoid) {
597 auto test = [](bool ok) -> exp_void {
598 if (ok) {
599 return {};
600 } else {
601 return unexpected(10);
602 }
603 };
604
605 auto r = test(true);
606 EXPECT_TRUE(r.ok());
607 r = test(false);
608 EXPECT_FALSE(r.ok());
609 EXPECT_EQ(10, r.error());
610 }
611
612 // copied from result_test.cpp
613 struct ConstructorTracker {
614 static size_t constructor_called;
615 static size_t copy_constructor_called;
616 static size_t move_constructor_called;
617 static size_t copy_assignment_called;
618 static size_t move_assignment_called;
619
620 template <typename T,
621 typename std::enable_if_t<std::is_convertible_v<T, std::string>>* = nullptr>
ConstructorTrackerConstructorTracker622 ConstructorTracker(T&& string) : string(string) {
623 ++constructor_called;
624 }
ConstructorTrackerConstructorTracker625 ConstructorTracker(const ConstructorTracker& ct) {
626 ++copy_constructor_called;
627 string = ct.string;
628 }
ConstructorTrackerConstructorTracker629 ConstructorTracker(ConstructorTracker&& ct) noexcept {
630 ++move_constructor_called;
631 string = std::move(ct.string);
632 }
operator =ConstructorTracker633 ConstructorTracker& operator=(const ConstructorTracker& ct) {
634 ++copy_assignment_called;
635 string = ct.string;
636 return *this;
637 }
operator =ConstructorTracker638 ConstructorTracker& operator=(ConstructorTracker&& ct) noexcept {
639 ++move_assignment_called;
640 string = std::move(ct.string);
641 return *this;
642 }
ResetConstructorTracker643 static void Reset() {
644 constructor_called = 0;
645 copy_constructor_called = 0;
646 move_constructor_called = 0;
647 copy_assignment_called = 0;
648 move_assignment_called = 0;
649 }
650 std::string string;
651 };
652
653 size_t ConstructorTracker::constructor_called = 0;
654 size_t ConstructorTracker::copy_constructor_called = 0;
655 size_t ConstructorTracker::move_constructor_called = 0;
656 size_t ConstructorTracker::copy_assignment_called = 0;
657 size_t ConstructorTracker::move_assignment_called = 0;
658
659 typedef expected<ConstructorTracker, int> exp_track;
660
TEST(Expected,testNumberOfCopies)661 TEST(Expected, testNumberOfCopies) {
662 // default constructor
663 ConstructorTracker::Reset();
664 exp_track e("hello");
665 EXPECT_EQ(1U, ConstructorTracker::constructor_called);
666 EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
667 EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
668 EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
669 EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
670
671 // copy constructor
672 ConstructorTracker::Reset();
673 exp_track e2 = e;
674 EXPECT_EQ(0U, ConstructorTracker::constructor_called);
675 EXPECT_EQ(1U, ConstructorTracker::copy_constructor_called);
676 EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
677 EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
678 EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
679
680 // move constructor
681 ConstructorTracker::Reset();
682 exp_track e3 = std::move(e);
683 EXPECT_EQ(0U, ConstructorTracker::constructor_called);
684 EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
685 EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
686 EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
687 EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
688
689 // construct from lvalue
690 ConstructorTracker::Reset();
691 ConstructorTracker ct = "hello";
692 exp_track e4(ct);
693 EXPECT_EQ(1U, ConstructorTracker::constructor_called);
694 EXPECT_EQ(1U, ConstructorTracker::copy_constructor_called);
695 EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
696 EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
697 EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
698
699 // construct from rvalue
700 ConstructorTracker::Reset();
701 ConstructorTracker ct2 = "hello";
702 exp_track e5(std::move(ct2));
703 EXPECT_EQ(1U, ConstructorTracker::constructor_called);
704 EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
705 EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
706 EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
707 EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
708
709 // copy assignment
710 ConstructorTracker::Reset();
711 exp_track e6 = "hello";
712 exp_track e7 = "world";
713 e7 = e6;
714 EXPECT_EQ(2U, ConstructorTracker::constructor_called);
715 EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
716 EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
717 EXPECT_EQ(1U, ConstructorTracker::copy_assignment_called);
718 EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
719
720 // move assignment
721 ConstructorTracker::Reset();
722 exp_track e8 = "hello";
723 exp_track e9 = "world";
724 e9 = std::move(e8);
725 EXPECT_EQ(2U, ConstructorTracker::constructor_called);
726 EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
727 EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
728 EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
729 EXPECT_EQ(1U, ConstructorTracker::move_assignment_called);
730
731 // swap
732 ConstructorTracker::Reset();
733 exp_track e10 = "hello";
734 exp_track e11 = "world";
735 std::swap(e10, e11);
736 EXPECT_EQ(2U, ConstructorTracker::constructor_called);
737 EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
738 EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
739 EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
740 EXPECT_EQ(2U, ConstructorTracker::move_assignment_called);
741 }
742
TEST(Expected,testNoCopyOnReturn)743 TEST(Expected, testNoCopyOnReturn) {
744 auto test = [](const std::string& in) -> exp_track {
745 if (in.empty()) {
746 return "literal string";
747 }
748 if (in == "test2") {
749 return ConstructorTracker(in + in + "2");
750 }
751 ConstructorTracker result(in + " " + in);
752 return result;
753 };
754
755 ConstructorTracker::Reset();
756 auto result1 = test("");
757 ASSERT_TRUE(result1.ok());
758 EXPECT_EQ("literal string", result1->string);
759 EXPECT_EQ(1U, ConstructorTracker::constructor_called);
760 EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
761 EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
762 EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
763 EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
764
765 ConstructorTracker::Reset();
766 auto result2 = test("test2");
767 ASSERT_TRUE(result2.ok());
768 EXPECT_EQ("test2test22", result2->string);
769 EXPECT_EQ(1U, ConstructorTracker::constructor_called);
770 EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
771 EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
772 EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
773 EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
774
775 ConstructorTracker::Reset();
776 auto result3 = test("test3");
777 ASSERT_TRUE(result3.ok());
778 EXPECT_EQ("test3 test3", result3->string);
779 EXPECT_EQ(1U, ConstructorTracker::constructor_called);
780 EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
781 EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
782 EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
783 EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
784 }
785
TEST(Expected,testNested)786 TEST(Expected, testNested) {
787 expected<exp_string, std::string> e = "hello";
788
789 EXPECT_TRUE(e.ok());
790 EXPECT_TRUE(e.has_value());
791 EXPECT_TRUE(e.value().has_value());
792 EXPECT_TRUE(e->ok());
793 EXPECT_EQ("hello", e.value().value());
794
795 expected<exp_string, std::string> e2 = unexpected("world");
796 EXPECT_FALSE(e2.has_value());
797 EXPECT_FALSE(e2.ok());
798 EXPECT_EQ("world", e2.error());
799
800 expected<exp_string, std::string> e3 = exp_string(unexpected("world"));
801 EXPECT_TRUE(e3.has_value());
802 EXPECT_FALSE(e3.value().has_value());
803 EXPECT_TRUE(e3.ok());
804 EXPECT_FALSE(e3->ok());
805 EXPECT_EQ("world", e3.value().error());
806 }
807
equals(const char * a,const char * b)808 constexpr bool equals(const char* a, const char* b) {
809 return (a == nullptr && b == nullptr) ||
810 (a != nullptr && b != nullptr && *a == *b &&
811 (*a == '\0' || equals(a + 1, b + 1)));
812 }
813
TEST(Expected,testConstexpr)814 TEST(Expected, testConstexpr) {
815 // Compliation error will occur if these expressions can't be
816 // evaluated at compile time
817 constexpr exp_int e(3);
818 constexpr exp_int::unexpected_type err(3);
819 constexpr int i = 4;
820
821 // default constructor
822 static_assert(exp_int().value() == 0);
823 // copy constructor
824 static_assert(exp_int(e).value() == 3);
825 // move constructor
826 static_assert(exp_int(exp_int(4)).value() == 4);
827 // copy construct from value
828 static_assert(exp_int(i).value() == 4);
829 // copy construct from unexpected
830 static_assert(exp_int(err).error() == 3);
831 // move costruct from unexpected
832 static_assert(exp_int(unexpected(3)).error() == 3);
833 // observers
834 static_assert(*exp_int(3) == 3);
835 static_assert(exp_int(3).has_value() == true);
836 static_assert(exp_int(3).value_or(4) == 3);
837
838 typedef expected<const char*, int> exp_s;
839 constexpr exp_s s("hello");
840 constexpr const char* c = "hello";
841 static_assert(equals(exp_s().value(), nullptr));
842 static_assert(equals(exp_s(s).value(), "hello"));
843 static_assert(equals(exp_s(exp_s("hello")).value(), "hello"));
844 static_assert(equals(exp_s("hello").value(), "hello"));
845 static_assert(equals(exp_s(c).value(), "hello"));
846 }
847
TEST(Expected,testWithNonConstructible)848 TEST(Expected, testWithNonConstructible) {
849 struct AssertNotConstructed {
850 AssertNotConstructed() = delete;
851 };
852
853 expected<int, AssertNotConstructed> v(42);
854 EXPECT_TRUE(v.has_value());
855 EXPECT_EQ(42, v.value());
856
857 expected<AssertNotConstructed, int> e(unexpected(42));
858 EXPECT_FALSE(e.has_value());
859 EXPECT_EQ(42, e.error());
860 }
861
TEST(Expected,testWithMoveOnlyType)862 TEST(Expected, testWithMoveOnlyType) {
863 typedef expected<std::unique_ptr<int>,std::unique_ptr<int>> exp_ptr;
864 exp_ptr e(std::make_unique<int>(3));
865 exp_ptr e2(unexpected(std::make_unique<int>(4)));
866
867 EXPECT_TRUE(e.has_value());
868 EXPECT_FALSE(e2.has_value());
869 EXPECT_EQ(3, *(e.value()));
870 EXPECT_EQ(4, *(e2.error()));
871
872 e2 = std::move(e);
873 EXPECT_TRUE(e.has_value());
874 EXPECT_TRUE(e2.has_value());
875 EXPECT_EQ(3, *(e2.value()));
876 }
877