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