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__anon4f341b710111::CopyDetector166 explicit CopyDetector(int xx) : x(xx) {}
CopyDetector__anon4f341b710111::CopyDetector167 CopyDetector(CopyDetector&& d) noexcept
168 : x(d.x), copied(false), moved(true) {}
CopyDetector__anon4f341b710111::CopyDetector169 CopyDetector(const CopyDetector& d) : x(d.x), copied(true), moved(false) {}
operator =__anon4f341b710111::CopyDetector170 CopyDetector& operator=(const CopyDetector& c) {
171 x = c.x;
172 copied = true;
173 moved = false;
174 return *this;
175 }
operator =__anon4f341b710111::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
TEST(StatusOr,StatusCtorForwards)295 TEST(StatusOr, StatusCtorForwards) {
296 absl::Status status(absl::StatusCode::kInternal, "Some error");
297
298 EXPECT_EQ(absl::StatusOr<int>(status).status().message(), "Some error");
299 EXPECT_EQ(status.message(), "Some error");
300
301 EXPECT_EQ(absl::StatusOr<int>(std::move(status)).status().message(),
302 "Some error");
303 EXPECT_NE(status.message(), "Some error");
304 }
305
306 // Define `EXPECT_DEATH_OR_THROW` to test the behavior of `StatusOr::value`,
307 // which either throws `BadStatusOrAccess` or `LOG(FATAL)` based on whether
308 // exceptions are enabled.
309 #ifdef ABSL_HAVE_EXCEPTIONS
310 #define EXPECT_DEATH_OR_THROW(statement, status_) \
311 EXPECT_THROW( \
312 { \
313 try { \
314 statement; \
315 } catch (const absl::BadStatusOrAccess& e) { \
316 EXPECT_EQ(e.status(), status_); \
317 throw; \
318 } \
319 }, \
320 absl::BadStatusOrAccess);
321 #else // ABSL_HAVE_EXCEPTIONS
322 #define EXPECT_DEATH_OR_THROW(statement, status) \
323 EXPECT_DEATH_IF_SUPPORTED(statement, status.ToString());
324 #endif // ABSL_HAVE_EXCEPTIONS
325
TEST(StatusOrDeathTest,TestDefaultCtorValue)326 TEST(StatusOrDeathTest, TestDefaultCtorValue) {
327 absl::StatusOr<int> thing;
328 EXPECT_DEATH_OR_THROW(thing.value(), absl::UnknownError(""));
329 const absl::StatusOr<int> thing2;
330 EXPECT_DEATH_OR_THROW(thing2.value(), absl::UnknownError(""));
331 }
332
TEST(StatusOrDeathTest,TestValueNotOk)333 TEST(StatusOrDeathTest, TestValueNotOk) {
334 absl::StatusOr<int> thing(absl::CancelledError());
335 EXPECT_DEATH_OR_THROW(thing.value(), absl::CancelledError());
336 }
337
TEST(StatusOrDeathTest,TestValueNotOkConst)338 TEST(StatusOrDeathTest, TestValueNotOkConst) {
339 const absl::StatusOr<int> thing(absl::UnknownError(""));
340 EXPECT_DEATH_OR_THROW(thing.value(), absl::UnknownError(""));
341 }
342
TEST(StatusOrDeathTest,TestPointerDefaultCtorValue)343 TEST(StatusOrDeathTest, TestPointerDefaultCtorValue) {
344 absl::StatusOr<int*> thing;
345 EXPECT_DEATH_OR_THROW(thing.value(), absl::UnknownError(""));
346 }
347
TEST(StatusOrDeathTest,TestPointerValueNotOk)348 TEST(StatusOrDeathTest, TestPointerValueNotOk) {
349 absl::StatusOr<int*> thing(absl::CancelledError());
350 EXPECT_DEATH_OR_THROW(thing.value(), absl::CancelledError());
351 }
352
TEST(StatusOrDeathTest,TestPointerValueNotOkConst)353 TEST(StatusOrDeathTest, TestPointerValueNotOkConst) {
354 const absl::StatusOr<int*> thing(absl::CancelledError());
355 EXPECT_DEATH_OR_THROW(thing.value(), absl::CancelledError());
356 }
357
358 #if GTEST_HAS_DEATH_TEST
TEST(StatusOrDeathTest,TestStatusCtorStatusOk)359 TEST(StatusOrDeathTest, TestStatusCtorStatusOk) {
360 EXPECT_DEBUG_DEATH(
361 {
362 // This will DCHECK
363 absl::StatusOr<int> thing(absl::OkStatus());
364 // In optimized mode, we are actually going to get error::INTERNAL for
365 // status here, rather than crashing, so check that.
366 EXPECT_FALSE(thing.ok());
367 EXPECT_EQ(thing.status().code(), absl::StatusCode::kInternal);
368 },
369 "An OK status is not a valid constructor argument");
370 }
371
TEST(StatusOrDeathTest,TestPointerStatusCtorStatusOk)372 TEST(StatusOrDeathTest, TestPointerStatusCtorStatusOk) {
373 EXPECT_DEBUG_DEATH(
374 {
375 absl::StatusOr<int*> thing(absl::OkStatus());
376 // In optimized mode, we are actually going to get error::INTERNAL for
377 // status here, rather than crashing, so check that.
378 EXPECT_FALSE(thing.ok());
379 EXPECT_EQ(thing.status().code(), absl::StatusCode::kInternal);
380 },
381 "An OK status is not a valid constructor argument");
382 }
383 #endif
384
TEST(StatusOr,ValueAccessor)385 TEST(StatusOr, ValueAccessor) {
386 const int kIntValue = 110;
387 {
388 absl::StatusOr<int> status_or(kIntValue);
389 EXPECT_EQ(kIntValue, status_or.value());
390 EXPECT_EQ(kIntValue, std::move(status_or).value());
391 }
392 {
393 absl::StatusOr<CopyDetector> status_or(kIntValue);
394 EXPECT_THAT(status_or,
395 IsOkAndHolds(CopyDetectorHas(kIntValue, false, false)));
396 CopyDetector copy_detector = status_or.value();
397 EXPECT_THAT(copy_detector, CopyDetectorHas(kIntValue, false, true));
398 copy_detector = std::move(status_or).value();
399 EXPECT_THAT(copy_detector, CopyDetectorHas(kIntValue, true, false));
400 }
401 }
402
TEST(StatusOr,BadValueAccess)403 TEST(StatusOr, BadValueAccess) {
404 const absl::Status kError = absl::CancelledError("message");
405 absl::StatusOr<int> status_or(kError);
406 EXPECT_DEATH_OR_THROW(status_or.value(), kError);
407 }
408
TEST(StatusOr,TestStatusCtor)409 TEST(StatusOr, TestStatusCtor) {
410 absl::StatusOr<int> thing(absl::CancelledError());
411 EXPECT_FALSE(thing.ok());
412 EXPECT_EQ(thing.status().code(), absl::StatusCode::kCancelled);
413 }
414
415
416
TEST(StatusOr,TestValueCtor)417 TEST(StatusOr, TestValueCtor) {
418 const int kI = 4;
419 const absl::StatusOr<int> thing(kI);
420 EXPECT_TRUE(thing.ok());
421 EXPECT_EQ(kI, *thing);
422 }
423
424 struct Foo {
425 const int x;
Foo__anon4f341b710111::Foo426 explicit Foo(int y) : x(y) {}
427 };
428
TEST(StatusOr,InPlaceConstruction)429 TEST(StatusOr, InPlaceConstruction) {
430 EXPECT_THAT(absl::StatusOr<Foo>(absl::in_place, 10),
431 IsOkAndHolds(Field(&Foo::x, 10)));
432 }
433
434 struct InPlaceHelper {
InPlaceHelper__anon4f341b710111::InPlaceHelper435 InPlaceHelper(std::initializer_list<int> xs, std::unique_ptr<int> yy)
436 : x(xs), y(std::move(yy)) {}
437 const std::vector<int> x;
438 std::unique_ptr<int> y;
439 };
440
TEST(StatusOr,InPlaceInitListConstruction)441 TEST(StatusOr, InPlaceInitListConstruction) {
442 absl::StatusOr<InPlaceHelper> status_or(absl::in_place, {10, 11, 12},
443 absl::make_unique<int>(13));
444 EXPECT_THAT(status_or, IsOkAndHolds(AllOf(
445 Field(&InPlaceHelper::x, ElementsAre(10, 11, 12)),
446 Field(&InPlaceHelper::y, Pointee(13)))));
447 }
448
TEST(StatusOr,Emplace)449 TEST(StatusOr, Emplace) {
450 absl::StatusOr<Foo> status_or_foo(10);
451 status_or_foo.emplace(20);
452 EXPECT_THAT(status_or_foo, IsOkAndHolds(Field(&Foo::x, 20)));
453 status_or_foo = absl::InvalidArgumentError("msg");
454 EXPECT_FALSE(status_or_foo.ok());
455 EXPECT_EQ(status_or_foo.status().code(), absl::StatusCode::kInvalidArgument);
456 EXPECT_EQ(status_or_foo.status().message(), "msg");
457 status_or_foo.emplace(20);
458 EXPECT_THAT(status_or_foo, IsOkAndHolds(Field(&Foo::x, 20)));
459 }
460
TEST(StatusOr,EmplaceInitializerList)461 TEST(StatusOr, EmplaceInitializerList) {
462 absl::StatusOr<InPlaceHelper> status_or(absl::in_place, {10, 11, 12},
463 absl::make_unique<int>(13));
464 status_or.emplace({1, 2, 3}, absl::make_unique<int>(4));
465 EXPECT_THAT(status_or,
466 IsOkAndHolds(AllOf(Field(&InPlaceHelper::x, ElementsAre(1, 2, 3)),
467 Field(&InPlaceHelper::y, Pointee(4)))));
468 status_or = absl::InvalidArgumentError("msg");
469 EXPECT_FALSE(status_or.ok());
470 EXPECT_EQ(status_or.status().code(), absl::StatusCode::kInvalidArgument);
471 EXPECT_EQ(status_or.status().message(), "msg");
472 status_or.emplace({1, 2, 3}, absl::make_unique<int>(4));
473 EXPECT_THAT(status_or,
474 IsOkAndHolds(AllOf(Field(&InPlaceHelper::x, ElementsAre(1, 2, 3)),
475 Field(&InPlaceHelper::y, Pointee(4)))));
476 }
477
TEST(StatusOr,TestCopyCtorStatusOk)478 TEST(StatusOr, TestCopyCtorStatusOk) {
479 const int kI = 4;
480 const absl::StatusOr<int> original(kI);
481 const absl::StatusOr<int> copy(original);
482 EXPECT_OK(copy.status());
483 EXPECT_EQ(*original, *copy);
484 }
485
TEST(StatusOr,TestCopyCtorStatusNotOk)486 TEST(StatusOr, TestCopyCtorStatusNotOk) {
487 absl::StatusOr<int> original(absl::CancelledError());
488 absl::StatusOr<int> copy(original);
489 EXPECT_EQ(copy.status().code(), absl::StatusCode::kCancelled);
490 }
491
TEST(StatusOr,TestCopyCtorNonAssignable)492 TEST(StatusOr, TestCopyCtorNonAssignable) {
493 const int kI = 4;
494 CopyNoAssign value(kI);
495 absl::StatusOr<CopyNoAssign> original(value);
496 absl::StatusOr<CopyNoAssign> copy(original);
497 EXPECT_OK(copy.status());
498 EXPECT_EQ(original->foo, copy->foo);
499 }
500
TEST(StatusOr,TestCopyCtorStatusOKConverting)501 TEST(StatusOr, TestCopyCtorStatusOKConverting) {
502 const int kI = 4;
503 absl::StatusOr<int> original(kI);
504 absl::StatusOr<double> copy(original);
505 EXPECT_OK(copy.status());
506 EXPECT_DOUBLE_EQ(*original, *copy);
507 }
508
TEST(StatusOr,TestCopyCtorStatusNotOkConverting)509 TEST(StatusOr, TestCopyCtorStatusNotOkConverting) {
510 absl::StatusOr<int> original(absl::CancelledError());
511 absl::StatusOr<double> copy(original);
512 EXPECT_EQ(copy.status(), original.status());
513 }
514
TEST(StatusOr,TestAssignmentStatusOk)515 TEST(StatusOr, TestAssignmentStatusOk) {
516 // Copy assignmment
517 {
518 const auto p = std::make_shared<int>(17);
519 absl::StatusOr<std::shared_ptr<int>> source(p);
520
521 absl::StatusOr<std::shared_ptr<int>> target;
522 target = source;
523
524 ASSERT_TRUE(target.ok());
525 EXPECT_OK(target.status());
526 EXPECT_EQ(p, *target);
527
528 ASSERT_TRUE(source.ok());
529 EXPECT_OK(source.status());
530 EXPECT_EQ(p, *source);
531 }
532
533 // Move asssignment
534 {
535 const auto p = std::make_shared<int>(17);
536 absl::StatusOr<std::shared_ptr<int>> source(p);
537
538 absl::StatusOr<std::shared_ptr<int>> target;
539 target = std::move(source);
540
541 ASSERT_TRUE(target.ok());
542 EXPECT_OK(target.status());
543 EXPECT_EQ(p, *target);
544
545 ASSERT_TRUE(source.ok());
546 EXPECT_OK(source.status());
547 EXPECT_EQ(nullptr, *source);
548 }
549 }
550
TEST(StatusOr,TestAssignmentStatusNotOk)551 TEST(StatusOr, TestAssignmentStatusNotOk) {
552 // Copy assignment
553 {
554 const absl::Status expected = absl::CancelledError();
555 absl::StatusOr<int> source(expected);
556
557 absl::StatusOr<int> target;
558 target = source;
559
560 EXPECT_FALSE(target.ok());
561 EXPECT_EQ(expected, target.status());
562
563 EXPECT_FALSE(source.ok());
564 EXPECT_EQ(expected, source.status());
565 }
566
567 // Move assignment
568 {
569 const absl::Status expected = absl::CancelledError();
570 absl::StatusOr<int> source(expected);
571
572 absl::StatusOr<int> target;
573 target = std::move(source);
574
575 EXPECT_FALSE(target.ok());
576 EXPECT_EQ(expected, target.status());
577
578 EXPECT_FALSE(source.ok());
579 EXPECT_EQ(source.status().code(), absl::StatusCode::kInternal);
580 }
581 }
582
TEST(StatusOr,TestAssignmentStatusOKConverting)583 TEST(StatusOr, TestAssignmentStatusOKConverting) {
584 // Copy assignment
585 {
586 const int kI = 4;
587 absl::StatusOr<int> source(kI);
588
589 absl::StatusOr<double> target;
590 target = source;
591
592 ASSERT_TRUE(target.ok());
593 EXPECT_OK(target.status());
594 EXPECT_DOUBLE_EQ(kI, *target);
595
596 ASSERT_TRUE(source.ok());
597 EXPECT_OK(source.status());
598 EXPECT_DOUBLE_EQ(kI, *source);
599 }
600
601 // Move assignment
602 {
603 const auto p = new int(17);
604 absl::StatusOr<std::unique_ptr<int>> source(absl::WrapUnique(p));
605
606 absl::StatusOr<std::shared_ptr<int>> target;
607 target = std::move(source);
608
609 ASSERT_TRUE(target.ok());
610 EXPECT_OK(target.status());
611 EXPECT_EQ(p, target->get());
612
613 ASSERT_TRUE(source.ok());
614 EXPECT_OK(source.status());
615 EXPECT_EQ(nullptr, source->get());
616 }
617 }
618
619 struct A {
620 int x;
621 };
622
623 struct ImplicitConstructibleFromA {
624 int x;
625 bool moved;
ImplicitConstructibleFromA__anon4f341b710111::ImplicitConstructibleFromA626 ImplicitConstructibleFromA(const A& a) // NOLINT
627 : x(a.x), moved(false) {}
ImplicitConstructibleFromA__anon4f341b710111::ImplicitConstructibleFromA628 ImplicitConstructibleFromA(A&& a) // NOLINT
629 : x(a.x), moved(true) {}
630 };
631
TEST(StatusOr,ImplicitConvertingConstructor)632 TEST(StatusOr, ImplicitConvertingConstructor) {
633 EXPECT_THAT(
634 absl::implicit_cast<absl::StatusOr<ImplicitConstructibleFromA>>(
635 absl::StatusOr<A>(A{11})),
636 IsOkAndHolds(AllOf(Field(&ImplicitConstructibleFromA::x, 11),
637 Field(&ImplicitConstructibleFromA::moved, true))));
638 absl::StatusOr<A> a(A{12});
639 EXPECT_THAT(
640 absl::implicit_cast<absl::StatusOr<ImplicitConstructibleFromA>>(a),
641 IsOkAndHolds(AllOf(Field(&ImplicitConstructibleFromA::x, 12),
642 Field(&ImplicitConstructibleFromA::moved, false))));
643 }
644
645 struct ExplicitConstructibleFromA {
646 int x;
647 bool moved;
ExplicitConstructibleFromA__anon4f341b710111::ExplicitConstructibleFromA648 explicit ExplicitConstructibleFromA(const A& a) : x(a.x), moved(false) {}
ExplicitConstructibleFromA__anon4f341b710111::ExplicitConstructibleFromA649 explicit ExplicitConstructibleFromA(A&& a) : x(a.x), moved(true) {}
650 };
651
TEST(StatusOr,ExplicitConvertingConstructor)652 TEST(StatusOr, ExplicitConvertingConstructor) {
653 EXPECT_FALSE(
654 (std::is_convertible<const absl::StatusOr<A>&,
655 absl::StatusOr<ExplicitConstructibleFromA>>::value));
656 EXPECT_FALSE(
657 (std::is_convertible<absl::StatusOr<A>&&,
658 absl::StatusOr<ExplicitConstructibleFromA>>::value));
659 EXPECT_THAT(
660 absl::StatusOr<ExplicitConstructibleFromA>(absl::StatusOr<A>(A{11})),
661 IsOkAndHolds(AllOf(Field(&ExplicitConstructibleFromA::x, 11),
662 Field(&ExplicitConstructibleFromA::moved, true))));
663 absl::StatusOr<A> a(A{12});
664 EXPECT_THAT(
665 absl::StatusOr<ExplicitConstructibleFromA>(a),
666 IsOkAndHolds(AllOf(Field(&ExplicitConstructibleFromA::x, 12),
667 Field(&ExplicitConstructibleFromA::moved, false))));
668 }
669
670 struct ImplicitConstructibleFromBool {
ImplicitConstructibleFromBool__anon4f341b710111::ImplicitConstructibleFromBool671 ImplicitConstructibleFromBool(bool y) : x(y) {} // NOLINT
672 bool x = false;
673 };
674
675 struct ConvertibleToBool {
ConvertibleToBool__anon4f341b710111::ConvertibleToBool676 explicit ConvertibleToBool(bool y) : x(y) {}
operator bool__anon4f341b710111::ConvertibleToBool677 operator bool() const { return x; } // NOLINT
678 bool x = false;
679 };
680
TEST(StatusOr,ImplicitBooleanConstructionWithImplicitCasts)681 TEST(StatusOr, ImplicitBooleanConstructionWithImplicitCasts) {
682 EXPECT_THAT(absl::StatusOr<bool>(absl::StatusOr<ConvertibleToBool>(true)),
683 IsOkAndHolds(true));
684 EXPECT_THAT(absl::StatusOr<bool>(absl::StatusOr<ConvertibleToBool>(false)),
685 IsOkAndHolds(false));
686 EXPECT_THAT(
687 absl::implicit_cast<absl::StatusOr<ImplicitConstructibleFromBool>>(
688 absl::StatusOr<bool>(false)),
689 IsOkAndHolds(Field(&ImplicitConstructibleFromBool::x, false)));
690 EXPECT_FALSE((std::is_convertible<
691 absl::StatusOr<ConvertibleToBool>,
692 absl::StatusOr<ImplicitConstructibleFromBool>>::value));
693 }
694
TEST(StatusOr,BooleanConstructionWithImplicitCasts)695 TEST(StatusOr, BooleanConstructionWithImplicitCasts) {
696 EXPECT_THAT(absl::StatusOr<bool>(absl::StatusOr<ConvertibleToBool>(true)),
697 IsOkAndHolds(true));
698 EXPECT_THAT(absl::StatusOr<bool>(absl::StatusOr<ConvertibleToBool>(false)),
699 IsOkAndHolds(false));
700 EXPECT_THAT(
701 absl::StatusOr<ImplicitConstructibleFromBool>{
702 absl::StatusOr<bool>(false)},
703 IsOkAndHolds(Field(&ImplicitConstructibleFromBool::x, false)));
704 EXPECT_THAT(
705 absl::StatusOr<ImplicitConstructibleFromBool>{
706 absl::StatusOr<bool>(absl::InvalidArgumentError(""))},
707 Not(IsOk()));
708
709 EXPECT_THAT(
710 absl::StatusOr<ImplicitConstructibleFromBool>{
711 absl::StatusOr<ConvertibleToBool>(ConvertibleToBool{false})},
712 IsOkAndHolds(Field(&ImplicitConstructibleFromBool::x, false)));
713 EXPECT_THAT(
714 absl::StatusOr<ImplicitConstructibleFromBool>{
715 absl::StatusOr<ConvertibleToBool>(absl::InvalidArgumentError(""))},
716 Not(IsOk()));
717 }
718
TEST(StatusOr,ConstImplicitCast)719 TEST(StatusOr, ConstImplicitCast) {
720 EXPECT_THAT(absl::implicit_cast<absl::StatusOr<bool>>(
721 absl::StatusOr<const bool>(true)),
722 IsOkAndHolds(true));
723 EXPECT_THAT(absl::implicit_cast<absl::StatusOr<bool>>(
724 absl::StatusOr<const bool>(false)),
725 IsOkAndHolds(false));
726 EXPECT_THAT(absl::implicit_cast<absl::StatusOr<const bool>>(
727 absl::StatusOr<bool>(true)),
728 IsOkAndHolds(true));
729 EXPECT_THAT(absl::implicit_cast<absl::StatusOr<const bool>>(
730 absl::StatusOr<bool>(false)),
731 IsOkAndHolds(false));
732 EXPECT_THAT(absl::implicit_cast<absl::StatusOr<const std::string>>(
733 absl::StatusOr<std::string>("foo")),
734 IsOkAndHolds("foo"));
735 EXPECT_THAT(absl::implicit_cast<absl::StatusOr<std::string>>(
736 absl::StatusOr<const std::string>("foo")),
737 IsOkAndHolds("foo"));
738 EXPECT_THAT(
739 absl::implicit_cast<absl::StatusOr<std::shared_ptr<const std::string>>>(
740 absl::StatusOr<std::shared_ptr<std::string>>(
741 std::make_shared<std::string>("foo"))),
742 IsOkAndHolds(Pointee(std::string("foo"))));
743 }
744
TEST(StatusOr,ConstExplicitConstruction)745 TEST(StatusOr, ConstExplicitConstruction) {
746 EXPECT_THAT(absl::StatusOr<bool>(absl::StatusOr<const bool>(true)),
747 IsOkAndHolds(true));
748 EXPECT_THAT(absl::StatusOr<bool>(absl::StatusOr<const bool>(false)),
749 IsOkAndHolds(false));
750 EXPECT_THAT(absl::StatusOr<const bool>(absl::StatusOr<bool>(true)),
751 IsOkAndHolds(true));
752 EXPECT_THAT(absl::StatusOr<const bool>(absl::StatusOr<bool>(false)),
753 IsOkAndHolds(false));
754 }
755
756 struct ExplicitConstructibleFromInt {
757 int x;
ExplicitConstructibleFromInt__anon4f341b710111::ExplicitConstructibleFromInt758 explicit ExplicitConstructibleFromInt(int y) : x(y) {}
759 };
760
TEST(StatusOr,ExplicitConstruction)761 TEST(StatusOr, ExplicitConstruction) {
762 EXPECT_THAT(absl::StatusOr<ExplicitConstructibleFromInt>(10),
763 IsOkAndHolds(Field(&ExplicitConstructibleFromInt::x, 10)));
764 }
765
TEST(StatusOr,ImplicitConstruction)766 TEST(StatusOr, ImplicitConstruction) {
767 // Check implicit casting works.
768 auto status_or =
769 absl::implicit_cast<absl::StatusOr<absl::variant<int, std::string>>>(10);
770 EXPECT_THAT(status_or, IsOkAndHolds(VariantWith<int>(10)));
771 }
772
TEST(StatusOr,ImplicitConstructionFromInitliazerList)773 TEST(StatusOr, ImplicitConstructionFromInitliazerList) {
774 // Note: dropping the explicit std::initializer_list<int> is not supported
775 // by absl::StatusOr or absl::optional.
776 auto status_or =
777 absl::implicit_cast<absl::StatusOr<std::vector<int>>>({{10, 20, 30}});
778 EXPECT_THAT(status_or, IsOkAndHolds(ElementsAre(10, 20, 30)));
779 }
780
TEST(StatusOr,UniquePtrImplicitConstruction)781 TEST(StatusOr, UniquePtrImplicitConstruction) {
782 auto status_or = absl::implicit_cast<absl::StatusOr<std::unique_ptr<Base1>>>(
783 absl::make_unique<Derived>());
784 EXPECT_THAT(status_or, IsOkAndHolds(Ne(nullptr)));
785 }
786
TEST(StatusOr,NestedStatusOrCopyAndMoveConstructorTests)787 TEST(StatusOr, NestedStatusOrCopyAndMoveConstructorTests) {
788 absl::StatusOr<absl::StatusOr<CopyDetector>> status_or = CopyDetector(10);
789 absl::StatusOr<absl::StatusOr<CopyDetector>> status_error =
790 absl::InvalidArgumentError("foo");
791 EXPECT_THAT(status_or,
792 IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, true, false))));
793 absl::StatusOr<absl::StatusOr<CopyDetector>> a = status_or;
794 EXPECT_THAT(a, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, false, true))));
795 absl::StatusOr<absl::StatusOr<CopyDetector>> a_err = status_error;
796 EXPECT_THAT(a_err, Not(IsOk()));
797
798 const absl::StatusOr<absl::StatusOr<CopyDetector>>& cref = status_or;
799 absl::StatusOr<absl::StatusOr<CopyDetector>> b = cref; // NOLINT
800 EXPECT_THAT(b, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, false, true))));
801 const absl::StatusOr<absl::StatusOr<CopyDetector>>& cref_err = status_error;
802 absl::StatusOr<absl::StatusOr<CopyDetector>> b_err = cref_err; // NOLINT
803 EXPECT_THAT(b_err, Not(IsOk()));
804
805 absl::StatusOr<absl::StatusOr<CopyDetector>> c = std::move(status_or);
806 EXPECT_THAT(c, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, true, false))));
807 absl::StatusOr<absl::StatusOr<CopyDetector>> c_err = std::move(status_error);
808 EXPECT_THAT(c_err, Not(IsOk()));
809 }
810
TEST(StatusOr,NestedStatusOrCopyAndMoveAssignment)811 TEST(StatusOr, NestedStatusOrCopyAndMoveAssignment) {
812 absl::StatusOr<absl::StatusOr<CopyDetector>> status_or = CopyDetector(10);
813 absl::StatusOr<absl::StatusOr<CopyDetector>> status_error =
814 absl::InvalidArgumentError("foo");
815 absl::StatusOr<absl::StatusOr<CopyDetector>> a;
816 a = status_or;
817 EXPECT_THAT(a, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, false, true))));
818 a = status_error;
819 EXPECT_THAT(a, Not(IsOk()));
820
821 const absl::StatusOr<absl::StatusOr<CopyDetector>>& cref = status_or;
822 a = cref;
823 EXPECT_THAT(a, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, false, true))));
824 const absl::StatusOr<absl::StatusOr<CopyDetector>>& cref_err = status_error;
825 a = cref_err;
826 EXPECT_THAT(a, Not(IsOk()));
827 a = std::move(status_or);
828 EXPECT_THAT(a, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, true, false))));
829 a = std::move(status_error);
830 EXPECT_THAT(a, Not(IsOk()));
831 }
832
833 struct Copyable {
Copyable__anon4f341b710111::Copyable834 Copyable() {}
Copyable__anon4f341b710111::Copyable835 Copyable(const Copyable&) {}
operator =__anon4f341b710111::Copyable836 Copyable& operator=(const Copyable&) { return *this; }
837 };
838
839 struct MoveOnly {
MoveOnly__anon4f341b710111::MoveOnly840 MoveOnly() {}
MoveOnly__anon4f341b710111::MoveOnly841 MoveOnly(MoveOnly&&) {}
operator =__anon4f341b710111::MoveOnly842 MoveOnly& operator=(MoveOnly&&) { return *this; }
843 };
844
845 struct NonMovable {
NonMovable__anon4f341b710111::NonMovable846 NonMovable() {}
847 NonMovable(const NonMovable&) = delete;
848 NonMovable(NonMovable&&) = delete;
849 NonMovable& operator=(const NonMovable&) = delete;
850 NonMovable& operator=(NonMovable&&) = delete;
851 };
852
TEST(StatusOr,CopyAndMoveAbility)853 TEST(StatusOr, CopyAndMoveAbility) {
854 EXPECT_TRUE(std::is_copy_constructible<Copyable>::value);
855 EXPECT_TRUE(std::is_copy_assignable<Copyable>::value);
856 EXPECT_TRUE(std::is_move_constructible<Copyable>::value);
857 EXPECT_TRUE(std::is_move_assignable<Copyable>::value);
858 EXPECT_FALSE(std::is_copy_constructible<MoveOnly>::value);
859 EXPECT_FALSE(std::is_copy_assignable<MoveOnly>::value);
860 EXPECT_TRUE(std::is_move_constructible<MoveOnly>::value);
861 EXPECT_TRUE(std::is_move_assignable<MoveOnly>::value);
862 EXPECT_FALSE(std::is_copy_constructible<NonMovable>::value);
863 EXPECT_FALSE(std::is_copy_assignable<NonMovable>::value);
864 EXPECT_FALSE(std::is_move_constructible<NonMovable>::value);
865 EXPECT_FALSE(std::is_move_assignable<NonMovable>::value);
866 }
867
TEST(StatusOr,StatusOrAnyCopyAndMoveConstructorTests)868 TEST(StatusOr, StatusOrAnyCopyAndMoveConstructorTests) {
869 absl::StatusOr<absl::any> status_or = CopyDetector(10);
870 absl::StatusOr<absl::any> status_error = absl::InvalidArgumentError("foo");
871 EXPECT_THAT(
872 status_or,
873 IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, true, false))));
874 absl::StatusOr<absl::any> a = status_or;
875 EXPECT_THAT(
876 a, IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, false, true))));
877 absl::StatusOr<absl::any> a_err = status_error;
878 EXPECT_THAT(a_err, Not(IsOk()));
879
880 const absl::StatusOr<absl::any>& cref = status_or;
881 // No lint for no-change copy.
882 absl::StatusOr<absl::any> b = cref; // NOLINT
883 EXPECT_THAT(
884 b, IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, false, true))));
885 const absl::StatusOr<absl::any>& cref_err = status_error;
886 // No lint for no-change copy.
887 absl::StatusOr<absl::any> b_err = cref_err; // NOLINT
888 EXPECT_THAT(b_err, Not(IsOk()));
889
890 absl::StatusOr<absl::any> c = std::move(status_or);
891 EXPECT_THAT(
892 c, IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, true, false))));
893 absl::StatusOr<absl::any> c_err = std::move(status_error);
894 EXPECT_THAT(c_err, Not(IsOk()));
895 }
896
TEST(StatusOr,StatusOrAnyCopyAndMoveAssignment)897 TEST(StatusOr, StatusOrAnyCopyAndMoveAssignment) {
898 absl::StatusOr<absl::any> status_or = CopyDetector(10);
899 absl::StatusOr<absl::any> status_error = absl::InvalidArgumentError("foo");
900 absl::StatusOr<absl::any> a;
901 a = status_or;
902 EXPECT_THAT(
903 a, IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, false, true))));
904 a = status_error;
905 EXPECT_THAT(a, Not(IsOk()));
906
907 const absl::StatusOr<absl::any>& cref = status_or;
908 a = cref;
909 EXPECT_THAT(
910 a, IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, false, true))));
911 const absl::StatusOr<absl::any>& cref_err = status_error;
912 a = cref_err;
913 EXPECT_THAT(a, Not(IsOk()));
914 a = std::move(status_or);
915 EXPECT_THAT(
916 a, IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, true, false))));
917 a = std::move(status_error);
918 EXPECT_THAT(a, Not(IsOk()));
919 }
920
TEST(StatusOr,StatusOrCopyAndMoveTestsConstructor)921 TEST(StatusOr, StatusOrCopyAndMoveTestsConstructor) {
922 absl::StatusOr<CopyDetector> status_or(10);
923 ASSERT_THAT(status_or, IsOkAndHolds(CopyDetectorHas(10, false, false)));
924 absl::StatusOr<CopyDetector> a(status_or);
925 EXPECT_THAT(a, IsOkAndHolds(CopyDetectorHas(10, false, true)));
926 const absl::StatusOr<CopyDetector>& cref = status_or;
927 absl::StatusOr<CopyDetector> b(cref); // NOLINT
928 EXPECT_THAT(b, IsOkAndHolds(CopyDetectorHas(10, false, true)));
929 absl::StatusOr<CopyDetector> c(std::move(status_or));
930 EXPECT_THAT(c, IsOkAndHolds(CopyDetectorHas(10, true, false)));
931 }
932
TEST(StatusOr,StatusOrCopyAndMoveTestsAssignment)933 TEST(StatusOr, StatusOrCopyAndMoveTestsAssignment) {
934 absl::StatusOr<CopyDetector> status_or(10);
935 ASSERT_THAT(status_or, IsOkAndHolds(CopyDetectorHas(10, false, false)));
936 absl::StatusOr<CopyDetector> a;
937 a = status_or;
938 EXPECT_THAT(a, IsOkAndHolds(CopyDetectorHas(10, false, true)));
939 const absl::StatusOr<CopyDetector>& cref = status_or;
940 absl::StatusOr<CopyDetector> b;
941 b = cref;
942 EXPECT_THAT(b, IsOkAndHolds(CopyDetectorHas(10, false, true)));
943 absl::StatusOr<CopyDetector> c;
944 c = std::move(status_or);
945 EXPECT_THAT(c, IsOkAndHolds(CopyDetectorHas(10, true, false)));
946 }
947
TEST(StatusOr,AbslAnyAssignment)948 TEST(StatusOr, AbslAnyAssignment) {
949 EXPECT_FALSE((std::is_assignable<absl::StatusOr<absl::any>,
950 absl::StatusOr<int>>::value));
951 absl::StatusOr<absl::any> status_or;
952 status_or = absl::InvalidArgumentError("foo");
953 EXPECT_THAT(status_or, Not(IsOk()));
954 }
955
TEST(StatusOr,ImplicitAssignment)956 TEST(StatusOr, ImplicitAssignment) {
957 absl::StatusOr<absl::variant<int, std::string>> status_or;
958 status_or = 10;
959 EXPECT_THAT(status_or, IsOkAndHolds(VariantWith<int>(10)));
960 }
961
TEST(StatusOr,SelfDirectInitAssignment)962 TEST(StatusOr, SelfDirectInitAssignment) {
963 absl::StatusOr<std::vector<int>> status_or = {{10, 20, 30}};
964 status_or = *status_or;
965 EXPECT_THAT(status_or, IsOkAndHolds(ElementsAre(10, 20, 30)));
966 }
967
TEST(StatusOr,ImplicitCastFromInitializerList)968 TEST(StatusOr, ImplicitCastFromInitializerList) {
969 absl::StatusOr<std::vector<int>> status_or = {{10, 20, 30}};
970 EXPECT_THAT(status_or, IsOkAndHolds(ElementsAre(10, 20, 30)));
971 }
972
TEST(StatusOr,UniquePtrImplicitAssignment)973 TEST(StatusOr, UniquePtrImplicitAssignment) {
974 absl::StatusOr<std::unique_ptr<Base1>> status_or;
975 status_or = absl::make_unique<Derived>();
976 EXPECT_THAT(status_or, IsOkAndHolds(Ne(nullptr)));
977 }
978
TEST(StatusOr,Pointer)979 TEST(StatusOr, Pointer) {
980 struct A {};
981 struct B : public A {};
982 struct C : private A {};
983
984 EXPECT_TRUE((std::is_constructible<absl::StatusOr<A*>, B*>::value));
985 EXPECT_TRUE((std::is_convertible<B*, absl::StatusOr<A*>>::value));
986 EXPECT_FALSE((std::is_constructible<absl::StatusOr<A*>, C*>::value));
987 EXPECT_FALSE((std::is_convertible<C*, absl::StatusOr<A*>>::value));
988 }
989
TEST(StatusOr,TestAssignmentStatusNotOkConverting)990 TEST(StatusOr, TestAssignmentStatusNotOkConverting) {
991 // Copy assignment
992 {
993 const absl::Status expected = absl::CancelledError();
994 absl::StatusOr<int> source(expected);
995
996 absl::StatusOr<double> target;
997 target = source;
998
999 EXPECT_FALSE(target.ok());
1000 EXPECT_EQ(expected, target.status());
1001
1002 EXPECT_FALSE(source.ok());
1003 EXPECT_EQ(expected, source.status());
1004 }
1005
1006 // Move assignment
1007 {
1008 const absl::Status expected = absl::CancelledError();
1009 absl::StatusOr<int> source(expected);
1010
1011 absl::StatusOr<double> target;
1012 target = std::move(source);
1013
1014 EXPECT_FALSE(target.ok());
1015 EXPECT_EQ(expected, target.status());
1016
1017 EXPECT_FALSE(source.ok());
1018 EXPECT_EQ(source.status().code(), absl::StatusCode::kInternal);
1019 }
1020 }
1021
TEST(StatusOr,SelfAssignment)1022 TEST(StatusOr, SelfAssignment) {
1023 // Copy-assignment, status OK
1024 {
1025 // A string long enough that it's likely to defeat any inline representation
1026 // optimization.
1027 const std::string long_str(128, 'a');
1028
1029 absl::StatusOr<std::string> so = long_str;
1030 so = *&so;
1031
1032 ASSERT_TRUE(so.ok());
1033 EXPECT_OK(so.status());
1034 EXPECT_EQ(long_str, *so);
1035 }
1036
1037 // Copy-assignment, error status
1038 {
1039 absl::StatusOr<int> so = absl::NotFoundError("taco");
1040 so = *&so;
1041
1042 EXPECT_FALSE(so.ok());
1043 EXPECT_EQ(so.status().code(), absl::StatusCode::kNotFound);
1044 EXPECT_EQ(so.status().message(), "taco");
1045 }
1046
1047 // Move-assignment with copyable type, status OK
1048 {
1049 absl::StatusOr<int> so = 17;
1050
1051 // Fool the compiler, which otherwise complains.
1052 auto& same = so;
1053 so = std::move(same);
1054
1055 ASSERT_TRUE(so.ok());
1056 EXPECT_OK(so.status());
1057 EXPECT_EQ(17, *so);
1058 }
1059
1060 // Move-assignment with copyable type, error status
1061 {
1062 absl::StatusOr<int> so = absl::NotFoundError("taco");
1063
1064 // Fool the compiler, which otherwise complains.
1065 auto& same = so;
1066 so = std::move(same);
1067
1068 EXPECT_FALSE(so.ok());
1069 EXPECT_EQ(so.status().code(), absl::StatusCode::kNotFound);
1070 EXPECT_EQ(so.status().message(), "taco");
1071 }
1072
1073 // Move-assignment with non-copyable type, status OK
1074 {
1075 const auto raw = new int(17);
1076 absl::StatusOr<std::unique_ptr<int>> so = absl::WrapUnique(raw);
1077
1078 // Fool the compiler, which otherwise complains.
1079 auto& same = so;
1080 so = std::move(same);
1081
1082 ASSERT_TRUE(so.ok());
1083 EXPECT_OK(so.status());
1084 EXPECT_EQ(raw, so->get());
1085 }
1086
1087 // Move-assignment with non-copyable type, error status
1088 {
1089 absl::StatusOr<std::unique_ptr<int>> so = absl::NotFoundError("taco");
1090
1091 // Fool the compiler, which otherwise complains.
1092 auto& same = so;
1093 so = std::move(same);
1094
1095 EXPECT_FALSE(so.ok());
1096 EXPECT_EQ(so.status().code(), absl::StatusCode::kNotFound);
1097 EXPECT_EQ(so.status().message(), "taco");
1098 }
1099 }
1100
1101 // These types form the overload sets of the constructors and the assignment
1102 // operators of `MockValue`. They distinguish construction from assignment,
1103 // lvalue from rvalue.
1104 struct FromConstructibleAssignableLvalue {};
1105 struct FromConstructibleAssignableRvalue {};
1106 struct FromImplicitConstructibleOnly {};
1107 struct FromAssignableOnly {};
1108
1109 // This class is for testing the forwarding value assignments of `StatusOr`.
1110 // `from_rvalue` indicates whether the constructor or the assignment taking
1111 // rvalue reference is called. `from_assignment` indicates whether any
1112 // assignment is called.
1113 struct MockValue {
1114 // Constructs `MockValue` from `FromConstructibleAssignableLvalue`.
MockValue__anon4f341b710111::MockValue1115 MockValue(const FromConstructibleAssignableLvalue&) // NOLINT
1116 : from_rvalue(false), assigned(false) {}
1117 // Constructs `MockValue` from `FromConstructibleAssignableRvalue`.
MockValue__anon4f341b710111::MockValue1118 MockValue(FromConstructibleAssignableRvalue&&) // NOLINT
1119 : from_rvalue(true), assigned(false) {}
1120 // Constructs `MockValue` from `FromImplicitConstructibleOnly`.
1121 // `MockValue` is not assignable from `FromImplicitConstructibleOnly`.
MockValue__anon4f341b710111::MockValue1122 MockValue(const FromImplicitConstructibleOnly&) // NOLINT
1123 : from_rvalue(false), assigned(false) {}
1124 // Assigns `FromConstructibleAssignableLvalue`.
operator =__anon4f341b710111::MockValue1125 MockValue& operator=(const FromConstructibleAssignableLvalue&) {
1126 from_rvalue = false;
1127 assigned = true;
1128 return *this;
1129 }
1130 // Assigns `FromConstructibleAssignableRvalue` (rvalue only).
operator =__anon4f341b710111::MockValue1131 MockValue& operator=(FromConstructibleAssignableRvalue&&) {
1132 from_rvalue = true;
1133 assigned = true;
1134 return *this;
1135 }
1136 // Assigns `FromAssignableOnly`, but not constructible from
1137 // `FromAssignableOnly`.
operator =__anon4f341b710111::MockValue1138 MockValue& operator=(const FromAssignableOnly&) {
1139 from_rvalue = false;
1140 assigned = true;
1141 return *this;
1142 }
1143 bool from_rvalue;
1144 bool assigned;
1145 };
1146
1147 // operator=(U&&)
TEST(StatusOr,PerfectForwardingAssignment)1148 TEST(StatusOr, PerfectForwardingAssignment) {
1149 // U == T
1150 constexpr int kValue1 = 10, kValue2 = 20;
1151 absl::StatusOr<CopyDetector> status_or;
1152 CopyDetector lvalue(kValue1);
1153 status_or = lvalue;
1154 EXPECT_THAT(status_or, IsOkAndHolds(CopyDetectorHas(kValue1, false, true)));
1155 status_or = CopyDetector(kValue2);
1156 EXPECT_THAT(status_or, IsOkAndHolds(CopyDetectorHas(kValue2, true, false)));
1157
1158 // U != T
1159 EXPECT_TRUE(
1160 (std::is_assignable<absl::StatusOr<MockValue>&,
1161 const FromConstructibleAssignableLvalue&>::value));
1162 EXPECT_TRUE((std::is_assignable<absl::StatusOr<MockValue>&,
1163 FromConstructibleAssignableLvalue&&>::value));
1164 EXPECT_FALSE(
1165 (std::is_assignable<absl::StatusOr<MockValue>&,
1166 const FromConstructibleAssignableRvalue&>::value));
1167 EXPECT_TRUE((std::is_assignable<absl::StatusOr<MockValue>&,
1168 FromConstructibleAssignableRvalue&&>::value));
1169 EXPECT_TRUE(
1170 (std::is_assignable<absl::StatusOr<MockValue>&,
1171 const FromImplicitConstructibleOnly&>::value));
1172 EXPECT_FALSE((std::is_assignable<absl::StatusOr<MockValue>&,
1173 const FromAssignableOnly&>::value));
1174
1175 absl::StatusOr<MockValue> from_lvalue(FromConstructibleAssignableLvalue{});
1176 EXPECT_FALSE(from_lvalue->from_rvalue);
1177 EXPECT_FALSE(from_lvalue->assigned);
1178 from_lvalue = FromConstructibleAssignableLvalue{};
1179 EXPECT_FALSE(from_lvalue->from_rvalue);
1180 EXPECT_TRUE(from_lvalue->assigned);
1181
1182 absl::StatusOr<MockValue> from_rvalue(FromConstructibleAssignableRvalue{});
1183 EXPECT_TRUE(from_rvalue->from_rvalue);
1184 EXPECT_FALSE(from_rvalue->assigned);
1185 from_rvalue = FromConstructibleAssignableRvalue{};
1186 EXPECT_TRUE(from_rvalue->from_rvalue);
1187 EXPECT_TRUE(from_rvalue->assigned);
1188
1189 absl::StatusOr<MockValue> from_implicit_constructible(
1190 FromImplicitConstructibleOnly{});
1191 EXPECT_FALSE(from_implicit_constructible->from_rvalue);
1192 EXPECT_FALSE(from_implicit_constructible->assigned);
1193 // construct a temporary `StatusOr` object and invoke the `StatusOr` move
1194 // assignment operator.
1195 from_implicit_constructible = FromImplicitConstructibleOnly{};
1196 EXPECT_FALSE(from_implicit_constructible->from_rvalue);
1197 EXPECT_FALSE(from_implicit_constructible->assigned);
1198 }
1199
TEST(StatusOr,TestStatus)1200 TEST(StatusOr, TestStatus) {
1201 absl::StatusOr<int> good(4);
1202 EXPECT_TRUE(good.ok());
1203 absl::StatusOr<int> bad(absl::CancelledError());
1204 EXPECT_FALSE(bad.ok());
1205 EXPECT_EQ(bad.status().code(), absl::StatusCode::kCancelled);
1206 }
1207
TEST(StatusOr,OperatorStarRefQualifiers)1208 TEST(StatusOr, OperatorStarRefQualifiers) {
1209 static_assert(
1210 std::is_same<const int&,
1211 decltype(*std::declval<const absl::StatusOr<int>&>())>(),
1212 "Unexpected ref-qualifiers");
1213 static_assert(
1214 std::is_same<int&, decltype(*std::declval<absl::StatusOr<int>&>())>(),
1215 "Unexpected ref-qualifiers");
1216 static_assert(
1217 std::is_same<const int&&,
1218 decltype(*std::declval<const absl::StatusOr<int>&&>())>(),
1219 "Unexpected ref-qualifiers");
1220 static_assert(
1221 std::is_same<int&&, decltype(*std::declval<absl::StatusOr<int>&&>())>(),
1222 "Unexpected ref-qualifiers");
1223 }
1224
TEST(StatusOr,OperatorStar)1225 TEST(StatusOr, OperatorStar) {
1226 const absl::StatusOr<std::string> const_lvalue("hello");
1227 EXPECT_EQ("hello", *const_lvalue);
1228
1229 absl::StatusOr<std::string> lvalue("hello");
1230 EXPECT_EQ("hello", *lvalue);
1231
1232 // Note: Recall that std::move() is equivalent to a static_cast to an rvalue
1233 // reference type.
1234 const absl::StatusOr<std::string> const_rvalue("hello");
1235 EXPECT_EQ("hello", *std::move(const_rvalue)); // NOLINT
1236
1237 absl::StatusOr<std::string> rvalue("hello");
1238 EXPECT_EQ("hello", *std::move(rvalue));
1239 }
1240
TEST(StatusOr,OperatorArrowQualifiers)1241 TEST(StatusOr, OperatorArrowQualifiers) {
1242 static_assert(
1243 std::is_same<
1244 const int*,
1245 decltype(std::declval<const absl::StatusOr<int>&>().operator->())>(),
1246 "Unexpected qualifiers");
1247 static_assert(
1248 std::is_same<
1249 int*, decltype(std::declval<absl::StatusOr<int>&>().operator->())>(),
1250 "Unexpected qualifiers");
1251 static_assert(
1252 std::is_same<
1253 const int*,
1254 decltype(std::declval<const absl::StatusOr<int>&&>().operator->())>(),
1255 "Unexpected qualifiers");
1256 static_assert(
1257 std::is_same<
1258 int*, decltype(std::declval<absl::StatusOr<int>&&>().operator->())>(),
1259 "Unexpected qualifiers");
1260 }
1261
TEST(StatusOr,OperatorArrow)1262 TEST(StatusOr, OperatorArrow) {
1263 const absl::StatusOr<std::string> const_lvalue("hello");
1264 EXPECT_EQ(std::string("hello"), const_lvalue->c_str());
1265
1266 absl::StatusOr<std::string> lvalue("hello");
1267 EXPECT_EQ(std::string("hello"), lvalue->c_str());
1268 }
1269
TEST(StatusOr,RValueStatus)1270 TEST(StatusOr, RValueStatus) {
1271 absl::StatusOr<int> so(absl::NotFoundError("taco"));
1272 const absl::Status s = std::move(so).status();
1273
1274 EXPECT_EQ(s.code(), absl::StatusCode::kNotFound);
1275 EXPECT_EQ(s.message(), "taco");
1276
1277 // Check that !ok() still implies !status().ok(), even after moving out of the
1278 // object. See the note on the rvalue ref-qualified status method.
1279 EXPECT_FALSE(so.ok()); // NOLINT
1280 EXPECT_FALSE(so.status().ok());
1281 EXPECT_EQ(so.status().code(), absl::StatusCode::kInternal);
1282 EXPECT_EQ(so.status().message(), "Status accessed after move.");
1283 }
1284
TEST(StatusOr,TestValue)1285 TEST(StatusOr, TestValue) {
1286 const int kI = 4;
1287 absl::StatusOr<int> thing(kI);
1288 EXPECT_EQ(kI, *thing);
1289 }
1290
TEST(StatusOr,TestValueConst)1291 TEST(StatusOr, TestValueConst) {
1292 const int kI = 4;
1293 const absl::StatusOr<int> thing(kI);
1294 EXPECT_EQ(kI, *thing);
1295 }
1296
TEST(StatusOr,TestPointerDefaultCtor)1297 TEST(StatusOr, TestPointerDefaultCtor) {
1298 absl::StatusOr<int*> thing;
1299 EXPECT_FALSE(thing.ok());
1300 EXPECT_EQ(thing.status().code(), absl::StatusCode::kUnknown);
1301 }
1302
1303
1304
TEST(StatusOr,TestPointerStatusCtor)1305 TEST(StatusOr, TestPointerStatusCtor) {
1306 absl::StatusOr<int*> thing(absl::CancelledError());
1307 EXPECT_FALSE(thing.ok());
1308 EXPECT_EQ(thing.status().code(), absl::StatusCode::kCancelled);
1309 }
1310
TEST(StatusOr,TestPointerValueCtor)1311 TEST(StatusOr, TestPointerValueCtor) {
1312 const int kI = 4;
1313
1314 // Construction from a non-null pointer
1315 {
1316 absl::StatusOr<const int*> so(&kI);
1317 EXPECT_TRUE(so.ok());
1318 EXPECT_OK(so.status());
1319 EXPECT_EQ(&kI, *so);
1320 }
1321
1322 // Construction from a null pointer constant
1323 {
1324 absl::StatusOr<const int*> so(nullptr);
1325 EXPECT_TRUE(so.ok());
1326 EXPECT_OK(so.status());
1327 EXPECT_EQ(nullptr, *so);
1328 }
1329
1330 // Construction from a non-literal null pointer
1331 {
1332 const int* const p = nullptr;
1333
1334 absl::StatusOr<const int*> so(p);
1335 EXPECT_TRUE(so.ok());
1336 EXPECT_OK(so.status());
1337 EXPECT_EQ(nullptr, *so);
1338 }
1339 }
1340
TEST(StatusOr,TestPointerCopyCtorStatusOk)1341 TEST(StatusOr, TestPointerCopyCtorStatusOk) {
1342 const int kI = 0;
1343 absl::StatusOr<const int*> original(&kI);
1344 absl::StatusOr<const int*> copy(original);
1345 EXPECT_OK(copy.status());
1346 EXPECT_EQ(*original, *copy);
1347 }
1348
TEST(StatusOr,TestPointerCopyCtorStatusNotOk)1349 TEST(StatusOr, TestPointerCopyCtorStatusNotOk) {
1350 absl::StatusOr<int*> original(absl::CancelledError());
1351 absl::StatusOr<int*> copy(original);
1352 EXPECT_EQ(copy.status().code(), absl::StatusCode::kCancelled);
1353 }
1354
TEST(StatusOr,TestPointerCopyCtorStatusOKConverting)1355 TEST(StatusOr, TestPointerCopyCtorStatusOKConverting) {
1356 Derived derived;
1357 absl::StatusOr<Derived*> original(&derived);
1358 absl::StatusOr<Base2*> copy(original);
1359 EXPECT_OK(copy.status());
1360 EXPECT_EQ(static_cast<const Base2*>(*original), *copy);
1361 }
1362
TEST(StatusOr,TestPointerCopyCtorStatusNotOkConverting)1363 TEST(StatusOr, TestPointerCopyCtorStatusNotOkConverting) {
1364 absl::StatusOr<Derived*> original(absl::CancelledError());
1365 absl::StatusOr<Base2*> copy(original);
1366 EXPECT_EQ(copy.status().code(), absl::StatusCode::kCancelled);
1367 }
1368
TEST(StatusOr,TestPointerAssignmentStatusOk)1369 TEST(StatusOr, TestPointerAssignmentStatusOk) {
1370 const int kI = 0;
1371 absl::StatusOr<const int*> source(&kI);
1372 absl::StatusOr<const int*> target;
1373 target = source;
1374 EXPECT_OK(target.status());
1375 EXPECT_EQ(*source, *target);
1376 }
1377
TEST(StatusOr,TestPointerAssignmentStatusNotOk)1378 TEST(StatusOr, TestPointerAssignmentStatusNotOk) {
1379 absl::StatusOr<int*> source(absl::CancelledError());
1380 absl::StatusOr<int*> target;
1381 target = source;
1382 EXPECT_EQ(target.status().code(), absl::StatusCode::kCancelled);
1383 }
1384
TEST(StatusOr,TestPointerAssignmentStatusOKConverting)1385 TEST(StatusOr, TestPointerAssignmentStatusOKConverting) {
1386 Derived derived;
1387 absl::StatusOr<Derived*> source(&derived);
1388 absl::StatusOr<Base2*> target;
1389 target = source;
1390 EXPECT_OK(target.status());
1391 EXPECT_EQ(static_cast<const Base2*>(*source), *target);
1392 }
1393
TEST(StatusOr,TestPointerAssignmentStatusNotOkConverting)1394 TEST(StatusOr, TestPointerAssignmentStatusNotOkConverting) {
1395 absl::StatusOr<Derived*> source(absl::CancelledError());
1396 absl::StatusOr<Base2*> target;
1397 target = source;
1398 EXPECT_EQ(target.status(), source.status());
1399 }
1400
TEST(StatusOr,TestPointerStatus)1401 TEST(StatusOr, TestPointerStatus) {
1402 const int kI = 0;
1403 absl::StatusOr<const int*> good(&kI);
1404 EXPECT_TRUE(good.ok());
1405 absl::StatusOr<const int*> bad(absl::CancelledError());
1406 EXPECT_EQ(bad.status().code(), absl::StatusCode::kCancelled);
1407 }
1408
TEST(StatusOr,TestPointerValue)1409 TEST(StatusOr, TestPointerValue) {
1410 const int kI = 0;
1411 absl::StatusOr<const int*> thing(&kI);
1412 EXPECT_EQ(&kI, *thing);
1413 }
1414
TEST(StatusOr,TestPointerValueConst)1415 TEST(StatusOr, TestPointerValueConst) {
1416 const int kI = 0;
1417 const absl::StatusOr<const int*> thing(&kI);
1418 EXPECT_EQ(&kI, *thing);
1419 }
1420
TEST(StatusOr,StatusOrVectorOfUniquePointerCanReserveAndResize)1421 TEST(StatusOr, StatusOrVectorOfUniquePointerCanReserveAndResize) {
1422 using EvilType = std::vector<std::unique_ptr<int>>;
1423 static_assert(std::is_copy_constructible<EvilType>::value, "");
1424 std::vector<::absl::StatusOr<EvilType>> v(5);
1425 v.reserve(v.capacity() + 10);
1426 v.resize(v.capacity() + 10);
1427 }
1428
TEST(StatusOr,ConstPayload)1429 TEST(StatusOr, ConstPayload) {
1430 // A reduced version of a problematic type found in the wild. All of the
1431 // operations below should compile.
1432 absl::StatusOr<const int> a;
1433
1434 // Copy-construction
1435 absl::StatusOr<const int> b(a);
1436
1437 // Copy-assignment
1438 EXPECT_FALSE(std::is_copy_assignable<absl::StatusOr<const int>>::value);
1439
1440 // Move-construction
1441 absl::StatusOr<const int> c(std::move(a));
1442
1443 // Move-assignment
1444 EXPECT_FALSE(std::is_move_assignable<absl::StatusOr<const int>>::value);
1445 }
1446
TEST(StatusOr,MapToStatusOrUniquePtr)1447 TEST(StatusOr, MapToStatusOrUniquePtr) {
1448 // A reduced version of a problematic type found in the wild. All of the
1449 // operations below should compile.
1450 using MapType = std::map<std::string, absl::StatusOr<std::unique_ptr<int>>>;
1451
1452 MapType a;
1453
1454 // Move-construction
1455 MapType b(std::move(a));
1456
1457 // Move-assignment
1458 a = std::move(b);
1459 }
1460
TEST(StatusOr,ValueOrOk)1461 TEST(StatusOr, ValueOrOk) {
1462 const absl::StatusOr<int> status_or = 0;
1463 EXPECT_EQ(status_or.value_or(-1), 0);
1464 }
1465
TEST(StatusOr,ValueOrDefault)1466 TEST(StatusOr, ValueOrDefault) {
1467 const absl::StatusOr<int> status_or = absl::CancelledError();
1468 EXPECT_EQ(status_or.value_or(-1), -1);
1469 }
1470
TEST(StatusOr,MoveOnlyValueOrOk)1471 TEST(StatusOr, MoveOnlyValueOrOk) {
1472 EXPECT_THAT(absl::StatusOr<std::unique_ptr<int>>(absl::make_unique<int>(0))
1473 .value_or(absl::make_unique<int>(-1)),
1474 Pointee(0));
1475 }
1476
TEST(StatusOr,MoveOnlyValueOrDefault)1477 TEST(StatusOr, MoveOnlyValueOrDefault) {
1478 EXPECT_THAT(absl::StatusOr<std::unique_ptr<int>>(absl::CancelledError())
1479 .value_or(absl::make_unique<int>(-1)),
1480 Pointee(-1));
1481 }
1482
MakeStatus()1483 static absl::StatusOr<int> MakeStatus() { return 100; }
1484
TEST(StatusOr,TestIgnoreError)1485 TEST(StatusOr, TestIgnoreError) { MakeStatus().IgnoreError(); }
1486
TEST(StatusOr,EqualityOperator)1487 TEST(StatusOr, EqualityOperator) {
1488 constexpr int kNumCases = 4;
1489 std::array<absl::StatusOr<int>, kNumCases> group1 = {
1490 absl::StatusOr<int>(1), absl::StatusOr<int>(2),
1491 absl::StatusOr<int>(absl::InvalidArgumentError("msg")),
1492 absl::StatusOr<int>(absl::InternalError("msg"))};
1493 std::array<absl::StatusOr<int>, kNumCases> group2 = {
1494 absl::StatusOr<int>(1), absl::StatusOr<int>(2),
1495 absl::StatusOr<int>(absl::InvalidArgumentError("msg")),
1496 absl::StatusOr<int>(absl::InternalError("msg"))};
1497 for (int i = 0; i < kNumCases; ++i) {
1498 for (int j = 0; j < kNumCases; ++j) {
1499 if (i == j) {
1500 EXPECT_TRUE(group1[i] == group2[j]);
1501 EXPECT_FALSE(group1[i] != group2[j]);
1502 } else {
1503 EXPECT_FALSE(group1[i] == group2[j]);
1504 EXPECT_TRUE(group1[i] != group2[j]);
1505 }
1506 }
1507 }
1508 }
1509
1510 struct MyType {
operator ==__anon4f341b710111::MyType1511 bool operator==(const MyType&) const { return true; }
1512 };
1513
1514 enum class ConvTraits { kNone = 0, kImplicit = 1, kExplicit = 2 };
1515
1516 // This class has conversion operator to `StatusOr<T>` based on value of
1517 // `conv_traits`.
1518 template <typename T, ConvTraits conv_traits = ConvTraits::kNone>
1519 struct StatusOrConversionBase {};
1520
1521 template <typename T>
1522 struct StatusOrConversionBase<T, ConvTraits::kImplicit> {
operator absl::StatusOr<T>__anon4f341b710111::StatusOrConversionBase1523 operator absl::StatusOr<T>() const& { // NOLINT
1524 return absl::InvalidArgumentError("conversion to absl::StatusOr");
1525 }
operator absl::StatusOr<T>__anon4f341b710111::StatusOrConversionBase1526 operator absl::StatusOr<T>() && { // NOLINT
1527 return absl::InvalidArgumentError("conversion to absl::StatusOr");
1528 }
1529 };
1530
1531 template <typename T>
1532 struct StatusOrConversionBase<T, ConvTraits::kExplicit> {
operator absl::StatusOr<T>__anon4f341b710111::StatusOrConversionBase1533 explicit operator absl::StatusOr<T>() const& {
1534 return absl::InvalidArgumentError("conversion to absl::StatusOr");
1535 }
operator absl::StatusOr<T>__anon4f341b710111::StatusOrConversionBase1536 explicit operator absl::StatusOr<T>() && {
1537 return absl::InvalidArgumentError("conversion to absl::StatusOr");
1538 }
1539 };
1540
1541 // This class has conversion operator to `T` based on the value of
1542 // `conv_traits`.
1543 template <typename T, ConvTraits conv_traits = ConvTraits::kNone>
1544 struct ConversionBase {};
1545
1546 template <typename T>
1547 struct ConversionBase<T, ConvTraits::kImplicit> {
operator T__anon4f341b710111::ConversionBase1548 operator T() const& { return t; } // NOLINT
operator T__anon4f341b710111::ConversionBase1549 operator T() && { return std::move(t); } // NOLINT
1550 T t;
1551 };
1552
1553 template <typename T>
1554 struct ConversionBase<T, ConvTraits::kExplicit> {
operator T__anon4f341b710111::ConversionBase1555 explicit operator T() const& { return t; }
operator T__anon4f341b710111::ConversionBase1556 explicit operator T() && { return std::move(t); }
1557 T t;
1558 };
1559
1560 // This class has conversion operator to `absl::Status` based on the value of
1561 // `conv_traits`.
1562 template <ConvTraits conv_traits = ConvTraits::kNone>
1563 struct StatusConversionBase {};
1564
1565 template <>
1566 struct StatusConversionBase<ConvTraits::kImplicit> {
operator absl::Status__anon4f341b710111::StatusConversionBase1567 operator absl::Status() const& { // NOLINT
1568 return absl::InternalError("conversion to Status");
1569 }
operator absl::Status__anon4f341b710111::StatusConversionBase1570 operator absl::Status() && { // NOLINT
1571 return absl::InternalError("conversion to Status");
1572 }
1573 };
1574
1575 template <>
1576 struct StatusConversionBase<ConvTraits::kExplicit> {
operator absl::Status__anon4f341b710111::StatusConversionBase1577 explicit operator absl::Status() const& { // NOLINT
1578 return absl::InternalError("conversion to Status");
1579 }
operator absl::Status__anon4f341b710111::StatusConversionBase1580 explicit operator absl::Status() && { // NOLINT
1581 return absl::InternalError("conversion to Status");
1582 }
1583 };
1584
1585 static constexpr int kConvToStatus = 1;
1586 static constexpr int kConvToStatusOr = 2;
1587 static constexpr int kConvToT = 4;
1588 static constexpr int kConvExplicit = 8;
1589
GetConvTraits(int bit,int config)1590 constexpr ConvTraits GetConvTraits(int bit, int config) {
1591 return (config & bit) == 0
1592 ? ConvTraits::kNone
1593 : ((config & kConvExplicit) == 0 ? ConvTraits::kImplicit
1594 : ConvTraits::kExplicit);
1595 }
1596
1597 // This class conditionally has conversion operator to `absl::Status`, `T`,
1598 // `StatusOr<T>`, based on values of the template parameters.
1599 template <typename T, int config>
1600 struct CustomType
1601 : StatusOrConversionBase<T, GetConvTraits(kConvToStatusOr, config)>,
1602 ConversionBase<T, GetConvTraits(kConvToT, config)>,
1603 StatusConversionBase<GetConvTraits(kConvToStatus, config)> {};
1604
1605 struct ConvertibleToAnyStatusOr {
1606 template <typename T>
operator absl::StatusOr<T>__anon4f341b710111::ConvertibleToAnyStatusOr1607 operator absl::StatusOr<T>() const { // NOLINT
1608 return absl::InvalidArgumentError("Conversion to absl::StatusOr");
1609 }
1610 };
1611
1612 // Test the rank of overload resolution for `StatusOr<T>` constructor and
1613 // assignment, from highest to lowest:
1614 // 1. T/Status
1615 // 2. U that has conversion operator to absl::StatusOr<T>
1616 // 3. U that is convertible to Status
1617 // 4. U that is convertible to T
TEST(StatusOr,ConstructionFromT)1618 TEST(StatusOr, ConstructionFromT) {
1619 // Construct absl::StatusOr<T> from T when T is convertible to
1620 // absl::StatusOr<T>
1621 {
1622 ConvertibleToAnyStatusOr v;
1623 absl::StatusOr<ConvertibleToAnyStatusOr> statusor(v);
1624 EXPECT_TRUE(statusor.ok());
1625 }
1626 {
1627 ConvertibleToAnyStatusOr v;
1628 absl::StatusOr<ConvertibleToAnyStatusOr> statusor = v;
1629 EXPECT_TRUE(statusor.ok());
1630 }
1631 // Construct absl::StatusOr<T> from T when T is explicitly convertible to
1632 // Status
1633 {
1634 CustomType<MyType, kConvToStatus | kConvExplicit> v;
1635 absl::StatusOr<CustomType<MyType, kConvToStatus | kConvExplicit>> statusor(
1636 v);
1637 EXPECT_TRUE(statusor.ok());
1638 }
1639 {
1640 CustomType<MyType, kConvToStatus | kConvExplicit> v;
1641 absl::StatusOr<CustomType<MyType, kConvToStatus | kConvExplicit>> statusor =
1642 v;
1643 EXPECT_TRUE(statusor.ok());
1644 }
1645 }
1646
1647 // Construct absl::StatusOr<T> from U when U is explicitly convertible to T
TEST(StatusOr,ConstructionFromTypeConvertibleToT)1648 TEST(StatusOr, ConstructionFromTypeConvertibleToT) {
1649 {
1650 CustomType<MyType, kConvToT | kConvExplicit> v;
1651 absl::StatusOr<MyType> statusor(v);
1652 EXPECT_TRUE(statusor.ok());
1653 }
1654 {
1655 CustomType<MyType, kConvToT> v;
1656 absl::StatusOr<MyType> statusor = v;
1657 EXPECT_TRUE(statusor.ok());
1658 }
1659 }
1660
1661 // Construct absl::StatusOr<T> from U when U has explicit conversion operator to
1662 // absl::StatusOr<T>
TEST(StatusOr,ConstructionFromTypeWithConversionOperatorToStatusOrT)1663 TEST(StatusOr, ConstructionFromTypeWithConversionOperatorToStatusOrT) {
1664 {
1665 CustomType<MyType, kConvToStatusOr | kConvExplicit> v;
1666 absl::StatusOr<MyType> statusor(v);
1667 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
1668 }
1669 {
1670 CustomType<MyType, kConvToT | kConvToStatusOr | kConvExplicit> v;
1671 absl::StatusOr<MyType> statusor(v);
1672 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
1673 }
1674 {
1675 CustomType<MyType, kConvToStatusOr | kConvToStatus | kConvExplicit> v;
1676 absl::StatusOr<MyType> statusor(v);
1677 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
1678 }
1679 {
1680 CustomType<MyType,
1681 kConvToT | kConvToStatusOr | kConvToStatus | kConvExplicit>
1682 v;
1683 absl::StatusOr<MyType> statusor(v);
1684 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
1685 }
1686 {
1687 CustomType<MyType, kConvToStatusOr> v;
1688 absl::StatusOr<MyType> statusor = v;
1689 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
1690 }
1691 {
1692 CustomType<MyType, kConvToT | kConvToStatusOr> v;
1693 absl::StatusOr<MyType> statusor = v;
1694 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
1695 }
1696 {
1697 CustomType<MyType, kConvToStatusOr | kConvToStatus> v;
1698 absl::StatusOr<MyType> statusor = v;
1699 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
1700 }
1701 {
1702 CustomType<MyType, kConvToT | kConvToStatusOr | kConvToStatus> v;
1703 absl::StatusOr<MyType> statusor = v;
1704 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
1705 }
1706 }
1707
TEST(StatusOr,ConstructionFromTypeConvertibleToStatus)1708 TEST(StatusOr, ConstructionFromTypeConvertibleToStatus) {
1709 // Construction fails because conversion to `Status` is explicit.
1710 {
1711 CustomType<MyType, kConvToStatus | kConvExplicit> v;
1712 absl::StatusOr<MyType> statusor(v);
1713 EXPECT_FALSE(statusor.ok());
1714 EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v));
1715 }
1716 {
1717 CustomType<MyType, kConvToT | kConvToStatus | kConvExplicit> v;
1718 absl::StatusOr<MyType> statusor(v);
1719 EXPECT_FALSE(statusor.ok());
1720 EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v));
1721 }
1722 {
1723 CustomType<MyType, kConvToStatus> v;
1724 absl::StatusOr<MyType> statusor = v;
1725 EXPECT_FALSE(statusor.ok());
1726 EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v));
1727 }
1728 {
1729 CustomType<MyType, kConvToT | kConvToStatus> v;
1730 absl::StatusOr<MyType> statusor = v;
1731 EXPECT_FALSE(statusor.ok());
1732 EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v));
1733 }
1734 }
1735
TEST(StatusOr,AssignmentFromT)1736 TEST(StatusOr, AssignmentFromT) {
1737 // Assign to absl::StatusOr<T> from T when T is convertible to
1738 // absl::StatusOr<T>
1739 {
1740 ConvertibleToAnyStatusOr v;
1741 absl::StatusOr<ConvertibleToAnyStatusOr> statusor;
1742 statusor = v;
1743 EXPECT_TRUE(statusor.ok());
1744 }
1745 // Assign to absl::StatusOr<T> from T when T is convertible to Status
1746 {
1747 CustomType<MyType, kConvToStatus> v;
1748 absl::StatusOr<CustomType<MyType, kConvToStatus>> statusor;
1749 statusor = v;
1750 EXPECT_TRUE(statusor.ok());
1751 }
1752 }
1753
TEST(StatusOr,AssignmentFromTypeConvertibleToT)1754 TEST(StatusOr, AssignmentFromTypeConvertibleToT) {
1755 // Assign to absl::StatusOr<T> from U when U is convertible to T
1756 {
1757 CustomType<MyType, kConvToT> v;
1758 absl::StatusOr<MyType> statusor;
1759 statusor = v;
1760 EXPECT_TRUE(statusor.ok());
1761 }
1762 }
1763
TEST(StatusOr,AssignmentFromTypeWithConversionOperatortoStatusOrT)1764 TEST(StatusOr, AssignmentFromTypeWithConversionOperatortoStatusOrT) {
1765 // Assign to absl::StatusOr<T> from U when U has conversion operator to
1766 // absl::StatusOr<T>
1767 {
1768 CustomType<MyType, kConvToStatusOr> v;
1769 absl::StatusOr<MyType> statusor;
1770 statusor = v;
1771 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
1772 }
1773 {
1774 CustomType<MyType, kConvToT | kConvToStatusOr> v;
1775 absl::StatusOr<MyType> statusor;
1776 statusor = v;
1777 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
1778 }
1779 {
1780 CustomType<MyType, kConvToStatusOr | kConvToStatus> v;
1781 absl::StatusOr<MyType> statusor;
1782 statusor = v;
1783 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
1784 }
1785 {
1786 CustomType<MyType, kConvToT | kConvToStatusOr | kConvToStatus> v;
1787 absl::StatusOr<MyType> statusor;
1788 statusor = v;
1789 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
1790 }
1791 }
1792
TEST(StatusOr,AssignmentFromTypeConvertibleToStatus)1793 TEST(StatusOr, AssignmentFromTypeConvertibleToStatus) {
1794 // Assign to absl::StatusOr<T> from U when U is convertible to Status
1795 {
1796 CustomType<MyType, kConvToStatus> v;
1797 absl::StatusOr<MyType> statusor;
1798 statusor = v;
1799 EXPECT_FALSE(statusor.ok());
1800 EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v));
1801 }
1802 {
1803 CustomType<MyType, kConvToT | kConvToStatus> v;
1804 absl::StatusOr<MyType> statusor;
1805 statusor = v;
1806 EXPECT_FALSE(statusor.ok());
1807 EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v));
1808 }
1809 }
1810
1811 } // namespace
1812