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