1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/types/expected.h"
6
7 #include <string>
8 #include <utility>
9 #include <vector>
10
11 #include "base/containers/contains.h"
12 #include "base/strings/to_string.h"
13 #include "base/test/gmock_expected_support.h"
14 #include "base/test/gtest_util.h"
15 #include "base/types/strong_alias.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace base {
20
21 namespace {
22
23 // Additional restrictions on implicit conversions. Not present in the C++23
24 // proposal.
25 static_assert(!std::is_convertible_v<int, expected<int, int>>);
26 static_assert(!std::is_convertible_v<long, expected<bool, long>>);
27
28 template <typename T>
29 struct Strong {
Strongbase::__anon58130c120111::Strong30 constexpr explicit Strong(T value) : value(std::move(value)) {}
31 T value;
32 };
33
34 template <typename T>
35 struct Weak {
36 // NOLINTNEXTLINE(google-explicit-constructor)
Weakbase::__anon58130c120111::Weak37 constexpr Weak(T value) : value(std::move(value)) {}
38 T value;
39 };
40
41 template <typename T>
42 struct StrongMoveOnly {
StrongMoveOnlybase::__anon58130c120111::StrongMoveOnly43 constexpr explicit StrongMoveOnly(T&& value) : value(std::move(value)) {}
StrongMoveOnlybase::__anon58130c120111::StrongMoveOnly44 constexpr StrongMoveOnly(StrongMoveOnly&& other)
45 : value(std::exchange(other.value, {})) {}
46
operator =base::__anon58130c120111::StrongMoveOnly47 constexpr StrongMoveOnly& operator=(StrongMoveOnly&& other) {
48 value = std::exchange(other.value, {});
49 return *this;
50 }
51
52 T value;
53 };
54
55 template <typename T>
56 struct WeakMoveOnly {
57 // NOLINTNEXTLINE(google-explicit-constructor)
WeakMoveOnlybase::__anon58130c120111::WeakMoveOnly58 constexpr WeakMoveOnly(T&& value) : value(std::move(value)) {}
WeakMoveOnlybase::__anon58130c120111::WeakMoveOnly59 constexpr WeakMoveOnly(WeakMoveOnly&& other)
60 : value(std::exchange(other.value, {})) {}
61 T value;
62 };
63
64 enum class Error {
65 kFail,
66 };
67
68 enum class CvRef {
69 kNone,
70 kRef,
71 kConstRef,
72 kRRef,
73 kConstRRef,
74 };
75
76 struct SaveCvRef {
77 constexpr SaveCvRef() = default;
SaveCvRefbase::__anon58130c120111::SaveCvRef78 constexpr SaveCvRef(SaveCvRef&) : cvref(CvRef::kRef) {}
SaveCvRefbase::__anon58130c120111::SaveCvRef79 constexpr SaveCvRef(const SaveCvRef&) : cvref(CvRef::kConstRef) {}
SaveCvRefbase::__anon58130c120111::SaveCvRef80 constexpr SaveCvRef(SaveCvRef&&) : cvref(CvRef::kRRef) {}
SaveCvRefbase::__anon58130c120111::SaveCvRef81 constexpr SaveCvRef(const SaveCvRef&&) : cvref(CvRef::kConstRRef) {}
82
SaveCvRefbase::__anon58130c120111::SaveCvRef83 constexpr explicit SaveCvRef(CvRef cvref) : cvref(cvref) {}
84
85 CvRef cvref = CvRef::kNone;
86 };
87
TEST(Ok,ValueConstructor)88 TEST(Ok, ValueConstructor) {
89 constexpr ok<int> o(42);
90 static_assert(o.value() == 42);
91 }
92
TEST(Ok,DefaultConstructor)93 TEST(Ok, DefaultConstructor) {
94 constexpr ok<int> o(absl::in_place);
95 static_assert(o.value() == 0);
96 }
97
TEST(Ok,InPlaceConstructor)98 TEST(Ok, InPlaceConstructor) {
99 constexpr ok<std::pair<int, double>> o(absl::in_place, 42, 3.14);
100 static_assert(o.value() == std::pair(42, 3.14));
101 }
102
TEST(Ok,InPlaceListConstructor)103 TEST(Ok, InPlaceListConstructor) {
104 ok<std::vector<int>> o(absl::in_place, {1, 2, 3});
105 EXPECT_EQ(o.value(), std::vector({1, 2, 3}));
106 }
107
TEST(Ok,ValueIsQualified)108 TEST(Ok, ValueIsQualified) {
109 using Ok = ok<int>;
110 static_assert(std::is_same_v<decltype(std::declval<Ok&>().value()), int&>);
111 static_assert(
112 std::is_same_v<decltype(std::declval<const Ok&>().value()), const int&>);
113 static_assert(std::is_same_v<decltype(std::declval<Ok>().value()), int&&>);
114 static_assert(
115 std::is_same_v<decltype(std::declval<const Ok>().value()), const int&&>);
116 }
117
TEST(Ok,MemberSwap)118 TEST(Ok, MemberSwap) {
119 ok o1(42);
120 ok o2(123);
121 o1.swap(o2);
122
123 EXPECT_EQ(o1.value(), 123);
124 EXPECT_EQ(o2.value(), 42);
125 }
126
TEST(Ok,EqualityOperators)127 TEST(Ok, EqualityOperators) {
128 static_assert(ok(42) == ok(42.0));
129 static_assert(ok(42) != ok(43));
130 }
131
TEST(Ok,FreeSwap)132 TEST(Ok, FreeSwap) {
133 ok o1(42);
134 ok o2(123);
135 swap(o1, o2);
136
137 EXPECT_EQ(o1.value(), 123);
138 EXPECT_EQ(o2.value(), 42);
139 }
140
TEST(Unexpected,ValueConstructor)141 TEST(Unexpected, ValueConstructor) {
142 constexpr unexpected<int> unex(42);
143 static_assert(unex.error() == 42);
144 }
145
TEST(Unexpected,DefaultConstructor)146 TEST(Unexpected, DefaultConstructor) {
147 constexpr unexpected<int> unex(absl::in_place);
148 static_assert(unex.error() == 0);
149 }
150
TEST(Unexpected,InPlaceConstructor)151 TEST(Unexpected, InPlaceConstructor) {
152 constexpr unexpected<std::pair<int, double>> unex(absl::in_place, 42, 3.14);
153 static_assert(unex.error() == std::pair(42, 3.14));
154 }
155
TEST(Unexpected,InPlaceListConstructor)156 TEST(Unexpected, InPlaceListConstructor) {
157 unexpected<std::vector<int>> unex(absl::in_place, {1, 2, 3});
158 EXPECT_EQ(unex.error(), std::vector({1, 2, 3}));
159 }
160
TEST(Unexpected,ErrorIsQualified)161 TEST(Unexpected, ErrorIsQualified) {
162 using Unex = unexpected<int>;
163 static_assert(std::is_same_v<decltype(std::declval<Unex&>().error()), int&>);
164 static_assert(std::is_same_v<decltype(std::declval<const Unex&>().error()),
165 const int&>);
166 static_assert(std::is_same_v<decltype(std::declval<Unex>().error()), int&&>);
167 static_assert(std::is_same_v<decltype(std::declval<const Unex>().error()),
168 const int&&>);
169 }
170
TEST(Unexpected,MemberSwap)171 TEST(Unexpected, MemberSwap) {
172 unexpected u1(42);
173 unexpected u2(123);
174 u1.swap(u2);
175
176 EXPECT_EQ(u1.error(), 123);
177 EXPECT_EQ(u2.error(), 42);
178 }
179
TEST(Unexpected,EqualityOperators)180 TEST(Unexpected, EqualityOperators) {
181 static_assert(unexpected(42) == unexpected(42.0));
182 static_assert(unexpected(42) != unexpected(43));
183 }
184
TEST(Unexpected,FreeSwap)185 TEST(Unexpected, FreeSwap) {
186 unexpected u1(42);
187 unexpected u2(123);
188 swap(u1, u2);
189
190 EXPECT_EQ(u1.error(), 123);
191 EXPECT_EQ(u2.error(), 42);
192 }
193
TEST(Expected,Triviality)194 TEST(Expected, Triviality) {
195 using TrivialExpected = expected<int, Error>;
196 static_assert(std::is_trivially_destructible_v<TrivialExpected>);
197
198 using NonTrivialExpected = expected<int, std::string>;
199 static_assert(!std::is_trivially_destructible_v<NonTrivialExpected>);
200 }
201
TEST(Expected,DefaultConstructor)202 TEST(Expected, DefaultConstructor) {
203 constexpr expected<int, Error> ex;
204 static_assert(ex.has_value());
205 EXPECT_EQ(ex.value(), 0);
206
207 static_assert(std::is_default_constructible_v<expected<int, Error>>);
208 static_assert(!std::is_default_constructible_v<expected<Strong<int>, Error>>);
209 }
210
TEST(Expected,CopyConstructor)211 TEST(Expected, CopyConstructor) {
212 {
213 constexpr expected<int, Error> ex1 = 42;
214 constexpr expected<int, Error> ex2 = ex1;
215 static_assert(ex2.has_value());
216 // Note: In theory this could be constexpr, but is currently not due to
217 // implementation details of absl::get [1].
218 // TODO: Make this a static_assert once this is fixed in Abseil, or we use
219 // std::variant. Similarly in the tests below.
220 // [1] https://github.com/abseil/abseil-cpp/blob/50739/absl/types/internal/variant.h#L548
221 EXPECT_EQ(ex2.value(), 42);
222 }
223
224 {
225 constexpr expected<int, Error> ex1 = unexpected(Error::kFail);
226 constexpr expected<int, Error> ex2 = ex1;
227 static_assert(!ex2.has_value());
228 EXPECT_EQ(ex2.error(), Error::kFail);
229 }
230 }
231
TEST(Expected,MoveConstructor)232 TEST(Expected, MoveConstructor) {
233 {
234 expected<StrongMoveOnly<int>, int> ex1 = StrongMoveOnly(42);
235 expected<StrongMoveOnly<int>, int> ex2 = std::move(ex1);
236 ASSERT_TRUE(ex2.has_value());
237 EXPECT_EQ(ex2.value().value, 42);
238 }
239
240 {
241 expected<int, StrongMoveOnly<int>> ex1 = unexpected(StrongMoveOnly(42));
242 expected<int, StrongMoveOnly<int>> ex2 = std::move(ex1);
243 ASSERT_FALSE(ex2.has_value());
244 EXPECT_EQ(ex2.error().value, 42);
245 }
246 }
247
TEST(Expected,ExplicitConvertingCopyConstructor)248 TEST(Expected, ExplicitConvertingCopyConstructor) {
249 {
250 expected<int, Error> ex1 = 42;
251 expected<Strong<int>, Error> ex2(ex1);
252 static_assert(!std::is_convertible_v<decltype(ex1), decltype(ex2)>);
253 ASSERT_TRUE(ex2.has_value());
254 EXPECT_EQ(ex2.value().value, 42);
255 }
256
257 {
258 expected<int, Error> ex1 = unexpected(Error::kFail);
259 expected<int, Strong<Error>> ex2(ex1);
260 static_assert(!std::is_convertible_v<decltype(ex1), decltype(ex2)>);
261 ASSERT_FALSE(ex2.has_value());
262 EXPECT_EQ(ex2.error().value, Error::kFail);
263 }
264 }
265
TEST(Expected,ImplicitConvertingCopyConstructor)266 TEST(Expected, ImplicitConvertingCopyConstructor) {
267 {
268 expected<int, Error> ex1 = 42;
269 expected<Weak<int>, Weak<Error>> ex2 = ex1;
270 ASSERT_TRUE(ex2.has_value());
271 EXPECT_EQ(ex2.value().value, 42);
272 }
273 {
274 expected<int, Error> ex1 = unexpected(Error::kFail);
275 expected<Weak<int>, Weak<Error>> ex2 = ex1;
276 ASSERT_FALSE(ex2.has_value());
277 EXPECT_EQ(ex2.error().value, Error::kFail);
278 }
279 }
280
TEST(Expected,ExplicitConvertingMoveConstructor)281 TEST(Expected, ExplicitConvertingMoveConstructor) {
282 {
283 expected<int, Error> ex1 = 42;
284 expected<StrongMoveOnly<int>, Error> ex2(std::move(ex1));
285 static_assert(
286 !std::is_convertible_v<decltype(std::move(ex1)), decltype(ex2)>);
287 ASSERT_TRUE(ex2.has_value());
288 EXPECT_EQ(ex2.value().value, 42);
289 }
290
291 {
292 expected<int, Error> ex1 = unexpected(Error::kFail);
293 expected<int, StrongMoveOnly<Error>> ex2(std::move(ex1));
294 static_assert(
295 !std::is_convertible_v<decltype(std::move(ex1)), decltype(ex2)>);
296 ASSERT_FALSE(ex2.has_value());
297 EXPECT_EQ(ex2.error().value, Error::kFail);
298 }
299 }
300
TEST(Expected,ImplicitConvertingMoveConstructor)301 TEST(Expected, ImplicitConvertingMoveConstructor) {
302 {
303 expected<int, Error> ex1 = 42;
304 expected<WeakMoveOnly<int>, Error> ex2 = std::move(ex1);
305 ASSERT_TRUE(ex2.has_value());
306 EXPECT_EQ(ex2.value().value, 42);
307 }
308
309 {
310 expected<int, Error> ex1 = unexpected(Error::kFail);
311 expected<int, WeakMoveOnly<Error>> ex2 = std::move(ex1);
312 ASSERT_FALSE(ex2.has_value());
313 EXPECT_EQ(ex2.error().value, Error::kFail);
314 }
315 }
316
TEST(Expected,ExplicitValueConstructor)317 TEST(Expected, ExplicitValueConstructor) {
318 {
319 constexpr expected<Strong<int>, int> ex(42);
320 static_assert(!std::is_convertible_v<int, decltype(ex)>);
321 static_assert(ex.has_value());
322 EXPECT_EQ(ex.value().value, 42);
323 }
324
325 {
326 constexpr expected<StrongMoveOnly<int>, int> ex(42);
327 static_assert(!std::is_constructible_v<decltype(ex), int&>);
328 static_assert(!std::is_convertible_v<int, decltype(ex)>);
329 static_assert(ex.has_value());
330 EXPECT_EQ(ex.value().value, 42);
331 }
332 }
333
TEST(Expected,ImplicitValueConstructor)334 TEST(Expected, ImplicitValueConstructor) {
335 {
336 constexpr expected<Weak<int>, Error> ex = 42;
337 static_assert(ex.has_value());
338 EXPECT_EQ(ex.value().value, 42);
339 }
340
341 {
342 constexpr expected<WeakMoveOnly<int>, Error> ex = 42;
343 static_assert(!std::is_convertible_v<int&, decltype(ex)>);
344 static_assert(ex.has_value());
345 EXPECT_EQ(ex.value().value, 42);
346 }
347 }
348
TEST(Expected,ExplicitOkConstructor)349 TEST(Expected, ExplicitOkConstructor) {
350 {
351 constexpr expected<Strong<int>, int> ex(ok(42));
352 static_assert(!std::is_convertible_v<ok<int>, decltype(ex)>);
353 static_assert(ex.has_value());
354 EXPECT_EQ(ex.value().value, 42);
355 }
356
357 {
358 constexpr expected<StrongMoveOnly<int>, int> ex(ok(42));
359 static_assert(!std::is_constructible_v<decltype(ex), ok<int>&>);
360 static_assert(!std::is_convertible_v<ok<int>, decltype(ex)>);
361 static_assert(ex.has_value());
362 EXPECT_EQ(ex.value().value, 42);
363 }
364 }
365
TEST(Expected,ImplicitOkConstructor)366 TEST(Expected, ImplicitOkConstructor) {
367 {
368 constexpr expected<Weak<int>, Error> ex = ok(42);
369 static_assert(ex.has_value());
370 EXPECT_EQ(ex.value().value, 42);
371 }
372
373 {
374 constexpr expected<WeakMoveOnly<int>, Error> ex = ok(42);
375 static_assert(!std::is_convertible_v<ok<int>&, decltype(ex)>);
376 static_assert(ex.has_value());
377 EXPECT_EQ(ex.value().value, 42);
378 }
379 }
380
TEST(Expected,ExplicitErrorConstructor)381 TEST(Expected, ExplicitErrorConstructor) {
382 {
383 constexpr expected<int, Strong<int>> ex(unexpected(42));
384 static_assert(!std::is_convertible_v<unexpected<int>, decltype(ex)>);
385 static_assert(!ex.has_value());
386 EXPECT_EQ(ex.error().value, 42);
387 }
388
389 {
390 constexpr expected<int, StrongMoveOnly<int>> ex(unexpected(42));
391 static_assert(!std::is_constructible_v<decltype(ex), unexpected<int>&>);
392 static_assert(!std::is_convertible_v<unexpected<int>, decltype(ex)>);
393 static_assert(!ex.has_value());
394 EXPECT_EQ(ex.error().value, 42);
395 }
396 }
397
TEST(Expected,ImplicitErrorConstructor)398 TEST(Expected, ImplicitErrorConstructor) {
399 {
400 constexpr expected<int, Weak<int>> ex = unexpected(42);
401 static_assert(!ex.has_value());
402 EXPECT_EQ(ex.error().value, 42);
403 }
404
405 {
406 constexpr expected<int, WeakMoveOnly<int>> ex = unexpected(42);
407 static_assert(!std::is_convertible_v<unexpected<int>&, decltype(ex)>);
408 static_assert(!ex.has_value());
409 EXPECT_EQ(ex.error().value, 42);
410 }
411 }
412
TEST(Expected,InPlaceConstructor)413 TEST(Expected, InPlaceConstructor) {
414 constexpr expected<Strong<int>, int> ex(absl::in_place, 42);
415 static_assert(ex.has_value());
416 EXPECT_EQ(ex.value().value, 42);
417 }
418
TEST(Expected,InPlaceListConstructor)419 TEST(Expected, InPlaceListConstructor) {
420 expected<std::vector<int>, int> ex(absl::in_place, {1, 2, 3});
421 EXPECT_THAT(ex, test::ValueIs(std::vector({1, 2, 3})));
422 }
423
TEST(Expected,UnexpectConstructor)424 TEST(Expected, UnexpectConstructor) {
425 constexpr expected<int, Strong<int>> ex(unexpect, 42);
426 static_assert(!ex.has_value());
427 EXPECT_EQ(ex.error().value, 42);
428 }
429
TEST(Expected,UnexpectListConstructor)430 TEST(Expected, UnexpectListConstructor) {
431 expected<int, std::vector<int>> ex(unexpect, {1, 2, 3});
432 EXPECT_THAT(ex, test::ErrorIs(std::vector({1, 2, 3})));
433 }
434
TEST(Expected,AssignValue)435 TEST(Expected, AssignValue) {
436 expected<int, int> ex = unexpected(0);
437 EXPECT_FALSE(ex.has_value());
438
439 ex = 42;
440 EXPECT_THAT(ex, test::ValueIs(42));
441
442 ex = 123;
443 EXPECT_THAT(ex, test::ValueIs(123));
444 }
445
TEST(Expected,CopyAssignOk)446 TEST(Expected, CopyAssignOk) {
447 expected<int, int> ex = unexpected(0);
448 EXPECT_FALSE(ex.has_value());
449
450 ex = ok(42);
451 EXPECT_THAT(ex, test::ValueIs(42));
452
453 ex = ok(123);
454 EXPECT_THAT(ex, test::ValueIs(123));
455 }
456
TEST(Expected,MoveAssignOk)457 TEST(Expected, MoveAssignOk) {
458 expected<StrongMoveOnly<int>, int> ex = unexpected(0);
459 EXPECT_FALSE(ex.has_value());
460
461 ex = ok(StrongMoveOnly(42));
462 ASSERT_TRUE(ex.has_value());
463 EXPECT_EQ(ex.value().value, 42);
464
465 ex = ok(StrongMoveOnly(123));
466 ASSERT_TRUE(ex.has_value());
467 EXPECT_EQ(ex.value().value, 123);
468 }
469
TEST(Expected,CopyAssignUnexpected)470 TEST(Expected, CopyAssignUnexpected) {
471 expected<int, int> ex;
472 EXPECT_TRUE(ex.has_value());
473
474 ex = unexpected(42);
475 EXPECT_THAT(ex, test::ErrorIs(42));
476
477 ex = unexpected(123);
478 EXPECT_THAT(ex, test::ErrorIs(123));
479 }
480
TEST(Expected,MoveAssignUnexpected)481 TEST(Expected, MoveAssignUnexpected) {
482 expected<int, StrongMoveOnly<int>> ex;
483 EXPECT_TRUE(ex.has_value());
484
485 ex = unexpected(StrongMoveOnly(42));
486 ASSERT_FALSE(ex.has_value());
487 EXPECT_EQ(ex.error().value, 42);
488
489 ex = unexpected(StrongMoveOnly(123));
490 ASSERT_FALSE(ex.has_value());
491 EXPECT_EQ(ex.error().value, 123);
492 }
493
TEST(Expected,Emplace)494 TEST(Expected, Emplace) {
495 expected<StrongMoveOnly<int>, int> ex = unexpected(0);
496 EXPECT_FALSE(ex.has_value());
497
498 ex.emplace(42);
499 ASSERT_TRUE(ex.has_value());
500 EXPECT_EQ(ex.value().value, 42);
501 }
502
TEST(Expected,EmplaceList)503 TEST(Expected, EmplaceList) {
504 expected<std::vector<int>, int> ex = unexpected(0);
505 EXPECT_FALSE(ex.has_value());
506
507 ex.emplace({1, 2, 3});
508 EXPECT_THAT(ex, test::ValueIs(std::vector({1, 2, 3})));
509 }
510
TEST(Expected,MemberSwap)511 TEST(Expected, MemberSwap) {
512 expected<int, int> ex1(42);
513 expected<int, int> ex2 = unexpected(123);
514
515 ex1.swap(ex2);
516 EXPECT_THAT(ex1, test::ErrorIs(123));
517 EXPECT_THAT(ex2, test::ValueIs(42));
518 }
519
TEST(Expected,FreeSwap)520 TEST(Expected, FreeSwap) {
521 expected<int, int> ex1(42);
522 expected<int, int> ex2 = unexpected(123);
523
524 swap(ex1, ex2);
525 EXPECT_THAT(ex1, test::ErrorIs(123));
526 EXPECT_THAT(ex2, test::ValueIs(42));
527 }
528
TEST(Expected,OperatorArrow)529 TEST(Expected, OperatorArrow) {
530 expected<Strong<int>, int> ex(0);
531 EXPECT_EQ(ex->value, 0);
532
533 ex->value = 1;
534 EXPECT_EQ(ex->value, 1);
535
536 constexpr expected<Strong<int>, int> c_ex(0);
537 EXPECT_EQ(c_ex->value, 0);
538 static_assert(std::is_same_v<decltype((c_ex->value)), const int&>);
539 }
540
TEST(Expected,OperatorStar)541 TEST(Expected, OperatorStar) {
542 expected<int, int> ex;
543 EXPECT_EQ(*ex, 0);
544
545 *ex = 1;
546 EXPECT_EQ(*ex, 1);
547
548 using Ex = expected<int, int>;
549 static_assert(std::is_same_v<decltype(*std::declval<Ex&>()), int&>);
550 static_assert(
551 std::is_same_v<decltype(*std::declval<const Ex&>()), const int&>);
552 static_assert(std::is_same_v<decltype(*std::declval<Ex&&>()), int&&>);
553 static_assert(
554 std::is_same_v<decltype(*std::declval<const Ex&&>()), const int&&>);
555 }
556
TEST(Expected,HasValue)557 TEST(Expected, HasValue) {
558 constexpr expected<int, int> ex;
559 static_assert(ex.has_value());
560
561 constexpr expected<int, int> unex = unexpected(0);
562 static_assert(!unex.has_value());
563 }
564
TEST(Expected,Value)565 TEST(Expected, Value) {
566 expected<int, int> ex;
567 EXPECT_EQ(ex.value(), 0);
568
569 ex.value() = 1;
570 EXPECT_EQ(ex.value(), 1);
571
572 using Ex = expected<int, int>;
573 static_assert(std::is_same_v<decltype(std::declval<Ex&>().value()), int&>);
574 static_assert(
575 std::is_same_v<decltype(std::declval<const Ex&>().value()), const int&>);
576 static_assert(std::is_same_v<decltype(std::declval<Ex&&>().value()), int&&>);
577 static_assert(std::is_same_v<decltype(std::declval<const Ex&&>().value()),
578 const int&&>);
579 }
580
TEST(Expected,Error)581 TEST(Expected, Error) {
582 expected<int, int> ex = unexpected(0);
583 EXPECT_EQ(ex.error(), 0);
584
585 ex.error() = 1;
586 EXPECT_EQ(ex.error(), 1);
587
588 using Ex = expected<int, int>;
589 static_assert(std::is_same_v<decltype(std::declval<Ex&>().error()), int&>);
590 static_assert(
591 std::is_same_v<decltype(std::declval<const Ex&>().error()), const int&>);
592 static_assert(std::is_same_v<decltype(std::declval<Ex&&>().error()), int&&>);
593 static_assert(std::is_same_v<decltype(std::declval<const Ex&&>().error()),
594 const int&&>);
595 }
596
TEST(Expected,ToString)597 TEST(Expected, ToString) {
598 // `expected` should have a custom string representation that prints the
599 // contained value/error.
600 const std::string value_str = ToString(expected<int, int>(123456));
601 EXPECT_FALSE(base::Contains(value_str, "-byte object at "));
602 EXPECT_TRUE(base::Contains(value_str, "123456"));
603 const std::string error_str =
604 ToString(expected<int, int>(unexpected(123456)));
605 EXPECT_FALSE(base::Contains(error_str, "-byte object at "));
606 EXPECT_TRUE(base::Contains(error_str, "123456"));
607 }
608
TEST(Expected,ValueOr)609 TEST(Expected, ValueOr) {
610 {
611 expected<int, int> ex;
612 EXPECT_EQ(ex.value_or(123), 0);
613
614 expected<int, int> unex = unexpected(0);
615 EXPECT_EQ(unex.value_or(123), 123);
616 }
617
618 {
619 expected<WeakMoveOnly<int>, int> ex(0);
620 EXPECT_EQ(std::move(ex).value_or(123).value, 0);
621
622 expected<WeakMoveOnly<int>, int> unex = unexpected(0);
623 EXPECT_EQ(std::move(unex).value_or(123).value, 123);
624 }
625 }
626
TEST(Expected,ErrorOr)627 TEST(Expected, ErrorOr) {
628 {
629 expected<int, int> ex;
630 EXPECT_EQ(ex.error_or(123), 123);
631
632 expected<int, int> unex = unexpected(0);
633 EXPECT_EQ(unex.error_or(123), 0);
634 }
635
636 {
637 expected<int, WeakMoveOnly<int>> ex(0);
638 EXPECT_EQ(std::move(ex).error_or(123).value, 123);
639
640 expected<int, WeakMoveOnly<int>> unex = unexpected(0);
641 EXPECT_EQ(std::move(unex).error_or(123).value, 0);
642 }
643 }
644
TEST(Expected,AndThen)645 TEST(Expected, AndThen) {
646 using ExIn = expected<SaveCvRef, SaveCvRef>;
647 using ExOut = expected<CvRef, SaveCvRef>;
648
649 auto get_ex_cvref = [](auto&& x) -> ExOut {
650 return SaveCvRef(std::forward<decltype(x)>(x)).cvref;
651 };
652
653 ExIn ex;
654 EXPECT_EQ(ex.and_then(get_ex_cvref), CvRef::kRef);
655 EXPECT_EQ(std::as_const(ex).and_then(get_ex_cvref), CvRef::kConstRef);
656 EXPECT_EQ(std::move(ex).and_then(get_ex_cvref), CvRef::kRRef);
657 EXPECT_EQ(std::move(std::as_const(ex)).and_then(get_ex_cvref),
658 CvRef::kConstRRef);
659
660 ExIn unex(unexpect);
661 EXPECT_EQ(unex.and_then(get_ex_cvref).error().cvref, CvRef::kRef);
662 EXPECT_EQ(std::as_const(unex).and_then(get_ex_cvref).error().cvref,
663 CvRef::kConstRef);
664 EXPECT_EQ(std::move(unex).and_then(get_ex_cvref).error().cvref, CvRef::kRRef);
665 EXPECT_EQ(std::move(std::as_const(unex)).and_then(get_ex_cvref).error().cvref,
666 CvRef::kConstRRef);
667
668 static_assert(
669 std::is_same_v<decltype(std::declval<ExIn&>().and_then(get_ex_cvref)),
670 ExOut>);
671 static_assert(
672 std::is_same_v<
673 decltype(std::declval<const ExIn&>().and_then(get_ex_cvref)), ExOut>);
674 static_assert(
675 std::is_same_v<decltype(std::declval<ExIn&&>().and_then(get_ex_cvref)),
676 ExOut>);
677 static_assert(std::is_same_v<decltype(std::declval<const ExIn&&>().and_then(
678 get_ex_cvref)),
679 ExOut>);
680 }
681
TEST(Expected,OrElse)682 TEST(Expected, OrElse) {
683 using ExIn = expected<SaveCvRef, SaveCvRef>;
684 using ExOut = expected<SaveCvRef, CvRef>;
685
686 auto get_unex_cvref = [](auto&& x) -> ExOut {
687 return unexpected(SaveCvRef(std::forward<decltype(x)>(x)).cvref);
688 };
689
690 ExIn ex;
691 EXPECT_EQ(ex.or_else(get_unex_cvref).value().cvref, CvRef::kRef);
692 EXPECT_EQ(std::as_const(ex).or_else(get_unex_cvref).value().cvref,
693 CvRef::kConstRef);
694 EXPECT_EQ(std::move(ex).or_else(get_unex_cvref).value().cvref, CvRef::kRRef);
695 EXPECT_EQ(std::move(std::as_const(ex)).or_else(get_unex_cvref).value().cvref,
696 CvRef::kConstRRef);
697
698 ExIn unex(unexpect);
699 EXPECT_EQ(unex.or_else(get_unex_cvref).error(), CvRef::kRef);
700 EXPECT_EQ(std::as_const(unex).or_else(get_unex_cvref).error(),
701 CvRef::kConstRef);
702 EXPECT_EQ(std::move(unex).or_else(get_unex_cvref).error(), CvRef::kRRef);
703 EXPECT_EQ(std::move(std::as_const(unex)).or_else(get_unex_cvref).error(),
704 CvRef::kConstRRef);
705
706 static_assert(
707 std::is_same_v<decltype(std::declval<ExIn&>().or_else(get_unex_cvref)),
708 ExOut>);
709 static_assert(std::is_same_v<decltype(std::declval<const ExIn&>().or_else(
710 get_unex_cvref)),
711 ExOut>);
712 static_assert(
713 std::is_same_v<decltype(std::declval<ExIn&&>().or_else(get_unex_cvref)),
714 ExOut>);
715 static_assert(std::is_same_v<decltype(std::declval<const ExIn&&>().or_else(
716 get_unex_cvref)),
717 ExOut>);
718 }
719
TEST(Expected,Transform)720 TEST(Expected, Transform) {
721 using ExIn = expected<SaveCvRef, SaveCvRef>;
722 using ExOut = expected<CvRef, SaveCvRef>;
723
724 auto get_cvref = [](auto&& x) {
725 return SaveCvRef(std::forward<decltype(x)>(x)).cvref;
726 };
727
728 {
729 ExIn ex;
730 EXPECT_EQ(ex.transform(get_cvref), CvRef::kRef);
731 EXPECT_EQ(std::as_const(ex).transform(get_cvref), CvRef::kConstRef);
732 EXPECT_EQ(std::move(ex).transform(get_cvref), CvRef::kRRef);
733 EXPECT_EQ(std::move(std::as_const(ex)).transform(get_cvref),
734 CvRef::kConstRRef);
735
736 ExIn unex(unexpect);
737 EXPECT_EQ(unex.transform(get_cvref).error().cvref, CvRef::kRef);
738 EXPECT_EQ(std::as_const(unex).transform(get_cvref).error().cvref,
739 CvRef::kConstRef);
740 EXPECT_EQ(std::move(unex).transform(get_cvref).error().cvref, CvRef::kRRef);
741 EXPECT_EQ(std::move(std::as_const(unex)).transform(get_cvref).error().cvref,
742 CvRef::kConstRRef);
743
744 static_assert(
745 std::is_same_v<decltype(std::declval<ExIn&>().transform(get_cvref)),
746 ExOut>);
747 static_assert(
748 std::is_same_v<
749 decltype(std::declval<const ExIn&>().transform(get_cvref)), ExOut>);
750 static_assert(
751 std::is_same_v<decltype(std::declval<ExIn&&>().transform(get_cvref)),
752 ExOut>);
753 static_assert(std::is_same_v<
754 decltype(std::declval<const ExIn&&>().transform(get_cvref)),
755 ExOut>);
756 }
757
758 // Test void transform.
759 {
760 using ExOutVoid = expected<void, SaveCvRef>;
761 CvRef cvref = CvRef::kNone;
762 auto write_cvref = [&cvref](auto&& x) {
763 cvref = SaveCvRef(std::forward<decltype(x)>(x)).cvref;
764 };
765
766 ExIn ex;
767 EXPECT_TRUE(ex.transform(write_cvref).has_value());
768 EXPECT_EQ(cvref, CvRef::kRef);
769 EXPECT_TRUE(std::as_const(ex).transform(write_cvref).has_value());
770 EXPECT_EQ(cvref, CvRef::kConstRef);
771 EXPECT_TRUE(std::move(ex).transform(write_cvref).has_value());
772 EXPECT_EQ(cvref, CvRef::kRRef);
773 EXPECT_TRUE(
774 std::move(std::as_const(ex)).transform(write_cvref).has_value());
775 EXPECT_EQ(cvref, CvRef::kConstRRef);
776
777 cvref = CvRef::kNone;
778 ExIn unex(unexpect);
779 EXPECT_EQ(unex.transform(write_cvref).error().cvref, CvRef::kRef);
780 EXPECT_EQ(cvref, CvRef::kNone);
781 EXPECT_EQ(std::as_const(unex).transform(write_cvref).error().cvref,
782 CvRef::kConstRef);
783 EXPECT_EQ(cvref, CvRef::kNone);
784 EXPECT_EQ(std::move(unex).transform(write_cvref).error().cvref,
785 CvRef::kRRef);
786 EXPECT_EQ(cvref, CvRef::kNone);
787 EXPECT_EQ(
788 std::move(std::as_const(unex)).transform(write_cvref).error().cvref,
789 CvRef::kConstRRef);
790 EXPECT_EQ(cvref, CvRef::kNone);
791
792 static_assert(
793 std::is_same_v<decltype(std::declval<ExIn&>().transform(write_cvref)),
794 ExOutVoid>);
795 static_assert(std::is_same_v<decltype(std::declval<const ExIn&>().transform(
796 write_cvref)),
797 ExOutVoid>);
798 static_assert(
799 std::is_same_v<decltype(std::declval<ExIn&&>().transform(write_cvref)),
800 ExOutVoid>);
801 static_assert(std::is_same_v<
802 decltype(std::declval<const ExIn&&>().transform(write_cvref)),
803 ExOutVoid>);
804 }
805 }
806
TEST(Expected,TransformError)807 TEST(Expected, TransformError) {
808 using ExIn = expected<SaveCvRef, SaveCvRef>;
809 using ExOut = expected<SaveCvRef, CvRef>;
810
811 auto get_cvref = [](auto&& x) {
812 return SaveCvRef(std::forward<decltype(x)>(x)).cvref;
813 };
814
815 ExIn ex;
816 EXPECT_EQ(ex.transform_error(get_cvref).value().cvref, CvRef::kRef);
817 EXPECT_EQ(std::as_const(ex).transform_error(get_cvref).value().cvref,
818 CvRef::kConstRef);
819 EXPECT_EQ(std::move(ex).transform_error(get_cvref).value().cvref,
820 CvRef::kRRef);
821 EXPECT_EQ(
822 std::move(std::as_const(ex)).transform_error(get_cvref).value().cvref,
823 CvRef::kConstRRef);
824
825 ExIn unex(unexpect);
826 EXPECT_EQ(unex.transform_error(get_cvref).error(), CvRef::kRef);
827 EXPECT_EQ(std::as_const(unex).transform_error(get_cvref).error(),
828 CvRef::kConstRef);
829 EXPECT_EQ(std::move(unex).transform_error(get_cvref).error(), CvRef::kRRef);
830 EXPECT_EQ(std::move(std::as_const(unex)).transform_error(get_cvref).error(),
831 CvRef::kConstRRef);
832
833 static_assert(
834 std::is_same_v<decltype(std::declval<ExIn&>().transform_error(get_cvref)),
835 ExOut>);
836 static_assert(
837 std::is_same_v<decltype(std::declval<const ExIn&>().transform_error(
838 get_cvref)),
839 ExOut>);
840 static_assert(
841 std::is_same_v<
842 decltype(std::declval<ExIn&&>().transform_error(get_cvref)), ExOut>);
843 static_assert(
844 std::is_same_v<decltype(std::declval<const ExIn&&>().transform_error(
845 get_cvref)),
846 ExOut>);
847 }
848
TEST(Expected,EqualityOperators)849 TEST(Expected, EqualityOperators) {
850 using ExInt = expected<int, int>;
851 using ExLong = expected<long, long>;
852
853 EXPECT_EQ(ExInt(42), ExLong(42));
854 EXPECT_EQ(ExLong(42), ExInt(42));
855 EXPECT_EQ(ExInt(42), 42);
856 EXPECT_EQ(42, ExInt(42));
857 EXPECT_EQ(ExInt(42), ok(42));
858 EXPECT_EQ(ok(42), ExInt(42));
859 EXPECT_EQ(ExInt(unexpect, 42), unexpected(42));
860 EXPECT_EQ(unexpected(42), ExInt(unexpect, 42));
861
862 EXPECT_NE(ExInt(42), ExLong(123));
863 EXPECT_NE(ExLong(123), ExInt(42));
864 EXPECT_NE(ExInt(42), 123);
865 EXPECT_NE(123, ExInt(42));
866 EXPECT_NE(ExInt(42), ok(123));
867 EXPECT_NE(ok(123), ExInt(42));
868 EXPECT_NE(ExInt(unexpect, 123), unexpected(42));
869 EXPECT_NE(unexpected(42), ExInt(unexpect, 123));
870 EXPECT_NE(ExInt(123), unexpected(123));
871 EXPECT_NE(unexpected(123), ExInt(123));
872 }
873
TEST(ExpectedDeathTest,UseAfterMove)874 TEST(ExpectedDeathTest, UseAfterMove) {
875 using ExpectedInt = expected<int, int>;
876 using ExpectedDouble = expected<double, double>;
877
878 ExpectedInt moved_from;
879 ExpectedInt ex = std::move(moved_from);
880
881 // Accessing moved from objects crashes.
882 // NOLINTBEGIN(bugprone-use-after-move)
883 EXPECT_DEATH_IF_SUPPORTED((void)ExpectedInt{moved_from}, "");
884 EXPECT_DEATH_IF_SUPPORTED((void)ExpectedInt{std::move(moved_from)}, "");
885 EXPECT_DEATH_IF_SUPPORTED((void)ExpectedDouble{moved_from}, "");
886 EXPECT_DEATH_IF_SUPPORTED((void)ExpectedDouble{std::move(moved_from)}, "");
887 EXPECT_DEATH_IF_SUPPORTED(ex = moved_from, "");
888 EXPECT_DEATH_IF_SUPPORTED(ex = std::move(moved_from), "");
889 EXPECT_DEATH_IF_SUPPORTED(ex.swap(moved_from), "");
890 EXPECT_DEATH_IF_SUPPORTED(moved_from.swap(ex), "");
891 EXPECT_DEATH_IF_SUPPORTED(moved_from.operator->(), "");
892 EXPECT_DEATH_IF_SUPPORTED(*moved_from, "");
893 EXPECT_DEATH_IF_SUPPORTED(moved_from.has_value(), "");
894 EXPECT_DEATH_IF_SUPPORTED(moved_from.value(), "");
895 EXPECT_DEATH_IF_SUPPORTED(moved_from.error(), "");
896 EXPECT_DEATH_IF_SUPPORTED(moved_from.value_or(0), "");
897 EXPECT_DEATH_IF_SUPPORTED(std::ignore = (ex == moved_from), "");
898 EXPECT_DEATH_IF_SUPPORTED(std::ignore = (moved_from == ex), "");
899 // NOLINTEND(bugprone-use-after-move)
900
901 // Accessing inactive union-members crashes.
902 EXPECT_DEATH_IF_SUPPORTED(ExpectedInt{}.error(), "");
903 EXPECT_DEATH_IF_SUPPORTED(ExpectedInt{unexpect}.value(), "");
904 }
905
TEST(ExpectedVoid,Triviality)906 TEST(ExpectedVoid, Triviality) {
907 using TrivialExpected = expected<void, int>;
908 static_assert(std::is_trivially_destructible_v<TrivialExpected>);
909
910 using NonTrivialExpected = expected<void, std::string>;
911 static_assert(!std::is_trivially_destructible_v<NonTrivialExpected>);
912 }
913
TEST(ExpectedVoid,DefaultConstructor)914 TEST(ExpectedVoid, DefaultConstructor) {
915 constexpr expected<void, int> ex;
916 static_assert(ex.has_value());
917 static_assert(std::is_default_constructible_v<expected<void, int>>);
918 }
919
TEST(ExpectedVoid,InPlaceConstructor)920 TEST(ExpectedVoid, InPlaceConstructor) {
921 constexpr expected<void, int> ex(absl::in_place);
922 static_assert(ex.has_value());
923 }
924
TEST(ExpectedVoid,CopyConstructor)925 TEST(ExpectedVoid, CopyConstructor) {
926 constexpr expected<void, int> ex1 = unexpected(42);
927 constexpr expected<void, int> ex2 = ex1;
928 static_assert(!ex2.has_value());
929 EXPECT_EQ(ex2.error(), 42);
930 }
931
TEST(ExpectedVoid,MoveConstructor)932 TEST(ExpectedVoid, MoveConstructor) {
933 expected<void, StrongMoveOnly<int>> ex1 = unexpected(StrongMoveOnly(42));
934 expected<void, StrongMoveOnly<int>> ex2 = std::move(ex1);
935 ASSERT_FALSE(ex2.has_value());
936 EXPECT_EQ(ex2.error().value, 42);
937 }
938
TEST(ExpectedVoid,ExplicitConvertingCopyConstructor)939 TEST(ExpectedVoid, ExplicitConvertingCopyConstructor) {
940 constexpr expected<void, int> ex1 = unexpected(42);
941 expected<const void, Strong<int>> ex2(ex1);
942 static_assert(!std::is_convertible_v<decltype(ex1), decltype(ex2)>);
943 ASSERT_FALSE(ex2.has_value());
944 EXPECT_EQ(ex2.error().value, 42);
945 }
946
TEST(ExpectedVoid,ImplicitConvertingCopyConstructor)947 TEST(ExpectedVoid, ImplicitConvertingCopyConstructor) {
948 constexpr expected<void, int> ex1 = unexpected(42);
949 expected<const void, Weak<int>> ex2 = ex1;
950 ASSERT_FALSE(ex2.has_value());
951 EXPECT_EQ(ex2.error().value, 42);
952 }
953
TEST(ExpectedVoid,ExplicitConvertingMoveConstructor)954 TEST(ExpectedVoid, ExplicitConvertingMoveConstructor) {
955 expected<void, int> ex1 = unexpected(42);
956 expected<const void, StrongMoveOnly<int>> ex2(std::move(ex1));
957 static_assert(
958 !std::is_convertible_v<decltype(std::move(ex1)), decltype(ex2)>);
959 ASSERT_FALSE(ex2.has_value());
960 EXPECT_EQ(ex2.error().value, 42);
961 }
962
TEST(ExpectedVoid,ImplicitConvertingMoveConstructor)963 TEST(ExpectedVoid, ImplicitConvertingMoveConstructor) {
964 expected<void, int> ex1 = unexpected(42);
965 expected<const void, WeakMoveOnly<int>> ex2 = std::move(ex1);
966 ASSERT_FALSE(ex2.has_value());
967 EXPECT_EQ(ex2.error().value, 42);
968 }
969
TEST(ExpectedVoid,OkConstructor)970 TEST(ExpectedVoid, OkConstructor) {
971 constexpr expected<void, int> ex = ok();
972 static_assert(ex.has_value());
973 }
974
TEST(ExpectedVoid,ExplicitErrorConstructor)975 TEST(ExpectedVoid, ExplicitErrorConstructor) {
976 {
977 constexpr expected<void, Strong<int>> ex(unexpected(42));
978 static_assert(!std::is_convertible_v<unexpected<int>, decltype(ex)>);
979 static_assert(!ex.has_value());
980 EXPECT_EQ(ex.error().value, 42);
981 }
982
983 {
984 constexpr expected<void, StrongMoveOnly<int>> ex(unexpected(42));
985 static_assert(!std::is_constructible_v<decltype(ex), unexpected<int>&>);
986 static_assert(!std::is_convertible_v<unexpected<int>, decltype(ex)>);
987 static_assert(!ex.has_value());
988 EXPECT_EQ(ex.error().value, 42);
989 }
990 }
991
TEST(ExpectedVoid,ImplicitErrorConstructor)992 TEST(ExpectedVoid, ImplicitErrorConstructor) {
993 {
994 constexpr expected<void, Weak<int>> ex = unexpected(42);
995 static_assert(!ex.has_value());
996 EXPECT_EQ(ex.error().value, 42);
997 }
998
999 {
1000 constexpr expected<void, WeakMoveOnly<int>> ex = unexpected(42);
1001 static_assert(!std::is_convertible_v<unexpected<int>&, decltype(ex)>);
1002 static_assert(!ex.has_value());
1003 EXPECT_EQ(ex.error().value, 42);
1004 }
1005 }
1006
TEST(ExpectedVoid,UnexpectConstructor)1007 TEST(ExpectedVoid, UnexpectConstructor) {
1008 constexpr expected<void, Strong<int>> ex(unexpect, 42);
1009 static_assert(!ex.has_value());
1010 EXPECT_EQ(ex.error().value, 42);
1011 }
1012
TEST(ExpectedVoid,UnexpectListConstructor)1013 TEST(ExpectedVoid, UnexpectListConstructor) {
1014 expected<void, std::vector<int>> ex(unexpect, {1, 2, 3});
1015 EXPECT_THAT(ex, test::ErrorIs(std::vector({1, 2, 3})));
1016 }
1017
TEST(ExpectedVoid,CopyAssignUnexpected)1018 TEST(ExpectedVoid, CopyAssignUnexpected) {
1019 expected<void, int> ex;
1020 EXPECT_TRUE(ex.has_value());
1021
1022 ex = unexpected(42);
1023 EXPECT_THAT(ex, test::ErrorIs(42));
1024
1025 ex = unexpected(123);
1026 EXPECT_THAT(ex, test::ErrorIs(123));
1027 }
1028
TEST(ExpectedVoid,MoveAssignUnexpected)1029 TEST(ExpectedVoid, MoveAssignUnexpected) {
1030 expected<void, StrongMoveOnly<int>> ex;
1031 EXPECT_TRUE(ex.has_value());
1032
1033 ex = unexpected(StrongMoveOnly(42));
1034 ASSERT_FALSE(ex.has_value());
1035 EXPECT_EQ(ex.error().value, 42);
1036
1037 ex = unexpected(StrongMoveOnly(123));
1038 ASSERT_FALSE(ex.has_value());
1039 EXPECT_EQ(ex.error().value, 123);
1040 }
1041
TEST(ExpectedVoid,Emplace)1042 TEST(ExpectedVoid, Emplace) {
1043 expected<void, int> ex = unexpected(0);
1044 EXPECT_FALSE(ex.has_value());
1045
1046 ex.emplace();
1047 ASSERT_TRUE(ex.has_value());
1048 }
1049
TEST(ExpectedVoid,MemberSwap)1050 TEST(ExpectedVoid, MemberSwap) {
1051 expected<void, int> ex1;
1052 expected<void, int> ex2 = unexpected(123);
1053
1054 ex1.swap(ex2);
1055 EXPECT_THAT(ex1, test::ErrorIs(123));
1056 ASSERT_TRUE(ex2.has_value());
1057 }
1058
TEST(ExpectedVoid,FreeSwap)1059 TEST(ExpectedVoid, FreeSwap) {
1060 expected<void, int> ex1;
1061 expected<void, int> ex2 = unexpected(123);
1062
1063 swap(ex1, ex2);
1064 EXPECT_THAT(ex1, test::ErrorIs(123));
1065 ASSERT_TRUE(ex2.has_value());
1066 }
1067
TEST(ExpectedVoid,OperatorStar)1068 TEST(ExpectedVoid, OperatorStar) {
1069 expected<void, int> ex;
1070 *ex;
1071 static_assert(std::is_void_v<decltype(*ex)>);
1072 }
1073
TEST(ExpectedVoid,HasValue)1074 TEST(ExpectedVoid, HasValue) {
1075 constexpr expected<void, int> ex;
1076 static_assert(ex.has_value());
1077
1078 constexpr expected<void, int> unex = unexpected(0);
1079 static_assert(!unex.has_value());
1080 }
1081
TEST(ExpectedVoid,Value)1082 TEST(ExpectedVoid, Value) {
1083 expected<void, int> ex;
1084 ex.value();
1085 static_assert(std::is_void_v<decltype(ex.value())>);
1086 }
1087
TEST(ExpectedVoid,Error)1088 TEST(ExpectedVoid, Error) {
1089 expected<void, int> ex = unexpected(0);
1090 EXPECT_EQ(ex.error(), 0);
1091
1092 ex.error() = 1;
1093 EXPECT_EQ(ex.error(), 1);
1094
1095 using Ex = expected<void, int>;
1096 static_assert(std::is_same_v<decltype(std::declval<Ex&>().error()), int&>);
1097 static_assert(
1098 std::is_same_v<decltype(std::declval<const Ex&>().error()), const int&>);
1099 static_assert(std::is_same_v<decltype(std::declval<Ex&&>().error()), int&&>);
1100 static_assert(std::is_same_v<decltype(std::declval<const Ex&&>().error()),
1101 const int&&>);
1102 }
1103
TEST(ExpectedVoid,ToString)1104 TEST(ExpectedVoid, ToString) {
1105 // `expected<void, ...>` should have a custom string representation (that
1106 // prints the contained error, if applicable).
1107 const std::string value_str = ToString(expected<void, int>());
1108 EXPECT_FALSE(base::Contains(value_str, "-byte object at "));
1109 const std::string error_str =
1110 ToString(expected<void, int>(unexpected(123456)));
1111 EXPECT_FALSE(base::Contains(error_str, "-byte object at "));
1112 EXPECT_TRUE(base::Contains(error_str, "123456"));
1113 }
1114
TEST(ExpectedVoid,ErrorOr)1115 TEST(ExpectedVoid, ErrorOr) {
1116 {
1117 expected<void, int> ex;
1118 EXPECT_EQ(ex.error_or(123), 123);
1119
1120 expected<void, int> unex = unexpected(0);
1121 EXPECT_EQ(unex.error_or(123), 0);
1122 }
1123
1124 {
1125 expected<void, WeakMoveOnly<int>> ex;
1126 EXPECT_EQ(std::move(ex).error_or(123).value, 123);
1127
1128 expected<void, WeakMoveOnly<int>> unex = unexpected(0);
1129 EXPECT_EQ(std::move(unex).error_or(123).value, 0);
1130 }
1131 }
1132
TEST(ExpectedVoid,AndThen)1133 TEST(ExpectedVoid, AndThen) {
1134 using ExIn = expected<void, SaveCvRef>;
1135 using ExOut = expected<bool, SaveCvRef>;
1136
1137 auto get_true = []() -> ExOut { return ok(true); };
1138
1139 ExIn ex;
1140 EXPECT_TRUE(ex.and_then(get_true).value());
1141 EXPECT_TRUE(std::as_const(ex).and_then(get_true).value());
1142 EXPECT_TRUE(std::move(ex).and_then(get_true).value());
1143 EXPECT_TRUE(std::move(std::as_const(ex)).and_then(get_true).value());
1144
1145 ExIn unex = unexpected(SaveCvRef());
1146 EXPECT_EQ(unex.and_then(get_true).error().cvref, CvRef::kRef);
1147 EXPECT_EQ(std::as_const(unex).and_then(get_true).error().cvref,
1148 CvRef::kConstRef);
1149 EXPECT_EQ(std::move(unex).and_then(get_true).error().cvref, CvRef::kRRef);
1150 EXPECT_EQ(std::move(std::as_const(unex)).and_then(get_true).error().cvref,
1151 CvRef::kConstRRef);
1152
1153 static_assert(
1154 std::is_same_v<decltype(std::declval<ExIn&>().and_then(get_true)),
1155 ExOut>);
1156 static_assert(
1157 std::is_same_v<decltype(std::declval<const ExIn&>().and_then(get_true)),
1158 ExOut>);
1159 static_assert(
1160 std::is_same_v<decltype(std::declval<ExIn&&>().and_then(get_true)),
1161 ExOut>);
1162 static_assert(
1163 std::is_same_v<decltype(std::declval<const ExIn&&>().and_then(get_true)),
1164 ExOut>);
1165 }
1166
TEST(ExpectedVoid,OrElse)1167 TEST(ExpectedVoid, OrElse) {
1168 using ExIn = expected<void, SaveCvRef>;
1169 using ExOut = expected<void, CvRef>;
1170
1171 auto get_unex_cvref = [](auto&& x) -> ExOut {
1172 return unexpected(SaveCvRef(std::forward<decltype(x)>(x)).cvref);
1173 };
1174
1175 ExIn ex;
1176 EXPECT_TRUE(ex.or_else(get_unex_cvref).has_value());
1177 EXPECT_TRUE(std::as_const(ex).or_else(get_unex_cvref).has_value());
1178 EXPECT_TRUE(std::move(ex).or_else(get_unex_cvref).has_value());
1179 EXPECT_TRUE(std::move(std::as_const(ex)).or_else(get_unex_cvref).has_value());
1180
1181 ExIn unex(unexpect);
1182 EXPECT_EQ(unex.or_else(get_unex_cvref).error(), CvRef::kRef);
1183 EXPECT_EQ(std::as_const(unex).or_else(get_unex_cvref).error(),
1184 CvRef::kConstRef);
1185 EXPECT_EQ(std::move(unex).or_else(get_unex_cvref).error(), CvRef::kRRef);
1186 EXPECT_EQ(std::move(std::as_const(unex)).or_else(get_unex_cvref).error(),
1187 CvRef::kConstRRef);
1188
1189 static_assert(
1190 std::is_same_v<decltype(std::declval<ExIn&>().or_else(get_unex_cvref)),
1191 ExOut>);
1192 static_assert(std::is_same_v<decltype(std::declval<const ExIn&>().or_else(
1193 get_unex_cvref)),
1194 ExOut>);
1195 static_assert(
1196 std::is_same_v<decltype(std::declval<ExIn&&>().or_else(get_unex_cvref)),
1197 ExOut>);
1198 static_assert(std::is_same_v<decltype(std::declval<const ExIn&&>().or_else(
1199 get_unex_cvref)),
1200 ExOut>);
1201 }
1202
TEST(ExpectedVoid,Transform)1203 TEST(ExpectedVoid, Transform) {
1204 using ExIn = expected<void, SaveCvRef>;
1205 using ExOut = expected<bool, SaveCvRef>;
1206 auto get_true = [] { return true; };
1207
1208 {
1209 ExIn ex;
1210 EXPECT_TRUE(ex.transform(get_true).value());
1211 EXPECT_TRUE(std::as_const(ex).transform(get_true).value());
1212 EXPECT_TRUE(std::move(ex).transform(get_true).value());
1213 EXPECT_TRUE(std::move(std::as_const(ex)).transform(get_true).value());
1214
1215 ExIn unex(unexpect);
1216 EXPECT_EQ(unex.transform(get_true).error().cvref, CvRef::kRef);
1217 EXPECT_EQ(std::as_const(unex).transform(get_true).error().cvref,
1218 CvRef::kConstRef);
1219 EXPECT_EQ(std::move(unex).transform(get_true).error().cvref, CvRef::kRRef);
1220 EXPECT_EQ(std::move(std::as_const(unex)).transform(get_true).error().cvref,
1221 CvRef::kConstRRef);
1222
1223 static_assert(
1224 std::is_same_v<decltype(std::declval<ExIn&>().transform(get_true)),
1225 ExOut>);
1226 static_assert(
1227 std::is_same_v<
1228 decltype(std::declval<const ExIn&>().transform(get_true)), ExOut>);
1229 static_assert(
1230 std::is_same_v<decltype(std::declval<ExIn&&>().transform(get_true)),
1231 ExOut>);
1232 static_assert(
1233 std::is_same_v<
1234 decltype(std::declval<const ExIn&&>().transform(get_true)), ExOut>);
1235 }
1236
1237 // Test void transform.
1238 {
1239 auto do_nothing = [] {};
1240
1241 ExIn ex;
1242 EXPECT_TRUE(ex.transform(do_nothing).has_value());
1243 EXPECT_TRUE(std::as_const(ex).transform(do_nothing).has_value());
1244 EXPECT_TRUE(std::move(ex).transform(do_nothing).has_value());
1245 EXPECT_TRUE(std::move(std::as_const(ex)).transform(do_nothing).has_value());
1246
1247 ExIn unex(unexpect);
1248 EXPECT_EQ(unex.transform(do_nothing).error().cvref, CvRef::kRef);
1249 EXPECT_EQ(std::as_const(unex).transform(do_nothing).error().cvref,
1250 CvRef::kConstRef);
1251 EXPECT_EQ(std::move(unex).transform(do_nothing).error().cvref,
1252 CvRef::kRRef);
1253 EXPECT_EQ(
1254 std::move(std::as_const(unex)).transform(do_nothing).error().cvref,
1255 CvRef::kConstRRef);
1256
1257 static_assert(
1258 std::is_same_v<decltype(std::declval<ExIn&>().transform(do_nothing)),
1259 ExIn>);
1260 static_assert(
1261 std::is_same_v<
1262 decltype(std::declval<const ExIn&>().transform(do_nothing)), ExIn>);
1263 static_assert(
1264 std::is_same_v<decltype(std::declval<ExIn&&>().transform(do_nothing)),
1265 ExIn>);
1266 static_assert(std::is_same_v<
1267 decltype(std::declval<const ExIn&&>().transform(do_nothing)),
1268 ExIn>);
1269 }
1270 }
1271
TEST(ExpectedVoid,TransformError)1272 TEST(ExpectedVoid, TransformError) {
1273 using ExIn = expected<void, SaveCvRef>;
1274 using ExOut = expected<void, CvRef>;
1275
1276 auto get_cvref = [](auto&& x) {
1277 return SaveCvRef(std::forward<decltype(x)>(x)).cvref;
1278 };
1279
1280 ExIn ex;
1281 EXPECT_TRUE(ex.transform_error(get_cvref).has_value());
1282 EXPECT_TRUE(std::as_const(ex).transform_error(get_cvref).has_value());
1283 EXPECT_TRUE(std::move(ex).transform_error(get_cvref).has_value());
1284 EXPECT_TRUE(
1285 std::move(std::as_const(ex)).transform_error(get_cvref).has_value());
1286
1287 ExIn unex(unexpect);
1288 EXPECT_EQ(unex.transform_error(get_cvref).error(), CvRef::kRef);
1289 EXPECT_EQ(std::as_const(unex).transform_error(get_cvref).error(),
1290 CvRef::kConstRef);
1291 EXPECT_EQ(std::move(unex).transform_error(get_cvref).error(), CvRef::kRRef);
1292 EXPECT_EQ(std::move(std::as_const(unex)).transform_error(get_cvref).error(),
1293 CvRef::kConstRRef);
1294
1295 static_assert(
1296 std::is_same_v<decltype(std::declval<ExIn&>().transform_error(get_cvref)),
1297 ExOut>);
1298 static_assert(
1299 std::is_same_v<decltype(std::declval<const ExIn&>().transform_error(
1300 get_cvref)),
1301 ExOut>);
1302 static_assert(
1303 std::is_same_v<
1304 decltype(std::declval<ExIn&&>().transform_error(get_cvref)), ExOut>);
1305 static_assert(
1306 std::is_same_v<decltype(std::declval<const ExIn&&>().transform_error(
1307 get_cvref)),
1308 ExOut>);
1309 }
1310
TEST(ExpectedVoid,EqualityOperators)1311 TEST(ExpectedVoid, EqualityOperators) {
1312 using Ex = expected<void, int>;
1313 using ConstEx = expected<const void, const int>;
1314
1315 EXPECT_EQ(Ex(), ConstEx());
1316 EXPECT_EQ(ConstEx(), Ex());
1317 EXPECT_EQ(Ex(unexpect, 42), unexpected(42));
1318 EXPECT_EQ(unexpected(42), Ex(unexpect, 42));
1319
1320 EXPECT_NE(Ex(unexpect, 123), unexpected(42));
1321 EXPECT_NE(unexpected(42), Ex(unexpect, 123));
1322 EXPECT_NE(Ex(), unexpected(0));
1323 EXPECT_NE(unexpected(0), Ex());
1324 }
1325
TEST(ExpectedVoidTest,DeathTests)1326 TEST(ExpectedVoidTest, DeathTests) {
1327 using ExpectedInt = expected<void, int>;
1328 using ExpectedDouble = expected<void, double>;
1329
1330 ExpectedInt moved_from;
1331 ExpectedInt ex = std::move(moved_from);
1332
1333 // Accessing moved from objects crashes.
1334 // NOLINTBEGIN(bugprone-use-after-move)
1335 EXPECT_DEATH_IF_SUPPORTED((void)ExpectedInt{moved_from}, "");
1336 EXPECT_DEATH_IF_SUPPORTED((void)ExpectedInt{std::move(moved_from)}, "");
1337 EXPECT_DEATH_IF_SUPPORTED((void)ExpectedDouble{moved_from}, "");
1338 EXPECT_DEATH_IF_SUPPORTED((void)ExpectedDouble{std::move(moved_from)}, "");
1339 EXPECT_DEATH_IF_SUPPORTED(ex = moved_from, "");
1340 EXPECT_DEATH_IF_SUPPORTED(ex = std::move(moved_from), "");
1341 EXPECT_DEATH_IF_SUPPORTED(ex.swap(moved_from), "");
1342 EXPECT_DEATH_IF_SUPPORTED(moved_from.swap(ex), "");
1343 EXPECT_DEATH_IF_SUPPORTED(*moved_from, "");
1344 EXPECT_DEATH_IF_SUPPORTED(moved_from.has_value(), "");
1345 EXPECT_DEATH_IF_SUPPORTED(moved_from.value(), "");
1346 EXPECT_DEATH_IF_SUPPORTED(moved_from.error(), "");
1347 EXPECT_DEATH_IF_SUPPORTED(std::ignore = (ex == moved_from), "");
1348 EXPECT_DEATH_IF_SUPPORTED(std::ignore = (moved_from == ex), "");
1349 // NOLINTEND(bugprone-use-after-move)
1350
1351 // Accessing inactive union-members crashes.
1352 EXPECT_DEATH_IF_SUPPORTED(ExpectedInt{}.error(), "");
1353 EXPECT_DEATH_IF_SUPPORTED(ExpectedInt{unexpect}.value(), "");
1354 }
1355
1356 } // namespace
1357
1358 } // namespace base
1359