• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 // These tests are a modified version of the tests for absl::StatusOr:
16 // inclusive-language: disable
17 // https://github.com/abseil/abseil-cpp/blob/master/absl/status/statusor_test.cc
18 // inclusive-language: enable
19 
20 #include <any>
21 #include <array>
22 #include <initializer_list>
23 #include <map>
24 #include <memory>
25 #include <string>
26 #include <string_view>
27 #include <type_traits>
28 #include <utility>
29 #include <variant>
30 #include <vector>
31 
32 #include "gtest/gtest.h"
33 #include "pw_result/result.h"
34 
35 namespace {
36 
37 #define EXPECT_OK(expression) EXPECT_EQ(::pw::OkStatus(), expression)
38 #define ASSERT_OK(expression) ASSERT_EQ(::pw::OkStatus(), expression)
39 
40 struct CopyDetector {
41   CopyDetector() = default;
CopyDetector__anon4731873d0111::CopyDetector42   explicit CopyDetector(int xx) : x(xx) {}
CopyDetector__anon4731873d0111::CopyDetector43   CopyDetector(CopyDetector&& d) noexcept
44       : x(d.x), copied(false), moved(true) {}
CopyDetector__anon4731873d0111::CopyDetector45   CopyDetector(const CopyDetector& d) : x(d.x), copied(true), moved(false) {}
operator =__anon4731873d0111::CopyDetector46   CopyDetector& operator=(const CopyDetector& c) {
47     x = c.x;
48     copied = true;
49     moved = false;
50     return *this;
51   }
operator =__anon4731873d0111::CopyDetector52   CopyDetector& operator=(CopyDetector&& c) noexcept {
53     x = c.x;
54     copied = false;
55     moved = true;
56     return *this;
57   }
58   int x = 0;
59   bool copied = false;
60   bool moved = false;
61 };
62 
63 // Define custom macros instead of the CopyDetectorHas matcher.
64 #define EXPECT_COPY_DETECTOR_HAS(                       \
65     value, expected_x, expected_moved, expected_copied) \
66   EXPECT_EQ(value.x, expected_x);                       \
67   EXPECT_EQ(value.moved, expected_moved);               \
68   EXPECT_EQ(value.copied, expected_copied)
69 
70 #define EXPECT_OK_AND_COPY_DETECTOR_HAS(                                      \
71     statusor_expr, expected_x, expected_moved, expected_copied)               \
72   do {                                                                        \
73     auto&& temp_status_or = statusor_expr;                                    \
74     ASSERT_EQ(::pw::OkStatus(), temp_status_or.status());                     \
75     EXPECT_COPY_DETECTOR_HAS(                                                 \
76         temp_status_or.value(), expected_x, expected_moved, expected_copied); \
77   } while (0)
78 
79 #define EXPECT_OK_AND_ANY_WITH_COPY_DETECTOR_HAS(                     \
80     statusor_expr, expected_x, expected_moved, expected_copied)       \
81   do {                                                                \
82     auto&& temp_status_or = statusor_expr;                            \
83     ASSERT_EQ(::pw::OkStatus(), temp_status_or.status());             \
84     const auto& temp_any_value =                                      \
85         std::any_cast<const CopyDetector&>(temp_status_or.value());   \
86     EXPECT_COPY_DETECTOR_HAS(                                         \
87         temp_any_value, expected_x, expected_moved, expected_copied); \
88   } while (0)
89 
90 class Base1 {
91  public:
~Base1()92   virtual ~Base1() {}
93   int pad;
94 };
95 
96 class Base2 {
97  public:
~Base2()98   virtual ~Base2() {}
99   int yetotherpad;
100 };
101 
102 class Derived : public Base1, public Base2 {
103  public:
~Derived()104   virtual ~Derived() {}
105   int evenmorepad;
106 };
107 
108 class CopyNoAssign {
109  public:
CopyNoAssign(int value)110   explicit CopyNoAssign(int value) : foo(value) {}
CopyNoAssign(const CopyNoAssign & other)111   CopyNoAssign(const CopyNoAssign& other) : foo(other.foo) {}
112   const CopyNoAssign& operator=(const CopyNoAssign&) = delete;
113 
114   int foo;
115 };
116 
ReturnUniquePtr()117 pw::Result<std::unique_ptr<int>> ReturnUniquePtr() {
118   // Uses implicit constructor from T&&
119   return std::make_unique<int>(0);
120 }
121 
TEST(Result,ElementType)122 TEST(Result, ElementType) {
123   static_assert(std::is_same<pw::Result<int>::value_type, int>(), "");
124   static_assert(std::is_same<pw::Result<char>::value_type, char>(), "");
125 }
126 
TEST(Result,TestMoveOnlyInitialization)127 TEST(Result, TestMoveOnlyInitialization) {
128   pw::Result<std::unique_ptr<int>> thing(ReturnUniquePtr());
129   ASSERT_TRUE(thing.ok());
130   EXPECT_EQ(0, **thing);
131   int* previous = thing->get();
132 
133   thing = ReturnUniquePtr();
134   EXPECT_TRUE(thing.ok());
135   EXPECT_EQ(0, **thing);
136   EXPECT_NE(previous, thing->get());
137 }
138 
TEST(Result,TestMoveOnlyValueExtraction)139 TEST(Result, TestMoveOnlyValueExtraction) {
140   pw::Result<std::unique_ptr<int>> thing(ReturnUniquePtr());
141   ASSERT_TRUE(thing.ok());
142   std::unique_ptr<int> ptr = *std::move(thing);
143   EXPECT_EQ(0, *ptr);
144 
145   thing = std::move(ptr);
146   ptr = std::move(*thing);
147   EXPECT_EQ(0, *ptr);
148 }
149 
TEST(Result,TestMoveOnlyInitializationFromTemporaryByValueOrDie)150 TEST(Result, TestMoveOnlyInitializationFromTemporaryByValueOrDie) {
151   std::unique_ptr<int> ptr(*ReturnUniquePtr());
152   EXPECT_EQ(0, *ptr);
153 }
154 
TEST(Result,TestValueOrDieOverloadForConstTemporary)155 TEST(Result, TestValueOrDieOverloadForConstTemporary) {
156   static_assert(
157       std::is_same<const int&&,
158                    decltype(std::declval<const pw::Result<int>&&>().value())>(),
159       "value() for const temporaries should return const T&&");
160 }
161 
TEST(Result,TestMoveOnlyConversion)162 TEST(Result, TestMoveOnlyConversion) {
163   pw::Result<std::unique_ptr<const int>> const_thing(ReturnUniquePtr());
164   EXPECT_TRUE(const_thing.ok());
165   EXPECT_EQ(0, **const_thing);
166 
167   // Test rvalue converting assignment
168   const int* const_previous = const_thing->get();
169   const_thing = ReturnUniquePtr();
170   EXPECT_TRUE(const_thing.ok());
171   EXPECT_EQ(0, **const_thing);
172   EXPECT_NE(const_previous, const_thing->get());
173 }
174 
TEST(Result,TestMoveOnlyVector)175 TEST(Result, TestMoveOnlyVector) {
176   // Check that pw::Result<MoveOnly> works in vector.
177   std::vector<pw::Result<std::unique_ptr<int>>> vec;
178   vec.push_back(ReturnUniquePtr());
179   vec.resize(2);
180   auto another_vec = std::move(vec);
181   EXPECT_EQ(0, **another_vec[0]);
182   EXPECT_EQ(pw::Status::Unknown(), another_vec[1].status());
183 }
184 
TEST(Result,TestDefaultCtor)185 TEST(Result, TestDefaultCtor) {
186   pw::Result<int> thing;
187   EXPECT_FALSE(thing.ok());
188   EXPECT_EQ(thing.status().code(), pw::Status::Unknown().code());
189 }
190 
TEST(Result,StatusCtorForwards)191 TEST(Result, StatusCtorForwards) {
192   pw::Status status = pw::Status::Internal();
193 
194   EXPECT_EQ(pw::Result<int>(status).status(), pw::Status::Internal());
195 
196   EXPECT_EQ(pw::Result<int>(std::move(status)).status(),
197             pw::Status::Internal());
198 }
199 
200 #define EXPECT_DEATH_OR_THROW(statement, status) \
201   EXPECT_DEATH_IF_SUPPORTED(statement, status.str());
202 
TEST(ResultDeathTest,TestDefaultCtorValue)203 TEST(ResultDeathTest, TestDefaultCtorValue) {
204   pw::Result<int> thing;
205   EXPECT_DEATH_OR_THROW(thing.value(), pw::Status::Unknown());
206   const pw::Result<int> thing2;
207   EXPECT_DEATH_OR_THROW(thing2.value(), pw::Status::Unknown());
208 }
209 
TEST(ResultDeathTest,TestValueNotOk)210 TEST(ResultDeathTest, TestValueNotOk) {
211   pw::Result<int> thing(pw::Status::Cancelled());
212   EXPECT_DEATH_OR_THROW(thing.value(), pw::Status::Cancelled());
213 }
214 
TEST(ResultDeathTest,TestValueNotOkConst)215 TEST(ResultDeathTest, TestValueNotOkConst) {
216   const pw::Result<int> thing(pw::Status::Unknown());
217   EXPECT_DEATH_OR_THROW(thing.value(), pw::Status::Unknown());
218 }
219 
TEST(ResultDeathTest,TestPointerDefaultCtorValue)220 TEST(ResultDeathTest, TestPointerDefaultCtorValue) {
221   pw::Result<int*> thing;
222   EXPECT_DEATH_OR_THROW(thing.value(), pw::Status::Unknown());
223 }
224 
TEST(ResultDeathTest,TestPointerValueNotOk)225 TEST(ResultDeathTest, TestPointerValueNotOk) {
226   pw::Result<int*> thing(pw::Status::Cancelled());
227   EXPECT_DEATH_OR_THROW(thing.value(), pw::Status::Cancelled());
228 }
229 
TEST(ResultDeathTest,TestPointerValueNotOkConst)230 TEST(ResultDeathTest, TestPointerValueNotOkConst) {
231   const pw::Result<int*> thing(pw::Status::Cancelled());
232   EXPECT_DEATH_OR_THROW(thing.value(), pw::Status::Cancelled());
233 }
234 
235 #if GTEST_HAS_DEATH_TEST
TEST(ResultDeathTest,TestStatusCtorStatusOk)236 TEST(ResultDeathTest, TestStatusCtorStatusOk) {
237   EXPECT_DEBUG_DEATH(
238       {
239         // This will DCHECK
240         pw::Result<int> thing(pw::OkStatus());
241         // In optimized mode, we are actually going to get error::INTERNAL for
242         // status here, rather than crashing, so check that.
243         EXPECT_FALSE(thing.ok());
244         EXPECT_EQ(thing.status().code(), pw::Status::Internal().code());
245       },
246       "An OK status is not a valid constructor argument");
247 }
248 
TEST(ResultDeathTest,TestPointerStatusCtorStatusOk)249 TEST(ResultDeathTest, TestPointerStatusCtorStatusOk) {
250   EXPECT_DEBUG_DEATH(
251       {
252         pw::Result<int*> thing(pw::OkStatus());
253         // In optimized mode, we are actually going to get error::INTERNAL for
254         // status here, rather than crashing, so check that.
255         EXPECT_FALSE(thing.ok());
256         EXPECT_EQ(thing.status().code(), pw::Status::Internal().code());
257       },
258       "An OK status is not a valid constructor argument");
259 }
260 #endif
261 
TEST(Result,ValueAccessor)262 TEST(Result, ValueAccessor) {
263   const int kIntValue = 110;
264   {
265     pw::Result<int> status_or(kIntValue);
266     EXPECT_EQ(kIntValue, status_or.value());
267     EXPECT_EQ(kIntValue, std::move(status_or).value());
268   }
269   {
270     pw::Result<CopyDetector> status_or(kIntValue);
271     EXPECT_OK_AND_COPY_DETECTOR_HAS(status_or, kIntValue, false, false);
272     CopyDetector copy_detector = status_or.value();
273     EXPECT_COPY_DETECTOR_HAS(copy_detector, kIntValue, false, true);
274     copy_detector = std::move(status_or).value();
275     EXPECT_COPY_DETECTOR_HAS(copy_detector, kIntValue, true, false);
276   }
277 }
278 
TEST(Result,BadValueAccess)279 TEST(Result, BadValueAccess) {
280   const pw::Status kError = pw::Status::Cancelled();
281   pw::Result<int> status_or(kError);
282   EXPECT_DEATH_OR_THROW(status_or.value(), kError);
283 }
284 
TEST(Result,TestStatusCtor)285 TEST(Result, TestStatusCtor) {
286   pw::Result<int> thing(pw::Status::Cancelled());
287   EXPECT_FALSE(thing.ok());
288   EXPECT_EQ(thing.status().code(), pw::Status::Cancelled().code());
289 }
290 
TEST(Result,TestValueCtor)291 TEST(Result, TestValueCtor) {
292   const int kI = 4;
293   const pw::Result<int> thing(kI);
294   EXPECT_TRUE(thing.ok());
295   EXPECT_EQ(kI, *thing);
296 }
297 
298 struct Foo {
299   const int x;
Foo__anon4731873d0111::Foo300   explicit Foo(int y) : x(y) {}
301 };
302 
TEST(Result,InPlaceConstruction)303 TEST(Result, InPlaceConstruction) {
304   pw::Result<Foo> status_or(std::in_place, 10);
305   ASSERT_TRUE(status_or.ok());
306   EXPECT_EQ(status_or->x, 10);
307 }
308 
309 struct InPlaceHelper {
InPlaceHelper__anon4731873d0111::InPlaceHelper310   InPlaceHelper(std::initializer_list<int> xs, std::unique_ptr<int> yy)
311       : x(xs), y(std::move(yy)) {}
312   const std::vector<int> x;
313   std::unique_ptr<int> y;
314 };
315 
TEST(Result,InPlaceInitListConstruction)316 TEST(Result, InPlaceInitListConstruction) {
317   pw::Result<InPlaceHelper> status_or(
318       std::in_place, {10, 11, 12}, std::make_unique<int>(13));
319   ASSERT_TRUE(status_or.ok());
320   ASSERT_EQ(status_or->x.size(), 3u);
321   EXPECT_EQ(status_or->x[0], 10);
322   EXPECT_EQ(status_or->x[1], 11);
323   EXPECT_EQ(status_or->x[2], 12);
324   EXPECT_EQ(*(status_or->y), 13);
325 }
326 
TEST(Result,Emplace)327 TEST(Result, Emplace) {
328   pw::Result<Foo> status_or_foo(10);
329   status_or_foo.emplace(20);
330 
331   ASSERT_TRUE(status_or_foo.ok());
332   EXPECT_EQ(status_or_foo->x, 20);
333 
334   status_or_foo = pw::Status::InvalidArgument();
335   EXPECT_FALSE(status_or_foo.ok());
336   EXPECT_EQ(status_or_foo.status().code(),
337             pw::Status::InvalidArgument().code());
338   status_or_foo.emplace(20);
339   ASSERT_TRUE(status_or_foo.ok());
340   EXPECT_EQ(status_or_foo->x, 20);
341 }
342 
TEST(Result,EmplaceInitializerList)343 TEST(Result, EmplaceInitializerList) {
344   pw::Result<InPlaceHelper> status_or(
345       std::in_place, {10, 11, 12}, std::make_unique<int>(13));
346   status_or.emplace({1, 2, 3}, std::make_unique<int>(4));
347   ASSERT_TRUE(status_or.ok());
348   ASSERT_EQ(status_or->x.size(), 3u);
349   EXPECT_EQ(status_or->x[0], 1);
350   EXPECT_EQ(status_or->x[1], 2);
351   EXPECT_EQ(status_or->x[2], 3);
352   EXPECT_EQ(*(status_or->y), 4);
353 
354   status_or = pw::Status::InvalidArgument();
355   EXPECT_FALSE(status_or.ok());
356   EXPECT_EQ(status_or.status().code(), pw::Status::InvalidArgument().code());
357 
358   status_or.emplace({1, 2, 3}, std::make_unique<int>(4));
359   ASSERT_TRUE(status_or.ok());
360   ASSERT_EQ(status_or->x.size(), 3u);
361   EXPECT_EQ(status_or->x[0], 1);
362   EXPECT_EQ(status_or->x[1], 2);
363   EXPECT_EQ(status_or->x[2], 3);
364   EXPECT_EQ(*(status_or->y), 4);
365 }
366 
TEST(Result,TestCopyCtorStatusOk)367 TEST(Result, TestCopyCtorStatusOk) {
368   const int kI = 4;
369   const pw::Result<int> original(kI);
370   const pw::Result<int> copy(original);
371   EXPECT_OK(copy.status());
372   EXPECT_EQ(*original, *copy);
373 }
374 
TEST(Result,TestCopyCtorStatusNotOk)375 TEST(Result, TestCopyCtorStatusNotOk) {
376   pw::Result<int> original(pw::Status::Cancelled());
377   pw::Result<int> copy(original);
378   EXPECT_EQ(copy.status().code(), pw::Status::Cancelled().code());
379 }
380 
TEST(Result,TestCopyCtorNonAssignable)381 TEST(Result, TestCopyCtorNonAssignable) {
382   const int kI = 4;
383   CopyNoAssign value(kI);
384   pw::Result<CopyNoAssign> original(value);
385   pw::Result<CopyNoAssign> copy(original);
386   EXPECT_OK(copy.status());
387   EXPECT_EQ(original->foo, copy->foo);
388 }
389 
TEST(Result,TestCopyCtorStatusOKConverting)390 TEST(Result, TestCopyCtorStatusOKConverting) {
391   const int kI = 4;
392   pw::Result<int> original(kI);
393   pw::Result<double> copy(original);
394   EXPECT_OK(copy.status());
395   EXPECT_EQ(*original, *copy);
396 }
397 
TEST(Result,TestCopyCtorStatusNotOkConverting)398 TEST(Result, TestCopyCtorStatusNotOkConverting) {
399   pw::Result<int> original(pw::Status::Cancelled());
400   pw::Result<double> copy(original);
401   EXPECT_EQ(copy.status(), original.status());
402 }
403 
TEST(Result,TestAssignmentStatusOk)404 TEST(Result, TestAssignmentStatusOk) {
405   // Copy assignmment
406   {
407     const auto p = std::make_shared<int>(17);
408     pw::Result<std::shared_ptr<int>> source(p);
409 
410     pw::Result<std::shared_ptr<int>> target;
411     target = source;
412 
413     ASSERT_TRUE(target.ok());
414     EXPECT_OK(target.status());
415     EXPECT_EQ(p, *target);
416 
417     ASSERT_TRUE(source.ok());
418     EXPECT_OK(source.status());
419     EXPECT_EQ(p, *source);
420   }
421 
422   // Move asssignment
423   {
424     const auto p = std::make_shared<int>(17);
425     pw::Result<std::shared_ptr<int>> source(p);
426 
427     pw::Result<std::shared_ptr<int>> target;
428     target = std::move(source);
429 
430     ASSERT_TRUE(target.ok());
431     EXPECT_OK(target.status());
432     EXPECT_EQ(p, *target);
433 
434     ASSERT_TRUE(source.ok());  // NOLINT(bugprone-use-after-move)
435     EXPECT_OK(source.status());
436     EXPECT_EQ(nullptr, *source);
437   }
438 }
439 
TEST(Result,TestAssignmentStatusNotOk)440 TEST(Result, TestAssignmentStatusNotOk) {
441   // Copy assignment
442   {
443     const pw::Status expected = pw::Status::Cancelled();
444     pw::Result<int> source(expected);
445 
446     pw::Result<int> target;
447     target = source;
448 
449     EXPECT_FALSE(target.ok());
450     EXPECT_EQ(expected, target.status());
451 
452     EXPECT_FALSE(source.ok());
453     EXPECT_EQ(expected, source.status());
454   }
455 
456   // Move assignment
457   {
458     const pw::Status expected = pw::Status::Cancelled();
459     pw::Result<int> source(expected);
460 
461     pw::Result<int> target;
462     target = std::move(source);
463 
464     EXPECT_FALSE(target.ok());
465     EXPECT_EQ(expected, target.status());
466 
467     EXPECT_FALSE(source.ok());  // NOLINT(bugprone-use-after-move)
468     // absl::Status sets itself to INTERNAL when moved, but pw::Status does not.
469     // EXPECT_EQ(source.status().code(), pw::Status::Internal().code());
470   }
471 }
472 
TEST(Result,TestAssignmentStatusOKConverting)473 TEST(Result, TestAssignmentStatusOKConverting) {
474   // Copy assignment
475   {
476     const int kI = 4;
477     pw::Result<int> source(kI);
478 
479     pw::Result<double> target;
480     target = source;
481 
482     ASSERT_TRUE(target.ok());
483     EXPECT_OK(target.status());
484     EXPECT_EQ(kI, *target);
485 
486     ASSERT_TRUE(source.ok());
487     EXPECT_OK(source.status());
488     EXPECT_EQ(kI, *source);
489   }
490 
491   // Move assignment
492   {
493     const auto p = new int(17);
494     pw::Result<std::unique_ptr<int>> source(p);
495 
496     pw::Result<std::shared_ptr<int>> target;
497     target = std::move(source);
498 
499     ASSERT_TRUE(target.ok());
500     EXPECT_OK(target.status());
501     EXPECT_EQ(p, target->get());
502 
503     ASSERT_TRUE(source.ok());  // NOLINT(bugprone-use-after-move)
504     EXPECT_OK(source.status());
505     EXPECT_EQ(nullptr, source->get());
506   }
507 }
508 
509 // implicit_cast
510 template <class T>
511 struct type_identity {
512   using type = T;
513 };
514 
515 template <typename To>
implicit_cast(typename type_identity<To>::type to)516 constexpr To implicit_cast(typename type_identity<To>::type to) {
517   return to;
518 }
519 
520 struct A {
521   int x;
522 };
523 
524 struct ImplicitConstructibleFromA {
525   int x;
526   bool moved;
ImplicitConstructibleFromA__anon4731873d0111::ImplicitConstructibleFromA527   ImplicitConstructibleFromA(const A& a)  // NOLINT
528       : x(a.x), moved(false) {}
ImplicitConstructibleFromA__anon4731873d0111::ImplicitConstructibleFromA529   ImplicitConstructibleFromA(A&& a)  // NOLINT
530       : x(a.x), moved(true) {}
531 };
532 
TEST(Result,ImplicitConvertingConstructor)533 TEST(Result, ImplicitConvertingConstructor) {
534   auto status_or = implicit_cast<pw::Result<ImplicitConstructibleFromA>>(
535       pw::Result<A>(A{11}));
536   ASSERT_OK(status_or.status());
537   EXPECT_EQ(status_or->x, 11);
538   EXPECT_TRUE(status_or->moved);
539 
540   pw::Result<A> a(A{12});
541   auto status_or_2 = implicit_cast<pw::Result<ImplicitConstructibleFromA>>(a);
542   ASSERT_OK(status_or_2.status());
543   EXPECT_EQ(status_or_2->x, 12);
544   EXPECT_FALSE(status_or_2->moved);
545 }
546 
547 struct ExplicitConstructibleFromA {
548   int x;
549   bool moved;
ExplicitConstructibleFromA__anon4731873d0111::ExplicitConstructibleFromA550   explicit ExplicitConstructibleFromA(const A& a) : x(a.x), moved(false) {}
ExplicitConstructibleFromA__anon4731873d0111::ExplicitConstructibleFromA551   explicit ExplicitConstructibleFromA(A&& a) : x(a.x), moved(true) {}
552 };
553 
TEST(Result,ExplicitConvertingConstructor)554 TEST(Result, ExplicitConvertingConstructor) {
555   EXPECT_FALSE(
556       (std::is_convertible<const pw::Result<A>&,
557                            pw::Result<ExplicitConstructibleFromA>>::value));
558   EXPECT_FALSE(
559       (std::is_convertible<pw::Result<A>&&,
560                            pw::Result<ExplicitConstructibleFromA>>::value));
561   auto a1 = pw::Result<ExplicitConstructibleFromA>(pw::Result<A>(A{11}));
562   ASSERT_OK(a1.status());
563   EXPECT_EQ(a1->x, 11);
564   EXPECT_TRUE(a1->moved);
565 
566   pw::Result<A> a(A{12});
567   auto a2 = pw::Result<ExplicitConstructibleFromA>(a);
568   ASSERT_OK(a2.status());
569   EXPECT_EQ(a2->x, 12);
570   EXPECT_FALSE(a2->moved);
571 }
572 
573 struct ImplicitConstructibleFromBool {
ImplicitConstructibleFromBool__anon4731873d0111::ImplicitConstructibleFromBool574   ImplicitConstructibleFromBool(bool y) : x(y) {}  // NOLINT
575   bool x = false;
576 };
577 
578 struct ConvertibleToBool {
ConvertibleToBool__anon4731873d0111::ConvertibleToBool579   explicit ConvertibleToBool(bool y) : x(y) {}
operator bool__anon4731873d0111::ConvertibleToBool580   operator bool() const { return x; }  // NOLINT
581   bool x = false;
582 };
583 
TEST(Result,ImplicitBooleanConstructionWithImplicitCasts)584 TEST(Result, ImplicitBooleanConstructionWithImplicitCasts) {
585   auto a = pw::Result<bool>(pw::Result<ConvertibleToBool>(true));
586   ASSERT_OK(a.status());
587   EXPECT_TRUE(*a);
588 
589   auto b = pw::Result<bool>(pw::Result<ConvertibleToBool>(false));
590   ASSERT_OK(b.status());
591   EXPECT_FALSE(*b);
592 
593   auto c = pw::Result<ImplicitConstructibleFromBool>(pw::Result<bool>(false));
594   ASSERT_OK(c.status());
595   EXPECT_EQ(c->x, false);
596   EXPECT_FALSE(
597       (std::is_convertible<pw::Result<ConvertibleToBool>,
598                            pw::Result<ImplicitConstructibleFromBool>>::value));
599 }
600 
TEST(Result,BooleanConstructionWithImplicitCasts)601 TEST(Result, BooleanConstructionWithImplicitCasts) {
602   auto a = pw::Result<bool>(pw::Result<ConvertibleToBool>(true));
603   ASSERT_OK(a.status());
604   EXPECT_TRUE(*a);
605 
606   auto b = pw::Result<bool>(pw::Result<ConvertibleToBool>(false));
607   ASSERT_OK(b.status());
608   EXPECT_FALSE(*b);
609 
610   auto c = pw::Result<ImplicitConstructibleFromBool>{pw::Result<bool>(false)};
611   ASSERT_OK(c.status());
612   EXPECT_FALSE(c->x);
613 
614   auto d = pw::Result<ImplicitConstructibleFromBool>{
615       pw::Result<bool>(pw::Status::InvalidArgument())};
616   EXPECT_FALSE(d.ok());
617 
618   auto e = pw::Result<ImplicitConstructibleFromBool>{
619       pw::Result<ConvertibleToBool>(ConvertibleToBool{false})};
620   ASSERT_OK(e.status());
621   EXPECT_FALSE(e->x);
622 
623   auto f = pw::Result<ImplicitConstructibleFromBool>{
624       pw::Result<ConvertibleToBool>(pw::Status::InvalidArgument())};
625   EXPECT_FALSE(f.ok());
626 }
627 
TEST(Result,ConstImplicitCast)628 TEST(Result, ConstImplicitCast) {
629   auto a = implicit_cast<pw::Result<bool>>(pw::Result<const bool>(true));
630   ASSERT_OK(a.status());
631   EXPECT_TRUE(*a);
632   auto b = implicit_cast<pw::Result<bool>>(pw::Result<const bool>(false));
633   ASSERT_OK(b.status());
634   EXPECT_FALSE(*b);
635   auto c = implicit_cast<pw::Result<const bool>>(pw::Result<bool>(true));
636   ASSERT_OK(c.status());
637   EXPECT_TRUE(*c);
638   auto d = implicit_cast<pw::Result<const bool>>(pw::Result<bool>(false));
639   ASSERT_OK(d.status());
640   EXPECT_FALSE(*d);
641   auto e = implicit_cast<pw::Result<const std::string>>(
642       pw::Result<std::string>("foo"));
643   ASSERT_OK(e.status());
644   EXPECT_EQ(*e, "foo");
645   auto f = implicit_cast<pw::Result<std::string>>(
646       pw::Result<const std::string>("foo"));
647   ASSERT_OK(f.status());
648   EXPECT_EQ(*f, "foo");
649   auto g = implicit_cast<pw::Result<std::shared_ptr<const std::string>>>(
650       pw::Result<std::shared_ptr<std::string>>(
651           std::make_shared<std::string>("foo")));
652   ASSERT_OK(g.status());
653   EXPECT_EQ(*(*g), "foo");
654 }
655 
TEST(Result,ConstExplicitConstruction)656 TEST(Result, ConstExplicitConstruction) {
657   auto a = pw::Result<bool>(pw::Result<const bool>(true));
658   ASSERT_OK(a.status());
659   EXPECT_TRUE(*a);
660   auto b = pw::Result<bool>(pw::Result<const bool>(false));
661   ASSERT_OK(b.status());
662   EXPECT_FALSE(*b);
663   auto c = pw::Result<const bool>(pw::Result<bool>(true));
664   ASSERT_OK(c.status());
665   EXPECT_TRUE(*c);
666   auto d = pw::Result<const bool>(pw::Result<bool>(false));
667   ASSERT_OK(d.status());
668   EXPECT_FALSE(*d);
669 }
670 
671 struct ExplicitConstructibleFromInt {
672   int x;
ExplicitConstructibleFromInt__anon4731873d0111::ExplicitConstructibleFromInt673   explicit ExplicitConstructibleFromInt(int y) : x(y) {}
674 };
675 
TEST(Result,ExplicitConstruction)676 TEST(Result, ExplicitConstruction) {
677   auto a = pw::Result<ExplicitConstructibleFromInt>(10);
678   ASSERT_OK(a.status());
679   EXPECT_EQ(a->x, 10);
680 }
681 
TEST(Result,ImplicitConstruction)682 TEST(Result, ImplicitConstruction) {
683   // Check implicit casting works.
684   auto status_or =
685       implicit_cast<pw::Result<std::variant<int, std::string>>>(10);
686   ASSERT_OK(status_or.status());
687   EXPECT_EQ(std::get<int>(*status_or), 10);
688 }
689 
TEST(Result,ImplicitConstructionFromInitliazerList)690 TEST(Result, ImplicitConstructionFromInitliazerList) {
691   // Note: dropping the explicit std::initializer_list<int> is not supported
692   // by pw::Result or std::optional.
693   auto status_or = implicit_cast<pw::Result<std::vector<int>>>({{10, 20, 30}});
694   ASSERT_OK(status_or.status());
695   ASSERT_EQ(status_or->size(), 3u);
696   EXPECT_EQ((*status_or)[0], 10);
697   EXPECT_EQ((*status_or)[1], 20);
698   EXPECT_EQ((*status_or)[2], 30);
699 }
700 
TEST(Result,UniquePtrImplicitConstruction)701 TEST(Result, UniquePtrImplicitConstruction) {
702   auto status_or = implicit_cast<pw::Result<std::unique_ptr<Base1>>>(
703       std::make_unique<Derived>());
704   ASSERT_OK(status_or.status());
705   EXPECT_NE(status_or->get(), nullptr);
706 }
707 
TEST(Result,NestedResultCopyAndMoveConstructorTests)708 TEST(Result, NestedResultCopyAndMoveConstructorTests) {
709   pw::Result<pw::Result<CopyDetector>> status_or = CopyDetector(10);
710   pw::Result<pw::Result<CopyDetector>> status_error =
711       pw::Status::InvalidArgument();
712   ASSERT_OK(status_or.status());
713   EXPECT_OK_AND_COPY_DETECTOR_HAS(*status_or, 10, true, false);
714   pw::Result<pw::Result<CopyDetector>> a = status_or;
715   EXPECT_OK_AND_COPY_DETECTOR_HAS(*a, 10, false, true);
716   pw::Result<pw::Result<CopyDetector>> a_err = status_error;
717   EXPECT_FALSE(a_err.ok());
718 
719   const pw::Result<pw::Result<CopyDetector>>& cref = status_or;
720   pw::Result<pw::Result<CopyDetector>> b = cref;  // NOLINT
721   ASSERT_OK(b.status());
722   EXPECT_OK_AND_COPY_DETECTOR_HAS(*b, 10, false, true);
723   const pw::Result<pw::Result<CopyDetector>>& cref_err = status_error;
724   pw::Result<pw::Result<CopyDetector>> b_err = cref_err;  // NOLINT
725   EXPECT_FALSE(b_err.ok());
726 
727   pw::Result<pw::Result<CopyDetector>> c = std::move(status_or);
728   ASSERT_OK(c.status());
729   EXPECT_OK_AND_COPY_DETECTOR_HAS(*c, 10, true, false);
730   pw::Result<pw::Result<CopyDetector>> c_err = std::move(status_error);
731   EXPECT_FALSE(c_err.ok());
732 }
733 
TEST(Result,NestedResultCopyAndMoveAssignment)734 TEST(Result, NestedResultCopyAndMoveAssignment) {
735   pw::Result<pw::Result<CopyDetector>> status_or = CopyDetector(10);
736   pw::Result<pw::Result<CopyDetector>> status_error =
737       pw::Status::InvalidArgument();
738   pw::Result<pw::Result<CopyDetector>> a;
739   a = status_or;
740   ASSERT_TRUE(a.ok());
741   EXPECT_OK_AND_COPY_DETECTOR_HAS(*a, 10, false, true);
742   a = status_error;
743   EXPECT_FALSE(a.ok());
744 
745   const pw::Result<pw::Result<CopyDetector>>& cref = status_or;
746   a = cref;
747   ASSERT_TRUE(a.ok());
748   EXPECT_OK_AND_COPY_DETECTOR_HAS(*a, 10, false, true);
749   const pw::Result<pw::Result<CopyDetector>>& cref_err = status_error;
750   a = cref_err;
751   EXPECT_FALSE(a.ok());
752   a = std::move(status_or);
753   ASSERT_TRUE(a.ok());
754   EXPECT_OK_AND_COPY_DETECTOR_HAS(*a, 10, true, false);
755   a = std::move(status_error);
756   EXPECT_FALSE(a.ok());
757 }
758 
759 struct Copyable {
Copyable__anon4731873d0111::Copyable760   Copyable() {}
Copyable__anon4731873d0111::Copyable761   Copyable(const Copyable&) {}
operator =__anon4731873d0111::Copyable762   Copyable& operator=(const Copyable&) { return *this; }
763 };
764 
765 struct MoveOnly {
MoveOnly__anon4731873d0111::MoveOnly766   MoveOnly() {}
MoveOnly__anon4731873d0111::MoveOnly767   MoveOnly(MoveOnly&&) {}
operator =__anon4731873d0111::MoveOnly768   MoveOnly& operator=(MoveOnly&&) { return *this; }
769 };
770 
771 struct NonMovable {
NonMovable__anon4731873d0111::NonMovable772   NonMovable() {}
773   NonMovable(const NonMovable&) = delete;
774   NonMovable(NonMovable&&) = delete;
775   NonMovable& operator=(const NonMovable&) = delete;
776   NonMovable& operator=(NonMovable&&) = delete;
777 };
778 
TEST(Result,CopyAndMoveAbility)779 TEST(Result, CopyAndMoveAbility) {
780   EXPECT_TRUE(std::is_copy_constructible<Copyable>::value);
781   EXPECT_TRUE(std::is_copy_assignable<Copyable>::value);
782   EXPECT_TRUE(std::is_move_constructible<Copyable>::value);
783   EXPECT_TRUE(std::is_move_assignable<Copyable>::value);
784   EXPECT_FALSE(std::is_copy_constructible<MoveOnly>::value);
785   EXPECT_FALSE(std::is_copy_assignable<MoveOnly>::value);
786   EXPECT_TRUE(std::is_move_constructible<MoveOnly>::value);
787   EXPECT_TRUE(std::is_move_assignable<MoveOnly>::value);
788   EXPECT_FALSE(std::is_copy_constructible<NonMovable>::value);
789   EXPECT_FALSE(std::is_copy_assignable<NonMovable>::value);
790   EXPECT_FALSE(std::is_move_constructible<NonMovable>::value);
791   EXPECT_FALSE(std::is_move_assignable<NonMovable>::value);
792 }
793 
TEST(Result,ResultAnyCopyAndMoveConstructorTests)794 TEST(Result, ResultAnyCopyAndMoveConstructorTests) {
795   pw::Result<std::any> status_or = CopyDetector(10);
796   pw::Result<std::any> status_error = pw::Status::InvalidArgument();
797   EXPECT_OK_AND_ANY_WITH_COPY_DETECTOR_HAS(status_or, 10, true, false);
798   pw::Result<std::any> a = status_or;
799   EXPECT_OK_AND_ANY_WITH_COPY_DETECTOR_HAS(a, 10, false, true);
800   pw::Result<std::any> a_err = status_error;
801   EXPECT_FALSE(a_err.ok());
802 
803   const pw::Result<std::any>& cref = status_or;
804   // No lint for no-change copy.
805   pw::Result<std::any> b = cref;  // NOLINT
806   EXPECT_OK_AND_ANY_WITH_COPY_DETECTOR_HAS(b, 10, false, true);
807   const pw::Result<std::any>& cref_err = status_error;
808   // No lint for no-change copy.
809   pw::Result<std::any> b_err = cref_err;  // NOLINT
810   EXPECT_FALSE(b_err.ok());
811 
812   pw::Result<std::any> c = std::move(status_or);
813   EXPECT_OK_AND_ANY_WITH_COPY_DETECTOR_HAS(c, 10, true, false);
814   pw::Result<std::any> c_err = std::move(status_error);
815   EXPECT_FALSE(c_err.ok());
816 }
817 
TEST(Result,ResultAnyCopyAndMoveAssignment)818 TEST(Result, ResultAnyCopyAndMoveAssignment) {
819   pw::Result<std::any> status_or = CopyDetector(10);
820   pw::Result<std::any> status_error = pw::Status::InvalidArgument();
821   pw::Result<std::any> a;
822   a = status_or;
823   EXPECT_OK_AND_ANY_WITH_COPY_DETECTOR_HAS(a, 10, false, true);
824   a = status_error;
825   EXPECT_FALSE(a.ok());
826 
827   const pw::Result<std::any>& cref = status_or;
828   a = cref;
829   EXPECT_OK_AND_ANY_WITH_COPY_DETECTOR_HAS(a, 10, false, true);
830   const pw::Result<std::any>& cref_err = status_error;
831   a = cref_err;
832   EXPECT_FALSE(a.ok());
833   a = std::move(status_or);
834   EXPECT_OK_AND_ANY_WITH_COPY_DETECTOR_HAS(a, 10, true, false);
835   a = std::move(status_error);
836   EXPECT_FALSE(a.ok());
837 }
838 
TEST(Result,ResultCopyAndMoveTestsConstructor)839 TEST(Result, ResultCopyAndMoveTestsConstructor) {
840   pw::Result<CopyDetector> status_or(10);
841   EXPECT_OK_AND_COPY_DETECTOR_HAS(status_or, 10, false, false);
842   pw::Result<CopyDetector> a(status_or);
843   EXPECT_OK_AND_COPY_DETECTOR_HAS(a, 10, false, true);
844   const pw::Result<CopyDetector>& cref = status_or;
845   pw::Result<CopyDetector> b(cref);  // NOLINT
846   EXPECT_OK_AND_COPY_DETECTOR_HAS(b, 10, false, true);
847   pw::Result<CopyDetector> c(std::move(status_or));
848   EXPECT_OK_AND_COPY_DETECTOR_HAS(c, 10, true, false);
849 }
850 
TEST(Result,ResultCopyAndMoveTestsAssignment)851 TEST(Result, ResultCopyAndMoveTestsAssignment) {
852   pw::Result<CopyDetector> status_or(10);
853   EXPECT_OK_AND_COPY_DETECTOR_HAS(status_or, 10, false, false);
854   pw::Result<CopyDetector> a;
855   a = status_or;
856   EXPECT_OK_AND_COPY_DETECTOR_HAS(a, 10, false, true);
857   const pw::Result<CopyDetector>& cref = status_or;
858   pw::Result<CopyDetector> b;
859   b = cref;
860   EXPECT_OK_AND_COPY_DETECTOR_HAS(b, 10, false, true);
861   pw::Result<CopyDetector> c;
862   c = std::move(status_or);
863   EXPECT_OK_AND_COPY_DETECTOR_HAS(c, 10, true, false);
864 }
865 
TEST(Result,StdAnyAssignment)866 TEST(Result, StdAnyAssignment) {
867   EXPECT_FALSE(
868       (std::is_assignable<pw::Result<std::any>, pw::Result<int>>::value));
869   pw::Result<std::any> status_or;
870   status_or = pw::Status::InvalidArgument();
871   EXPECT_FALSE(status_or.ok());
872 }
873 
TEST(Result,ImplicitAssignment)874 TEST(Result, ImplicitAssignment) {
875   pw::Result<std::variant<int, std::string>> status_or;
876   status_or = 10;
877   ASSERT_OK(status_or.status());
878   EXPECT_EQ(std::get<int>(*status_or), 10);
879 }
880 
TEST(Result,SelfDirectInitAssignment)881 TEST(Result, SelfDirectInitAssignment) {
882   pw::Result<std::vector<int>> status_or = {{10, 20, 30}};
883   status_or = *status_or;
884   ASSERT_OK(status_or.status());
885   ASSERT_EQ(status_or->size(), 3u);
886   EXPECT_EQ((*status_or)[0], 10);
887   EXPECT_EQ((*status_or)[1], 20);
888   EXPECT_EQ((*status_or)[2], 30);
889 }
890 
TEST(Result,ImplicitCastFromInitializerList)891 TEST(Result, ImplicitCastFromInitializerList) {
892   pw::Result<std::vector<int>> status_or = {{10, 20, 30}};
893   ASSERT_OK(status_or.status());
894   ASSERT_EQ(status_or->size(), 3u);
895   EXPECT_EQ((*status_or)[0], 10);
896   EXPECT_EQ((*status_or)[1], 20);
897   EXPECT_EQ((*status_or)[2], 30);
898 }
899 
TEST(Result,UniquePtrImplicitAssignment)900 TEST(Result, UniquePtrImplicitAssignment) {
901   pw::Result<std::unique_ptr<Base1>> status_or;
902   status_or = std::make_unique<Derived>();
903   ASSERT_OK(status_or.status());
904   EXPECT_NE(status_or->get(), nullptr);
905 }
906 
TEST(Result,Pointer)907 TEST(Result, Pointer) {
908   struct Base {};
909   struct B : public Base {};
910   struct C : private Base {};
911 
912   EXPECT_TRUE((std::is_constructible<pw::Result<Base*>, B*>::value));
913   EXPECT_TRUE((std::is_convertible<B*, pw::Result<Base*>>::value));
914   EXPECT_FALSE((std::is_constructible<pw::Result<Base*>, C*>::value));
915   EXPECT_FALSE((std::is_convertible<C*, pw::Result<Base*>>::value));
916 }
917 
TEST(Result,TestAssignmentStatusNotOkConverting)918 TEST(Result, TestAssignmentStatusNotOkConverting) {
919   // Copy assignment
920   {
921     const pw::Status expected = pw::Status::Cancelled();
922     pw::Result<int> source(expected);
923 
924     pw::Result<double> target;
925     target = source;
926 
927     EXPECT_FALSE(target.ok());
928     EXPECT_EQ(expected, target.status());
929 
930     EXPECT_FALSE(source.ok());
931     EXPECT_EQ(expected, source.status());
932   }
933 
934   // Move assignment
935   {
936     const pw::Status expected = pw::Status::Cancelled();
937     pw::Result<int> source(expected);
938 
939     pw::Result<double> target;
940     target = std::move(source);
941 
942     EXPECT_FALSE(target.ok());
943     EXPECT_EQ(expected, target.status());
944 
945     EXPECT_FALSE(source.ok());  // NOLINT(bugprone-use-after-move)
946 
947     // absl::Status sets itself to INTERNAL when moved, but pw::Status does not.
948     // EXPECT_EQ(source.status().code(), pw::Status::Internal().code());
949   }
950 }
951 
TEST(Result,SelfAssignment)952 TEST(Result, SelfAssignment) {
953   // Copy-assignment, status OK
954   {
955     // A string long enough that it's likely to defeat any inline representation
956     // optimization.
957     const std::string long_str(128, 'a');
958 
959     pw::Result<std::string> so = long_str;
960     so = *&so;
961 
962     ASSERT_TRUE(so.ok());
963     EXPECT_OK(so.status());
964     EXPECT_EQ(long_str, *so);
965   }
966 
967   // Copy-assignment, error status
968   {
969     pw::Result<int> so = pw::Status::NotFound();
970     so = *&so;
971 
972     EXPECT_FALSE(so.ok());
973     EXPECT_EQ(so.status().code(), pw::Status::NotFound().code());
974   }
975 
976   // Move-assignment with copyable type, status OK
977   {
978     pw::Result<int> so = 17;
979 
980     // Fool the compiler, which otherwise complains.
981     auto& same = so;
982     so = std::move(same);
983 
984     ASSERT_TRUE(so.ok());
985     EXPECT_OK(so.status());
986     EXPECT_EQ(17, *so);
987   }
988 
989   // Move-assignment with copyable type, error status
990   {
991     pw::Result<int> so = pw::Status::NotFound();
992 
993     // Fool the compiler, which otherwise complains.
994     auto& same = so;
995     so = std::move(same);
996 
997     EXPECT_FALSE(so.ok());
998     EXPECT_EQ(so.status().code(), pw::Status::NotFound().code());
999   }
1000 
1001   // Move-assignment with non-copyable type, status OK
1002   {
1003     const auto raw = new int(17);
1004     pw::Result<std::unique_ptr<int>> so = std::unique_ptr<int>(raw);
1005 
1006     // Fool the compiler, which otherwise complains.
1007     auto& same = so;
1008     so = std::move(same);
1009 
1010     ASSERT_TRUE(so.ok());
1011     EXPECT_OK(so.status());
1012     EXPECT_EQ(raw, so->get());
1013   }
1014 
1015   // Move-assignment with non-copyable type, error status
1016   {
1017     pw::Result<std::unique_ptr<int>> so = pw::Status::NotFound();
1018 
1019     // Fool the compiler, which otherwise complains.
1020     auto& same = so;
1021     so = std::move(same);
1022 
1023     EXPECT_FALSE(so.ok());
1024     EXPECT_EQ(so.status().code(), pw::Status::NotFound().code());
1025   }
1026 }
1027 
1028 // These types form the overload sets of the constructors and the assignment
1029 // operators of `MockValue`. They distinguish construction from assignment,
1030 // lvalue from rvalue.
1031 struct FromConstructibleAssignableLvalue {};
1032 struct FromConstructibleAssignableRvalue {};
1033 struct FromImplicitConstructibleOnly {};
1034 struct FromAssignableOnly {};
1035 
1036 // This class is for testing the forwarding value assignments of `Result`.
1037 // `from_rvalue` indicates whether the constructor or the assignment taking
1038 // rvalue reference is called. `from_assignment` indicates whether any
1039 // assignment is called.
1040 struct MockValue {
1041   // Constructs `MockValue` from `FromConstructibleAssignableLvalue`.
MockValue__anon4731873d0111::MockValue1042   MockValue(const FromConstructibleAssignableLvalue&)  // NOLINT
1043       : from_rvalue(false), assigned(false) {}
1044   // Constructs `MockValue` from `FromConstructibleAssignableRvalue`.
MockValue__anon4731873d0111::MockValue1045   MockValue(FromConstructibleAssignableRvalue&&)  // NOLINT
1046       : from_rvalue(true), assigned(false) {}
1047   // Constructs `MockValue` from `FromImplicitConstructibleOnly`.
1048   // `MockValue` is not assignable from `FromImplicitConstructibleOnly`.
MockValue__anon4731873d0111::MockValue1049   MockValue(const FromImplicitConstructibleOnly&)  // NOLINT
1050       : from_rvalue(false), assigned(false) {}
1051   // Assigns `FromConstructibleAssignableLvalue`.
operator =__anon4731873d0111::MockValue1052   MockValue& operator=(const FromConstructibleAssignableLvalue&) {
1053     from_rvalue = false;
1054     assigned = true;
1055     return *this;
1056   }
1057   // Assigns `FromConstructibleAssignableRvalue` (rvalue only).
operator =__anon4731873d0111::MockValue1058   MockValue& operator=(FromConstructibleAssignableRvalue&&) {
1059     from_rvalue = true;
1060     assigned = true;
1061     return *this;
1062   }
1063   // Assigns `FromAssignableOnly`, but not constructible from
1064   // `FromAssignableOnly`.
operator =__anon4731873d0111::MockValue1065   MockValue& operator=(const FromAssignableOnly&) {
1066     from_rvalue = false;
1067     assigned = true;
1068     return *this;
1069   }
1070   bool from_rvalue;
1071   bool assigned;
1072 };
1073 
1074 // operator=(U&&)
TEST(Result,PerfectForwardingAssignment)1075 TEST(Result, PerfectForwardingAssignment) {
1076   // U == T
1077   constexpr int kValue1 = 10, kValue2 = 20;
1078   pw::Result<CopyDetector> status_or;
1079   CopyDetector lvalue(kValue1);
1080   status_or = lvalue;
1081   EXPECT_OK_AND_COPY_DETECTOR_HAS(status_or, kValue1, false, true);
1082   status_or = CopyDetector(kValue2);
1083   EXPECT_OK_AND_COPY_DETECTOR_HAS(status_or, kValue2, true, false);
1084 
1085   // U != T
1086   EXPECT_TRUE(
1087       (std::is_assignable<pw::Result<MockValue>&,
1088                           const FromConstructibleAssignableLvalue&>::value));
1089   EXPECT_TRUE((std::is_assignable<pw::Result<MockValue>&,
1090                                   FromConstructibleAssignableLvalue&&>::value));
1091   EXPECT_FALSE(
1092       (std::is_assignable<pw::Result<MockValue>&,
1093                           const FromConstructibleAssignableRvalue&>::value));
1094   EXPECT_TRUE((std::is_assignable<pw::Result<MockValue>&,
1095                                   FromConstructibleAssignableRvalue&&>::value));
1096   EXPECT_TRUE(
1097       (std::is_assignable<pw::Result<MockValue>&,
1098                           const FromImplicitConstructibleOnly&>::value));
1099   EXPECT_FALSE((std::is_assignable<pw::Result<MockValue>&,
1100                                    const FromAssignableOnly&>::value));
1101 
1102   pw::Result<MockValue> from_lvalue(FromConstructibleAssignableLvalue{});
1103   EXPECT_FALSE(from_lvalue->from_rvalue);
1104   EXPECT_FALSE(from_lvalue->assigned);
1105   from_lvalue = FromConstructibleAssignableLvalue{};
1106   EXPECT_FALSE(from_lvalue->from_rvalue);
1107   EXPECT_TRUE(from_lvalue->assigned);
1108 
1109   pw::Result<MockValue> from_rvalue(FromConstructibleAssignableRvalue{});
1110   EXPECT_TRUE(from_rvalue->from_rvalue);
1111   EXPECT_FALSE(from_rvalue->assigned);
1112   from_rvalue = FromConstructibleAssignableRvalue{};
1113   EXPECT_TRUE(from_rvalue->from_rvalue);
1114   EXPECT_TRUE(from_rvalue->assigned);
1115 
1116   pw::Result<MockValue> from_implicit_constructible(
1117       FromImplicitConstructibleOnly{});
1118   EXPECT_FALSE(from_implicit_constructible->from_rvalue);
1119   EXPECT_FALSE(from_implicit_constructible->assigned);
1120   // construct a temporary `Result` object and invoke the `Result` move
1121   // assignment operator.
1122   from_implicit_constructible = FromImplicitConstructibleOnly{};
1123   EXPECT_FALSE(from_implicit_constructible->from_rvalue);
1124   EXPECT_FALSE(from_implicit_constructible->assigned);
1125 }
1126 
TEST(Result,TestStatus)1127 TEST(Result, TestStatus) {
1128   pw::Result<int> good(4);
1129   EXPECT_TRUE(good.ok());
1130   pw::Result<int> bad(pw::Status::Cancelled());
1131   EXPECT_FALSE(bad.ok());
1132   EXPECT_EQ(bad.status().code(), pw::Status::Cancelled().code());
1133 }
1134 
TEST(Result,OperatorStarRefQualifiers)1135 TEST(Result, OperatorStarRefQualifiers) {
1136   static_assert(
1137       std::is_same<const int&,
1138                    decltype(*std::declval<const pw::Result<int>&>())>(),
1139       "Unexpected ref-qualifiers");
1140   static_assert(
1141       std::is_same<int&, decltype(*std::declval<pw::Result<int>&>())>(),
1142       "Unexpected ref-qualifiers");
1143   static_assert(
1144       std::is_same<const int&&,
1145                    decltype(*std::declval<const pw::Result<int>&&>())>(),
1146       "Unexpected ref-qualifiers");
1147   static_assert(
1148       std::is_same<int&&, decltype(*std::declval<pw::Result<int>&&>())>(),
1149       "Unexpected ref-qualifiers");
1150 }
1151 
TEST(Result,OperatorStar)1152 TEST(Result, OperatorStar) {
1153   const pw::Result<std::string> const_lvalue("hello");
1154   EXPECT_EQ("hello", *const_lvalue);
1155 
1156   pw::Result<std::string> lvalue("hello");
1157   EXPECT_EQ("hello", *lvalue);
1158 
1159   // Note: Recall that std::move() is equivalent to a static_cast to an rvalue
1160   // reference type.
1161   const pw::Result<std::string> const_rvalue("hello");
1162   EXPECT_EQ("hello", *std::move(const_rvalue));  // NOLINT
1163 
1164   pw::Result<std::string> rvalue("hello");
1165   EXPECT_EQ("hello", *std::move(rvalue));
1166 }
1167 
TEST(Result,OperatorArrowQualifiers)1168 TEST(Result, OperatorArrowQualifiers) {
1169   static_assert(
1170       std::is_same<
1171           const int*,
1172           decltype(std::declval<const pw::Result<int>&>().operator->())>(),
1173       "Unexpected qualifiers");
1174   static_assert(
1175       std::is_same<int*,
1176                    decltype(std::declval<pw::Result<int>&>().operator->())>(),
1177       "Unexpected qualifiers");
1178   static_assert(
1179       std::is_same<
1180           const int*,
1181           decltype(std::declval<const pw::Result<int>&&>().operator->())>(),
1182       "Unexpected qualifiers");
1183   static_assert(
1184       std::is_same<int*,
1185                    decltype(std::declval<pw::Result<int>&&>().operator->())>(),
1186       "Unexpected qualifiers");
1187 }
1188 
TEST(Result,OperatorArrow)1189 TEST(Result, OperatorArrow) {
1190   const pw::Result<std::string> const_lvalue("hello");
1191   EXPECT_EQ(std::string("hello"), const_lvalue->c_str());
1192 
1193   pw::Result<std::string> lvalue("hello");
1194   EXPECT_EQ(std::string("hello"), lvalue->c_str());
1195 }
1196 
TEST(Result,RValueStatus)1197 TEST(Result, RValueStatus) {
1198   pw::Result<int> so(pw::Status::NotFound());
1199   const pw::Status s = std::move(so).status();
1200 
1201   EXPECT_EQ(s.code(), pw::Status::NotFound().code());
1202 
1203   // Check that !ok() still implies !status().ok(), even after moving out of the
1204   // object. See the note on the rvalue ref-qualified status method.
1205   EXPECT_FALSE(so.ok());  // NOLINT
1206   EXPECT_FALSE(so.status().ok());
1207 
1208   // absl::Status sets itself to INTERNAL when moved, but pw::Status does not.
1209   // EXPECT_EQ(so.status().code(), pw::Status::Internal().code());
1210 }
1211 
TEST(Result,TestValue)1212 TEST(Result, TestValue) {
1213   const int kI = 4;
1214   pw::Result<int> thing(kI);
1215   EXPECT_EQ(kI, *thing);
1216 }
1217 
TEST(Result,TestValueConst)1218 TEST(Result, TestValueConst) {
1219   const int kI = 4;
1220   const pw::Result<int> thing(kI);
1221   EXPECT_EQ(kI, *thing);
1222 }
1223 
TEST(Result,TestPointerDefaultCtor)1224 TEST(Result, TestPointerDefaultCtor) {
1225   pw::Result<int*> thing;
1226   EXPECT_FALSE(thing.ok());
1227   EXPECT_EQ(thing.status().code(), pw::Status::Unknown().code());
1228 }
1229 
TEST(Result,TestPointerStatusCtor)1230 TEST(Result, TestPointerStatusCtor) {
1231   pw::Result<int*> thing(pw::Status::Cancelled());
1232   EXPECT_FALSE(thing.ok());
1233   EXPECT_EQ(thing.status().code(), pw::Status::Cancelled().code());
1234 }
1235 
TEST(Result,TestPointerValueCtor)1236 TEST(Result, TestPointerValueCtor) {
1237   const int kI = 4;
1238 
1239   // Construction from a non-null pointer
1240   {
1241     pw::Result<const int*> so(&kI);
1242     EXPECT_TRUE(so.ok());
1243     EXPECT_OK(so.status());
1244     EXPECT_EQ(&kI, *so);
1245   }
1246 
1247   // Construction from a null pointer constant
1248   {
1249     pw::Result<const int*> so(nullptr);
1250     EXPECT_TRUE(so.ok());
1251     EXPECT_OK(so.status());
1252     EXPECT_EQ(nullptr, *so);
1253   }
1254 
1255   // Construction from a non-literal null pointer
1256   {
1257     const int* const p = nullptr;
1258 
1259     pw::Result<const int*> so(p);
1260     EXPECT_TRUE(so.ok());
1261     EXPECT_OK(so.status());
1262     EXPECT_EQ(nullptr, *so);
1263   }
1264 }
1265 
TEST(Result,TestPointerCopyCtorStatusOk)1266 TEST(Result, TestPointerCopyCtorStatusOk) {
1267   const int kI = 0;
1268   pw::Result<const int*> original(&kI);
1269   pw::Result<const int*> copy(original);
1270   EXPECT_OK(copy.status());
1271   EXPECT_EQ(*original, *copy);
1272 }
1273 
TEST(Result,TestPointerCopyCtorStatusNotOk)1274 TEST(Result, TestPointerCopyCtorStatusNotOk) {
1275   pw::Result<int*> original(pw::Status::Cancelled());
1276   pw::Result<int*> copy(original);
1277   EXPECT_EQ(copy.status().code(), pw::Status::Cancelled().code());
1278 }
1279 
TEST(Result,TestPointerCopyCtorStatusOKConverting)1280 TEST(Result, TestPointerCopyCtorStatusOKConverting) {
1281   Derived derived;
1282   pw::Result<Derived*> original(&derived);
1283   pw::Result<Base2*> copy(original);
1284   EXPECT_OK(copy.status());
1285   EXPECT_EQ(static_cast<const Base2*>(*original), *copy);
1286 }
1287 
TEST(Result,TestPointerCopyCtorStatusNotOkConverting)1288 TEST(Result, TestPointerCopyCtorStatusNotOkConverting) {
1289   pw::Result<Derived*> original(pw::Status::Cancelled());
1290   pw::Result<Base2*> copy(original);
1291   EXPECT_EQ(copy.status().code(), pw::Status::Cancelled().code());
1292 }
1293 
TEST(Result,TestPointerAssignmentStatusOk)1294 TEST(Result, TestPointerAssignmentStatusOk) {
1295   const int kI = 0;
1296   pw::Result<const int*> source(&kI);
1297   pw::Result<const int*> target;
1298   target = source;
1299   EXPECT_OK(target.status());
1300   EXPECT_EQ(*source, *target);
1301 }
1302 
TEST(Result,TestPointerAssignmentStatusNotOk)1303 TEST(Result, TestPointerAssignmentStatusNotOk) {
1304   pw::Result<int*> source(pw::Status::Cancelled());
1305   pw::Result<int*> target;
1306   target = source;
1307   EXPECT_EQ(target.status().code(), pw::Status::Cancelled().code());
1308 }
1309 
TEST(Result,TestPointerAssignmentStatusOKConverting)1310 TEST(Result, TestPointerAssignmentStatusOKConverting) {
1311   Derived derived;
1312   pw::Result<Derived*> source(&derived);
1313   pw::Result<Base2*> target;
1314   target = source;
1315   EXPECT_OK(target.status());
1316   EXPECT_EQ(static_cast<const Base2*>(*source), *target);
1317 }
1318 
TEST(Result,TestPointerAssignmentStatusNotOkConverting)1319 TEST(Result, TestPointerAssignmentStatusNotOkConverting) {
1320   pw::Result<Derived*> source(pw::Status::Cancelled());
1321   pw::Result<Base2*> target;
1322   target = source;
1323   EXPECT_EQ(target.status(), source.status());
1324 }
1325 
TEST(Result,TestPointerStatus)1326 TEST(Result, TestPointerStatus) {
1327   const int kI = 0;
1328   pw::Result<const int*> good(&kI);
1329   EXPECT_TRUE(good.ok());
1330   pw::Result<const int*> bad(pw::Status::Cancelled());
1331   EXPECT_EQ(bad.status().code(), pw::Status::Cancelled().code());
1332 }
1333 
TEST(Result,TestPointerValue)1334 TEST(Result, TestPointerValue) {
1335   const int kI = 0;
1336   pw::Result<const int*> thing(&kI);
1337   EXPECT_EQ(&kI, *thing);
1338 }
1339 
TEST(Result,TestPointerValueConst)1340 TEST(Result, TestPointerValueConst) {
1341   const int kI = 0;
1342   const pw::Result<const int*> thing(&kI);
1343   EXPECT_EQ(&kI, *thing);
1344 }
1345 
TEST(Result,ResultVectorOfUniquePointerCanReserveAndResize)1346 TEST(Result, ResultVectorOfUniquePointerCanReserveAndResize) {
1347   using EvilType = std::vector<std::unique_ptr<int>>;
1348   static_assert(std::is_copy_constructible<EvilType>::value, "");
1349   std::vector<::pw::Result<EvilType>> v(5);
1350   v.reserve(v.capacity() + 10);
1351   v.resize(v.capacity() + 10);
1352 }
1353 
TEST(Result,ConstPayload)1354 TEST(Result, ConstPayload) {
1355   // A reduced version of a problematic type found in the wild. All of the
1356   // operations below should compile.
1357   pw::Result<const int> a;
1358 
1359   // Copy-construction
1360   pw::Result<const int> b(a);
1361 
1362   // Copy-assignment
1363   EXPECT_FALSE(std::is_copy_assignable<pw::Result<const int>>::value);
1364 
1365   // Move-construction
1366   pw::Result<const int> c(std::move(a));
1367 
1368   // Move-assignment
1369   EXPECT_FALSE(std::is_move_assignable<pw::Result<const int>>::value);
1370 }
1371 
TEST(Result,MapToResultUniquePtr)1372 TEST(Result, MapToResultUniquePtr) {
1373   // A reduced version of a problematic type found in the wild. All of the
1374   // operations below should compile.
1375   using MapType = std::map<std::string, pw::Result<std::unique_ptr<int>>>;
1376 
1377   MapType a;
1378 
1379   // Move-construction
1380   MapType b(std::move(a));
1381 
1382   // Move-assignment
1383   a = std::move(b);
1384 }
1385 
TEST(Result,ValueOrOk)1386 TEST(Result, ValueOrOk) {
1387   const pw::Result<int> status_or = 0;
1388   EXPECT_EQ(status_or.value_or(-1), 0);
1389 }
1390 
TEST(Result,ValueOrDefault)1391 TEST(Result, ValueOrDefault) {
1392   const pw::Result<int> status_or = pw::Status::Cancelled();
1393   EXPECT_EQ(status_or.value_or(-1), -1);
1394 }
1395 
TEST(Result,MoveOnlyValueOrOk)1396 TEST(Result, MoveOnlyValueOrOk) {
1397   pw::Result<std::unique_ptr<int>> status_or = std::make_unique<int>(0);
1398   ASSERT_TRUE(status_or.ok());
1399   auto value = std::move(status_or).value_or(std::make_unique<int>(-1));
1400   EXPECT_EQ(*value, 0);
1401 }
1402 
TEST(Result,MoveOnlyValueOrDefault)1403 TEST(Result, MoveOnlyValueOrDefault) {
1404   pw::Result<std::unique_ptr<int>> status_or(pw::Status::Cancelled());
1405   ASSERT_FALSE(status_or.ok());
1406   auto value = std::move(status_or).value_or(std::make_unique<int>(-1));
1407   EXPECT_EQ(*value, -1);
1408 }
1409 
MakeStatus()1410 static pw::Result<int> MakeStatus() { return 100; }
1411 
TEST(Result,TestIgnoreError)1412 TEST(Result, TestIgnoreError) { MakeStatus().IgnoreError(); }
1413 
TEST(Result,EqualityOperator)1414 TEST(Result, EqualityOperator) {
1415   constexpr int kNumCases = 4;
1416   std::array<pw::Result<int>, kNumCases> group1 = {
1417       pw::Result<int>(1),
1418       pw::Result<int>(2),
1419       pw::Result<int>(pw::Status::InvalidArgument()),
1420       pw::Result<int>(pw::Status::Internal())};
1421   std::array<pw::Result<int>, kNumCases> group2 = {
1422       pw::Result<int>(1),
1423       pw::Result<int>(2),
1424       pw::Result<int>(pw::Status::InvalidArgument()),
1425       pw::Result<int>(pw::Status::Internal())};
1426   for (int i = 0; i < kNumCases; ++i) {
1427     for (int j = 0; j < kNumCases; ++j) {
1428       if (i == j) {
1429         EXPECT_TRUE(group1[i] == group2[j]);
1430         EXPECT_FALSE(group1[i] != group2[j]);
1431       } else {
1432         EXPECT_FALSE(group1[i] == group2[j]);
1433         EXPECT_TRUE(group1[i] != group2[j]);
1434       }
1435     }
1436   }
1437 }
1438 
1439 struct MyType {
operator ==__anon4731873d0111::MyType1440   bool operator==(const MyType&) const { return true; }
1441 };
1442 
1443 enum class ConvTraits { kNone = 0, kImplicit = 1, kExplicit = 2 };
1444 
1445 // This class has conversion operator to `Result<T>` based on value of
1446 // `conv_traits`.
1447 template <typename T, ConvTraits conv_traits = ConvTraits::kNone>
1448 struct ResultConversionBase {};
1449 
1450 template <typename T>
1451 struct ResultConversionBase<T, ConvTraits::kImplicit> {
operator pw::Result<T>__anon4731873d0111::ResultConversionBase1452   operator pw::Result<T>() const& {  // NOLINT
1453     return pw::Status::InvalidArgument();
1454   }
operator pw::Result<T>__anon4731873d0111::ResultConversionBase1455   operator pw::Result<T>() && {  // NOLINT
1456     return pw::Status::InvalidArgument();
1457   }
1458 };
1459 
1460 template <typename T>
1461 struct ResultConversionBase<T, ConvTraits::kExplicit> {
operator pw::Result<T>__anon4731873d0111::ResultConversionBase1462   explicit operator pw::Result<T>() const& {
1463     return pw::Status::InvalidArgument();
1464   }
operator pw::Result<T>__anon4731873d0111::ResultConversionBase1465   explicit operator pw::Result<T>() && { return pw::Status::InvalidArgument(); }
1466 };
1467 
1468 // This class has conversion operator to `T` based on the value of
1469 // `conv_traits`.
1470 template <typename T, ConvTraits conv_traits = ConvTraits::kNone>
1471 struct ConversionBase {};
1472 
1473 template <typename T>
1474 struct ConversionBase<T, ConvTraits::kImplicit> {
operator T__anon4731873d0111::ConversionBase1475   operator T() const& { return t; }         // NOLINT
operator T__anon4731873d0111::ConversionBase1476   operator T() && { return std::move(t); }  // NOLINT
1477   T t;
1478 };
1479 
1480 template <typename T>
1481 struct ConversionBase<T, ConvTraits::kExplicit> {
operator T__anon4731873d0111::ConversionBase1482   explicit operator T() const& { return t; }
operator T__anon4731873d0111::ConversionBase1483   explicit operator T() && { return std::move(t); }
1484   T t;
1485 };
1486 
1487 // This class has conversion operator to `pw::Status` based on the value of
1488 // `conv_traits`.
1489 template <ConvTraits conv_traits = ConvTraits::kNone>
1490 struct StatusConversionBase {};
1491 
1492 template <>
1493 struct StatusConversionBase<ConvTraits::kImplicit> {
operator pw::Status__anon4731873d0111::StatusConversionBase1494   operator pw::Status() const& {  // NOLINT
1495     return pw::Status::Internal();
1496   }
operator pw::Status__anon4731873d0111::StatusConversionBase1497   operator pw::Status() && {  // NOLINT
1498     return pw::Status::Internal();
1499   }
1500 };
1501 
1502 template <>
1503 struct StatusConversionBase<ConvTraits::kExplicit> {
operator pw::Status__anon4731873d0111::StatusConversionBase1504   explicit operator pw::Status() const& {  // NOLINT
1505     return pw::Status::Internal();
1506   }
operator pw::Status__anon4731873d0111::StatusConversionBase1507   explicit operator pw::Status() && {  // NOLINT
1508     return pw::Status::Internal();
1509   }
1510 };
1511 
1512 static constexpr int kConvToStatus = 1;
1513 static constexpr int kConvToResult = 2;
1514 static constexpr int kConvToT = 4;
1515 static constexpr int kConvExplicit = 8;
1516 
GetConvTraits(int bit,int config)1517 constexpr ConvTraits GetConvTraits(int bit, int config) {
1518   return (config & bit) == 0
1519              ? ConvTraits::kNone
1520              : ((config & kConvExplicit) == 0 ? ConvTraits::kImplicit
1521                                               : ConvTraits::kExplicit);
1522 }
1523 
1524 // This class conditionally has conversion operator to `pw::Status`, `T`,
1525 // `Result<T>`, based on values of the template parameters.
1526 template <typename T, int config>
1527 struct CustomType
1528     : ResultConversionBase<T, GetConvTraits(kConvToResult, config)>,
1529       ConversionBase<T, GetConvTraits(kConvToT, config)>,
1530       StatusConversionBase<GetConvTraits(kConvToStatus, config)> {};
1531 
1532 struct ConvertibleToAnyResult {
1533   template <typename T>
operator pw::Result<T>__anon4731873d0111::ConvertibleToAnyResult1534   operator pw::Result<T>() const {  // NOLINT
1535     return pw::Status::InvalidArgument();
1536   }
1537 };
1538 
1539 // Test the rank of overload resolution for `Result<T>` constructor and
1540 // assignment, from highest to lowest:
1541 // 1. T/Status
1542 // 2. U that has conversion operator to pw::Result<T>
1543 // 3. U that is convertible to Status
1544 // 4. U that is convertible to T
TEST(Result,ConstructionFromT)1545 TEST(Result, ConstructionFromT) {
1546   // Construct pw::Result<T> from T when T is convertible to
1547   // pw::Result<T>
1548   {
1549     ConvertibleToAnyResult v;
1550     pw::Result<ConvertibleToAnyResult> statusor(v);
1551     EXPECT_TRUE(statusor.ok());
1552   }
1553   {
1554     ConvertibleToAnyResult v;
1555     pw::Result<ConvertibleToAnyResult> statusor = v;
1556     EXPECT_TRUE(statusor.ok());
1557   }
1558   // Construct pw::Result<T> from T when T is explicitly convertible to
1559   // Status
1560   {
1561     CustomType<MyType, kConvToStatus | kConvExplicit> v;
1562     pw::Result<CustomType<MyType, kConvToStatus | kConvExplicit>> statusor(v);
1563     EXPECT_TRUE(statusor.ok());
1564   }
1565   {
1566     CustomType<MyType, kConvToStatus | kConvExplicit> v;
1567     pw::Result<CustomType<MyType, kConvToStatus | kConvExplicit>> statusor = v;
1568     EXPECT_TRUE(statusor.ok());
1569   }
1570 }
1571 
1572 // Construct pw::Result<T> from U when U is explicitly convertible to T
TEST(Result,ConstructionFromTypeConvertibleToT)1573 TEST(Result, ConstructionFromTypeConvertibleToT) {
1574   {
1575     CustomType<MyType, kConvToT | kConvExplicit> v;
1576     pw::Result<MyType> statusor(v);
1577     EXPECT_TRUE(statusor.ok());
1578   }
1579   {
1580     CustomType<MyType, kConvToT> v;
1581     pw::Result<MyType> statusor = v;
1582     EXPECT_TRUE(statusor.ok());
1583   }
1584 }
1585 
1586 // Construct pw::Result<T> from U when U has explicit conversion operator to
1587 // pw::Result<T>
TEST(Result,ConstructionFromTypeWithConversionOperatorToResultT)1588 TEST(Result, ConstructionFromTypeWithConversionOperatorToResultT) {
1589   {
1590     CustomType<MyType, kConvToResult | kConvExplicit> v;
1591     pw::Result<MyType> statusor(v);
1592     EXPECT_EQ(statusor, v.operator pw::Result<MyType>());
1593   }
1594   {
1595     CustomType<MyType, kConvToT | kConvToResult | kConvExplicit> v;
1596     pw::Result<MyType> statusor(v);
1597     EXPECT_EQ(statusor, v.operator pw::Result<MyType>());
1598   }
1599   {
1600     CustomType<MyType, kConvToResult | kConvToStatus | kConvExplicit> v;
1601     pw::Result<MyType> statusor(v);
1602     EXPECT_EQ(statusor, v.operator pw::Result<MyType>());
1603   }
1604   {
1605     CustomType<MyType, kConvToT | kConvToResult | kConvToStatus | kConvExplicit>
1606         v;
1607     pw::Result<MyType> statusor(v);
1608     EXPECT_EQ(statusor, v.operator pw::Result<MyType>());
1609   }
1610   {
1611     CustomType<MyType, kConvToResult> v;
1612     pw::Result<MyType> statusor = v;
1613     EXPECT_EQ(statusor, v.operator pw::Result<MyType>());
1614   }
1615   {
1616     CustomType<MyType, kConvToT | kConvToResult> v;
1617     pw::Result<MyType> statusor = v;
1618     EXPECT_EQ(statusor, v.operator pw::Result<MyType>());
1619   }
1620   {
1621     CustomType<MyType, kConvToResult | kConvToStatus> v;
1622     pw::Result<MyType> statusor = v;
1623     EXPECT_EQ(statusor, v.operator pw::Result<MyType>());
1624   }
1625   {
1626     CustomType<MyType, kConvToT | kConvToResult | kConvToStatus> v;
1627     pw::Result<MyType> statusor = v;
1628     EXPECT_EQ(statusor, v.operator pw::Result<MyType>());
1629   }
1630 }
1631 
TEST(Result,ConstructionFromTypeConvertibleToStatus)1632 TEST(Result, ConstructionFromTypeConvertibleToStatus) {
1633   // Construction fails because conversion to `Status` is explicit.
1634   {
1635     CustomType<MyType, kConvToStatus | kConvExplicit> v;
1636     pw::Result<MyType> statusor(v);
1637     EXPECT_FALSE(statusor.ok());
1638     EXPECT_EQ(statusor.status(), static_cast<pw::Status>(v));
1639   }
1640   {
1641     CustomType<MyType, kConvToT | kConvToStatus | kConvExplicit> v;
1642     pw::Result<MyType> statusor(v);
1643     EXPECT_FALSE(statusor.ok());
1644     EXPECT_EQ(statusor.status(), static_cast<pw::Status>(v));
1645   }
1646   {
1647     CustomType<MyType, kConvToStatus> v;
1648     pw::Result<MyType> statusor = v;
1649     EXPECT_FALSE(statusor.ok());
1650     EXPECT_EQ(statusor.status(), static_cast<pw::Status>(v));
1651   }
1652   {
1653     CustomType<MyType, kConvToT | kConvToStatus> v;
1654     pw::Result<MyType> statusor = v;
1655     EXPECT_FALSE(statusor.ok());
1656     EXPECT_EQ(statusor.status(), static_cast<pw::Status>(v));
1657   }
1658 }
1659 
TEST(Result,AssignmentFromT)1660 TEST(Result, AssignmentFromT) {
1661   // Assign to pw::Result<T> from T when T is convertible to
1662   // pw::Result<T>
1663   {
1664     ConvertibleToAnyResult v;
1665     pw::Result<ConvertibleToAnyResult> statusor;
1666     statusor = v;
1667     EXPECT_TRUE(statusor.ok());
1668   }
1669   // Assign to pw::Result<T> from T when T is convertible to Status
1670   {
1671     CustomType<MyType, kConvToStatus> v;
1672     pw::Result<CustomType<MyType, kConvToStatus>> statusor;
1673     statusor = v;
1674     EXPECT_TRUE(statusor.ok());
1675   }
1676 }
1677 
TEST(Result,AssignmentFromTypeConvertibleToT)1678 TEST(Result, AssignmentFromTypeConvertibleToT) {
1679   // Assign to pw::Result<T> from U when U is convertible to T
1680   {
1681     CustomType<MyType, kConvToT> v;
1682     pw::Result<MyType> statusor;
1683     statusor = v;
1684     EXPECT_TRUE(statusor.ok());
1685   }
1686 }
1687 
TEST(Result,AssignmentFromTypeWithConversionOperatortoResultT)1688 TEST(Result, AssignmentFromTypeWithConversionOperatortoResultT) {
1689   // Assign to pw::Result<T> from U when U has conversion operator to
1690   // pw::Result<T>
1691   {
1692     CustomType<MyType, kConvToResult> v;
1693     pw::Result<MyType> statusor;
1694     statusor = v;
1695     EXPECT_EQ(statusor, v.operator pw::Result<MyType>());
1696   }
1697   {
1698     CustomType<MyType, kConvToT | kConvToResult> v;
1699     pw::Result<MyType> statusor;
1700     statusor = v;
1701     EXPECT_EQ(statusor, v.operator pw::Result<MyType>());
1702   }
1703   {
1704     CustomType<MyType, kConvToResult | kConvToStatus> v;
1705     pw::Result<MyType> statusor;
1706     statusor = v;
1707     EXPECT_EQ(statusor, v.operator pw::Result<MyType>());
1708   }
1709   {
1710     CustomType<MyType, kConvToT | kConvToResult | kConvToStatus> v;
1711     pw::Result<MyType> statusor;
1712     statusor = v;
1713     EXPECT_EQ(statusor, v.operator pw::Result<MyType>());
1714   }
1715 }
1716 
TEST(Result,AssignmentFromTypeConvertibleToStatus)1717 TEST(Result, AssignmentFromTypeConvertibleToStatus) {
1718   // Assign to pw::Result<T> from U when U is convertible to Status
1719   {
1720     CustomType<MyType, kConvToStatus> v;
1721     pw::Result<MyType> statusor;
1722     statusor = v;
1723     EXPECT_FALSE(statusor.ok());
1724     EXPECT_EQ(statusor.status(), static_cast<pw::Status>(v));
1725   }
1726   {
1727     CustomType<MyType, kConvToT | kConvToStatus> v;
1728     pw::Result<MyType> statusor;
1729     statusor = v;
1730     EXPECT_FALSE(statusor.ok());
1731     EXPECT_EQ(statusor.status(), static_cast<pw::Status>(v));
1732   }
1733 }
1734 
1735 }  // namespace
1736