Fix copyright lines for Bits.h and move BitsBenchmark.cpp
[folly.git] / folly / test / ExpectedTest.cpp
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
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
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <folly/Expected.h>
18 #include <folly/Portability.h>
19 #include <folly/portability/GTest.h>
20
21 #include <algorithm>
22 #include <iomanip>
23 #include <memory>
24 #include <string>
25 #include <type_traits>
26 #include <vector>
27
28 #include <glog/logging.h>
29
30 using std::unique_ptr;
31 using std::shared_ptr;
32
33 namespace folly {
34
35 enum class E { E1, E2 };
36
37 std::ostream& operator<<(std::ostream& os, E e) {
38   switch (e) {
39     case E::E1:
40       return os << "E::E1";
41     case E::E2:
42       return os << "E::E2";
43     default:;
44   }
45   return os;
46 }
47
48 template <class V, class E>
49 std::ostream& operator<<(std::ostream& os, const Expected<V, E>& e) {
50   if (e) {
51     os << "Expected(" << e.value() << ')';
52   } else {
53     os << "Unexpected(" << e.error() << ')';
54   }
55   return os;
56 }
57
58 struct NoDefault {
59   NoDefault(int, int) {}
60   char a, b, c;
61 };
62
63 TEST(Expected, NoDefault) {
64   static_assert(
65       std::is_default_constructible<Expected<NoDefault, int>>::value, "");
66   Expected<NoDefault, int> x{in_place, 42, 42};
67   EXPECT_TRUE(bool(x));
68   x.emplace(4, 5);
69   EXPECT_TRUE(bool(x));
70   x = makeUnexpected(42);
71   EXPECT_FALSE(bool(x));
72   EXPECT_EQ(42, x.error());
73 }
74
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);
82 }
83
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));
88 }
89
90 TEST(Expected, Const) {
91   { // default construct
92     Expected<const int, int> ex;
93     EXPECT_FALSE(bool(ex));
94     EXPECT_EQ(0, ex.error());
95     ex.emplace(4);
96     EXPECT_EQ(4, *ex);
97     ex.emplace(5);
98     EXPECT_EQ(5, *ex);
99     ex = makeUnexpected(42);
100     EXPECT_FALSE(bool(ex));
101     EXPECT_EQ(42, ex.error());
102   }
103   { // copy-constructed
104     const int x = 6;
105     Expected<const int, int> ex{in_place, x};
106     Expected<const int, int> ex2 = ex;
107     EXPECT_EQ(6, *ex2);
108   }
109   { // move-constructed
110     const int x = 7;
111     Expected<const int, int> ex{in_place, std::move(x)};
112     Expected<const int, int> ex2 = std::move(ex);
113     EXPECT_EQ(7, *ex2);
114   }
115   // no assignment allowed
116   EXPECT_FALSE((std::is_copy_assignable<Expected<const int, int>>::value));
117 }
118
119 TEST(Expected, Simple) {
120   Expected<int, int> ex;
121   EXPECT_FALSE(bool(ex));
122   EXPECT_EQ(42, ex.value_or(42));
123   ex.emplace(4);
124   EXPECT_TRUE(bool(ex));
125   EXPECT_EQ(4, *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));
131 }
132
133 class MoveTester {
134  public:
135   /* implicit */ MoveTester(const char* s) : s_(s) {}
136   MoveTester(const MoveTester&) = default;
137   MoveTester(MoveTester&& other) noexcept {
138     s_ = std::move(other.s_);
139     other.s_ = "";
140   }
141   MoveTester& operator=(const MoveTester&) = default;
142   MoveTester& operator=(MoveTester&& other) noexcept {
143     s_ = std::move(other.s_);
144     other.s_ = "";
145     return *this;
146   }
147
148  private:
149   friend bool operator==(const MoveTester& o1, const MoveTester& o2);
150   std::string s_;
151 };
152
153 bool operator==(const MoveTester& o1, const MoveTester& o2) {
154   return o1.s_ == o2.s_;
155 }
156
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)));
163   EXPECT_EQ("", dflt);
164   EXPECT_EQ("world", ex.value_or("world"));
165
166   dflt = "hello";
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)));
172   EXPECT_EQ("", dflt);
173   EXPECT_EQ("world", exc.value_or("world"));
174
175   dflt = "hello";
176   ex = "meow";
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
181 }
182
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)));
187 }
188
189 struct ExpectingDeleter {
190   explicit ExpectingDeleter(int expected) : expected(expected) {}
191   int expected;
192   void operator()(const int* ptr) {
193     EXPECT_EQ(*ptr, expected);
194     delete ptr;
195   }
196 };
197
198 TEST(Expected, value_move) {
199   auto ptr = Expected<std::unique_ptr<int, ExpectingDeleter>, int>(
200                  in_place, new int(42), ExpectingDeleter{1337})
201                  .value();
202   *ptr = 1337;
203 }
204
205 TEST(Expected, dereference_move) {
206   auto ptr = *Expected<std::unique_ptr<int, ExpectingDeleter>, int>(
207       in_place, new int(42), ExpectingDeleter{1337});
208   *ptr = 1337;
209 }
210
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());
219 }
220
221 TEST(Expected, Unique) {
222   Expected<unique_ptr<int>, int> ex;
223
224   ex = makeUnexpected(-1);
225   EXPECT_FALSE(bool(ex));
226   // empty->emplaced
227   ex.emplace(new int(5));
228   EXPECT_TRUE(bool(ex));
229   EXPECT_EQ(5, **ex);
230
231   ex = makeUnexpected(-1);
232   // empty->moved
233   ex = std::make_unique<int>(6);
234   EXPECT_EQ(6, **ex);
235   // full->moved
236   ex = std::make_unique<int>(7);
237   EXPECT_EQ(7, **ex);
238
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);
245
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));
251   EXPECT_EQ(7, **ex);
252 }
253
254 TEST(Expected, Shared) {
255   shared_ptr<int> ptr;
256   Expected<shared_ptr<int>, int> ex{unexpected, -1};
257   EXPECT_FALSE(bool(ex));
258   // empty->emplaced
259   ex.emplace(new int(5));
260   EXPECT_TRUE(bool(ex));
261   ptr = ex.value();
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());
266   // full->copied
267   ex = ptr;
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());
272   // full->moved
273   ex = std::move(ptr);
274   EXPECT_EQ(1, ex->use_count());
275   EXPECT_EQ(nullptr, ptr.get());
276   {
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());
284     copied = moved;
285     EXPECT_EQ(2, moved->use_count());
286   }
287 }
288
289 TEST(Expected, Order) {
290   std::vector<Expected<int, E>> vect{
291       {unexpected, E::E1}, {3}, {1}, {unexpected, E::E1}, {2},
292   };
293   std::vector<Expected<int, E>> expected{
294       {unexpected, E::E1}, {unexpected, E::E1}, {1}, {2}, {3},
295   };
296   std::sort(vect.begin(), vect.end());
297   EXPECT_EQ(vect, expected);
298 }
299
300 TEST(Expected, Swap) {
301   Expected<std::string, E> a;
302   Expected<std::string, E> b;
303
304   swap(a, b);
305   EXPECT_FALSE(a.hasValue());
306   EXPECT_FALSE(b.hasValue());
307
308   a = "hello";
309   EXPECT_TRUE(a.hasValue());
310   EXPECT_FALSE(b.hasValue());
311   EXPECT_EQ("hello", a.value());
312
313   swap(a, b);
314   EXPECT_FALSE(a.hasValue());
315   EXPECT_TRUE(b.hasValue());
316   EXPECT_EQ("hello", b.value());
317
318   a = "bye";
319   EXPECT_TRUE(a.hasValue());
320   EXPECT_EQ("bye", a.value());
321
322   swap(a, b);
323 }
324
325 TEST(Expected, Comparisons) {
326   Expected<int, E> o_;
327   Expected<int, E> o1(1);
328   Expected<int, E> o2(2);
329
330   EXPECT_TRUE(o_ <= (o_));
331   EXPECT_TRUE(o_ == (o_));
332   EXPECT_TRUE(o_ >= (o_));
333
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);
342
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);
351
352   /* folly::Expected explicitly doesn't support comparisons with contained value
353   EXPECT_TRUE(1 < o2);
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);
360   EXPECT_TRUE(2 > o1);
361
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);
370   */
371 }
372
373 TEST(Expected, Conversions) {
374   Expected<bool, E> mbool;
375   Expected<short, E> mshort;
376   Expected<char*, E> mstr;
377   Expected<int, E> mint;
378
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));
383
384   // intended explicit operator bool, for if (ex).
385   bool b(mbool);
386   EXPECT_FALSE(b);
387
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
391       ;
392     }
393   }
394
395   mbool = false;
396   EXPECT_TRUE(bool(mbool));
397   EXPECT_FALSE(*mbool);
398
399   mbool = true;
400   EXPECT_TRUE(bool(mbool));
401   EXPECT_TRUE(*mbool);
402
403   mbool = {unexpected, E::E1};
404   EXPECT_FALSE(bool(mbool));
405
406   // No conversion allowed; does not compile
407   // mbool == false;
408 }
409
410 TEST(Expected, Pointee) {
411   Expected<int, E> x;
412   EXPECT_FALSE(get_pointer(x));
413   x = 1;
414   EXPECT_TRUE(get_pointer(x));
415   *get_pointer(x) = 2;
416   EXPECT_TRUE(*x == 2);
417   x = {unexpected, E::E1};
418   EXPECT_FALSE(get_pointer(x));
419 }
420
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");
427   *exStr = "cde";
428   EXPECT_EQ(s, "abc");
429   EXPECT_EQ(*exStr, "cde");
430
431   // L-value version
432   std::string s2("abc");
433   auto exStr2 = makeExpected<E>(s2);
434   ASSERT_TRUE(exStr2.hasValue());
435   EXPECT_EQ(*exStr2, "abc");
436   *exStr2 = "cde";
437   // it's vital to check that s2 wasn't clobbered
438   EXPECT_EQ(s2, "abc");
439
440   // L-value reference version
441   std::string& s3(s2);
442   auto exStr3 = makeExpected<E>(s3);
443   ASSERT_TRUE(exStr3.hasValue());
444   EXPECT_EQ(*exStr3, "abc");
445   *exStr3 = "cde";
446   EXPECT_EQ(s3, "abc");
447
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);
454 }
455
456 #if __CLANG_PREREQ(3, 6)
457 #pragma clang diagnostic push
458 #pragma clang diagnostic ignored "-Wself-move"
459 #endif
460
461 TEST(Expected, SelfAssignment) {
462   Expected<std::string, E> a = "42";
463   a = a;
464   ASSERT_TRUE(a.hasValue() && a.value() == "42");
465
466   Expected<std::string, E> b = "23333333";
467   b = std::move(b);
468   ASSERT_TRUE(b.hasValue() && b.value() == "23333333");
469 }
470
471 #if __CLANG_PREREQ(3, 6)
472 #pragma clang diagnostic pop
473 #endif
474
475 class ContainsExpected {
476  public:
477   ContainsExpected() {}
478   explicit ContainsExpected(int x) : ex_(x) {}
479   bool hasValue() const {
480     return ex_.hasValue();
481   }
482   int value() const {
483     return ex_.value();
484   }
485
486   ContainsExpected(const ContainsExpected& other) = default;
487   ContainsExpected& operator=(const ContainsExpected& other) = default;
488   ContainsExpected(ContainsExpected&& other) = default;
489   ContainsExpected& operator=(ContainsExpected&& other) = default;
490
491  private:
492   Expected<int, E> ex_;
493 };
494
495 /**
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
498  * defined.
499  */
500 TEST(Expected, AssignmentContained) {
501   {
502     ContainsExpected source(5), target;
503     target = source;
504     EXPECT_TRUE(target.hasValue());
505     EXPECT_EQ(5, target.value());
506   }
507
508   {
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());
514   }
515
516   {
517     ContainsExpected ex_uninit, target(10);
518     target = ex_uninit;
519     EXPECT_FALSE(target.hasValue());
520   }
521 }
522
523 TEST(Expected, Exceptions) {
524   Expected<int, E> empty;
525   EXPECT_THROW(empty.value(), Unexpected<E>::BadExpectedAccess);
526 }
527
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);
534 };
535
536 TEST(Expected, NoThrowDefaultConstructible) {
537   EXPECT_TRUE(
538       (std::is_nothrow_default_constructible<Expected<bool, E>>::value));
539   EXPECT_TRUE(
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));
545 }
546
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));
551   EXPECT_FALSE((
552       std::is_nothrow_move_constructible<Expected<ThrowingBadness, E>>::value));
553 }
554
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));
559   EXPECT_FALSE(
560       (std::is_nothrow_move_assignable<Expected<ThrowingBadness, E>>::value));
561 }
562
563 struct NoSelfAssign {
564   NoSelfAssign() = default;
565   NoSelfAssign(NoSelfAssign&&) = default;
566   NoSelfAssign(const NoSelfAssign&) = default;
567   NoSelfAssign& operator=(NoSelfAssign&& that) {
568     EXPECT_NE(this, &that);
569     return *this;
570   }
571   NoSelfAssign& operator=(const NoSelfAssign& that) {
572     EXPECT_NE(this, &that);
573     return *this;
574   }
575 };
576
577 #ifdef __GNUC__
578 #pragma GCC diagnostic push
579 #pragma GCC diagnostic ignored "-Wpragmas"
580 #pragma GCC diagnostic ignored "-Wself-move"
581 #endif
582
583 TEST(Expected, NoSelfAssign) {
584   folly::Expected<NoSelfAssign, int> e {NoSelfAssign{}};
585   e = e; // @nolint
586   e = std::move(e); // @nolint
587 }
588
589 #ifdef __GNUC__
590 #pragma GCC diagnostic pop
591 #endif
592
593 struct NoDestructor {};
594
595 struct WithDestructor {
596   ~WithDestructor();
597 };
598
599 TEST(Expected, TriviallyDestructible) {
600   // These could all be static_asserts but EXPECT_* give much nicer output on
601   // failure.
602   EXPECT_TRUE(
603       (std::is_trivially_destructible<Expected<NoDestructor, E>>::value));
604   EXPECT_TRUE((std::is_trivially_destructible<Expected<int, E>>::value));
605   EXPECT_FALSE(
606       (std::is_trivially_destructible<Expected<WithDestructor, E>>::value));
607 }
608
609 struct NoConstructor {};
610
611 struct WithConstructor {
612   WithConstructor();
613 };
614
615 TEST(Expected, TriviallyCopyable) {
616   // These could all be static_asserts but EXPECT_* give much nicer output on
617   // failure.
618   EXPECT_TRUE((IsTriviallyCopyable<Expected<int, E>>::value));
619   EXPECT_TRUE((IsTriviallyCopyable<Expected<char*, E>>::value));
620   EXPECT_TRUE(
621       (IsTriviallyCopyable<Expected<NoDestructor, E>>::value));
622   EXPECT_FALSE(
623       (IsTriviallyCopyable<Expected<WithDestructor, E>>::value));
624   EXPECT_TRUE(
625       (IsTriviallyCopyable<Expected<NoConstructor, E>>::value));
626   EXPECT_FALSE(
627       (IsTriviallyCopyable<Expected<std::string, E>>::value));
628   EXPECT_FALSE(
629       (IsTriviallyCopyable<Expected<int, std::string>>::value));
630 // libstdc++ with GCC 4.x doesn't have std::is_trivially_copyable
631 #if (defined(__clang__) && !defined(_LIBCPP_VERSION)) || \
632     !(defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5)
633   EXPECT_TRUE(
634       (IsTriviallyCopyable<Expected<WithConstructor, E>>::value));
635 #endif
636   EXPECT_TRUE(
637       (IsTriviallyCopyable<Expected<Expected<int, E>, E>>::value));
638 }
639
640 TEST(Expected, Then) {
641   // Lifting
642   {
643     Expected<int, E> ex = Expected<std::unique_ptr<int>, E>{
644         in_place, new int(42)}.then([](std::unique_ptr<int> p) { return *p; });
645     EXPECT_TRUE(bool(ex));
646     EXPECT_EQ(42, *ex);
647   }
648
649   // Flattening
650   {
651     Expected<int, E> ex =
652         Expected<std::unique_ptr<int>, E>{in_place, new int(42)}.then(
653             [](std::unique_ptr<int> p) { return makeExpected<E>(*p); });
654     EXPECT_TRUE(bool(ex));
655     EXPECT_EQ(42, *ex);
656   }
657
658   // Void
659   {
660     Expected<Unit, E> ex = Expected<std::unique_ptr<int>, E>{
661         in_place, new int(42)}.then([](std::unique_ptr<int>) {});
662     EXPECT_TRUE(bool(ex));
663   }
664
665   // Non-flattening (different error codes)
666   {
667     Expected<Expected<int, int>, E> ex =
668         Expected<std::unique_ptr<int>, E>{in_place, new int(42)}.then(
669             [](std::unique_ptr<int> p) { return makeExpected<int>(*p); });
670     EXPECT_TRUE(bool(ex));
671     EXPECT_TRUE(bool(*ex));
672     EXPECT_EQ(42, **ex);
673   }
674
675   {
676     // Error case:
677     Expected<int, E> ex = Expected<std::unique_ptr<int>, E>{
678         unexpected, E::E1}.then([](std::unique_ptr<int> p) -> int {
679       ADD_FAILURE();
680       return *p;
681     });
682     EXPECT_FALSE(bool(ex));
683     EXPECT_EQ(E::E1, ex.error());
684   }
685
686   // Chaining
687   {
688     Expected<std::string, E> ex =
689         Expected<std::unique_ptr<int>, E>{in_place, new int(42)}.then(
690             [](std::unique_ptr<int> p) { return makeExpected<E>(*p); },
691             [](int i) { return i == 42 ? "yes" : "no"; });
692     EXPECT_TRUE(bool(ex));
693     EXPECT_EQ("yes", *ex);
694   }
695
696   // Chaining with errors
697   {
698     Expected<std::string, E> ex =
699         Expected<std::unique_ptr<int>, E>{in_place, new int(42)}.then(
700             [](std::unique_ptr<int>) {
701               return Expected<int, E>(unexpected, E::E1);
702             },
703             [](int i) { return i == 42 ? "yes" : "no"; });
704     EXPECT_FALSE(bool(ex));
705     EXPECT_EQ(E::E1, ex.error());
706   }
707 }
708
709 TEST(Expected, ThenOrThrow) {
710   {
711     int e =
712         Expected<std::unique_ptr<int>, E>{in_place, new int(42)}.thenOrThrow(
713             [](std::unique_ptr<int> p) { return *p; });
714     EXPECT_EQ(42, e);
715   }
716
717   {
718     EXPECT_THROW(
719         (Expected<std::unique_ptr<int>, E>{unexpected, E::E1}.thenOrThrow(
720             [](std::unique_ptr<int> p) { return *p; })),
721         Unexpected<E>::BadExpectedAccess);
722   }
723
724   {
725     EXPECT_THROW(
726         (Expected<std::unique_ptr<int>, E>{unexpected, E::E1}.thenOrThrow(
727             [](std::unique_ptr<int> p) { return *p; },
728             [](E) { return std::runtime_error(""); })),
729         std::runtime_error);
730   }
731
732   {
733     EXPECT_THROW(
734         (Expected<std::unique_ptr<int>, E>{unexpected, E::E1}.thenOrThrow(
735             [](std::unique_ptr<int> p) { return *p; },
736             [](E) { throw std::runtime_error(""); })),
737         std::runtime_error);
738   }
739
740   {
741     EXPECT_THROW(
742         (Expected<std::unique_ptr<int>, E>{unexpected, E::E1}.thenOrThrow(
743             [](std::unique_ptr<int> p) { return *p; }, [](E) {})),
744         Unexpected<E>::BadExpectedAccess);
745   }
746 }
747 } // namespace folly