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