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