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