2 * Copyright 2016 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <folly/Expected.h>
18 #include <folly/Portability.h>
19 #include <folly/portability/GTest.h>
25 #include <type_traits>
28 #include <glog/logging.h>
30 using std::unique_ptr;
31 using std::shared_ptr;
35 enum class E { E1, E2 };
37 std::ostream& operator<<(std::ostream& os, E e) {
48 template <class V, class E>
49 std::ostream& operator<<(std::ostream& os, const Expected<V, E>& e) {
51 os << "Expected(" << e.value() << ')';
53 os << "Unexpected(" << e.error() << ')';
59 NoDefault(int, int) {}
63 TEST(Expected, NoDefault) {
65 std::is_default_constructible<Expected<NoDefault, int>>::value, "");
66 Expected<NoDefault, int> x{in_place, 42, 42};
70 x = makeUnexpected(42);
71 EXPECT_FALSE(bool(x));
72 EXPECT_EQ(42, x.error());
75 TEST(Expected, String) {
76 Expected<std::string, int> maybeString;
77 EXPECT_FALSE(bool(maybeString));
78 EXPECT_EQ(0, maybeString.error());
79 maybeString = "hello";
80 EXPECT_TRUE(bool(maybeString));
81 EXPECT_EQ("hello", *maybeString);
84 TEST(Expected, Ambiguous) {
85 // Potentially ambiguous and confusing construction and assignment disallowed:
86 EXPECT_FALSE((std::is_constructible<Expected<int, int>, int>::value));
87 EXPECT_FALSE((std::is_assignable<Expected<int, int>&, int>::value));
90 TEST(Expected, Const) {
91 { // default construct
92 Expected<const int, int> ex;
93 EXPECT_FALSE(bool(ex));
94 EXPECT_EQ(0, ex.error());
99 ex = makeUnexpected(42);
100 EXPECT_FALSE(bool(ex));
101 EXPECT_EQ(42, ex.error());
103 { // copy-constructed
105 Expected<const int, int> ex{in_place, x};
106 Expected<const int, int> ex2 = ex;
109 { // move-constructed
111 Expected<const int, int> ex{in_place, std::move(x)};
112 Expected<const int, int> ex2 = std::move(ex);
115 // no assignment allowed
116 EXPECT_FALSE((std::is_copy_assignable<Expected<const int, int>>::value));
119 TEST(Expected, Simple) {
120 Expected<int, int> ex;
121 EXPECT_FALSE(bool(ex));
122 EXPECT_EQ(42, ex.value_or(42));
124 EXPECT_TRUE(bool(ex));
126 EXPECT_EQ(4, ex.value_or(42));
127 ex = makeUnexpected(-1);
128 EXPECT_FALSE(bool(ex));
129 EXPECT_EQ(-1, ex.error());
130 EXPECT_EQ(42, ex.value_or(42));
135 /* implicit */ MoveTester(const char* s) : s_(s) {}
136 MoveTester(const MoveTester&) = default;
137 MoveTester(MoveTester&& other) noexcept {
138 s_ = std::move(other.s_);
141 MoveTester& operator=(const MoveTester&) = default;
142 MoveTester& operator=(MoveTester&& other) noexcept {
143 s_ = std::move(other.s_);
149 friend bool operator==(const MoveTester& o1, const MoveTester& o2);
153 bool operator==(const MoveTester& o1, const MoveTester& o2) {
154 return o1.s_ == o2.s_;
157 TEST(Expected, value_or_rvalue_arg) {
158 Expected<MoveTester, int> ex = makeUnexpected(-1);
159 MoveTester dflt = "hello";
160 EXPECT_EQ("hello", ex.value_or(dflt));
161 EXPECT_EQ("hello", dflt);
162 EXPECT_EQ("hello", ex.value_or(std::move(dflt)));
164 EXPECT_EQ("world", ex.value_or("world"));
167 // Make sure that the const overload works on const objects
168 const auto& exc = ex;
169 EXPECT_EQ("hello", exc.value_or(dflt));
170 EXPECT_EQ("hello", dflt);
171 EXPECT_EQ("hello", exc.value_or(std::move(dflt)));
173 EXPECT_EQ("world", exc.value_or("world"));
177 EXPECT_EQ("meow", ex.value_or(dflt));
178 EXPECT_EQ("hello", dflt);
179 EXPECT_EQ("meow", ex.value_or(std::move(dflt)));
180 EXPECT_EQ("hello", dflt); // only moved if used
183 TEST(Expected, value_or_noncopyable) {
184 Expected<std::unique_ptr<int>, int> ex{unexpected, 42};
185 std::unique_ptr<int> dflt(new int(42));
186 EXPECT_EQ(42, *std::move(ex).value_or(std::move(dflt)));
189 struct ExpectingDeleter {
190 explicit ExpectingDeleter(int expected) : expected(expected) {}
192 void operator()(const int* ptr) {
193 EXPECT_EQ(*ptr, expected);
198 TEST(Expected, value_move) {
199 auto ptr = Expected<std::unique_ptr<int, ExpectingDeleter>, int>(
200 in_place, new int(42), ExpectingDeleter{1337})
205 TEST(Expected, dereference_move) {
206 auto ptr = *Expected<std::unique_ptr<int, ExpectingDeleter>, int>(
207 in_place, new int(42), ExpectingDeleter{1337});
211 TEST(Expected, EmptyConstruct) {
212 Expected<int, int> ex{unexpected, 42};
213 EXPECT_FALSE(bool(ex));
214 Expected<int, int> test1(ex);
215 EXPECT_FALSE(bool(test1));
216 Expected<int, int> test2(std::move(ex));
217 EXPECT_FALSE(bool(test2));
218 EXPECT_EQ(42, test2.error());
221 TEST(Expected, Unique) {
222 Expected<unique_ptr<int>, int> ex;
224 ex = makeUnexpected(-1);
225 EXPECT_FALSE(bool(ex));
227 ex.emplace(new int(5));
228 EXPECT_TRUE(bool(ex));
231 ex = makeUnexpected(-1);
233 ex = unique_ptr<int>(new int(6));
236 ex = unique_ptr<int>(new int(7));
239 // move it out by move construct
240 Expected<unique_ptr<int>, int> moved(std::move(ex));
241 EXPECT_TRUE(bool(moved));
242 EXPECT_TRUE(bool(ex));
243 EXPECT_EQ(nullptr, ex->get());
244 EXPECT_EQ(7, **moved);
246 EXPECT_TRUE(bool(moved));
247 ex = std::move(moved); // move it back by move assign
248 EXPECT_TRUE(bool(moved));
249 EXPECT_EQ(nullptr, moved->get());
250 EXPECT_TRUE(bool(ex));
254 TEST(Expected, Shared) {
256 Expected<shared_ptr<int>, int> ex{unexpected, -1};
257 EXPECT_FALSE(bool(ex));
259 ex.emplace(new int(5));
260 EXPECT_TRUE(bool(ex));
262 EXPECT_EQ(ptr.get(), ex->get());
263 EXPECT_EQ(2, ptr.use_count());
264 ex = makeUnexpected(-1);
265 EXPECT_EQ(1, ptr.use_count());
268 EXPECT_EQ(2, ptr.use_count());
269 EXPECT_EQ(ptr.get(), ex->get());
270 ex = makeUnexpected(-1);
271 EXPECT_EQ(1, ptr.use_count());
274 EXPECT_EQ(1, ex->use_count());
275 EXPECT_EQ(nullptr, ptr.get());
277 EXPECT_EQ(1, ex->use_count());
278 Expected<shared_ptr<int>, int> copied(ex);
279 EXPECT_EQ(2, ex->use_count());
280 Expected<shared_ptr<int>, int> moved(std::move(ex));
281 EXPECT_EQ(2, moved->use_count());
282 moved.emplace(new int(6));
283 EXPECT_EQ(1, moved->use_count());
285 EXPECT_EQ(2, moved->use_count());
289 TEST(Expected, Order) {
290 std::vector<Expected<int, E>> vect{
291 {unexpected, E::E1}, {3}, {1}, {unexpected, E::E1}, {2},
293 std::vector<Expected<int, E>> expected{
294 {unexpected, E::E1}, {unexpected, E::E1}, {1}, {2}, {3},
296 std::sort(vect.begin(), vect.end());
297 EXPECT_EQ(vect, expected);
300 TEST(Expected, Swap) {
301 Expected<std::string, E> a;
302 Expected<std::string, E> b;
305 EXPECT_FALSE(a.hasValue());
306 EXPECT_FALSE(b.hasValue());
309 EXPECT_TRUE(a.hasValue());
310 EXPECT_FALSE(b.hasValue());
311 EXPECT_EQ("hello", a.value());
314 EXPECT_FALSE(a.hasValue());
315 EXPECT_TRUE(b.hasValue());
316 EXPECT_EQ("hello", b.value());
319 EXPECT_TRUE(a.hasValue());
320 EXPECT_EQ("bye", a.value());
325 TEST(Expected, Comparisons) {
327 Expected<int, E> o1(1);
328 Expected<int, E> o2(2);
330 EXPECT_TRUE(o_ <= (o_));
331 EXPECT_TRUE(o_ == (o_));
332 EXPECT_TRUE(o_ >= (o_));
334 EXPECT_TRUE(o1 < o2);
335 EXPECT_TRUE(o1 <= o2);
336 EXPECT_TRUE(o1 <= (o1));
337 EXPECT_TRUE(o1 == (o1));
338 EXPECT_TRUE(o1 != o2);
339 EXPECT_TRUE(o1 >= (o1));
340 EXPECT_TRUE(o2 >= o1);
341 EXPECT_TRUE(o2 > o1);
343 EXPECT_FALSE(o2 < o1);
344 EXPECT_FALSE(o2 <= o1);
345 EXPECT_FALSE(o2 <= o1);
346 EXPECT_FALSE(o2 == o1);
347 EXPECT_FALSE(o1 != (o1));
348 EXPECT_FALSE(o1 >= o2);
349 EXPECT_FALSE(o1 >= o2);
350 EXPECT_FALSE(o1 > o2);
352 /* folly::Expected explicitly doesn't support comparisons with contained value
354 EXPECT_TRUE(1 <= o2);
355 EXPECT_TRUE(1 <= o1);
356 EXPECT_TRUE(1 == o1);
357 EXPECT_TRUE(2 != o1);
358 EXPECT_TRUE(1 >= o1);
359 EXPECT_TRUE(2 >= o1);
362 EXPECT_FALSE(o2 < 1);
363 EXPECT_FALSE(o2 <= 1);
364 EXPECT_FALSE(o2 <= 1);
365 EXPECT_FALSE(o2 == 1);
366 EXPECT_FALSE(o2 != 2);
367 EXPECT_FALSE(o1 >= 2);
368 EXPECT_FALSE(o1 >= 2);
369 EXPECT_FALSE(o1 > 2);
373 TEST(Expected, Conversions) {
374 Expected<bool, E> mbool;
375 Expected<short, E> mshort;
376 Expected<char*, E> mstr;
377 Expected<int, E> mint;
379 EXPECT_FALSE((std::is_convertible<Expected<bool, E>&, bool>::value));
380 EXPECT_FALSE((std::is_convertible<Expected<short, E>&, short>::value));
381 EXPECT_FALSE((std::is_convertible<Expected<char*, E>&, char*>::value));
382 EXPECT_FALSE((std::is_convertible<Expected<int, E>&, int>::value));
384 // intended explicit operator bool, for if (ex).
388 // Truthy tests work and are not ambiguous
389 if (mbool && mshort && mstr && mint) { // only checks not-empty
390 if (*mbool && *mshort && *mstr && *mint) { // only checks value
396 EXPECT_TRUE(bool(mbool));
397 EXPECT_FALSE(*mbool);
400 EXPECT_TRUE(bool(mbool));
403 mbool = {unexpected, E::E1};
404 EXPECT_FALSE(bool(mbool));
406 // No conversion allowed; does not compile
410 TEST(Expected, Pointee) {
412 EXPECT_FALSE(get_pointer(x));
414 EXPECT_TRUE(get_pointer(x));
416 EXPECT_TRUE(*x == 2);
417 x = {unexpected, E::E1};
418 EXPECT_FALSE(get_pointer(x));
421 TEST(Expected, MakeOptional) {
422 // const L-value version
423 const std::string s("abc");
424 auto exStr = makeExpected<E>(s);
425 ASSERT_TRUE(exStr.hasValue());
426 EXPECT_EQ(*exStr, "abc");
429 EXPECT_EQ(*exStr, "cde");
432 std::string s2("abc");
433 auto exStr2 = makeExpected<E>(s2);
434 ASSERT_TRUE(exStr2.hasValue());
435 EXPECT_EQ(*exStr2, "abc");
437 // it's vital to check that s2 wasn't clobbered
438 EXPECT_EQ(s2, "abc");
440 // L-value reference version
442 auto exStr3 = makeExpected<E>(s3);
443 ASSERT_TRUE(exStr3.hasValue());
444 EXPECT_EQ(*exStr3, "abc");
446 EXPECT_EQ(s3, "abc");
448 // R-value ref version
449 unique_ptr<int> pInt(new int(3));
450 auto exIntPtr = makeExpected<E>(std::move(pInt));
451 EXPECT_TRUE(pInt.get() == nullptr);
452 ASSERT_TRUE(exIntPtr.hasValue());
453 EXPECT_EQ(**exIntPtr, 3);
456 #if __CLANG_PREREQ(3, 6)
457 #pragma clang diagnostic push
458 #pragma clang diagnostic ignored "-Wself-move"
461 TEST(Expected, SelfAssignment) {
462 Expected<std::string, E> a = "42";
464 ASSERT_TRUE(a.hasValue() && a.value() == "42");
466 Expected<std::string, E> b = "23333333";
468 ASSERT_TRUE(b.hasValue() && b.value() == "23333333");
471 #if __CLANG_PREREQ(3, 6)
472 #pragma clang diagnostic pop
475 class ContainsExpected {
477 ContainsExpected() {}
478 explicit ContainsExpected(int x) : ex_(x) {}
479 bool hasValue() const {
480 return ex_.hasValue();
486 ContainsExpected(const ContainsExpected& other) = default;
487 ContainsExpected& operator=(const ContainsExpected& other) = default;
488 ContainsExpected(ContainsExpected&& other) = default;
489 ContainsExpected& operator=(ContainsExpected&& other) = default;
492 Expected<int, E> ex_;
496 * Test that a class containing an Expected can be copy and move assigned.
497 * This was broken under gcc 4.7 until assignment operators were explicitly
500 TEST(Expected, AssignmentContained) {
502 ContainsExpected source(5), target;
504 EXPECT_TRUE(target.hasValue());
505 EXPECT_EQ(5, target.value());
509 ContainsExpected source(5), target;
510 target = std::move(source);
511 EXPECT_TRUE(target.hasValue());
512 EXPECT_EQ(5, target.value());
513 EXPECT_TRUE(source.hasValue());
517 ContainsExpected ex_uninit, target(10);
519 EXPECT_FALSE(target.hasValue());
523 TEST(Expected, Exceptions) {
524 Expected<int, E> empty;
525 EXPECT_THROW(empty.value(), Unexpected<E>::BadExpectedAccess);
528 struct ThrowingBadness {
529 ThrowingBadness() noexcept(false);
530 ThrowingBadness(const ThrowingBadness&) noexcept(false);
531 ThrowingBadness(ThrowingBadness&&) noexcept(false);
532 ThrowingBadness& operator=(const ThrowingBadness&) noexcept(false);
533 ThrowingBadness& operator=(ThrowingBadness&&) noexcept(false);
536 TEST(Expected, NoThrowDefaultConstructible) {
538 (std::is_nothrow_default_constructible<Expected<bool, E>>::value));
540 (std::is_nothrow_default_constructible<Expected<std::string, E>>::value));
541 EXPECT_TRUE((std::is_nothrow_default_constructible<
542 Expected<ThrowingBadness, E>>::value));
543 EXPECT_FALSE((std::is_nothrow_default_constructible<
544 Expected<int, ThrowingBadness>>::value));
547 TEST(Expected, NoThrowMoveConstructible) {
548 EXPECT_TRUE((std::is_nothrow_move_constructible<Expected<bool, E>>::value));
549 EXPECT_TRUE((std::is_nothrow_move_constructible<
550 Expected<std::unique_ptr<int>, E>>::value));
552 std::is_nothrow_move_constructible<Expected<ThrowingBadness, E>>::value));
555 TEST(Expected, NoThrowMoveAssignable) {
556 EXPECT_TRUE((std::is_nothrow_move_assignable<Expected<bool, E>>::value));
557 EXPECT_TRUE((std::is_nothrow_move_assignable<
558 Expected<std::unique_ptr<int>, E>>::value));
560 (std::is_nothrow_move_assignable<Expected<ThrowingBadness, E>>::value));
563 struct NoDestructor {};
565 struct WithDestructor {
569 TEST(Expected, TriviallyDestructible) {
570 // These could all be static_asserts but EXPECT_* give much nicer output on
573 (std::is_trivially_destructible<Expected<NoDestructor, E>>::value));
574 EXPECT_TRUE((std::is_trivially_destructible<Expected<int, E>>::value));
576 (std::is_trivially_destructible<Expected<WithDestructor, E>>::value));
579 struct NoConstructor {};
581 struct WithConstructor {
585 TEST(Expected, TriviallyCopyable) {
586 // These could all be static_asserts but EXPECT_* give much nicer output on
588 EXPECT_TRUE((IsTriviallyCopyable<Expected<int, E>>::value));
589 EXPECT_TRUE((IsTriviallyCopyable<Expected<char*, E>>::value));
591 (IsTriviallyCopyable<Expected<NoDestructor, E>>::value));
593 (IsTriviallyCopyable<Expected<WithDestructor, E>>::value));
595 (IsTriviallyCopyable<Expected<NoConstructor, E>>::value));
597 (IsTriviallyCopyable<Expected<std::string, E>>::value));
599 (IsTriviallyCopyable<Expected<int, std::string>>::value));
600 // libstdc++ with GCC 4.x doesn't have std::is_trivially_copyable
601 #if (defined(__clang__) && !defined(_LIBCPP_VERSION)) || \
602 !(defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5)
604 (IsTriviallyCopyable<Expected<WithConstructor, E>>::value));
607 (IsTriviallyCopyable<Expected<Expected<int, E>, E>>::value));
610 TEST(Expected, Then) {
613 Expected<int, E> ex = Expected<std::unique_ptr<int>, E>{
614 in_place, new int(42)}.then([](std::unique_ptr<int> p) { return *p; });
615 EXPECT_TRUE(bool(ex));
621 Expected<int, E> ex =
622 Expected<std::unique_ptr<int>, E>{in_place, new int(42)}.then(
623 [](std::unique_ptr<int> p) { return makeExpected<E>(*p); });
624 EXPECT_TRUE(bool(ex));
630 Expected<Unit, E> ex = Expected<std::unique_ptr<int>, E>{
631 in_place, new int(42)}.then([](std::unique_ptr<int>) {});
632 EXPECT_TRUE(bool(ex));
635 // Non-flattening (different error codes)
637 Expected<Expected<int, int>, E> ex =
638 Expected<std::unique_ptr<int>, E>{in_place, new int(42)}.then(
639 [](std::unique_ptr<int> p) { return makeExpected<int>(*p); });
640 EXPECT_TRUE(bool(ex));
641 EXPECT_TRUE(bool(*ex));
647 Expected<int, E> ex = Expected<std::unique_ptr<int>, E>{
648 unexpected, E::E1}.then([](std::unique_ptr<int> p) -> int {
652 EXPECT_FALSE(bool(ex));
653 EXPECT_EQ(E::E1, ex.error());
658 Expected<std::string, E> ex =
659 Expected<std::unique_ptr<int>, E>{in_place, new int(42)}.then(
660 [](std::unique_ptr<int> p) { return makeExpected<E>(*p); },
661 [](int i) { return i == 42 ? "yes" : "no"; });
662 EXPECT_TRUE(bool(ex));
663 EXPECT_EQ("yes", *ex);
666 // Chaining with errors
668 Expected<std::string, E> ex =
669 Expected<std::unique_ptr<int>, E>{in_place, new int(42)}.then(
670 [](std::unique_ptr<int>) {
671 return Expected<int, E>(unexpected, E::E1);
673 [](int i) { return i == 42 ? "yes" : "no"; });
674 EXPECT_FALSE(bool(ex));
675 EXPECT_EQ(E::E1, ex.error());
679 TEST(Expected, ThenOrThrow) {
682 Expected<std::unique_ptr<int>, E>{in_place, new int(42)}.thenOrThrow(
683 [](std::unique_ptr<int> p) { return *p; });
689 (Expected<std::unique_ptr<int>, E>{unexpected, E::E1}.thenOrThrow(
690 [](std::unique_ptr<int> p) { return *p; })),
691 Unexpected<E>::BadExpectedAccess);
696 (Expected<std::unique_ptr<int>, E>{unexpected, E::E1}.thenOrThrow(
697 [](std::unique_ptr<int> p) { return *p; },
698 [](E) { return std::runtime_error(""); })),
704 (Expected<std::unique_ptr<int>, E>{unexpected, E::E1}.thenOrThrow(
705 [](std::unique_ptr<int> p) { return *p; },
706 [](E) { throw std::runtime_error(""); })),
712 (Expected<std::unique_ptr<int>, E>{unexpected, E::E1}.thenOrThrow(
713 [](std::unique_ptr<int> p) { return *p; }, [](E) {})),
714 Unexpected<E>::BadExpectedAccess);