• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/types/expected.h"
6 
7 #include <string>
8 #include <utility>
9 #include <vector>
10 
11 #include "base/containers/contains.h"
12 #include "base/strings/to_string.h"
13 #include "base/test/gmock_expected_support.h"
14 #include "base/test/gtest_util.h"
15 #include "base/types/strong_alias.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 
19 namespace base {
20 
21 namespace {
22 
23 // Additional restrictions on implicit conversions. Not present in the C++23
24 // proposal.
25 static_assert(!std::is_convertible_v<int, expected<int, int>>);
26 static_assert(!std::is_convertible_v<long, expected<bool, long>>);
27 
28 template <typename T>
29 struct Strong {
Strongbase::__anon58130c120111::Strong30   constexpr explicit Strong(T value) : value(std::move(value)) {}
31   T value;
32 };
33 
34 template <typename T>
35 struct Weak {
36   // NOLINTNEXTLINE(google-explicit-constructor)
Weakbase::__anon58130c120111::Weak37   constexpr Weak(T value) : value(std::move(value)) {}
38   T value;
39 };
40 
41 template <typename T>
42 struct StrongMoveOnly {
StrongMoveOnlybase::__anon58130c120111::StrongMoveOnly43   constexpr explicit StrongMoveOnly(T&& value) : value(std::move(value)) {}
StrongMoveOnlybase::__anon58130c120111::StrongMoveOnly44   constexpr StrongMoveOnly(StrongMoveOnly&& other)
45       : value(std::exchange(other.value, {})) {}
46 
operator =base::__anon58130c120111::StrongMoveOnly47   constexpr StrongMoveOnly& operator=(StrongMoveOnly&& other) {
48     value = std::exchange(other.value, {});
49     return *this;
50   }
51 
52   T value;
53 };
54 
55 template <typename T>
56 struct WeakMoveOnly {
57   // NOLINTNEXTLINE(google-explicit-constructor)
WeakMoveOnlybase::__anon58130c120111::WeakMoveOnly58   constexpr WeakMoveOnly(T&& value) : value(std::move(value)) {}
WeakMoveOnlybase::__anon58130c120111::WeakMoveOnly59   constexpr WeakMoveOnly(WeakMoveOnly&& other)
60       : value(std::exchange(other.value, {})) {}
61   T value;
62 };
63 
64 enum class Error {
65   kFail,
66 };
67 
68 enum class CvRef {
69   kNone,
70   kRef,
71   kConstRef,
72   kRRef,
73   kConstRRef,
74 };
75 
76 struct SaveCvRef {
77   constexpr SaveCvRef() = default;
SaveCvRefbase::__anon58130c120111::SaveCvRef78   constexpr SaveCvRef(SaveCvRef&) : cvref(CvRef::kRef) {}
SaveCvRefbase::__anon58130c120111::SaveCvRef79   constexpr SaveCvRef(const SaveCvRef&) : cvref(CvRef::kConstRef) {}
SaveCvRefbase::__anon58130c120111::SaveCvRef80   constexpr SaveCvRef(SaveCvRef&&) : cvref(CvRef::kRRef) {}
SaveCvRefbase::__anon58130c120111::SaveCvRef81   constexpr SaveCvRef(const SaveCvRef&&) : cvref(CvRef::kConstRRef) {}
82 
SaveCvRefbase::__anon58130c120111::SaveCvRef83   constexpr explicit SaveCvRef(CvRef cvref) : cvref(cvref) {}
84 
85   CvRef cvref = CvRef::kNone;
86 };
87 
TEST(Ok,ValueConstructor)88 TEST(Ok, ValueConstructor) {
89   constexpr ok<int> o(42);
90   static_assert(o.value() == 42);
91 }
92 
TEST(Ok,DefaultConstructor)93 TEST(Ok, DefaultConstructor) {
94   constexpr ok<int> o(absl::in_place);
95   static_assert(o.value() == 0);
96 }
97 
TEST(Ok,InPlaceConstructor)98 TEST(Ok, InPlaceConstructor) {
99   constexpr ok<std::pair<int, double>> o(absl::in_place, 42, 3.14);
100   static_assert(o.value() == std::pair(42, 3.14));
101 }
102 
TEST(Ok,InPlaceListConstructor)103 TEST(Ok, InPlaceListConstructor) {
104   ok<std::vector<int>> o(absl::in_place, {1, 2, 3});
105   EXPECT_EQ(o.value(), std::vector({1, 2, 3}));
106 }
107 
TEST(Ok,ValueIsQualified)108 TEST(Ok, ValueIsQualified) {
109   using Ok = ok<int>;
110   static_assert(std::is_same_v<decltype(std::declval<Ok&>().value()), int&>);
111   static_assert(
112       std::is_same_v<decltype(std::declval<const Ok&>().value()), const int&>);
113   static_assert(std::is_same_v<decltype(std::declval<Ok>().value()), int&&>);
114   static_assert(
115       std::is_same_v<decltype(std::declval<const Ok>().value()), const int&&>);
116 }
117 
TEST(Ok,MemberSwap)118 TEST(Ok, MemberSwap) {
119   ok o1(42);
120   ok o2(123);
121   o1.swap(o2);
122 
123   EXPECT_EQ(o1.value(), 123);
124   EXPECT_EQ(o2.value(), 42);
125 }
126 
TEST(Ok,EqualityOperators)127 TEST(Ok, EqualityOperators) {
128   static_assert(ok(42) == ok(42.0));
129   static_assert(ok(42) != ok(43));
130 }
131 
TEST(Ok,FreeSwap)132 TEST(Ok, FreeSwap) {
133   ok o1(42);
134   ok o2(123);
135   swap(o1, o2);
136 
137   EXPECT_EQ(o1.value(), 123);
138   EXPECT_EQ(o2.value(), 42);
139 }
140 
TEST(Unexpected,ValueConstructor)141 TEST(Unexpected, ValueConstructor) {
142   constexpr unexpected<int> unex(42);
143   static_assert(unex.error() == 42);
144 }
145 
TEST(Unexpected,DefaultConstructor)146 TEST(Unexpected, DefaultConstructor) {
147   constexpr unexpected<int> unex(absl::in_place);
148   static_assert(unex.error() == 0);
149 }
150 
TEST(Unexpected,InPlaceConstructor)151 TEST(Unexpected, InPlaceConstructor) {
152   constexpr unexpected<std::pair<int, double>> unex(absl::in_place, 42, 3.14);
153   static_assert(unex.error() == std::pair(42, 3.14));
154 }
155 
TEST(Unexpected,InPlaceListConstructor)156 TEST(Unexpected, InPlaceListConstructor) {
157   unexpected<std::vector<int>> unex(absl::in_place, {1, 2, 3});
158   EXPECT_EQ(unex.error(), std::vector({1, 2, 3}));
159 }
160 
TEST(Unexpected,ErrorIsQualified)161 TEST(Unexpected, ErrorIsQualified) {
162   using Unex = unexpected<int>;
163   static_assert(std::is_same_v<decltype(std::declval<Unex&>().error()), int&>);
164   static_assert(std::is_same_v<decltype(std::declval<const Unex&>().error()),
165                                const int&>);
166   static_assert(std::is_same_v<decltype(std::declval<Unex>().error()), int&&>);
167   static_assert(std::is_same_v<decltype(std::declval<const Unex>().error()),
168                                const int&&>);
169 }
170 
TEST(Unexpected,MemberSwap)171 TEST(Unexpected, MemberSwap) {
172   unexpected u1(42);
173   unexpected u2(123);
174   u1.swap(u2);
175 
176   EXPECT_EQ(u1.error(), 123);
177   EXPECT_EQ(u2.error(), 42);
178 }
179 
TEST(Unexpected,EqualityOperators)180 TEST(Unexpected, EqualityOperators) {
181   static_assert(unexpected(42) == unexpected(42.0));
182   static_assert(unexpected(42) != unexpected(43));
183 }
184 
TEST(Unexpected,FreeSwap)185 TEST(Unexpected, FreeSwap) {
186   unexpected u1(42);
187   unexpected u2(123);
188   swap(u1, u2);
189 
190   EXPECT_EQ(u1.error(), 123);
191   EXPECT_EQ(u2.error(), 42);
192 }
193 
TEST(Expected,Triviality)194 TEST(Expected, Triviality) {
195   using TrivialExpected = expected<int, Error>;
196   static_assert(std::is_trivially_destructible_v<TrivialExpected>);
197 
198   using NonTrivialExpected = expected<int, std::string>;
199   static_assert(!std::is_trivially_destructible_v<NonTrivialExpected>);
200 }
201 
TEST(Expected,DefaultConstructor)202 TEST(Expected, DefaultConstructor) {
203   constexpr expected<int, Error> ex;
204   static_assert(ex.has_value());
205   EXPECT_EQ(ex.value(), 0);
206 
207   static_assert(std::is_default_constructible_v<expected<int, Error>>);
208   static_assert(!std::is_default_constructible_v<expected<Strong<int>, Error>>);
209 }
210 
TEST(Expected,CopyConstructor)211 TEST(Expected, CopyConstructor) {
212   {
213     constexpr expected<int, Error> ex1 = 42;
214     constexpr expected<int, Error> ex2 = ex1;
215     static_assert(ex2.has_value());
216     // Note: In theory this could be constexpr, but is currently not due to
217     // implementation details of absl::get [1].
218     // TODO: Make this a static_assert once this is fixed in Abseil, or we use
219     // std::variant. Similarly in the tests below.
220     // [1] https://github.com/abseil/abseil-cpp/blob/50739/absl/types/internal/variant.h#L548
221     EXPECT_EQ(ex2.value(), 42);
222   }
223 
224   {
225     constexpr expected<int, Error> ex1 = unexpected(Error::kFail);
226     constexpr expected<int, Error> ex2 = ex1;
227     static_assert(!ex2.has_value());
228     EXPECT_EQ(ex2.error(), Error::kFail);
229   }
230 }
231 
TEST(Expected,MoveConstructor)232 TEST(Expected, MoveConstructor) {
233   {
234     expected<StrongMoveOnly<int>, int> ex1 = StrongMoveOnly(42);
235     expected<StrongMoveOnly<int>, int> ex2 = std::move(ex1);
236     ASSERT_TRUE(ex2.has_value());
237     EXPECT_EQ(ex2.value().value, 42);
238   }
239 
240   {
241     expected<int, StrongMoveOnly<int>> ex1 = unexpected(StrongMoveOnly(42));
242     expected<int, StrongMoveOnly<int>> ex2 = std::move(ex1);
243     ASSERT_FALSE(ex2.has_value());
244     EXPECT_EQ(ex2.error().value, 42);
245   }
246 }
247 
TEST(Expected,ExplicitConvertingCopyConstructor)248 TEST(Expected, ExplicitConvertingCopyConstructor) {
249   {
250     expected<int, Error> ex1 = 42;
251     expected<Strong<int>, Error> ex2(ex1);
252     static_assert(!std::is_convertible_v<decltype(ex1), decltype(ex2)>);
253     ASSERT_TRUE(ex2.has_value());
254     EXPECT_EQ(ex2.value().value, 42);
255   }
256 
257   {
258     expected<int, Error> ex1 = unexpected(Error::kFail);
259     expected<int, Strong<Error>> ex2(ex1);
260     static_assert(!std::is_convertible_v<decltype(ex1), decltype(ex2)>);
261     ASSERT_FALSE(ex2.has_value());
262     EXPECT_EQ(ex2.error().value, Error::kFail);
263   }
264 }
265 
TEST(Expected,ImplicitConvertingCopyConstructor)266 TEST(Expected, ImplicitConvertingCopyConstructor) {
267   {
268     expected<int, Error> ex1 = 42;
269     expected<Weak<int>, Weak<Error>> ex2 = ex1;
270     ASSERT_TRUE(ex2.has_value());
271     EXPECT_EQ(ex2.value().value, 42);
272   }
273   {
274     expected<int, Error> ex1 = unexpected(Error::kFail);
275     expected<Weak<int>, Weak<Error>> ex2 = ex1;
276     ASSERT_FALSE(ex2.has_value());
277     EXPECT_EQ(ex2.error().value, Error::kFail);
278   }
279 }
280 
TEST(Expected,ExplicitConvertingMoveConstructor)281 TEST(Expected, ExplicitConvertingMoveConstructor) {
282   {
283     expected<int, Error> ex1 = 42;
284     expected<StrongMoveOnly<int>, Error> ex2(std::move(ex1));
285     static_assert(
286         !std::is_convertible_v<decltype(std::move(ex1)), decltype(ex2)>);
287     ASSERT_TRUE(ex2.has_value());
288     EXPECT_EQ(ex2.value().value, 42);
289   }
290 
291   {
292     expected<int, Error> ex1 = unexpected(Error::kFail);
293     expected<int, StrongMoveOnly<Error>> ex2(std::move(ex1));
294     static_assert(
295         !std::is_convertible_v<decltype(std::move(ex1)), decltype(ex2)>);
296     ASSERT_FALSE(ex2.has_value());
297     EXPECT_EQ(ex2.error().value, Error::kFail);
298   }
299 }
300 
TEST(Expected,ImplicitConvertingMoveConstructor)301 TEST(Expected, ImplicitConvertingMoveConstructor) {
302   {
303     expected<int, Error> ex1 = 42;
304     expected<WeakMoveOnly<int>, Error> ex2 = std::move(ex1);
305     ASSERT_TRUE(ex2.has_value());
306     EXPECT_EQ(ex2.value().value, 42);
307   }
308 
309   {
310     expected<int, Error> ex1 = unexpected(Error::kFail);
311     expected<int, WeakMoveOnly<Error>> ex2 = std::move(ex1);
312     ASSERT_FALSE(ex2.has_value());
313     EXPECT_EQ(ex2.error().value, Error::kFail);
314   }
315 }
316 
TEST(Expected,ExplicitValueConstructor)317 TEST(Expected, ExplicitValueConstructor) {
318   {
319     constexpr expected<Strong<int>, int> ex(42);
320     static_assert(!std::is_convertible_v<int, decltype(ex)>);
321     static_assert(ex.has_value());
322     EXPECT_EQ(ex.value().value, 42);
323   }
324 
325   {
326     constexpr expected<StrongMoveOnly<int>, int> ex(42);
327     static_assert(!std::is_constructible_v<decltype(ex), int&>);
328     static_assert(!std::is_convertible_v<int, decltype(ex)>);
329     static_assert(ex.has_value());
330     EXPECT_EQ(ex.value().value, 42);
331   }
332 }
333 
TEST(Expected,ImplicitValueConstructor)334 TEST(Expected, ImplicitValueConstructor) {
335   {
336     constexpr expected<Weak<int>, Error> ex = 42;
337     static_assert(ex.has_value());
338     EXPECT_EQ(ex.value().value, 42);
339   }
340 
341   {
342     constexpr expected<WeakMoveOnly<int>, Error> ex = 42;
343     static_assert(!std::is_convertible_v<int&, decltype(ex)>);
344     static_assert(ex.has_value());
345     EXPECT_EQ(ex.value().value, 42);
346   }
347 }
348 
TEST(Expected,ExplicitOkConstructor)349 TEST(Expected, ExplicitOkConstructor) {
350   {
351     constexpr expected<Strong<int>, int> ex(ok(42));
352     static_assert(!std::is_convertible_v<ok<int>, decltype(ex)>);
353     static_assert(ex.has_value());
354     EXPECT_EQ(ex.value().value, 42);
355   }
356 
357   {
358     constexpr expected<StrongMoveOnly<int>, int> ex(ok(42));
359     static_assert(!std::is_constructible_v<decltype(ex), ok<int>&>);
360     static_assert(!std::is_convertible_v<ok<int>, decltype(ex)>);
361     static_assert(ex.has_value());
362     EXPECT_EQ(ex.value().value, 42);
363   }
364 }
365 
TEST(Expected,ImplicitOkConstructor)366 TEST(Expected, ImplicitOkConstructor) {
367   {
368     constexpr expected<Weak<int>, Error> ex = ok(42);
369     static_assert(ex.has_value());
370     EXPECT_EQ(ex.value().value, 42);
371   }
372 
373   {
374     constexpr expected<WeakMoveOnly<int>, Error> ex = ok(42);
375     static_assert(!std::is_convertible_v<ok<int>&, decltype(ex)>);
376     static_assert(ex.has_value());
377     EXPECT_EQ(ex.value().value, 42);
378   }
379 }
380 
TEST(Expected,ExplicitErrorConstructor)381 TEST(Expected, ExplicitErrorConstructor) {
382   {
383     constexpr expected<int, Strong<int>> ex(unexpected(42));
384     static_assert(!std::is_convertible_v<unexpected<int>, decltype(ex)>);
385     static_assert(!ex.has_value());
386     EXPECT_EQ(ex.error().value, 42);
387   }
388 
389   {
390     constexpr expected<int, StrongMoveOnly<int>> ex(unexpected(42));
391     static_assert(!std::is_constructible_v<decltype(ex), unexpected<int>&>);
392     static_assert(!std::is_convertible_v<unexpected<int>, decltype(ex)>);
393     static_assert(!ex.has_value());
394     EXPECT_EQ(ex.error().value, 42);
395   }
396 }
397 
TEST(Expected,ImplicitErrorConstructor)398 TEST(Expected, ImplicitErrorConstructor) {
399   {
400     constexpr expected<int, Weak<int>> ex = unexpected(42);
401     static_assert(!ex.has_value());
402     EXPECT_EQ(ex.error().value, 42);
403   }
404 
405   {
406     constexpr expected<int, WeakMoveOnly<int>> ex = unexpected(42);
407     static_assert(!std::is_convertible_v<unexpected<int>&, decltype(ex)>);
408     static_assert(!ex.has_value());
409     EXPECT_EQ(ex.error().value, 42);
410   }
411 }
412 
TEST(Expected,InPlaceConstructor)413 TEST(Expected, InPlaceConstructor) {
414   constexpr expected<Strong<int>, int> ex(absl::in_place, 42);
415   static_assert(ex.has_value());
416   EXPECT_EQ(ex.value().value, 42);
417 }
418 
TEST(Expected,InPlaceListConstructor)419 TEST(Expected, InPlaceListConstructor) {
420   expected<std::vector<int>, int> ex(absl::in_place, {1, 2, 3});
421   EXPECT_THAT(ex, test::ValueIs(std::vector({1, 2, 3})));
422 }
423 
TEST(Expected,UnexpectConstructor)424 TEST(Expected, UnexpectConstructor) {
425   constexpr expected<int, Strong<int>> ex(unexpect, 42);
426   static_assert(!ex.has_value());
427   EXPECT_EQ(ex.error().value, 42);
428 }
429 
TEST(Expected,UnexpectListConstructor)430 TEST(Expected, UnexpectListConstructor) {
431   expected<int, std::vector<int>> ex(unexpect, {1, 2, 3});
432   EXPECT_THAT(ex, test::ErrorIs(std::vector({1, 2, 3})));
433 }
434 
TEST(Expected,AssignValue)435 TEST(Expected, AssignValue) {
436   expected<int, int> ex = unexpected(0);
437   EXPECT_FALSE(ex.has_value());
438 
439   ex = 42;
440   EXPECT_THAT(ex, test::ValueIs(42));
441 
442   ex = 123;
443   EXPECT_THAT(ex, test::ValueIs(123));
444 }
445 
TEST(Expected,CopyAssignOk)446 TEST(Expected, CopyAssignOk) {
447   expected<int, int> ex = unexpected(0);
448   EXPECT_FALSE(ex.has_value());
449 
450   ex = ok(42);
451   EXPECT_THAT(ex, test::ValueIs(42));
452 
453   ex = ok(123);
454   EXPECT_THAT(ex, test::ValueIs(123));
455 }
456 
TEST(Expected,MoveAssignOk)457 TEST(Expected, MoveAssignOk) {
458   expected<StrongMoveOnly<int>, int> ex = unexpected(0);
459   EXPECT_FALSE(ex.has_value());
460 
461   ex = ok(StrongMoveOnly(42));
462   ASSERT_TRUE(ex.has_value());
463   EXPECT_EQ(ex.value().value, 42);
464 
465   ex = ok(StrongMoveOnly(123));
466   ASSERT_TRUE(ex.has_value());
467   EXPECT_EQ(ex.value().value, 123);
468 }
469 
TEST(Expected,CopyAssignUnexpected)470 TEST(Expected, CopyAssignUnexpected) {
471   expected<int, int> ex;
472   EXPECT_TRUE(ex.has_value());
473 
474   ex = unexpected(42);
475   EXPECT_THAT(ex, test::ErrorIs(42));
476 
477   ex = unexpected(123);
478   EXPECT_THAT(ex, test::ErrorIs(123));
479 }
480 
TEST(Expected,MoveAssignUnexpected)481 TEST(Expected, MoveAssignUnexpected) {
482   expected<int, StrongMoveOnly<int>> ex;
483   EXPECT_TRUE(ex.has_value());
484 
485   ex = unexpected(StrongMoveOnly(42));
486   ASSERT_FALSE(ex.has_value());
487   EXPECT_EQ(ex.error().value, 42);
488 
489   ex = unexpected(StrongMoveOnly(123));
490   ASSERT_FALSE(ex.has_value());
491   EXPECT_EQ(ex.error().value, 123);
492 }
493 
TEST(Expected,Emplace)494 TEST(Expected, Emplace) {
495   expected<StrongMoveOnly<int>, int> ex = unexpected(0);
496   EXPECT_FALSE(ex.has_value());
497 
498   ex.emplace(42);
499   ASSERT_TRUE(ex.has_value());
500   EXPECT_EQ(ex.value().value, 42);
501 }
502 
TEST(Expected,EmplaceList)503 TEST(Expected, EmplaceList) {
504   expected<std::vector<int>, int> ex = unexpected(0);
505   EXPECT_FALSE(ex.has_value());
506 
507   ex.emplace({1, 2, 3});
508   EXPECT_THAT(ex, test::ValueIs(std::vector({1, 2, 3})));
509 }
510 
TEST(Expected,MemberSwap)511 TEST(Expected, MemberSwap) {
512   expected<int, int> ex1(42);
513   expected<int, int> ex2 = unexpected(123);
514 
515   ex1.swap(ex2);
516   EXPECT_THAT(ex1, test::ErrorIs(123));
517   EXPECT_THAT(ex2, test::ValueIs(42));
518 }
519 
TEST(Expected,FreeSwap)520 TEST(Expected, FreeSwap) {
521   expected<int, int> ex1(42);
522   expected<int, int> ex2 = unexpected(123);
523 
524   swap(ex1, ex2);
525   EXPECT_THAT(ex1, test::ErrorIs(123));
526   EXPECT_THAT(ex2, test::ValueIs(42));
527 }
528 
TEST(Expected,OperatorArrow)529 TEST(Expected, OperatorArrow) {
530   expected<Strong<int>, int> ex(0);
531   EXPECT_EQ(ex->value, 0);
532 
533   ex->value = 1;
534   EXPECT_EQ(ex->value, 1);
535 
536   constexpr expected<Strong<int>, int> c_ex(0);
537   EXPECT_EQ(c_ex->value, 0);
538   static_assert(std::is_same_v<decltype((c_ex->value)), const int&>);
539 }
540 
TEST(Expected,OperatorStar)541 TEST(Expected, OperatorStar) {
542   expected<int, int> ex;
543   EXPECT_EQ(*ex, 0);
544 
545   *ex = 1;
546   EXPECT_EQ(*ex, 1);
547 
548   using Ex = expected<int, int>;
549   static_assert(std::is_same_v<decltype(*std::declval<Ex&>()), int&>);
550   static_assert(
551       std::is_same_v<decltype(*std::declval<const Ex&>()), const int&>);
552   static_assert(std::is_same_v<decltype(*std::declval<Ex&&>()), int&&>);
553   static_assert(
554       std::is_same_v<decltype(*std::declval<const Ex&&>()), const int&&>);
555 }
556 
TEST(Expected,HasValue)557 TEST(Expected, HasValue) {
558   constexpr expected<int, int> ex;
559   static_assert(ex.has_value());
560 
561   constexpr expected<int, int> unex = unexpected(0);
562   static_assert(!unex.has_value());
563 }
564 
TEST(Expected,Value)565 TEST(Expected, Value) {
566   expected<int, int> ex;
567   EXPECT_EQ(ex.value(), 0);
568 
569   ex.value() = 1;
570   EXPECT_EQ(ex.value(), 1);
571 
572   using Ex = expected<int, int>;
573   static_assert(std::is_same_v<decltype(std::declval<Ex&>().value()), int&>);
574   static_assert(
575       std::is_same_v<decltype(std::declval<const Ex&>().value()), const int&>);
576   static_assert(std::is_same_v<decltype(std::declval<Ex&&>().value()), int&&>);
577   static_assert(std::is_same_v<decltype(std::declval<const Ex&&>().value()),
578                                const int&&>);
579 }
580 
TEST(Expected,Error)581 TEST(Expected, Error) {
582   expected<int, int> ex = unexpected(0);
583   EXPECT_EQ(ex.error(), 0);
584 
585   ex.error() = 1;
586   EXPECT_EQ(ex.error(), 1);
587 
588   using Ex = expected<int, int>;
589   static_assert(std::is_same_v<decltype(std::declval<Ex&>().error()), int&>);
590   static_assert(
591       std::is_same_v<decltype(std::declval<const Ex&>().error()), const int&>);
592   static_assert(std::is_same_v<decltype(std::declval<Ex&&>().error()), int&&>);
593   static_assert(std::is_same_v<decltype(std::declval<const Ex&&>().error()),
594                                const int&&>);
595 }
596 
TEST(Expected,ToString)597 TEST(Expected, ToString) {
598   // `expected` should have a custom string representation that prints the
599   // contained value/error.
600   const std::string value_str = ToString(expected<int, int>(123456));
601   EXPECT_FALSE(base::Contains(value_str, "-byte object at "));
602   EXPECT_TRUE(base::Contains(value_str, "123456"));
603   const std::string error_str =
604       ToString(expected<int, int>(unexpected(123456)));
605   EXPECT_FALSE(base::Contains(error_str, "-byte object at "));
606   EXPECT_TRUE(base::Contains(error_str, "123456"));
607 }
608 
TEST(Expected,ValueOr)609 TEST(Expected, ValueOr) {
610   {
611     expected<int, int> ex;
612     EXPECT_EQ(ex.value_or(123), 0);
613 
614     expected<int, int> unex = unexpected(0);
615     EXPECT_EQ(unex.value_or(123), 123);
616   }
617 
618   {
619     expected<WeakMoveOnly<int>, int> ex(0);
620     EXPECT_EQ(std::move(ex).value_or(123).value, 0);
621 
622     expected<WeakMoveOnly<int>, int> unex = unexpected(0);
623     EXPECT_EQ(std::move(unex).value_or(123).value, 123);
624   }
625 }
626 
TEST(Expected,ErrorOr)627 TEST(Expected, ErrorOr) {
628   {
629     expected<int, int> ex;
630     EXPECT_EQ(ex.error_or(123), 123);
631 
632     expected<int, int> unex = unexpected(0);
633     EXPECT_EQ(unex.error_or(123), 0);
634   }
635 
636   {
637     expected<int, WeakMoveOnly<int>> ex(0);
638     EXPECT_EQ(std::move(ex).error_or(123).value, 123);
639 
640     expected<int, WeakMoveOnly<int>> unex = unexpected(0);
641     EXPECT_EQ(std::move(unex).error_or(123).value, 0);
642   }
643 }
644 
TEST(Expected,AndThen)645 TEST(Expected, AndThen) {
646   using ExIn = expected<SaveCvRef, SaveCvRef>;
647   using ExOut = expected<CvRef, SaveCvRef>;
648 
649   auto get_ex_cvref = [](auto&& x) -> ExOut {
650     return SaveCvRef(std::forward<decltype(x)>(x)).cvref;
651   };
652 
653   ExIn ex;
654   EXPECT_EQ(ex.and_then(get_ex_cvref), CvRef::kRef);
655   EXPECT_EQ(std::as_const(ex).and_then(get_ex_cvref), CvRef::kConstRef);
656   EXPECT_EQ(std::move(ex).and_then(get_ex_cvref), CvRef::kRRef);
657   EXPECT_EQ(std::move(std::as_const(ex)).and_then(get_ex_cvref),
658             CvRef::kConstRRef);
659 
660   ExIn unex(unexpect);
661   EXPECT_EQ(unex.and_then(get_ex_cvref).error().cvref, CvRef::kRef);
662   EXPECT_EQ(std::as_const(unex).and_then(get_ex_cvref).error().cvref,
663             CvRef::kConstRef);
664   EXPECT_EQ(std::move(unex).and_then(get_ex_cvref).error().cvref, CvRef::kRRef);
665   EXPECT_EQ(std::move(std::as_const(unex)).and_then(get_ex_cvref).error().cvref,
666             CvRef::kConstRRef);
667 
668   static_assert(
669       std::is_same_v<decltype(std::declval<ExIn&>().and_then(get_ex_cvref)),
670                      ExOut>);
671   static_assert(
672       std::is_same_v<
673           decltype(std::declval<const ExIn&>().and_then(get_ex_cvref)), ExOut>);
674   static_assert(
675       std::is_same_v<decltype(std::declval<ExIn&&>().and_then(get_ex_cvref)),
676                      ExOut>);
677   static_assert(std::is_same_v<decltype(std::declval<const ExIn&&>().and_then(
678                                    get_ex_cvref)),
679                                ExOut>);
680 }
681 
TEST(Expected,OrElse)682 TEST(Expected, OrElse) {
683   using ExIn = expected<SaveCvRef, SaveCvRef>;
684   using ExOut = expected<SaveCvRef, CvRef>;
685 
686   auto get_unex_cvref = [](auto&& x) -> ExOut {
687     return unexpected(SaveCvRef(std::forward<decltype(x)>(x)).cvref);
688   };
689 
690   ExIn ex;
691   EXPECT_EQ(ex.or_else(get_unex_cvref).value().cvref, CvRef::kRef);
692   EXPECT_EQ(std::as_const(ex).or_else(get_unex_cvref).value().cvref,
693             CvRef::kConstRef);
694   EXPECT_EQ(std::move(ex).or_else(get_unex_cvref).value().cvref, CvRef::kRRef);
695   EXPECT_EQ(std::move(std::as_const(ex)).or_else(get_unex_cvref).value().cvref,
696             CvRef::kConstRRef);
697 
698   ExIn unex(unexpect);
699   EXPECT_EQ(unex.or_else(get_unex_cvref).error(), CvRef::kRef);
700   EXPECT_EQ(std::as_const(unex).or_else(get_unex_cvref).error(),
701             CvRef::kConstRef);
702   EXPECT_EQ(std::move(unex).or_else(get_unex_cvref).error(), CvRef::kRRef);
703   EXPECT_EQ(std::move(std::as_const(unex)).or_else(get_unex_cvref).error(),
704             CvRef::kConstRRef);
705 
706   static_assert(
707       std::is_same_v<decltype(std::declval<ExIn&>().or_else(get_unex_cvref)),
708                      ExOut>);
709   static_assert(std::is_same_v<decltype(std::declval<const ExIn&>().or_else(
710                                    get_unex_cvref)),
711                                ExOut>);
712   static_assert(
713       std::is_same_v<decltype(std::declval<ExIn&&>().or_else(get_unex_cvref)),
714                      ExOut>);
715   static_assert(std::is_same_v<decltype(std::declval<const ExIn&&>().or_else(
716                                    get_unex_cvref)),
717                                ExOut>);
718 }
719 
TEST(Expected,Transform)720 TEST(Expected, Transform) {
721   using ExIn = expected<SaveCvRef, SaveCvRef>;
722   using ExOut = expected<CvRef, SaveCvRef>;
723 
724   auto get_cvref = [](auto&& x) {
725     return SaveCvRef(std::forward<decltype(x)>(x)).cvref;
726   };
727 
728   {
729     ExIn ex;
730     EXPECT_EQ(ex.transform(get_cvref), CvRef::kRef);
731     EXPECT_EQ(std::as_const(ex).transform(get_cvref), CvRef::kConstRef);
732     EXPECT_EQ(std::move(ex).transform(get_cvref), CvRef::kRRef);
733     EXPECT_EQ(std::move(std::as_const(ex)).transform(get_cvref),
734               CvRef::kConstRRef);
735 
736     ExIn unex(unexpect);
737     EXPECT_EQ(unex.transform(get_cvref).error().cvref, CvRef::kRef);
738     EXPECT_EQ(std::as_const(unex).transform(get_cvref).error().cvref,
739               CvRef::kConstRef);
740     EXPECT_EQ(std::move(unex).transform(get_cvref).error().cvref, CvRef::kRRef);
741     EXPECT_EQ(std::move(std::as_const(unex)).transform(get_cvref).error().cvref,
742               CvRef::kConstRRef);
743 
744     static_assert(
745         std::is_same_v<decltype(std::declval<ExIn&>().transform(get_cvref)),
746                        ExOut>);
747     static_assert(
748         std::is_same_v<
749             decltype(std::declval<const ExIn&>().transform(get_cvref)), ExOut>);
750     static_assert(
751         std::is_same_v<decltype(std::declval<ExIn&&>().transform(get_cvref)),
752                        ExOut>);
753     static_assert(std::is_same_v<
754                   decltype(std::declval<const ExIn&&>().transform(get_cvref)),
755                   ExOut>);
756   }
757 
758   // Test void transform.
759   {
760     using ExOutVoid = expected<void, SaveCvRef>;
761     CvRef cvref = CvRef::kNone;
762     auto write_cvref = [&cvref](auto&& x) {
763       cvref = SaveCvRef(std::forward<decltype(x)>(x)).cvref;
764     };
765 
766     ExIn ex;
767     EXPECT_TRUE(ex.transform(write_cvref).has_value());
768     EXPECT_EQ(cvref, CvRef::kRef);
769     EXPECT_TRUE(std::as_const(ex).transform(write_cvref).has_value());
770     EXPECT_EQ(cvref, CvRef::kConstRef);
771     EXPECT_TRUE(std::move(ex).transform(write_cvref).has_value());
772     EXPECT_EQ(cvref, CvRef::kRRef);
773     EXPECT_TRUE(
774         std::move(std::as_const(ex)).transform(write_cvref).has_value());
775     EXPECT_EQ(cvref, CvRef::kConstRRef);
776 
777     cvref = CvRef::kNone;
778     ExIn unex(unexpect);
779     EXPECT_EQ(unex.transform(write_cvref).error().cvref, CvRef::kRef);
780     EXPECT_EQ(cvref, CvRef::kNone);
781     EXPECT_EQ(std::as_const(unex).transform(write_cvref).error().cvref,
782               CvRef::kConstRef);
783     EXPECT_EQ(cvref, CvRef::kNone);
784     EXPECT_EQ(std::move(unex).transform(write_cvref).error().cvref,
785               CvRef::kRRef);
786     EXPECT_EQ(cvref, CvRef::kNone);
787     EXPECT_EQ(
788         std::move(std::as_const(unex)).transform(write_cvref).error().cvref,
789         CvRef::kConstRRef);
790     EXPECT_EQ(cvref, CvRef::kNone);
791 
792     static_assert(
793         std::is_same_v<decltype(std::declval<ExIn&>().transform(write_cvref)),
794                        ExOutVoid>);
795     static_assert(std::is_same_v<decltype(std::declval<const ExIn&>().transform(
796                                      write_cvref)),
797                                  ExOutVoid>);
798     static_assert(
799         std::is_same_v<decltype(std::declval<ExIn&&>().transform(write_cvref)),
800                        ExOutVoid>);
801     static_assert(std::is_same_v<
802                   decltype(std::declval<const ExIn&&>().transform(write_cvref)),
803                   ExOutVoid>);
804   }
805 }
806 
TEST(Expected,TransformError)807 TEST(Expected, TransformError) {
808   using ExIn = expected<SaveCvRef, SaveCvRef>;
809   using ExOut = expected<SaveCvRef, CvRef>;
810 
811   auto get_cvref = [](auto&& x) {
812     return SaveCvRef(std::forward<decltype(x)>(x)).cvref;
813   };
814 
815   ExIn ex;
816   EXPECT_EQ(ex.transform_error(get_cvref).value().cvref, CvRef::kRef);
817   EXPECT_EQ(std::as_const(ex).transform_error(get_cvref).value().cvref,
818             CvRef::kConstRef);
819   EXPECT_EQ(std::move(ex).transform_error(get_cvref).value().cvref,
820             CvRef::kRRef);
821   EXPECT_EQ(
822       std::move(std::as_const(ex)).transform_error(get_cvref).value().cvref,
823       CvRef::kConstRRef);
824 
825   ExIn unex(unexpect);
826   EXPECT_EQ(unex.transform_error(get_cvref).error(), CvRef::kRef);
827   EXPECT_EQ(std::as_const(unex).transform_error(get_cvref).error(),
828             CvRef::kConstRef);
829   EXPECT_EQ(std::move(unex).transform_error(get_cvref).error(), CvRef::kRRef);
830   EXPECT_EQ(std::move(std::as_const(unex)).transform_error(get_cvref).error(),
831             CvRef::kConstRRef);
832 
833   static_assert(
834       std::is_same_v<decltype(std::declval<ExIn&>().transform_error(get_cvref)),
835                      ExOut>);
836   static_assert(
837       std::is_same_v<decltype(std::declval<const ExIn&>().transform_error(
838                          get_cvref)),
839                      ExOut>);
840   static_assert(
841       std::is_same_v<
842           decltype(std::declval<ExIn&&>().transform_error(get_cvref)), ExOut>);
843   static_assert(
844       std::is_same_v<decltype(std::declval<const ExIn&&>().transform_error(
845                          get_cvref)),
846                      ExOut>);
847 }
848 
TEST(Expected,EqualityOperators)849 TEST(Expected, EqualityOperators) {
850   using ExInt = expected<int, int>;
851   using ExLong = expected<long, long>;
852 
853   EXPECT_EQ(ExInt(42), ExLong(42));
854   EXPECT_EQ(ExLong(42), ExInt(42));
855   EXPECT_EQ(ExInt(42), 42);
856   EXPECT_EQ(42, ExInt(42));
857   EXPECT_EQ(ExInt(42), ok(42));
858   EXPECT_EQ(ok(42), ExInt(42));
859   EXPECT_EQ(ExInt(unexpect, 42), unexpected(42));
860   EXPECT_EQ(unexpected(42), ExInt(unexpect, 42));
861 
862   EXPECT_NE(ExInt(42), ExLong(123));
863   EXPECT_NE(ExLong(123), ExInt(42));
864   EXPECT_NE(ExInt(42), 123);
865   EXPECT_NE(123, ExInt(42));
866   EXPECT_NE(ExInt(42), ok(123));
867   EXPECT_NE(ok(123), ExInt(42));
868   EXPECT_NE(ExInt(unexpect, 123), unexpected(42));
869   EXPECT_NE(unexpected(42), ExInt(unexpect, 123));
870   EXPECT_NE(ExInt(123), unexpected(123));
871   EXPECT_NE(unexpected(123), ExInt(123));
872 }
873 
TEST(ExpectedDeathTest,UseAfterMove)874 TEST(ExpectedDeathTest, UseAfterMove) {
875   using ExpectedInt = expected<int, int>;
876   using ExpectedDouble = expected<double, double>;
877 
878   ExpectedInt moved_from;
879   ExpectedInt ex = std::move(moved_from);
880 
881   // Accessing moved from objects crashes.
882   // NOLINTBEGIN(bugprone-use-after-move)
883   EXPECT_DEATH_IF_SUPPORTED((void)ExpectedInt{moved_from}, "");
884   EXPECT_DEATH_IF_SUPPORTED((void)ExpectedInt{std::move(moved_from)}, "");
885   EXPECT_DEATH_IF_SUPPORTED((void)ExpectedDouble{moved_from}, "");
886   EXPECT_DEATH_IF_SUPPORTED((void)ExpectedDouble{std::move(moved_from)}, "");
887   EXPECT_DEATH_IF_SUPPORTED(ex = moved_from, "");
888   EXPECT_DEATH_IF_SUPPORTED(ex = std::move(moved_from), "");
889   EXPECT_DEATH_IF_SUPPORTED(ex.swap(moved_from), "");
890   EXPECT_DEATH_IF_SUPPORTED(moved_from.swap(ex), "");
891   EXPECT_DEATH_IF_SUPPORTED(moved_from.operator->(), "");
892   EXPECT_DEATH_IF_SUPPORTED(*moved_from, "");
893   EXPECT_DEATH_IF_SUPPORTED(moved_from.has_value(), "");
894   EXPECT_DEATH_IF_SUPPORTED(moved_from.value(), "");
895   EXPECT_DEATH_IF_SUPPORTED(moved_from.error(), "");
896   EXPECT_DEATH_IF_SUPPORTED(moved_from.value_or(0), "");
897   EXPECT_DEATH_IF_SUPPORTED(std::ignore = (ex == moved_from), "");
898   EXPECT_DEATH_IF_SUPPORTED(std::ignore = (moved_from == ex), "");
899   // NOLINTEND(bugprone-use-after-move)
900 
901   // Accessing inactive union-members crashes.
902   EXPECT_DEATH_IF_SUPPORTED(ExpectedInt{}.error(), "");
903   EXPECT_DEATH_IF_SUPPORTED(ExpectedInt{unexpect}.value(), "");
904 }
905 
TEST(ExpectedVoid,Triviality)906 TEST(ExpectedVoid, Triviality) {
907   using TrivialExpected = expected<void, int>;
908   static_assert(std::is_trivially_destructible_v<TrivialExpected>);
909 
910   using NonTrivialExpected = expected<void, std::string>;
911   static_assert(!std::is_trivially_destructible_v<NonTrivialExpected>);
912 }
913 
TEST(ExpectedVoid,DefaultConstructor)914 TEST(ExpectedVoid, DefaultConstructor) {
915   constexpr expected<void, int> ex;
916   static_assert(ex.has_value());
917   static_assert(std::is_default_constructible_v<expected<void, int>>);
918 }
919 
TEST(ExpectedVoid,InPlaceConstructor)920 TEST(ExpectedVoid, InPlaceConstructor) {
921   constexpr expected<void, int> ex(absl::in_place);
922   static_assert(ex.has_value());
923 }
924 
TEST(ExpectedVoid,CopyConstructor)925 TEST(ExpectedVoid, CopyConstructor) {
926   constexpr expected<void, int> ex1 = unexpected(42);
927   constexpr expected<void, int> ex2 = ex1;
928   static_assert(!ex2.has_value());
929   EXPECT_EQ(ex2.error(), 42);
930 }
931 
TEST(ExpectedVoid,MoveConstructor)932 TEST(ExpectedVoid, MoveConstructor) {
933   expected<void, StrongMoveOnly<int>> ex1 = unexpected(StrongMoveOnly(42));
934   expected<void, StrongMoveOnly<int>> ex2 = std::move(ex1);
935   ASSERT_FALSE(ex2.has_value());
936   EXPECT_EQ(ex2.error().value, 42);
937 }
938 
TEST(ExpectedVoid,ExplicitConvertingCopyConstructor)939 TEST(ExpectedVoid, ExplicitConvertingCopyConstructor) {
940   constexpr expected<void, int> ex1 = unexpected(42);
941   expected<const void, Strong<int>> ex2(ex1);
942   static_assert(!std::is_convertible_v<decltype(ex1), decltype(ex2)>);
943   ASSERT_FALSE(ex2.has_value());
944   EXPECT_EQ(ex2.error().value, 42);
945 }
946 
TEST(ExpectedVoid,ImplicitConvertingCopyConstructor)947 TEST(ExpectedVoid, ImplicitConvertingCopyConstructor) {
948   constexpr expected<void, int> ex1 = unexpected(42);
949   expected<const void, Weak<int>> ex2 = ex1;
950   ASSERT_FALSE(ex2.has_value());
951   EXPECT_EQ(ex2.error().value, 42);
952 }
953 
TEST(ExpectedVoid,ExplicitConvertingMoveConstructor)954 TEST(ExpectedVoid, ExplicitConvertingMoveConstructor) {
955   expected<void, int> ex1 = unexpected(42);
956   expected<const void, StrongMoveOnly<int>> ex2(std::move(ex1));
957   static_assert(
958       !std::is_convertible_v<decltype(std::move(ex1)), decltype(ex2)>);
959   ASSERT_FALSE(ex2.has_value());
960   EXPECT_EQ(ex2.error().value, 42);
961 }
962 
TEST(ExpectedVoid,ImplicitConvertingMoveConstructor)963 TEST(ExpectedVoid, ImplicitConvertingMoveConstructor) {
964   expected<void, int> ex1 = unexpected(42);
965   expected<const void, WeakMoveOnly<int>> ex2 = std::move(ex1);
966   ASSERT_FALSE(ex2.has_value());
967   EXPECT_EQ(ex2.error().value, 42);
968 }
969 
TEST(ExpectedVoid,OkConstructor)970 TEST(ExpectedVoid, OkConstructor) {
971   constexpr expected<void, int> ex = ok();
972   static_assert(ex.has_value());
973 }
974 
TEST(ExpectedVoid,ExplicitErrorConstructor)975 TEST(ExpectedVoid, ExplicitErrorConstructor) {
976   {
977     constexpr expected<void, Strong<int>> ex(unexpected(42));
978     static_assert(!std::is_convertible_v<unexpected<int>, decltype(ex)>);
979     static_assert(!ex.has_value());
980     EXPECT_EQ(ex.error().value, 42);
981   }
982 
983   {
984     constexpr expected<void, StrongMoveOnly<int>> ex(unexpected(42));
985     static_assert(!std::is_constructible_v<decltype(ex), unexpected<int>&>);
986     static_assert(!std::is_convertible_v<unexpected<int>, decltype(ex)>);
987     static_assert(!ex.has_value());
988     EXPECT_EQ(ex.error().value, 42);
989   }
990 }
991 
TEST(ExpectedVoid,ImplicitErrorConstructor)992 TEST(ExpectedVoid, ImplicitErrorConstructor) {
993   {
994     constexpr expected<void, Weak<int>> ex = unexpected(42);
995     static_assert(!ex.has_value());
996     EXPECT_EQ(ex.error().value, 42);
997   }
998 
999   {
1000     constexpr expected<void, WeakMoveOnly<int>> ex = unexpected(42);
1001     static_assert(!std::is_convertible_v<unexpected<int>&, decltype(ex)>);
1002     static_assert(!ex.has_value());
1003     EXPECT_EQ(ex.error().value, 42);
1004   }
1005 }
1006 
TEST(ExpectedVoid,UnexpectConstructor)1007 TEST(ExpectedVoid, UnexpectConstructor) {
1008   constexpr expected<void, Strong<int>> ex(unexpect, 42);
1009   static_assert(!ex.has_value());
1010   EXPECT_EQ(ex.error().value, 42);
1011 }
1012 
TEST(ExpectedVoid,UnexpectListConstructor)1013 TEST(ExpectedVoid, UnexpectListConstructor) {
1014   expected<void, std::vector<int>> ex(unexpect, {1, 2, 3});
1015   EXPECT_THAT(ex, test::ErrorIs(std::vector({1, 2, 3})));
1016 }
1017 
TEST(ExpectedVoid,CopyAssignUnexpected)1018 TEST(ExpectedVoid, CopyAssignUnexpected) {
1019   expected<void, int> ex;
1020   EXPECT_TRUE(ex.has_value());
1021 
1022   ex = unexpected(42);
1023   EXPECT_THAT(ex, test::ErrorIs(42));
1024 
1025   ex = unexpected(123);
1026   EXPECT_THAT(ex, test::ErrorIs(123));
1027 }
1028 
TEST(ExpectedVoid,MoveAssignUnexpected)1029 TEST(ExpectedVoid, MoveAssignUnexpected) {
1030   expected<void, StrongMoveOnly<int>> ex;
1031   EXPECT_TRUE(ex.has_value());
1032 
1033   ex = unexpected(StrongMoveOnly(42));
1034   ASSERT_FALSE(ex.has_value());
1035   EXPECT_EQ(ex.error().value, 42);
1036 
1037   ex = unexpected(StrongMoveOnly(123));
1038   ASSERT_FALSE(ex.has_value());
1039   EXPECT_EQ(ex.error().value, 123);
1040 }
1041 
TEST(ExpectedVoid,Emplace)1042 TEST(ExpectedVoid, Emplace) {
1043   expected<void, int> ex = unexpected(0);
1044   EXPECT_FALSE(ex.has_value());
1045 
1046   ex.emplace();
1047   ASSERT_TRUE(ex.has_value());
1048 }
1049 
TEST(ExpectedVoid,MemberSwap)1050 TEST(ExpectedVoid, MemberSwap) {
1051   expected<void, int> ex1;
1052   expected<void, int> ex2 = unexpected(123);
1053 
1054   ex1.swap(ex2);
1055   EXPECT_THAT(ex1, test::ErrorIs(123));
1056   ASSERT_TRUE(ex2.has_value());
1057 }
1058 
TEST(ExpectedVoid,FreeSwap)1059 TEST(ExpectedVoid, FreeSwap) {
1060   expected<void, int> ex1;
1061   expected<void, int> ex2 = unexpected(123);
1062 
1063   swap(ex1, ex2);
1064   EXPECT_THAT(ex1, test::ErrorIs(123));
1065   ASSERT_TRUE(ex2.has_value());
1066 }
1067 
TEST(ExpectedVoid,OperatorStar)1068 TEST(ExpectedVoid, OperatorStar) {
1069   expected<void, int> ex;
1070   *ex;
1071   static_assert(std::is_void_v<decltype(*ex)>);
1072 }
1073 
TEST(ExpectedVoid,HasValue)1074 TEST(ExpectedVoid, HasValue) {
1075   constexpr expected<void, int> ex;
1076   static_assert(ex.has_value());
1077 
1078   constexpr expected<void, int> unex = unexpected(0);
1079   static_assert(!unex.has_value());
1080 }
1081 
TEST(ExpectedVoid,Value)1082 TEST(ExpectedVoid, Value) {
1083   expected<void, int> ex;
1084   ex.value();
1085   static_assert(std::is_void_v<decltype(ex.value())>);
1086 }
1087 
TEST(ExpectedVoid,Error)1088 TEST(ExpectedVoid, Error) {
1089   expected<void, int> ex = unexpected(0);
1090   EXPECT_EQ(ex.error(), 0);
1091 
1092   ex.error() = 1;
1093   EXPECT_EQ(ex.error(), 1);
1094 
1095   using Ex = expected<void, int>;
1096   static_assert(std::is_same_v<decltype(std::declval<Ex&>().error()), int&>);
1097   static_assert(
1098       std::is_same_v<decltype(std::declval<const Ex&>().error()), const int&>);
1099   static_assert(std::is_same_v<decltype(std::declval<Ex&&>().error()), int&&>);
1100   static_assert(std::is_same_v<decltype(std::declval<const Ex&&>().error()),
1101                                const int&&>);
1102 }
1103 
TEST(ExpectedVoid,ToString)1104 TEST(ExpectedVoid, ToString) {
1105   // `expected<void, ...>` should have a custom string representation (that
1106   // prints the contained error, if applicable).
1107   const std::string value_str = ToString(expected<void, int>());
1108   EXPECT_FALSE(base::Contains(value_str, "-byte object at "));
1109   const std::string error_str =
1110       ToString(expected<void, int>(unexpected(123456)));
1111   EXPECT_FALSE(base::Contains(error_str, "-byte object at "));
1112   EXPECT_TRUE(base::Contains(error_str, "123456"));
1113 }
1114 
TEST(ExpectedVoid,ErrorOr)1115 TEST(ExpectedVoid, ErrorOr) {
1116   {
1117     expected<void, int> ex;
1118     EXPECT_EQ(ex.error_or(123), 123);
1119 
1120     expected<void, int> unex = unexpected(0);
1121     EXPECT_EQ(unex.error_or(123), 0);
1122   }
1123 
1124   {
1125     expected<void, WeakMoveOnly<int>> ex;
1126     EXPECT_EQ(std::move(ex).error_or(123).value, 123);
1127 
1128     expected<void, WeakMoveOnly<int>> unex = unexpected(0);
1129     EXPECT_EQ(std::move(unex).error_or(123).value, 0);
1130   }
1131 }
1132 
TEST(ExpectedVoid,AndThen)1133 TEST(ExpectedVoid, AndThen) {
1134   using ExIn = expected<void, SaveCvRef>;
1135   using ExOut = expected<bool, SaveCvRef>;
1136 
1137   auto get_true = []() -> ExOut { return ok(true); };
1138 
1139   ExIn ex;
1140   EXPECT_TRUE(ex.and_then(get_true).value());
1141   EXPECT_TRUE(std::as_const(ex).and_then(get_true).value());
1142   EXPECT_TRUE(std::move(ex).and_then(get_true).value());
1143   EXPECT_TRUE(std::move(std::as_const(ex)).and_then(get_true).value());
1144 
1145   ExIn unex = unexpected(SaveCvRef());
1146   EXPECT_EQ(unex.and_then(get_true).error().cvref, CvRef::kRef);
1147   EXPECT_EQ(std::as_const(unex).and_then(get_true).error().cvref,
1148             CvRef::kConstRef);
1149   EXPECT_EQ(std::move(unex).and_then(get_true).error().cvref, CvRef::kRRef);
1150   EXPECT_EQ(std::move(std::as_const(unex)).and_then(get_true).error().cvref,
1151             CvRef::kConstRRef);
1152 
1153   static_assert(
1154       std::is_same_v<decltype(std::declval<ExIn&>().and_then(get_true)),
1155                      ExOut>);
1156   static_assert(
1157       std::is_same_v<decltype(std::declval<const ExIn&>().and_then(get_true)),
1158                      ExOut>);
1159   static_assert(
1160       std::is_same_v<decltype(std::declval<ExIn&&>().and_then(get_true)),
1161                      ExOut>);
1162   static_assert(
1163       std::is_same_v<decltype(std::declval<const ExIn&&>().and_then(get_true)),
1164                      ExOut>);
1165 }
1166 
TEST(ExpectedVoid,OrElse)1167 TEST(ExpectedVoid, OrElse) {
1168   using ExIn = expected<void, SaveCvRef>;
1169   using ExOut = expected<void, CvRef>;
1170 
1171   auto get_unex_cvref = [](auto&& x) -> ExOut {
1172     return unexpected(SaveCvRef(std::forward<decltype(x)>(x)).cvref);
1173   };
1174 
1175   ExIn ex;
1176   EXPECT_TRUE(ex.or_else(get_unex_cvref).has_value());
1177   EXPECT_TRUE(std::as_const(ex).or_else(get_unex_cvref).has_value());
1178   EXPECT_TRUE(std::move(ex).or_else(get_unex_cvref).has_value());
1179   EXPECT_TRUE(std::move(std::as_const(ex)).or_else(get_unex_cvref).has_value());
1180 
1181   ExIn unex(unexpect);
1182   EXPECT_EQ(unex.or_else(get_unex_cvref).error(), CvRef::kRef);
1183   EXPECT_EQ(std::as_const(unex).or_else(get_unex_cvref).error(),
1184             CvRef::kConstRef);
1185   EXPECT_EQ(std::move(unex).or_else(get_unex_cvref).error(), CvRef::kRRef);
1186   EXPECT_EQ(std::move(std::as_const(unex)).or_else(get_unex_cvref).error(),
1187             CvRef::kConstRRef);
1188 
1189   static_assert(
1190       std::is_same_v<decltype(std::declval<ExIn&>().or_else(get_unex_cvref)),
1191                      ExOut>);
1192   static_assert(std::is_same_v<decltype(std::declval<const ExIn&>().or_else(
1193                                    get_unex_cvref)),
1194                                ExOut>);
1195   static_assert(
1196       std::is_same_v<decltype(std::declval<ExIn&&>().or_else(get_unex_cvref)),
1197                      ExOut>);
1198   static_assert(std::is_same_v<decltype(std::declval<const ExIn&&>().or_else(
1199                                    get_unex_cvref)),
1200                                ExOut>);
1201 }
1202 
TEST(ExpectedVoid,Transform)1203 TEST(ExpectedVoid, Transform) {
1204   using ExIn = expected<void, SaveCvRef>;
1205   using ExOut = expected<bool, SaveCvRef>;
1206   auto get_true = [] { return true; };
1207 
1208   {
1209     ExIn ex;
1210     EXPECT_TRUE(ex.transform(get_true).value());
1211     EXPECT_TRUE(std::as_const(ex).transform(get_true).value());
1212     EXPECT_TRUE(std::move(ex).transform(get_true).value());
1213     EXPECT_TRUE(std::move(std::as_const(ex)).transform(get_true).value());
1214 
1215     ExIn unex(unexpect);
1216     EXPECT_EQ(unex.transform(get_true).error().cvref, CvRef::kRef);
1217     EXPECT_EQ(std::as_const(unex).transform(get_true).error().cvref,
1218               CvRef::kConstRef);
1219     EXPECT_EQ(std::move(unex).transform(get_true).error().cvref, CvRef::kRRef);
1220     EXPECT_EQ(std::move(std::as_const(unex)).transform(get_true).error().cvref,
1221               CvRef::kConstRRef);
1222 
1223     static_assert(
1224         std::is_same_v<decltype(std::declval<ExIn&>().transform(get_true)),
1225                        ExOut>);
1226     static_assert(
1227         std::is_same_v<
1228             decltype(std::declval<const ExIn&>().transform(get_true)), ExOut>);
1229     static_assert(
1230         std::is_same_v<decltype(std::declval<ExIn&&>().transform(get_true)),
1231                        ExOut>);
1232     static_assert(
1233         std::is_same_v<
1234             decltype(std::declval<const ExIn&&>().transform(get_true)), ExOut>);
1235   }
1236 
1237   // Test void transform.
1238   {
1239     auto do_nothing = [] {};
1240 
1241     ExIn ex;
1242     EXPECT_TRUE(ex.transform(do_nothing).has_value());
1243     EXPECT_TRUE(std::as_const(ex).transform(do_nothing).has_value());
1244     EXPECT_TRUE(std::move(ex).transform(do_nothing).has_value());
1245     EXPECT_TRUE(std::move(std::as_const(ex)).transform(do_nothing).has_value());
1246 
1247     ExIn unex(unexpect);
1248     EXPECT_EQ(unex.transform(do_nothing).error().cvref, CvRef::kRef);
1249     EXPECT_EQ(std::as_const(unex).transform(do_nothing).error().cvref,
1250               CvRef::kConstRef);
1251     EXPECT_EQ(std::move(unex).transform(do_nothing).error().cvref,
1252               CvRef::kRRef);
1253     EXPECT_EQ(
1254         std::move(std::as_const(unex)).transform(do_nothing).error().cvref,
1255         CvRef::kConstRRef);
1256 
1257     static_assert(
1258         std::is_same_v<decltype(std::declval<ExIn&>().transform(do_nothing)),
1259                        ExIn>);
1260     static_assert(
1261         std::is_same_v<
1262             decltype(std::declval<const ExIn&>().transform(do_nothing)), ExIn>);
1263     static_assert(
1264         std::is_same_v<decltype(std::declval<ExIn&&>().transform(do_nothing)),
1265                        ExIn>);
1266     static_assert(std::is_same_v<
1267                   decltype(std::declval<const ExIn&&>().transform(do_nothing)),
1268                   ExIn>);
1269   }
1270 }
1271 
TEST(ExpectedVoid,TransformError)1272 TEST(ExpectedVoid, TransformError) {
1273   using ExIn = expected<void, SaveCvRef>;
1274   using ExOut = expected<void, CvRef>;
1275 
1276   auto get_cvref = [](auto&& x) {
1277     return SaveCvRef(std::forward<decltype(x)>(x)).cvref;
1278   };
1279 
1280   ExIn ex;
1281   EXPECT_TRUE(ex.transform_error(get_cvref).has_value());
1282   EXPECT_TRUE(std::as_const(ex).transform_error(get_cvref).has_value());
1283   EXPECT_TRUE(std::move(ex).transform_error(get_cvref).has_value());
1284   EXPECT_TRUE(
1285       std::move(std::as_const(ex)).transform_error(get_cvref).has_value());
1286 
1287   ExIn unex(unexpect);
1288   EXPECT_EQ(unex.transform_error(get_cvref).error(), CvRef::kRef);
1289   EXPECT_EQ(std::as_const(unex).transform_error(get_cvref).error(),
1290             CvRef::kConstRef);
1291   EXPECT_EQ(std::move(unex).transform_error(get_cvref).error(), CvRef::kRRef);
1292   EXPECT_EQ(std::move(std::as_const(unex)).transform_error(get_cvref).error(),
1293             CvRef::kConstRRef);
1294 
1295   static_assert(
1296       std::is_same_v<decltype(std::declval<ExIn&>().transform_error(get_cvref)),
1297                      ExOut>);
1298   static_assert(
1299       std::is_same_v<decltype(std::declval<const ExIn&>().transform_error(
1300                          get_cvref)),
1301                      ExOut>);
1302   static_assert(
1303       std::is_same_v<
1304           decltype(std::declval<ExIn&&>().transform_error(get_cvref)), ExOut>);
1305   static_assert(
1306       std::is_same_v<decltype(std::declval<const ExIn&&>().transform_error(
1307                          get_cvref)),
1308                      ExOut>);
1309 }
1310 
TEST(ExpectedVoid,EqualityOperators)1311 TEST(ExpectedVoid, EqualityOperators) {
1312   using Ex = expected<void, int>;
1313   using ConstEx = expected<const void, const int>;
1314 
1315   EXPECT_EQ(Ex(), ConstEx());
1316   EXPECT_EQ(ConstEx(), Ex());
1317   EXPECT_EQ(Ex(unexpect, 42), unexpected(42));
1318   EXPECT_EQ(unexpected(42), Ex(unexpect, 42));
1319 
1320   EXPECT_NE(Ex(unexpect, 123), unexpected(42));
1321   EXPECT_NE(unexpected(42), Ex(unexpect, 123));
1322   EXPECT_NE(Ex(), unexpected(0));
1323   EXPECT_NE(unexpected(0), Ex());
1324 }
1325 
TEST(ExpectedVoidTest,DeathTests)1326 TEST(ExpectedVoidTest, DeathTests) {
1327   using ExpectedInt = expected<void, int>;
1328   using ExpectedDouble = expected<void, double>;
1329 
1330   ExpectedInt moved_from;
1331   ExpectedInt ex = std::move(moved_from);
1332 
1333   // Accessing moved from objects crashes.
1334   // NOLINTBEGIN(bugprone-use-after-move)
1335   EXPECT_DEATH_IF_SUPPORTED((void)ExpectedInt{moved_from}, "");
1336   EXPECT_DEATH_IF_SUPPORTED((void)ExpectedInt{std::move(moved_from)}, "");
1337   EXPECT_DEATH_IF_SUPPORTED((void)ExpectedDouble{moved_from}, "");
1338   EXPECT_DEATH_IF_SUPPORTED((void)ExpectedDouble{std::move(moved_from)}, "");
1339   EXPECT_DEATH_IF_SUPPORTED(ex = moved_from, "");
1340   EXPECT_DEATH_IF_SUPPORTED(ex = std::move(moved_from), "");
1341   EXPECT_DEATH_IF_SUPPORTED(ex.swap(moved_from), "");
1342   EXPECT_DEATH_IF_SUPPORTED(moved_from.swap(ex), "");
1343   EXPECT_DEATH_IF_SUPPORTED(*moved_from, "");
1344   EXPECT_DEATH_IF_SUPPORTED(moved_from.has_value(), "");
1345   EXPECT_DEATH_IF_SUPPORTED(moved_from.value(), "");
1346   EXPECT_DEATH_IF_SUPPORTED(moved_from.error(), "");
1347   EXPECT_DEATH_IF_SUPPORTED(std::ignore = (ex == moved_from), "");
1348   EXPECT_DEATH_IF_SUPPORTED(std::ignore = (moved_from == ex), "");
1349   // NOLINTEND(bugprone-use-after-move)
1350 
1351   // Accessing inactive union-members crashes.
1352   EXPECT_DEATH_IF_SUPPORTED(ExpectedInt{}.error(), "");
1353   EXPECT_DEATH_IF_SUPPORTED(ExpectedInt{unexpect}.value(), "");
1354 }
1355 
1356 }  // namespace
1357 
1358 }  // namespace base
1359