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.3;
108   exp_int e2 = e;
109 
110   EXPECT_TRUE(e.has_value());
111   EXPECT_TRUE(e2.has_value());
112   EXPECT_EQ(3.3, e.value());
113   EXPECT_EQ(3, e2.value());
114 }
115 
TEST(Expected,testMoveConstructibleFromConvertibleType)116 TEST(Expected, testMoveConstructibleFromConvertibleType) {
117   exp_double e = 3.3;
118   exp_int e2 = std::move(e);
119 
120   EXPECT_TRUE(e.has_value());
121   EXPECT_TRUE(e2.has_value());
122   EXPECT_EQ(3.3, 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.5;
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.5, 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.3;         // 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.5);
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.5, 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.5);
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.5, 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.5;
263   e2 = 10.5;
264   EXPECT_EQ(10.5, 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.5;
283   e2 = unexpected(10.5);
284   EXPECT_FALSE(e2.has_value());
285   EXPECT_EQ(10.5, 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.5);
327 
328   EXPECT_TRUE(exp.has_value());
329   EXPECT_EQ(3, t.a);
330   EXPECT_EQ(10.5, 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 
340 // For the swap tests, call swap using an unqualified identifier, which should
341 // find the namespace-scope android::base::swap() function using
342 // argument-dependent lookup. The usual idiom for swapping an arbitrary C++ type
343 // is `using std::swap; swap(...);`.
TEST(Expected,testSwapExpectedExpected)344 TEST(Expected, testSwapExpectedExpected) {
345   exp_int e = 10;
346   exp_int e2 = 20;
347   swap(e, e2);
348 
349   EXPECT_TRUE(e.has_value());
350   EXPECT_TRUE(e2.has_value());
351   EXPECT_EQ(20, e.value());
352   EXPECT_EQ(10, e2.value());
353 
354   exp_void e3;
355   exp_void e4;
356   swap(e3, e4);
357 
358   EXPECT_TRUE(e3.has_value());
359   EXPECT_TRUE(e4.has_value());
360 }
361 
TEST(Expected,testSwapUnexpectedUnexpected)362 TEST(Expected, testSwapUnexpectedUnexpected) {
363   exp_int e = unexpected(10);
364   exp_int e2 = unexpected(20);
365   swap(e, e2);
366   EXPECT_FALSE(e.has_value());
367   EXPECT_FALSE(e2.has_value());
368   EXPECT_EQ(20, e.error());
369   EXPECT_EQ(10, e2.error());
370 
371   exp_void e3 = unexpected(10);
372   exp_void e4 = unexpected(20);
373   swap(e3, e4);
374   EXPECT_FALSE(e3.has_value());
375   EXPECT_FALSE(e4.has_value());
376   EXPECT_EQ(20, e3.error());
377   EXPECT_EQ(10, e4.error());
378 }
379 
TEST(Expected,testSwapExpectedUnepected)380 TEST(Expected, testSwapExpectedUnepected) {
381   exp_int e = 10;
382   exp_int e2 = unexpected(30);
383   swap(e, e2);
384   EXPECT_FALSE(e.has_value());
385   EXPECT_TRUE(e2.has_value());
386   EXPECT_EQ(30, e.error());
387   EXPECT_EQ(10, e2.value());
388 
389   exp_void e3;
390   exp_void e4 = unexpected(10);
391   swap(e3, e4);
392   EXPECT_FALSE(e3.has_value());
393   EXPECT_TRUE(e4.has_value());
394   EXPECT_EQ(10, e3.error());
395 }
396 
TEST(Expected,testNonswappable)397 TEST(Expected, testNonswappable) {
398   struct NoSwap {
399     NoSwap(int val) : val(val) {}
400     NoSwap(const NoSwap& other) : val(other.val) {}
401     NoSwap(NoSwap&& other) : val(other.val) {}
402     int val;
403   };
404 
405   // NoSwap has no namespace-scope swap function, and because it lacks a
406   // move assignment operator, std::swap is also not defined for it.
407   static_assert(!std::is_move_assignable_v<NoSwap>);
408   static_assert(!std::is_swappable_v<NoSwap>);
409 
410   // A non-swappable type may still be used in the expected class.
411   expected<NoSwap, int> e1(NoSwap(3));
412   EXPECT_EQ(3, e1.value().val);
413   expected<int, NoSwap> e2(unexpected(NoSwap(5)));
414   EXPECT_EQ(5, e2.error().val);
415   expected<void, NoSwap> e3(unexpected(NoSwap(7)));
416   EXPECT_EQ(7, e3.error().val);
417 
418   static_assert(!std::is_move_assignable_v<decltype(e1)>);
419   static_assert(!std::is_move_assignable_v<decltype(e2)>);
420   static_assert(!std::is_move_assignable_v<decltype(e3)>);
421   static_assert(!std::is_swappable_v<decltype(e1)>);
422   static_assert(!std::is_swappable_v<decltype(e2)>);
423   static_assert(!std::is_swappable_v<decltype(e3)>);
424 }
425 
TEST(Expected,testDereference)426 TEST(Expected, testDereference) {
427   struct T {
428     int a;
429     double b;
430     T() {}
431     T(int a, double b) : a(a), b(b) {}
432   };
433   expected<T, int> exp = T(3, 10.5);
434 
435   EXPECT_EQ(3, exp->a);
436   EXPECT_EQ(10.5, exp->b);
437 
438   EXPECT_EQ(3, (*exp).a);
439   EXPECT_EQ(10.5, (*exp).b);
440 }
441 
TEST(Expected,testTest)442 TEST(Expected, testTest) {
443   exp_int e = 10;
444   EXPECT_TRUE(e.ok());
445   EXPECT_TRUE(e.has_value());
446 
447   exp_int e2 = unexpected(10);
448   EXPECT_FALSE(e2.ok());
449   EXPECT_FALSE(e2.has_value());
450 }
451 
TEST(Expected,testGetValue)452 TEST(Expected, testGetValue) {
453   exp_int e = 10;
454   EXPECT_EQ(10, e.value());
455   EXPECT_EQ(10, e.value_or(20));
456 
457   exp_int e2 = unexpected(10);
458   EXPECT_EQ(10, e2.error());
459   EXPECT_EQ(20, e2.value_or(20));
460 }
461 
TEST(Expected,testSameValues)462 TEST(Expected, testSameValues) {
463   exp_int e = 10;
464   exp_int e2 = 10;
465   EXPECT_TRUE(e == e2);
466   EXPECT_TRUE(e2 == e);
467   EXPECT_FALSE(e != e2);
468   EXPECT_FALSE(e2 != e);
469 
470   exp_void e3;
471   exp_void e4;
472   EXPECT_TRUE(e3 == e4);
473   EXPECT_TRUE(e4 == e3);
474   EXPECT_FALSE(e3 != e4);
475   EXPECT_FALSE(e4 != e3);
476 }
477 
TEST(Expected,testDifferentValues)478 TEST(Expected, testDifferentValues) {
479   exp_int e = 10;
480   exp_int e2 = 20;
481   EXPECT_FALSE(e == e2);
482   EXPECT_FALSE(e2 == e);
483   EXPECT_TRUE(e != e2);
484   EXPECT_TRUE(e2 != e);
485 }
486 
TEST(Expected,testValueWithError)487 TEST(Expected, testValueWithError) {
488   exp_int e = 10;
489   exp_int e2 = unexpected(10);
490   EXPECT_FALSE(e == e2);
491   EXPECT_FALSE(e2 == e);
492   EXPECT_TRUE(e != e2);
493   EXPECT_TRUE(e2 != e);
494 
495   exp_void e3;
496   exp_void e4 = unexpected(10);
497   EXPECT_FALSE(e3 == e4);
498   EXPECT_FALSE(e4 == e3);
499   EXPECT_TRUE(e3 != e4);
500   EXPECT_TRUE(e4 != e3);
501 }
502 
TEST(Expected,testSameErrors)503 TEST(Expected, testSameErrors) {
504   exp_int e = unexpected(10);
505   exp_int e2 = unexpected(10);
506   EXPECT_TRUE(e == e2);
507   EXPECT_TRUE(e2 == e);
508   EXPECT_FALSE(e != e2);
509   EXPECT_FALSE(e2 != e);
510 
511   exp_void e3 = unexpected(10);
512   exp_void e4 = unexpected(10);
513   EXPECT_TRUE(e3 == e4);
514   EXPECT_TRUE(e4 == e3);
515   EXPECT_FALSE(e3 != e4);
516   EXPECT_FALSE(e4 != e3);
517 }
518 
TEST(Expected,testDifferentErrors)519 TEST(Expected, testDifferentErrors) {
520   exp_int e = unexpected(10);
521   exp_int e2 = unexpected(20);
522   EXPECT_FALSE(e == e2);
523   EXPECT_FALSE(e2 == e);
524   EXPECT_TRUE(e != e2);
525   EXPECT_TRUE(e2 != e);
526 
527   exp_void e3 = unexpected(10);
528   exp_void e4 = unexpected(20);
529   EXPECT_FALSE(e3 == e4);
530   EXPECT_FALSE(e4 == e3);
531   EXPECT_TRUE(e3 != e4);
532   EXPECT_TRUE(e4 != e3);
533 }
534 
TEST(Expected,testCompareWithSameError)535 TEST(Expected, testCompareWithSameError) {
536   exp_int e = unexpected(10);
537   exp_int::unexpected_type error{10};
538   EXPECT_TRUE(e == error);
539   EXPECT_TRUE(error == e);
540   EXPECT_FALSE(e != error);
541   EXPECT_FALSE(error != e);
542 
543   exp_void e2 = unexpected(10);
544   exp_void::unexpected_type error2{10};
545   EXPECT_TRUE(e2 == error2);
546   EXPECT_TRUE(error2 == e2);
547   EXPECT_FALSE(e2 != error2);
548   EXPECT_FALSE(error2 != e2);
549 }
550 
TEST(Expected,testCompareWithDifferentError)551 TEST(Expected, testCompareWithDifferentError) {
552   exp_int e = unexpected(10);
553   exp_int::unexpected_type error{20};
554   EXPECT_FALSE(e == error);
555   EXPECT_FALSE(error == e);
556   EXPECT_TRUE(e != error);
557   EXPECT_TRUE(error != e);
558 
559   exp_void e2 = unexpected(10);
560   exp_void::unexpected_type error2{20};
561   EXPECT_FALSE(e2 == error2);
562   EXPECT_FALSE(error2 == e2);
563   EXPECT_TRUE(e2 != error2);
564   EXPECT_TRUE(error2 != e2);
565 }
566 
TEST(Expected,testCompareDifferentType)567 TEST(Expected, testCompareDifferentType) {
568   expected<int,int> e = 10;
569   expected<int32_t, int> e2 = 10;
570   EXPECT_TRUE(e == e2);
571   e2 = 20;
572   EXPECT_FALSE(e == e2);
573 
574   expected<std::string_view,int> e3 = "hello";
575   expected<std::string,int> e4 = "hello";
576   EXPECT_TRUE(e3 == e4);
577   e4 = "world";
578   EXPECT_FALSE(e3 == e4);
579 
580   expected<void,int> e5;
581   expected<int,int> e6 = 10;
582   EXPECT_FALSE(e5 == e6);
583   EXPECT_FALSE(e6 == e5);
584 }
585 
TEST(Expected,testDivideExample)586 TEST(Expected, testDivideExample) {
587   struct QR {
588     int quotient;
589     int remainder;
590     QR(int q, int r) noexcept : quotient(q), remainder(r) {}
591     bool operator==(const QR& rhs) const {
592       return quotient == rhs.quotient && remainder == rhs.remainder;
593     }
594     bool operator!=(const QR& rhs) const {
595       return quotient != rhs.quotient || remainder == rhs.remainder;
596     }
597   };
598 
599   auto divide = [](int x, int y) -> expected<QR,E> {
600     if (y == 0) {
601       return unexpected(E("divide by zero", -1));
602     } else {
603       return QR(x / y, x % y);
604     }
605   };
606 
607   EXPECT_FALSE(divide(10, 0).ok());
608   EXPECT_EQ("divide by zero", divide(10, 0).error().message);
609   EXPECT_EQ(-1, divide(10, 0).error().cause);
610 
611   EXPECT_TRUE(divide(10, 3).ok());
612   EXPECT_EQ(QR(3, 1), *divide(10, 3));
613 }
614 
TEST(Expected,testPair)615 TEST(Expected, testPair) {
616   auto test = [](bool yes) -> exp_pair {
617     if (yes) {
618       return exp_pair({"yes", 42});
619     } else {
620       return unexpected(42);
621     }
622   };
623 
624   auto r = test(true);
625   EXPECT_TRUE(r.ok());
626   EXPECT_EQ("yes", r->first);
627 }
628 
TEST(Expected,testVoid)629 TEST(Expected, testVoid) {
630   auto test = [](bool ok) -> exp_void {
631     if (ok) {
632       return {};
633     } else {
634       return unexpected(10);
635     }
636   };
637 
638   auto r = test(true);
639   EXPECT_TRUE(r.ok());
640   r = test(false);
641   EXPECT_FALSE(r.ok());
642   EXPECT_EQ(10, r.error());
643 }
644 
645 // copied from result_test.cpp
646 struct ConstructorTracker {
647   static size_t constructor_called;
648   static size_t copy_constructor_called;
649   static size_t move_constructor_called;
650   static size_t copy_assignment_called;
651   static size_t move_assignment_called;
652 
653   template <typename T,
654     typename std::enable_if_t<std::is_convertible_v<T, std::string>>* = nullptr>
ConstructorTrackerConstructorTracker655   ConstructorTracker(T&& string) : string(string) {
656     ++constructor_called;
657   }
ConstructorTrackerConstructorTracker658   ConstructorTracker(const ConstructorTracker& ct) {
659     ++copy_constructor_called;
660     string = ct.string;
661   }
ConstructorTrackerConstructorTracker662   ConstructorTracker(ConstructorTracker&& ct) noexcept {
663     ++move_constructor_called;
664     string = std::move(ct.string);
665   }
operator =ConstructorTracker666   ConstructorTracker& operator=(const ConstructorTracker& ct) {
667     ++copy_assignment_called;
668     string = ct.string;
669     return *this;
670   }
operator =ConstructorTracker671   ConstructorTracker& operator=(ConstructorTracker&& ct) noexcept {
672     ++move_assignment_called;
673     string = std::move(ct.string);
674     return *this;
675   }
ResetConstructorTracker676   static void Reset() {
677     constructor_called = 0;
678     copy_constructor_called = 0;
679     move_constructor_called = 0;
680     copy_assignment_called = 0;
681     move_assignment_called = 0;
682   }
683   std::string string;
684 };
685 
686 size_t ConstructorTracker::constructor_called = 0;
687 size_t ConstructorTracker::copy_constructor_called = 0;
688 size_t ConstructorTracker::move_constructor_called = 0;
689 size_t ConstructorTracker::copy_assignment_called = 0;
690 size_t ConstructorTracker::move_assignment_called = 0;
691 
692 typedef expected<ConstructorTracker, int> exp_track;
693 
TEST(Expected,testNumberOfCopies)694 TEST(Expected, testNumberOfCopies) {
695   // ordinary constructor
696   ConstructorTracker::Reset();
697   exp_track e("hello");
698   EXPECT_EQ(1U, ConstructorTracker::constructor_called);
699   EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
700   EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
701   EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
702   EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
703 
704   // copy constructor
705   ConstructorTracker::Reset();
706   exp_track e2 = e;
707   EXPECT_EQ(0U, ConstructorTracker::constructor_called);
708   EXPECT_EQ(1U, ConstructorTracker::copy_constructor_called);
709   EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
710   EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
711   EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
712 
713   // move constructor
714   ConstructorTracker::Reset();
715   exp_track e3 = std::move(e);
716   EXPECT_EQ(0U, ConstructorTracker::constructor_called);
717   EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
718   EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
719   EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
720   EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
721 
722   // construct from lvalue
723   ConstructorTracker::Reset();
724   ConstructorTracker ct = "hello";
725   exp_track e4(ct);
726   EXPECT_EQ(1U, ConstructorTracker::constructor_called);
727   EXPECT_EQ(1U, ConstructorTracker::copy_constructor_called);
728   EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
729   EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
730   EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
731 
732   // construct from rvalue
733   ConstructorTracker::Reset();
734   ConstructorTracker ct2 = "hello";
735   exp_track e5(std::move(ct2));
736   EXPECT_EQ(1U, 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(0U, ConstructorTracker::move_assignment_called);
741 
742   // copy assignment
743   ConstructorTracker::Reset();
744   exp_track e6 = "hello";
745   exp_track e7 = "world";
746   e7 = e6;
747   EXPECT_EQ(2U, ConstructorTracker::constructor_called);
748   EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
749   EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
750   EXPECT_EQ(1U, ConstructorTracker::copy_assignment_called);
751   EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
752 
753   // move assignment
754   ConstructorTracker::Reset();
755   exp_track e8 = "hello";
756   exp_track e9 = "world";
757   e9 = std::move(e8);
758   EXPECT_EQ(2U, ConstructorTracker::constructor_called);
759   EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
760   EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
761   EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
762   EXPECT_EQ(1U, ConstructorTracker::move_assignment_called);
763 
764   // swap
765   ConstructorTracker::Reset();
766   exp_track e10 = "hello";
767   exp_track e11 = "world";
768   swap(e10, e11);
769   EXPECT_EQ(2U, 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(2U, ConstructorTracker::move_assignment_called);
774 }
775 
TEST(Expected,testCopiesWithDifferentValueOrErrorTypes)776 TEST(Expected, testCopiesWithDifferentValueOrErrorTypes) {
777   ConstructorTracker::Reset();
778   // copy success value
779   expected<std::string, int> e1 = "hello";
780   expected<ConstructorTracker, int> e2 = e1;
781   // move success value
782   expected<std::string, int> e3 = "hello";
783   expected<ConstructorTracker, int> e4 = std::move(e3);
784   // copy error value
785   expected<int, std::string> e5 = unexpected("hello");
786   expected<int, ConstructorTracker> e6 = e5;
787   // move error value
788   expected<int, std::string> e7 = unexpected("hello");
789   expected<int, ConstructorTracker> e8 = std::move(e7);
790 
791   EXPECT_EQ(4U, ConstructorTracker::constructor_called);
792   EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
793   EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
794   EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
795   EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
796 }
797 
798 // Constructing an expected type from a different expected type where either the
799 // value or the error type is ConstructorTracker in both expected types.
TEST(Expected,testCopyOrMoveTrackerAcrossExpectedConversion)800 TEST(Expected, testCopyOrMoveTrackerAcrossExpectedConversion) {
801   struct IntObj {
802     IntObj(int) {}
803   };
804 
805   // same value type, copy
806   ConstructorTracker::Reset();
807   expected<ConstructorTracker, int> e1 = std::string("hello");
808   expected<ConstructorTracker, IntObj> e2 = e1;
809   EXPECT_EQ(1U, ConstructorTracker::constructor_called);
810   EXPECT_EQ(1U, ConstructorTracker::copy_constructor_called);
811   EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
812   EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
813   EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
814 
815   // same value type, move
816   ConstructorTracker::Reset();
817   expected<ConstructorTracker, int> e3 = std::string("hello");
818   expected<ConstructorTracker, IntObj> e4 = std::move(e3);
819   EXPECT_EQ(1U, ConstructorTracker::constructor_called);
820   EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
821   EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
822   EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
823   EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
824 
825   // same error type, copy
826   ConstructorTracker::Reset();
827   expected<int, ConstructorTracker> e5 = unexpected(std::string("hello"));
828   expected<IntObj, ConstructorTracker> e6 = e5;
829   EXPECT_EQ(1U, ConstructorTracker::constructor_called);
830   EXPECT_EQ(1U, ConstructorTracker::copy_constructor_called);
831   EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
832   EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
833   EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
834 
835   // same error type, move
836   ConstructorTracker::Reset();
837   expected<int, ConstructorTracker> e7 = unexpected(std::string("hello"));
838   expected<IntObj, ConstructorTracker> e8 = std::move(e7);
839   EXPECT_EQ(1U, ConstructorTracker::constructor_called);
840   EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
841   EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
842   EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
843   EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
844 }
845 
TEST(Expected,testNoCopyOnReturn)846 TEST(Expected, testNoCopyOnReturn) {
847   auto test = [](const std::string& in) -> exp_track {
848     if (in.empty()) {
849       return "literal string";
850     }
851     if (in == "test2") {
852       return ConstructorTracker(in + in + "2");
853     }
854     ConstructorTracker result(in + " " + in);
855     return result;
856   };
857 
858   ConstructorTracker::Reset();
859   auto result1 = test("");
860   ASSERT_TRUE(result1.ok());
861   EXPECT_EQ("literal string", result1->string);
862   EXPECT_EQ(1U, ConstructorTracker::constructor_called);
863   EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
864   EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
865   EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
866   EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
867 
868   ConstructorTracker::Reset();
869   auto result2 = test("test2");
870   ASSERT_TRUE(result2.ok());
871   EXPECT_EQ("test2test22", result2->string);
872   EXPECT_EQ(1U, ConstructorTracker::constructor_called);
873   EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
874   EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
875   EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
876   EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
877 
878   ConstructorTracker::Reset();
879   auto result3 = test("test3");
880   ASSERT_TRUE(result3.ok());
881   EXPECT_EQ("test3 test3", result3->string);
882   EXPECT_EQ(1U, ConstructorTracker::constructor_called);
883   EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
884   EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
885   EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
886   EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
887 }
888 
TEST(Expected,testNested)889 TEST(Expected, testNested) {
890   expected<exp_string, std::string> e = "hello";
891 
892   EXPECT_TRUE(e.ok());
893   EXPECT_TRUE(e.has_value());
894   EXPECT_TRUE(e.value().has_value());
895   EXPECT_TRUE(e->ok());
896   EXPECT_EQ("hello", e.value().value());
897 
898   expected<exp_string, std::string> e2 = unexpected("world");
899   EXPECT_FALSE(e2.has_value());
900   EXPECT_FALSE(e2.ok());
901   EXPECT_EQ("world", e2.error());
902 
903   expected<exp_string, std::string> e3 = exp_string(unexpected("world"));
904   EXPECT_TRUE(e3.has_value());
905   EXPECT_FALSE(e3.value().has_value());
906   EXPECT_TRUE(e3.ok());
907   EXPECT_FALSE(e3->ok());
908   EXPECT_EQ("world", e3.value().error());
909 }
910 
equals(const char * a,const char * b)911 constexpr bool equals(const char* a, const char* b) {
912   return (a == nullptr && b == nullptr) ||
913       (a != nullptr && b != nullptr && *a == *b &&
914        (*a == '\0' || equals(a + 1, b + 1)));
915 }
916 
TEST(Expected,testConstexpr)917 TEST(Expected, testConstexpr) {
918   // Compilation error will occur if these expressions can't be
919   // evaluated at compile time
920   constexpr exp_int e(3);
921   constexpr exp_int::unexpected_type err(3);
922   constexpr int i = 4;
923 
924   // default constructor
925   static_assert(exp_int().value() == 0);
926   // copy constructor
927   static_assert(exp_int(e).value() == 3);
928   // move constructor
929   static_assert(exp_int(exp_int(4)).value() == 4);
930   // copy construct from value
931   static_assert(exp_int(i).value() == 4);
932   // copy construct from unexpected
933   static_assert(exp_int(err).error() == 3);
934   // move construct from unexpected
935   static_assert(exp_int(unexpected(3)).error() == 3);
936   // observers
937   static_assert(*exp_int(3) == 3);
938   static_assert(exp_int(3).has_value() == true);
939   static_assert(static_cast<bool>(exp_int(3)));
940   static_assert(!static_cast<bool>(exp_int(err)));
941   static_assert(exp_int(3).value_or(4) == 3);
942 
943   typedef expected<const char*, int> exp_s;
944   constexpr exp_s s("hello");
945   constexpr const char* c = "hello";
946   static_assert(equals(exp_s().value(), nullptr));
947   static_assert(equals(exp_s(s).value(), "hello"));
948   static_assert(equals(exp_s(exp_s("hello")).value(), "hello"));
949   static_assert(equals(exp_s("hello").value(), "hello"));
950   static_assert(equals(exp_s(c).value(), "hello"));
951 }
952 
TEST(Expected,testWithNonConstructible)953 TEST(Expected, testWithNonConstructible) {
954    struct AssertNotConstructed {
955      AssertNotConstructed() = delete;
956    };
957 
958    expected<int, AssertNotConstructed> v(42);
959    EXPECT_TRUE(v.has_value());
960    EXPECT_EQ(42, v.value());
961 
962    expected<AssertNotConstructed, int> e(unexpected(42));
963    EXPECT_FALSE(e.has_value());
964    EXPECT_EQ(42, e.error());
965 }
966 
TEST(Expected,testWithMoveOnlyType)967 TEST(Expected, testWithMoveOnlyType) {
968   typedef expected<std::unique_ptr<int>,std::unique_ptr<int>> exp_ptr;
969   exp_ptr e(std::make_unique<int>(3));
970   exp_ptr e2(unexpected(std::make_unique<int>(4)));
971 
972   EXPECT_TRUE(e.has_value());
973   EXPECT_FALSE(e2.has_value());
974   EXPECT_EQ(3, *(e.value()));
975   EXPECT_EQ(4, *(e2.error()));
976 
977   e2 = std::move(e);
978   EXPECT_TRUE(e.has_value());
979   EXPECT_TRUE(e2.has_value());
980   EXPECT_EQ(3, *(e2.value()));
981 }
982 
983 // Verify that operator bool doesn't cause surprising behavior when converting
984 // between expected types. See wg21.link/LWG3836.
TEST(Expected,testExpectedConversionWithBoolType)985 TEST(Expected, testExpectedConversionWithBoolType) {
986   expected<bool, int> e1{false};
987   expected<bool, long> e2{e1};
988   EXPECT_TRUE(e1.has_value());
989   EXPECT_TRUE(e2.has_value());
990   EXPECT_FALSE(e1.value());
991   EXPECT_FALSE(e2.value());
992 
993   expected<bool, int> e3{unexpected{17}};
994   expected<bool, long> e4{e3};
995   EXPECT_FALSE(e3.has_value());
996   EXPECT_FALSE(e4.has_value());
997   EXPECT_EQ(17, e3.error());
998   EXPECT_EQ(17, e4.error());
999 }
1000 
TEST(Expected,testConversionToClassWithExplicitCtor)1001 TEST(Expected, testConversionToClassWithExplicitCtor) {
1002   struct IntObj {
1003     explicit IntObj(int val) : val(val) {}
1004     int val;
1005   };
1006 
1007   expected<int, int> e1(3);
1008   expected<IntObj, int> e2(e1);
1009   EXPECT_TRUE(e2.has_value());
1010   EXPECT_EQ(3, e2.value().val);
1011 
1012   expected<int, int> e3(unexpected(4));
1013   expected<int, IntObj> e4(e3);
1014   EXPECT_FALSE(e4.has_value());
1015   EXPECT_EQ(4, e4.error().val);
1016 }
1017 
TEST(Expected,testNoexcept)1018 TEST(Expected, testNoexcept) {
1019   struct Foo {
1020     Foo(int) noexcept {}
1021   };
1022   struct Bar {
1023     Bar(Foo) noexcept {}
1024   };
1025   expected<Foo, Foo> e1{3};
1026   expected<Foo, Foo> e2{4};
1027   expected<Bar, Bar> e3{e1};
1028   Foo foo{5};
1029   static_assert(noexcept(expected<Foo, Foo>(e1)));
1030   static_assert(noexcept(expected<Foo, Foo>(std::move(e1))));
1031   static_assert(noexcept(expected<Foo, Foo>(foo)));
1032   static_assert(noexcept(expected<Foo, Foo>(std::move(foo))));
1033   static_assert(noexcept(expected<Foo, Foo>(unexpected(Foo(5)))));
1034   static_assert(noexcept(expected<Bar, Bar>(e1)));
1035   static_assert(noexcept(expected<Bar, Bar>(std::move(e1))));
1036   static_assert(noexcept(expected<Bar, Bar>(foo)));
1037   static_assert(noexcept(expected<Bar, Bar>(std::move(foo))));
1038   static_assert(noexcept(expected<Bar, Bar>(unexpected(Bar(foo)))));
1039   static_assert(noexcept(e2 = e1));
1040   static_assert(noexcept(e2 = std::move(e1)));
1041   static_assert(noexcept(e3 = e1));
1042   static_assert(noexcept(e3 = std::move(e1)));
1043   static_assert(noexcept(e1 = Foo(5)));
1044   static_assert(noexcept(e3 = Foo(5)));
1045 
1046   // std::string's move constructor is noexcept, but copying a string can throw
1047   // bad_alloc.
1048   expected<Foo, std::string> e11{11};
1049   expected<Foo, std::string> e12{12};
1050   expected<Bar, std::string> e13{e11};
1051   std::string err = "hello";
1052   static_assert(!noexcept(expected<Foo, std::string>(e11)));
1053   static_assert(noexcept(expected<Foo, std::string>(std::move(e11))));
1054   static_assert(noexcept(expected<Foo, std::string>(foo)));
1055   static_assert(noexcept(expected<Foo, std::string>(std::move(foo))));
1056   static_assert(noexcept(expected<Foo, std::string>(unexpected(std::move(err)))));
1057   static_assert(!noexcept(expected<Bar, std::string>(e11)));
1058   static_assert(noexcept(expected<Bar, std::string>(std::move(e11))));
1059   static_assert(noexcept(expected<Bar, std::string>(foo)));
1060   static_assert(noexcept(expected<Bar, std::string>(std::move(foo))));
1061   static_assert(!noexcept(e12 = e11));
1062   static_assert(noexcept(e12 = std::move(e11)));
1063   static_assert(!noexcept(e13 = e11));
1064   static_assert(noexcept(e13 = std::move(e11)));
1065 }
1066