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