945797bc5e409252de708e727af14104188ebd4b
[folly.git] / folly / Expected.h
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 /**
18  * Like folly::Optional, but can store a value *or* an error.
19  *
20  * @author Eric Niebler (eniebler@fb.com)
21  */
22
23 #pragma once
24
25 #include <cstddef>
26 #include <initializer_list>
27 #include <new>
28 #include <stdexcept>
29 #include <type_traits>
30 #include <utility>
31
32 #include <glog/logging.h>
33
34 #include <folly/Likely.h>
35 #include <folly/Optional.h>
36 #include <folly/Portability.h>
37 #include <folly/Preprocessor.h>
38 #include <folly/Traits.h>
39 #include <folly/Unit.h>
40 #include <folly/Utility.h>
41
42 #define FOLLY_EXPECTED_ID(X) FB_CONCATENATE(FB_CONCATENATE(Folly, X), __LINE__)
43
44 #define FOLLY_REQUIRES_IMPL(...)                                            \
45   bool FOLLY_EXPECTED_ID(Requires) = false,                                 \
46        typename std::enable_if<                                             \
47            (FOLLY_EXPECTED_ID(Requires) || static_cast<bool>(__VA_ARGS__)), \
48            int>::type = 0
49
50 #define FOLLY_REQUIRES_TRAILING(...) , FOLLY_REQUIRES_IMPL(__VA_ARGS__)
51
52 #define FOLLY_REQUIRES(...) template <FOLLY_REQUIRES_IMPL(__VA_ARGS__)>
53
54 /**
55  * gcc-4.7 warns about use of uninitialized memory around the use of storage_
56  * even though this is explicitly initialized at each point.
57  */
58 #if defined(__GNUC__) && !defined(__clang__)
59 #pragma GCC diagnostic push
60 #pragma GCC diagnostic ignored "-Wuninitialized"
61 #pragma GCC diagnostic ignored "-Wpragmas"
62 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
63 #endif // __GNUC__
64
65 namespace folly {
66
67 /**
68  * Forward declarations
69  */
70 template <class Error>
71 class Unexpected;
72
73 template <class Error>
74 constexpr Unexpected<typename std::decay<Error>::type> makeUnexpected(Error&&);
75
76 template <class Value, class Error>
77 class Expected;
78
79 template <class Error, class Value>
80 constexpr Expected<typename std::decay<Value>::type, Error> makeExpected(
81     Value&&);
82
83 /**
84  * Alias for an Expected type's assiciated value_type
85  */
86 template <class Expected>
87 using ExpectedValueType =
88     typename std::remove_reference<Expected>::type::value_type;
89
90 /**
91  * Alias for an Expected type's assiciated error_type
92  */
93 template <class Expected>
94 using ExpectedErrorType =
95     typename std::remove_reference<Expected>::type::error_type;
96
97 // Details...
98 namespace expected_detail {
99
100 template <typename Value, typename Error>
101 struct PromiseReturn;
102
103 #ifdef _MSC_VER
104 // MSVC 2015 can't handle the StrictConjunction, so we have
105 // to use std::conjunction instead.
106 template <template <class...> class Trait, class... Ts>
107 using StrictAllOf = std::conjunction<Trait<Ts>...>;
108 #else
109 template <template <class...> class Trait, class... Ts>
110 using StrictAllOf = StrictConjunction<Trait<Ts>...>;
111 #endif
112
113 template <class T>
114 using IsCopyable = StrictConjunction<
115     std::is_copy_constructible<T>,
116     std::is_copy_assignable<T>>;
117
118 template <class T>
119 using IsMovable = StrictConjunction<
120     std::is_move_constructible<T>,
121     std::is_move_assignable<T>>;
122
123 template <class T>
124 using IsNothrowCopyable = StrictConjunction<
125     std::is_nothrow_copy_constructible<T>,
126     std::is_nothrow_copy_assignable<T>>;
127
128 template <class T>
129 using IsNothrowMovable = StrictConjunction<
130     std::is_nothrow_move_constructible<T>,
131     std::is_nothrow_move_assignable<T>>;
132
133 template <class From, class To>
134 using IsConvertible = StrictConjunction<
135     std::is_constructible<To, From>,
136     std::is_assignable<To&, From>>;
137
138 template <class T, class U>
139 auto doEmplaceAssign(int, T& t, U&& u) -> decltype(void(t = (U &&)u)) {
140   t = (U &&)u;
141 }
142
143 template <class T, class U>
144 auto doEmplaceAssign(long, T& t, U&& u) -> decltype(void(T((U &&)u))) {
145   t.~T();
146   ::new ((void*)std::addressof(t)) T((U &&)u);
147 }
148
149 template <class T, class... Us>
150 auto doEmplaceAssign(int, T& t, Us&&... us)
151     -> decltype(void(t = T((Us &&)us...))) {
152   t = T((Us &&)us...);
153 }
154
155 template <class T, class... Us>
156 auto doEmplaceAssign(long, T& t, Us&&... us)
157     -> decltype(void(T((Us &&)us...))) {
158   t.~T();
159   ::new ((void*)std::addressof(t)) T((Us &&)us...);
160 }
161
162 struct EmptyTag {};
163 struct ValueTag {};
164 struct ErrorTag {};
165 enum class Which : unsigned char { eEmpty, eValue, eError };
166 enum class StorageType { ePODStruct, ePODUnion, eUnion };
167
168 template <class Value, class Error>
169 constexpr StorageType getStorageType() {
170   return StrictAllOf<IsTriviallyCopyable, Value, Error>::value
171       ? (sizeof(std::pair<Value, Error>) <= sizeof(void * [2]) &&
172                  StrictAllOf<std::is_trivial, Value, Error>::value
173              ? StorageType::ePODStruct
174              : StorageType::ePODUnion)
175       : StorageType::eUnion;
176 }
177
178 template <
179     class Value,
180     class Error,
181     StorageType = expected_detail::getStorageType<Value, Error>()> // ePODUnion
182 struct ExpectedStorage {
183   using value_type = Value;
184   using error_type = Error;
185   union {
186     Value value_;
187     Error error_;
188     char ch_;
189   };
190   Which which_;
191
192   template <class E = Error, class = decltype(E{})>
193   constexpr ExpectedStorage() noexcept(noexcept(E{}))
194       : error_{}, which_(Which::eError) {}
195   explicit constexpr ExpectedStorage(EmptyTag) noexcept
196       : ch_{}, which_(Which::eEmpty) {}
197   template <class... Vs>
198   explicit constexpr ExpectedStorage(ValueTag, Vs&&... vs) noexcept(
199       noexcept(Value(static_cast<Vs&&>(vs)...)))
200       : value_(static_cast<Vs&&>(vs)...), which_(Which::eValue) {}
201   template <class... Es>
202   explicit constexpr ExpectedStorage(ErrorTag, Es&&... es) noexcept(
203       noexcept(Error(static_cast<Es&&>(es)...)))
204       : error_(static_cast<Es&&>(es)...), which_(Which::eError) {}
205   void clear() noexcept {}
206   static constexpr bool uninitializedByException() noexcept {
207     // Although which_ may temporarily be eEmpty during construction, it
208     // is always either eValue or eError for a fully-constructed Expected.
209     return false;
210   }
211   template <class... Vs>
212   void assignValue(Vs&&... vs) {
213     expected_detail::doEmplaceAssign(0, value_, static_cast<Vs&&>(vs)...);
214     which_ = Which::eValue;
215   }
216   template <class... Es>
217   void assignError(Es&&... es) {
218     expected_detail::doEmplaceAssign(0, error_, static_cast<Es&&>(es)...);
219     which_ = Which::eError;
220   }
221   template <class Other>
222   void assign(Other&& that) {
223     switch (that.which_) {
224       case Which::eValue:
225         this->assignValue(static_cast<Other&&>(that).value());
226         break;
227       case Which::eError:
228         this->assignError(static_cast<Other&&>(that).error());
229         break;
230       default:
231         this->clear();
232         break;
233     }
234   }
235   Value& value() & {
236     return value_;
237   }
238   const Value& value() const& {
239     return value_;
240   }
241   Value&& value() && {
242     return std::move(value_);
243   }
244   // TODO (t17322426): remove when VS2015 support is deprecated
245   // VS2015 static analyzer incorrectly flags these as unreachable in certain
246   // circumstances. VS2017 does not have this problem on the same code.
247   FOLLY_PUSH_WARNING
248   FOLLY_MSVC_DISABLE_WARNING(4702) // unreachable code
249   Error& error() & {
250     return error_;
251   }
252   const Error& error() const& {
253     return error_;
254   }
255   Error&& error() && {
256     return std::move(error_);
257   }
258   FOLLY_POP_WARNING
259 };
260
261 template <class Value, class Error>
262 struct ExpectedUnion {
263   union {
264     Value value_;
265     Error error_;
266     char ch_{};
267   };
268   Which which_ = Which::eEmpty;
269
270   explicit constexpr ExpectedUnion(EmptyTag) noexcept {}
271   template <class... Vs>
272   explicit constexpr ExpectedUnion(ValueTag, Vs&&... vs) noexcept(
273       noexcept(Value(static_cast<Vs&&>(vs)...)))
274       : value_(static_cast<Vs&&>(vs)...), which_(Which::eValue) {}
275   template <class... Es>
276   explicit constexpr ExpectedUnion(ErrorTag, Es&&... es) noexcept(
277       noexcept(Error(static_cast<Es&&>(es)...)))
278       : error_(static_cast<Es&&>(es)...), which_(Which::eError) {}
279   ExpectedUnion(const ExpectedUnion&) {}
280   ExpectedUnion(ExpectedUnion&&) noexcept {}
281   ExpectedUnion& operator=(const ExpectedUnion&) {
282     return *this;
283   }
284   ExpectedUnion& operator=(ExpectedUnion&&) noexcept {
285     return *this;
286   }
287   ~ExpectedUnion() {}
288   Value& value() & {
289     return value_;
290   }
291   const Value& value() const& {
292     return value_;
293   }
294   Value&& value() && {
295     return std::move(value_);
296   }
297   Error& error() & {
298     return error_;
299   }
300   const Error& error() const& {
301     return error_;
302   }
303   Error&& error() && {
304     return std::move(error_);
305   }
306 };
307
308 template <class Derived, bool, bool Noexcept>
309 struct CopyConstructible {
310   constexpr CopyConstructible() = default;
311   CopyConstructible(const CopyConstructible& that) noexcept(Noexcept) {
312     static_cast<Derived*>(this)->assign(static_cast<const Derived&>(that));
313   }
314   constexpr CopyConstructible(CopyConstructible&&) = default;
315   CopyConstructible& operator=(const CopyConstructible&) = default;
316   CopyConstructible& operator=(CopyConstructible&&) = default;
317 };
318
319 template <class Derived, bool Noexcept>
320 struct CopyConstructible<Derived, false, Noexcept> {
321   constexpr CopyConstructible() = default;
322   CopyConstructible(const CopyConstructible&) = delete;
323   constexpr CopyConstructible(CopyConstructible&&) = default;
324   CopyConstructible& operator=(const CopyConstructible&) = default;
325   CopyConstructible& operator=(CopyConstructible&&) = default;
326 };
327
328 template <class Derived, bool, bool Noexcept>
329 struct MoveConstructible {
330   constexpr MoveConstructible() = default;
331   constexpr MoveConstructible(const MoveConstructible&) = default;
332   MoveConstructible(MoveConstructible&& that) noexcept(Noexcept) {
333     static_cast<Derived*>(this)->assign(std::move(static_cast<Derived&>(that)));
334   }
335   MoveConstructible& operator=(const MoveConstructible&) = default;
336   MoveConstructible& operator=(MoveConstructible&&) = default;
337 };
338
339 template <class Derived, bool Noexcept>
340 struct MoveConstructible<Derived, false, Noexcept> {
341   constexpr MoveConstructible() = default;
342   constexpr MoveConstructible(const MoveConstructible&) = default;
343   MoveConstructible(MoveConstructible&&) = delete;
344   MoveConstructible& operator=(const MoveConstructible&) = default;
345   MoveConstructible& operator=(MoveConstructible&&) = default;
346 };
347
348 template <class Derived, bool, bool Noexcept>
349 struct CopyAssignable {
350   constexpr CopyAssignable() = default;
351   constexpr CopyAssignable(const CopyAssignable&) = default;
352   constexpr CopyAssignable(CopyAssignable&&) = default;
353   CopyAssignable& operator=(const CopyAssignable& that) noexcept(Noexcept) {
354     static_cast<Derived*>(this)->assign(static_cast<const Derived&>(that));
355     return *this;
356   }
357   CopyAssignable& operator=(CopyAssignable&&) = default;
358 };
359
360 template <class Derived, bool Noexcept>
361 struct CopyAssignable<Derived, false, Noexcept> {
362   constexpr CopyAssignable() = default;
363   constexpr CopyAssignable(const CopyAssignable&) = default;
364   constexpr CopyAssignable(CopyAssignable&&) = default;
365   CopyAssignable& operator=(const CopyAssignable&) = delete;
366   CopyAssignable& operator=(CopyAssignable&&) = default;
367 };
368
369 template <class Derived, bool, bool Noexcept>
370 struct MoveAssignable {
371   constexpr MoveAssignable() = default;
372   constexpr MoveAssignable(const MoveAssignable&) = default;
373   constexpr MoveAssignable(MoveAssignable&&) = default;
374   MoveAssignable& operator=(const MoveAssignable&) = default;
375   MoveAssignable& operator=(MoveAssignable&& that) noexcept(Noexcept) {
376     static_cast<Derived*>(this)->assign(std::move(static_cast<Derived&>(that)));
377     return *this;
378   }
379 };
380
381 template <class Derived, bool Noexcept>
382 struct MoveAssignable<Derived, false, Noexcept> {
383   constexpr MoveAssignable() = default;
384   constexpr MoveAssignable(const MoveAssignable&) = default;
385   constexpr MoveAssignable(MoveAssignable&&) = default;
386   MoveAssignable& operator=(const MoveAssignable&) = default;
387   MoveAssignable& operator=(MoveAssignable&& that) = delete;
388 };
389
390 template <class Value, class Error>
391 struct ExpectedStorage<Value, Error, StorageType::eUnion>
392     : ExpectedUnion<Value, Error>,
393       CopyConstructible<
394           ExpectedStorage<Value, Error, StorageType::eUnion>,
395           StrictAllOf<std::is_copy_constructible, Value, Error>::value,
396           StrictAllOf<std::is_nothrow_copy_constructible, Value, Error>::value>,
397       MoveConstructible<
398           ExpectedStorage<Value, Error, StorageType::eUnion>,
399           StrictAllOf<std::is_move_constructible, Value, Error>::value,
400           StrictAllOf<std::is_nothrow_move_constructible, Value, Error>::value>,
401       CopyAssignable<
402           ExpectedStorage<Value, Error, StorageType::eUnion>,
403           StrictAllOf<IsCopyable, Value, Error>::value,
404           StrictAllOf<IsNothrowCopyable, Value, Error>::value>,
405       MoveAssignable<
406           ExpectedStorage<Value, Error, StorageType::eUnion>,
407           StrictAllOf<IsMovable, Value, Error>::value,
408           StrictAllOf<IsNothrowMovable, Value, Error>::value> {
409   using value_type = Value;
410   using error_type = Error;
411   using Base = ExpectedUnion<Value, Error>;
412   template <class E = Error, class = decltype(E{})>
413   constexpr ExpectedStorage() noexcept(noexcept(E{})) : Base{ErrorTag{}} {}
414   ExpectedStorage(const ExpectedStorage&) = default;
415   ExpectedStorage(ExpectedStorage&&) = default;
416   ExpectedStorage& operator=(const ExpectedStorage&) = default;
417   ExpectedStorage& operator=(ExpectedStorage&&) = default;
418   using ExpectedUnion<Value, Error>::ExpectedUnion;
419   ~ExpectedStorage() {
420     clear();
421   }
422   void clear() noexcept {
423     switch (this->which_) {
424       case Which::eValue:
425         this->value().~Value();
426         break;
427       case Which::eError:
428         this->error().~Error();
429         break;
430       default:
431         break;
432     }
433     this->which_ = Which::eEmpty;
434   }
435   bool uninitializedByException() const noexcept {
436     return this->which_ == Which::eEmpty;
437   }
438   template <class... Vs>
439   void assignValue(Vs&&... vs) {
440     if (this->which_ == Which::eValue) {
441       expected_detail::doEmplaceAssign(
442           0, this->value(), static_cast<Vs&&>(vs)...);
443     } else {
444       this->clear();
445       ::new ((void*)std::addressof(this->value()))
446           Value(static_cast<Vs&&>(vs)...);
447       this->which_ = Which::eValue;
448     }
449   }
450   template <class... Es>
451   void assignError(Es&&... es) {
452     if (this->which_ == Which::eError) {
453       expected_detail::doEmplaceAssign(
454           0, this->error(), static_cast<Es&&>(es)...);
455     } else {
456       this->clear();
457       ::new ((void*)std::addressof(this->error()))
458           Error(static_cast<Es&&>(es)...);
459       this->which_ = Which::eError;
460     }
461   }
462   bool isSelfAssign(const ExpectedStorage* that) const {
463     return this == that;
464   }
465   constexpr bool isSelfAssign(const void*) const {
466     return false;
467   }
468   template <class Other>
469   void assign(Other&& that) {
470     if (isSelfAssign(&that)) {
471       return;
472     }
473     switch (that.which_) {
474       case Which::eValue:
475         this->assignValue(static_cast<Other&&>(that).value());
476         break;
477       case Which::eError:
478         this->assignError(static_cast<Other&&>(that).error());
479         break;
480       default:
481         this->clear();
482         break;
483     }
484   }
485 };
486
487 // For small (pointer-sized) trivial types, a struct is faster than a union.
488 template <class Value, class Error>
489 struct ExpectedStorage<Value, Error, StorageType::ePODStruct> {
490   using value_type = Value;
491   using error_type = Error;
492   Which which_;
493   Error error_;
494   Value value_;
495
496   constexpr ExpectedStorage() noexcept
497       : which_(Which::eError), error_{}, value_{} {}
498   explicit constexpr ExpectedStorage(EmptyTag) noexcept
499       : which_(Which::eEmpty), error_{}, value_{} {}
500   template <class... Vs>
501   explicit constexpr ExpectedStorage(ValueTag, Vs&&... vs) noexcept(
502       noexcept(Value(static_cast<Vs&&>(vs)...)))
503       : which_(Which::eValue), error_{}, value_(static_cast<Vs&&>(vs)...) {}
504   template <class... Es>
505   explicit constexpr ExpectedStorage(ErrorTag, Es&&... es) noexcept(
506       noexcept(Error(static_cast<Es&&>(es)...)))
507       : which_(Which::eError), error_(static_cast<Es&&>(es)...), value_{} {}
508   void clear() noexcept {}
509   constexpr static bool uninitializedByException() noexcept {
510     return false;
511   }
512   template <class... Vs>
513   void assignValue(Vs&&... vs) {
514     expected_detail::doEmplaceAssign(0, value_, static_cast<Vs&&>(vs)...);
515     which_ = Which::eValue;
516   }
517   template <class... Es>
518   void assignError(Es&&... es) {
519     expected_detail::doEmplaceAssign(0, error_, static_cast<Es&&>(es)...);
520     which_ = Which::eError;
521   }
522   template <class Other>
523   void assign(Other&& that) {
524     switch (that.which_) {
525       case Which::eValue:
526         this->assignValue(static_cast<Other&&>(that).value());
527         break;
528       case Which::eError:
529         this->assignError(static_cast<Other&&>(that).error());
530         break;
531       default:
532         this->clear();
533         break;
534     }
535   }
536   Value& value() & {
537     return value_;
538   }
539   const Value& value() const& {
540     return value_;
541   }
542   Value&& value() && {
543     return std::move(value_);
544   }
545   // TODO (t17322426): remove when VS2015 support is deprecated
546   // VS2015 static analyzer incorrectly flags these as unreachable in certain
547   // circumstances. VS2017 does not have this problem on the same code.
548   FOLLY_PUSH_WARNING
549   FOLLY_MSVC_DISABLE_WARNING(4702) // unreachable code
550   Error& error() & {
551     return error_;
552   }
553   const Error& error() const& {
554     return error_;
555   }
556   Error&& error() && {
557     return std::move(error_);
558   }
559   FOLLY_POP_WARNING
560 };
561
562 namespace expected_detail_ExpectedHelper {
563 // Tricky hack so that Expected::then can handle lambdas that return void
564 template <class T>
565 inline T&& operator,(T&& t, Unit) noexcept {
566   return static_cast<T&&>(t);
567 }
568
569 struct ExpectedHelper {
570   template <class Error, class T>
571   static constexpr Expected<T, Error> return_(T t) {
572     return folly::makeExpected<Error>(t);
573   }
574   template <
575       class Error,
576       class T,
577       class U FOLLY_REQUIRES_TRAILING(
578           expected_detail::IsConvertible<U&&, Error>::value)>
579   static constexpr Expected<T, Error> return_(Expected<T, U> t) {
580     return t;
581   }
582
583   template <class This>
584   static typename std::decay<This>::type then_(This&& ex) {
585     return static_cast<This&&>(ex);
586   }
587
588   FOLLY_PUSH_WARNING
589   // Don't warn about not using the overloaded comma operator.
590   FOLLY_MSVC_DISABLE_WARNING(4913)
591   template <
592       class This,
593       class Fn,
594       class... Fns,
595       class E = ExpectedErrorType<This>,
596       class T = ExpectedHelper>
597   static auto then_(This&& ex, Fn&& fn, Fns&&... fns) -> decltype(T::then_(
598       T::template return_<E>(
599           (std::declval<Fn>()(std::declval<This>().value()), unit)),
600       std::declval<Fns>()...)) {
601     if (LIKELY(ex.which_ == expected_detail::Which::eValue)) {
602       return T::then_(
603           T::template return_<E>(
604               // Uses the comma operator defined above IFF the lambda
605               // returns non-void.
606               (static_cast<Fn&&>(fn)(static_cast<This&&>(ex).value()), unit)),
607           static_cast<Fns&&>(fns)...);
608     }
609     return makeUnexpected(static_cast<This&&>(ex).error());
610   }
611
612   template <
613       class This,
614       class Yes,
615       class No,
616       class Ret = decltype(std::declval<Yes>()(std::declval<This>().value())),
617       class Err = decltype(std::declval<No>()(std::declval<This>().error()))
618           FOLLY_REQUIRES_TRAILING(!std::is_void<Err>::value)>
619   static Ret thenOrThrow_(This&& ex, Yes&& yes, No&& no) {
620     if (LIKELY(ex.which_ == expected_detail::Which::eValue)) {
621       return Ret(static_cast<Yes&&>(yes)(static_cast<This&&>(ex).value()));
622     }
623     throw static_cast<No&&>(no)(static_cast<This&&>(ex).error());
624   }
625
626   template <
627       class This,
628       class Yes,
629       class No,
630       class Ret = decltype(std::declval<Yes>()(std::declval<This>().value())),
631       class Err = decltype(std::declval<No>()(std::declval<This&>().error()))
632           FOLLY_REQUIRES_TRAILING(std::is_void<Err>::value)>
633   static Ret thenOrThrow_(This&& ex, Yes&& yes, No&& no) {
634     if (LIKELY(ex.which_ == expected_detail::Which::eValue)) {
635       return Ret(static_cast<Yes&&>(yes)(static_cast<This&&>(ex).value()));
636     }
637     static_cast<No&&>(no)(ex.error());
638     throw typename Unexpected<ExpectedErrorType<This>>::MakeBadExpectedAccess()(
639         static_cast<This&&>(ex).error());
640   }
641   FOLLY_POP_WARNING
642 };
643 } // namespace expected_detail_ExpectedHelper
644 /* using override */ using expected_detail_ExpectedHelper::ExpectedHelper;
645
646 struct UnexpectedTag {};
647
648 } // namespace expected_detail
649
650 using unexpected_t =
651     expected_detail::UnexpectedTag (&)(expected_detail::UnexpectedTag);
652
653 inline expected_detail::UnexpectedTag unexpected(
654     expected_detail::UnexpectedTag = {}) {
655   return {};
656 }
657
658 /**
659  * An exception type thrown by Expected on catastrophic logic errors.
660  */
661 class BadExpectedAccess : public std::logic_error {
662  public:
663   BadExpectedAccess() : std::logic_error("bad Expected access") {}
664 };
665
666 namespace expected_detail {
667
668 [[noreturn]] void throwBadExpectedAccess();
669
670 } // namespace expected_detail
671
672 /**
673  * Unexpected - a helper type used to disambiguate the construction of
674  * Expected objects in the error state.
675  */
676 template <class Error>
677 class Unexpected final {
678   template <class E>
679   friend class Unexpected;
680   template <class V, class E>
681   friend class Expected;
682   friend struct expected_detail::ExpectedHelper;
683
684  public:
685   /**
686    * Unexpected::BadExpectedAccess - An exception type thrown by Expected
687    * when the user tries to access the nested value but the Expected object is
688    * actually storing an error code.
689    */
690   class BadExpectedAccess : public folly::BadExpectedAccess {
691    public:
692     explicit BadExpectedAccess(Error err)
693         : folly::BadExpectedAccess{}, error_(std::move(err)) {}
694     /**
695      * The error code that was held by the Expected object when the user
696      * erroneously requested the value.
697      */
698     Error error() const {
699       return error_;
700     }
701
702    private:
703     Error error_;
704   };
705
706   /**
707    * Constructors
708    */
709   Unexpected() = default;
710   Unexpected(const Unexpected&) = default;
711   Unexpected(Unexpected&&) = default;
712   Unexpected& operator=(const Unexpected&) = default;
713   Unexpected& operator=(Unexpected&&) = default;
714   constexpr /* implicit */ Unexpected(const Error& err) : error_(err) {}
715   constexpr /* implicit */ Unexpected(Error&& err) : error_(std::move(err)) {}
716
717   template <class Other FOLLY_REQUIRES_TRAILING(
718       std::is_constructible<Error, Other&&>::value)>
719   constexpr /* implicit */ Unexpected(Unexpected<Other> that)
720       : error_(std::move(that.error())) {}
721
722   /**
723    * Assignment
724    */
725   template <class Other FOLLY_REQUIRES_TRAILING(
726       std::is_assignable<Error&, Other&&>::value)>
727   Unexpected& operator=(Unexpected<Other> that) {
728     error_ = std::move(that.error());
729   }
730
731   /**
732    * Observers
733    */
734   Error& error() & {
735     return error_;
736   }
737   const Error& error() const& {
738     return error_;
739   }
740   Error&& error() && {
741     return std::move(error_);
742   }
743
744  private:
745   struct MakeBadExpectedAccess {
746     template <class E>
747     BadExpectedAccess operator()(E&& err) const {
748       return BadExpectedAccess(static_cast<E&&>(err));
749     }
750   };
751
752   Error error_;
753 };
754
755 template <
756     class Error FOLLY_REQUIRES_TRAILING(IsEqualityComparable<Error>::value)>
757 inline bool operator==(
758     const Unexpected<Error>& lhs,
759     const Unexpected<Error>& rhs) {
760   return lhs.error() == rhs.error();
761 }
762
763 template <
764     class Error FOLLY_REQUIRES_TRAILING(IsEqualityComparable<Error>::value)>
765 inline bool operator!=(
766     const Unexpected<Error>& lhs,
767     const Unexpected<Error>& rhs) {
768   return !(lhs == rhs);
769 }
770
771 /**
772  * For constructing an Unexpected object from an error code. Unexpected objects
773  * are implicitly convertible to Expected object in the error state. Usage is
774  * as follows:
775  *
776  * enum class MyErrorCode { BAD_ERROR, WORSE_ERROR };
777  * Expected<int, MyErrorCode> myAPI() {
778  *   int i = // ...;
779  *   return i ? makeExpected<MyErrorCode>(i)
780  *            : makeUnexpected(MyErrorCode::BAD_ERROR);
781  * }
782  */
783 template <class Error>
784 constexpr Unexpected<typename std::decay<Error>::type> makeUnexpected(
785     Error&& err) {
786   return Unexpected<typename std::decay<Error>::type>{
787       static_cast<Error&&>(err)};
788 }
789
790 /**
791  * Expected - For holding a value or an error. Useful as an alternative to
792  * exceptions, for APIs where throwing on failure would be too expensive.
793  *
794  * Expected<Value, Error> is a variant over the types Value and Error.
795  *
796  * Expected does not offer support for references. Use
797  * Expected<std::reference_wrapper<T>, Error> if your API needs to return a
798  * reference or an error.
799  *
800  * Expected offers a continuation-based interface to reduce the boilerplate
801  * of checking error codes. The Expected::then member function takes a lambda
802  * that is to execute should the Expected object contain a value. The return
803  * value of the lambda is wrapped in an Expected and returned. If the lambda is
804  * not executed because the Expected contains an error, the error is returned
805  * immediately in a new Expected object.
806  *
807  * Expected<int, Error> funcTheFirst();
808  * Expected<std::string, Error> funcTheSecond() {
809  *   return funcTheFirst().then([](int i) { return std::to_string(i); });
810  * }
811  *
812  * The above line of code could more verbosely written as:
813  *
814  * Expected<std::string, Error> funcTheSecond() {
815  *   if (auto ex = funcTheFirst()) {
816  *     return std::to_string(*ex);
817  *   }
818  *   return makeUnexpected(ex.error());
819  * }
820  *
821  * Continuations can chain, like:
822  *
823  * Expected<D, Error> maybeD = someFunc()
824  *     .then([](A a){return B(a);})
825  *     .then([](B b){return C(b);})
826  *     .then([](C c){return D(c);});
827  *
828  * To avoid the redundant error checking that would happen if a call at the
829  * front of the chain returns an error, these call chains can be collaped into
830  * a single call to .then:
831  *
832  * Expected<D, Error> maybeD = someFunc()
833  *     .then([](A a){return B(a);},
834  *           [](B b){return C(b);},
835  *           [](C c){return D(c);});
836  *
837  * The result of .then() is wrapped into Expected< ~, Error > if it isn't
838  * of that form already. Consider the following code:
839  *
840  * extern Expected<std::string, Error> readLineFromIO();
841  * extern Expected<int, Error> parseInt(std::string);
842  * extern int increment(int);
843  *
844  * Expected<int, Error> x = readLineFromIO().then(parseInt).then(increment);
845  *
846  * From the code above, we see that .then() works both with functions that
847  * return an Expected< ~, Error > (like parseInt) and with ones that return
848  * a plain value (like increment). In the case of parseInt, .then() returns
849  * the result of parseInt as-is. In the case of increment, it wraps the int
850  * that increment returns into an Expected< int, Error >.
851  *
852  * Sometimes when using a continuation you would prefer an exception to be
853  * thrown for a value-less Expected. For that you can use .thenOrThrow, as
854  * follows:
855  *
856  * B b = someFunc()
857  *     .thenOrThrow([](A a){return B(a);});
858  *
859  * The above call to thenOrThrow will invoke the lambda if the Expected returned
860  * by someFunc() contains a value. Otherwise, it will throw an exception of type
861  * Unexpected<Error>::BadExpectedAccess. If you prefer it throw an exception of
862  * a different type, you can pass a second lambda to thenOrThrow:
863  *
864  * B b = someFunc()
865  *     .thenOrThrow([](A a){return B(a);},
866  *                  [](Error e) {throw MyException(e);});
867  *
868  * Like C++17's std::variant, Expected offers the almost-never-empty guarantee;
869  * that is, an Expected<Value, Error> almost always contains either a Value or
870  * and Error. Partially-formed Expected objects occur when an assignment to
871  * an Expected object that would change the type of the contained object (Value-
872  * to-Error or vice versa) throws. Trying to access either the contained value
873  * or error object causes Expected to throw folly::BadExpectedAccess.
874  *
875  * Expected models OptionalPointee, so calling 'get_pointer(ex)' will return a
876  * pointer to nullptr if the 'ex' is in the error state, and a pointer to the
877  * value otherwise:
878  *
879  *  Expected<int, Error> maybeInt = ...;
880  *  if (int* v = get_pointer(maybeInt)) {
881  *    cout << *v << endl;
882  *  }
883  */
884 template <class Value, class Error>
885 class Expected final : expected_detail::ExpectedStorage<Value, Error> {
886   template <class, class>
887   friend class Expected;
888   template <class, class, expected_detail::StorageType>
889   friend struct expected_detail::ExpectedStorage;
890   friend struct expected_detail::ExpectedHelper;
891   using Base = expected_detail::ExpectedStorage<Value, Error>;
892   using MakeBadExpectedAccess =
893       typename Unexpected<Error>::MakeBadExpectedAccess;
894   Base& base() & {
895     return *this;
896   }
897   const Base& base() const& {
898     return *this;
899   }
900   Base&& base() && {
901     return std::move(*this);
902   }
903
904  public:
905   using value_type = Value;
906   using error_type = Error;
907   using IsTriviallyCopyable = typename expected_detail::
908       StrictAllOf<IsTriviallyCopyable, Value, Error>::type;
909
910   template <class U>
911   using rebind = Expected<U, Error>;
912
913   static_assert(
914       !std::is_reference<Value>::value,
915       "Expected may not be used with reference types");
916   static_assert(
917       !std::is_abstract<Value>::value,
918       "Expected may not be used with abstract types");
919
920   /*
921    * Constructors
922    */
923   template <class B = Base, class = decltype(B{})>
924   Expected() noexcept(noexcept(B{})) : Base{} {}
925   Expected(const Expected& that) = default;
926   Expected(Expected&& that) = default;
927
928   template <
929       class V,
930       class E FOLLY_REQUIRES_TRAILING(
931           !std::is_same<Expected<V, E>, Expected>::value &&
932           std::is_constructible<Value, V&&>::value &&
933           std::is_constructible<Error, E&&>::value)>
934   Expected(Expected<V, E> that) : Base{expected_detail::EmptyTag{}} {
935     *this = std::move(that);
936   }
937
938   FOLLY_REQUIRES(std::is_copy_constructible<Value>::value)
939   constexpr /* implicit */ Expected(const Value& val) noexcept(
940       noexcept(Value(val)))
941       : Base{expected_detail::ValueTag{}, val} {}
942
943   FOLLY_REQUIRES(std::is_move_constructible<Value>::value)
944   constexpr /* implicit */ Expected(Value&& val) noexcept(
945       noexcept(Value(std::move(val))))
946       : Base{expected_detail::ValueTag{}, std::move(val)} {}
947
948   template <class T FOLLY_REQUIRES_TRAILING(
949       std::is_convertible<T, Value>::value &&
950       !std::is_convertible<T, Error>::value)>
951   constexpr /* implicit */ Expected(T&& val) noexcept(
952       noexcept(Value(static_cast<T&&>(val))))
953       : Base{expected_detail::ValueTag{}, static_cast<T&&>(val)} {}
954
955   template <class... Ts FOLLY_REQUIRES_TRAILING(
956       std::is_constructible<Value, Ts&&...>::value)>
957   explicit constexpr Expected(in_place_t, Ts&&... ts) noexcept(
958       noexcept(Value(std::declval<Ts>()...)))
959       : Base{expected_detail::ValueTag{}, static_cast<Ts&&>(ts)...} {}
960
961   template <
962       class U,
963       class... Ts FOLLY_REQUIRES_TRAILING(
964           std::is_constructible<Value, std::initializer_list<U>&, Ts&&...>::
965               value)>
966   explicit constexpr Expected(
967       in_place_t,
968       std::initializer_list<U> il,
969       Ts&&... ts) noexcept(noexcept(Value(std::declval<Ts>()...)))
970       : Base{expected_detail::ValueTag{}, il, static_cast<Ts&&>(ts)...} {}
971
972   // If overload resolution selects one of these deleted functions, that
973   // means you need to use makeUnexpected
974   /* implicit */ Expected(const Error&) = delete;
975   /* implicit */ Expected(Error&&) = delete;
976
977   FOLLY_REQUIRES(std::is_copy_constructible<Error>::value)
978   constexpr Expected(unexpected_t, const Error& err) noexcept(
979       noexcept(Error(err)))
980       : Base{expected_detail::ErrorTag{}, err} {}
981
982   FOLLY_REQUIRES(std::is_move_constructible<Error>::value)
983   constexpr Expected(unexpected_t, Error&& err) noexcept(
984       noexcept(Error(std::move(err))))
985       : Base{expected_detail::ErrorTag{}, std::move(err)} {}
986
987   FOLLY_REQUIRES(std::is_copy_constructible<Error>::value)
988   constexpr /* implicit */ Expected(const Unexpected<Error>& err) noexcept(
989       noexcept(Error(err.error())))
990       : Base{expected_detail::ErrorTag{}, err.error()} {}
991
992   FOLLY_REQUIRES(std::is_move_constructible<Error>::value)
993   constexpr /* implicit */ Expected(Unexpected<Error>&& err) noexcept(
994       noexcept(Error(std::move(err.error()))))
995       : Base{expected_detail::ErrorTag{}, std::move(err.error())} {}
996
997   /*
998    * Assignment operators
999    */
1000   Expected& operator=(const Expected& that) = default;
1001   Expected& operator=(Expected&& that) = default;
1002
1003   template <
1004       class V,
1005       class E FOLLY_REQUIRES_TRAILING(
1006           !std::is_same<Expected<V, E>, Expected>::value &&
1007           expected_detail::IsConvertible<V&&, Value>::value &&
1008           expected_detail::IsConvertible<E&&, Error>::value)>
1009   Expected& operator=(Expected<V, E> that) {
1010     this->assign(std::move(that));
1011     return *this;
1012   }
1013
1014   FOLLY_REQUIRES(expected_detail::IsCopyable<Value>::value)
1015   Expected& operator=(const Value& val) noexcept(
1016       expected_detail::IsNothrowCopyable<Value>::value) {
1017     this->assignValue(val);
1018     return *this;
1019   }
1020
1021   FOLLY_REQUIRES(expected_detail::IsMovable<Value>::value)
1022   Expected& operator=(Value&& val) noexcept(
1023       expected_detail::IsNothrowMovable<Value>::value) {
1024     this->assignValue(std::move(val));
1025     return *this;
1026   }
1027
1028   template <class T FOLLY_REQUIRES_TRAILING(
1029       std::is_convertible<T, Value>::value &&
1030       !std::is_convertible<T, Error>::value)>
1031   Expected& operator=(T&& val) {
1032     this->assignValue(static_cast<T&&>(val));
1033     return *this;
1034   }
1035
1036   FOLLY_REQUIRES(expected_detail::IsCopyable<Error>::value)
1037   Expected& operator=(const Unexpected<Error>& err) noexcept(
1038       expected_detail::IsNothrowCopyable<Error>::value) {
1039     this->assignError(err.error());
1040     return *this;
1041   }
1042
1043   FOLLY_REQUIRES(expected_detail::IsMovable<Error>::value)
1044   Expected& operator=(Unexpected<Error>&& err) noexcept(
1045       expected_detail::IsNothrowMovable<Error>::value) {
1046     this->assignError(std::move(err.error()));
1047     return *this;
1048   }
1049
1050   // Used only when an Expected is used with coroutines on MSVC
1051   /* implicit */ Expected(const expected_detail::PromiseReturn<Value, Error>& p)
1052       : Expected{} {
1053     p.promise_->value_ = this;
1054   }
1055
1056   template <class... Ts FOLLY_REQUIRES_TRAILING(
1057       std::is_constructible<Value, Ts&&...>::value)>
1058   void emplace(Ts&&... ts) {
1059     this->assignValue(static_cast<Ts&&>(ts)...);
1060   }
1061
1062   /**
1063    * swap
1064    */
1065   void swap(Expected& that) noexcept(
1066       expected_detail::StrictAllOf<IsNothrowSwappable, Value, Error>::value) {
1067     if (this->uninitializedByException() || that.uninitializedByException()) {
1068       expected_detail::throwBadExpectedAccess();
1069     }
1070     using std::swap;
1071     if (*this) {
1072       if (that) {
1073         swap(this->value_, that.value_);
1074       } else {
1075         Error e(std::move(that.error_));
1076         that.assignValue(std::move(this->value_));
1077         this->assignError(std::move(e));
1078       }
1079     } else {
1080       if (!that) {
1081         swap(this->error_, that.error_);
1082       } else {
1083         Error e(std::move(this->error_));
1084         this->assignValue(std::move(that.value_));
1085         that.assignError(std::move(e));
1086       }
1087     }
1088   }
1089
1090   // If overload resolution selects one of these deleted functions, that
1091   // means you need to use makeUnexpected
1092   /* implicit */ Expected& operator=(const Error&) = delete;
1093   /* implicit */ Expected& operator=(Error&&) = delete;
1094
1095   /**
1096    * Relational Operators
1097    */
1098   template <class Val, class Err>
1099   friend typename std::enable_if<IsEqualityComparable<Val>::value, bool>::type
1100   operator==(const Expected<Val, Err>& lhs, const Expected<Val, Err>& rhs);
1101   template <class Val, class Err>
1102   friend typename std::enable_if<IsLessThanComparable<Val>::value, bool>::type
1103   operator<(const Expected<Val, Err>& lhs, const Expected<Val, Err>& rhs);
1104
1105   /*
1106    * Accessors
1107    */
1108   constexpr bool hasValue() const noexcept {
1109     return expected_detail::Which::eValue == this->which_;
1110   }
1111
1112   constexpr bool hasError() const noexcept {
1113     return expected_detail::Which::eError == this->which_;
1114   }
1115
1116   using Base::uninitializedByException;
1117
1118   const Value& value() const& {
1119     requireValue();
1120     return this->Base::value();
1121   }
1122
1123   Value& value() & {
1124     requireValue();
1125     return this->Base::value();
1126   }
1127
1128   Value&& value() && {
1129     requireValue();
1130     return std::move(this->Base::value());
1131   }
1132
1133   const Error& error() const& {
1134     requireError();
1135     return this->Base::error();
1136   }
1137
1138   Error& error() & {
1139     requireError();
1140     return this->Base::error();
1141   }
1142
1143   Error&& error() && {
1144     requireError();
1145     return std::move(this->Base::error());
1146   }
1147
1148   // Return a copy of the value if set, or a given default if not.
1149   template <class U>
1150   Value value_or(U&& dflt) const& {
1151     if (LIKELY(this->which_ == expected_detail::Which::eValue)) {
1152       return this->value_;
1153     }
1154     return static_cast<U&&>(dflt);
1155   }
1156
1157   template <class U>
1158   Value value_or(U&& dflt) && {
1159     if (LIKELY(this->which_ == expected_detail::Which::eValue)) {
1160       return std::move(this->value_);
1161     }
1162     return static_cast<U&&>(dflt);
1163   }
1164
1165   explicit constexpr operator bool() const noexcept {
1166     return hasValue();
1167   }
1168
1169   const Value& operator*() const& {
1170     return this->value();
1171   }
1172
1173   Value& operator*() & {
1174     return this->value();
1175   }
1176
1177   Value&& operator*() && {
1178     return std::move(this->value());
1179   }
1180
1181   const Value* operator->() const {
1182     return std::addressof(this->value());
1183   }
1184
1185   Value* operator->() {
1186     return std::addressof(this->value());
1187   }
1188
1189   const Value* get_pointer() const& noexcept {
1190     return hasValue() ? std::addressof(this->value_) : nullptr;
1191   }
1192
1193   Value* get_pointer() & noexcept {
1194     return hasValue() ? std::addressof(this->value_) : nullptr;
1195   }
1196
1197   Value* get_pointer() && = delete;
1198
1199   /**
1200    * then
1201    */
1202   template <class... Fns FOLLY_REQUIRES_TRAILING(sizeof...(Fns) >= 1)>
1203   auto then(Fns&&... fns) const& -> decltype(
1204       expected_detail::ExpectedHelper::then_(
1205           std::declval<const Base&>(),
1206           std::declval<Fns>()...)) {
1207     if (this->uninitializedByException()) {
1208       expected_detail::throwBadExpectedAccess();
1209     }
1210     return expected_detail::ExpectedHelper::then_(
1211         base(), static_cast<Fns&&>(fns)...);
1212   }
1213
1214   template <class... Fns FOLLY_REQUIRES_TRAILING(sizeof...(Fns) >= 1)>
1215   auto then(Fns&&... fns) & -> decltype(expected_detail::ExpectedHelper::then_(
1216       std::declval<Base&>(),
1217       std::declval<Fns>()...)) {
1218     if (this->uninitializedByException()) {
1219       expected_detail::throwBadExpectedAccess();
1220     }
1221     return expected_detail::ExpectedHelper::then_(
1222         base(), static_cast<Fns&&>(fns)...);
1223   }
1224
1225   template <class... Fns FOLLY_REQUIRES_TRAILING(sizeof...(Fns) >= 1)>
1226   auto then(Fns&&... fns) && -> decltype(expected_detail::ExpectedHelper::then_(
1227       std::declval<Base&&>(),
1228       std::declval<Fns>()...)) {
1229     if (this->uninitializedByException()) {
1230       expected_detail::throwBadExpectedAccess();
1231     }
1232     return expected_detail::ExpectedHelper::then_(
1233         std::move(base()), static_cast<Fns&&>(fns)...);
1234   }
1235
1236   /**
1237    * thenOrThrow
1238    */
1239   template <class Yes, class No = MakeBadExpectedAccess>
1240   auto thenOrThrow(Yes&& yes, No&& no = No{}) const& -> decltype(
1241       std::declval<Yes>()(std::declval<const Value&>())) {
1242     using Ret = decltype(std::declval<Yes>()(std::declval<const Value&>()));
1243     if (this->uninitializedByException()) {
1244       expected_detail::throwBadExpectedAccess();
1245     }
1246     return Ret(expected_detail::ExpectedHelper::thenOrThrow_(
1247         base(), static_cast<Yes&&>(yes), static_cast<No&&>(no)));
1248   }
1249
1250   template <class Yes, class No = MakeBadExpectedAccess>
1251   auto thenOrThrow(Yes&& yes, No&& no = No{}) & -> decltype(
1252       std::declval<Yes>()(std::declval<Value&>())) {
1253     using Ret = decltype(std::declval<Yes>()(std::declval<Value&>()));
1254     if (this->uninitializedByException()) {
1255       expected_detail::throwBadExpectedAccess();
1256     }
1257     return Ret(expected_detail::ExpectedHelper::thenOrThrow_(
1258         base(), static_cast<Yes&&>(yes), static_cast<No&&>(no)));
1259   }
1260
1261   template <class Yes, class No = MakeBadExpectedAccess>
1262   auto thenOrThrow(Yes&& yes, No&& no = No{}) && -> decltype(
1263       std::declval<Yes>()(std::declval<Value&&>())) {
1264     using Ret = decltype(std::declval<Yes>()(std::declval<Value&&>()));
1265     if (this->uninitializedByException()) {
1266       expected_detail::throwBadExpectedAccess();
1267     }
1268     return Ret(expected_detail::ExpectedHelper::thenOrThrow_(
1269         std::move(base()), static_cast<Yes&&>(yes), static_cast<No&&>(no)));
1270   }
1271
1272  private:
1273   void requireValue() const {
1274     if (UNLIKELY(!hasValue())) {
1275       if (LIKELY(hasError())) {
1276         throw typename Unexpected<Error>::BadExpectedAccess(this->error_);
1277       }
1278       expected_detail::throwBadExpectedAccess();
1279     }
1280   }
1281
1282   void requireError() const {
1283     if (UNLIKELY(!hasError())) {
1284       expected_detail::throwBadExpectedAccess();
1285     }
1286   }
1287
1288   expected_detail::Which which() const noexcept {
1289     return this->which_;
1290   }
1291 };
1292
1293 template <class Value, class Error>
1294 inline typename std::enable_if<IsEqualityComparable<Value>::value, bool>::type
1295 operator==(
1296     const Expected<Value, Error>& lhs,
1297     const Expected<Value, Error>& rhs) {
1298   if (UNLIKELY(lhs.uninitializedByException())) {
1299     expected_detail::throwBadExpectedAccess();
1300   }
1301   if (UNLIKELY(lhs.which_ != rhs.which_)) {
1302     return false;
1303   }
1304   if (UNLIKELY(lhs.hasError())) {
1305     return true; // All error states are considered equal
1306   }
1307   return lhs.value_ == rhs.value_;
1308 }
1309
1310 template <
1311     class Value,
1312     class Error FOLLY_REQUIRES_TRAILING(IsEqualityComparable<Value>::value)>
1313 inline bool operator!=(
1314     const Expected<Value, Error>& lhs,
1315     const Expected<Value, Error>& rhs) {
1316   return !(rhs == lhs);
1317 }
1318
1319 template <class Value, class Error>
1320 inline typename std::enable_if<IsLessThanComparable<Value>::value, bool>::type
1321 operator<(
1322     const Expected<Value, Error>& lhs,
1323     const Expected<Value, Error>& rhs) {
1324   if (UNLIKELY(
1325           lhs.uninitializedByException() || rhs.uninitializedByException())) {
1326     expected_detail::throwBadExpectedAccess();
1327   }
1328   if (UNLIKELY(lhs.hasError())) {
1329     return !rhs.hasError();
1330   }
1331   if (UNLIKELY(rhs.hasError())) {
1332     return false;
1333   }
1334   return lhs.value_ < rhs.value_;
1335 }
1336
1337 template <
1338     class Value,
1339     class Error FOLLY_REQUIRES_TRAILING(IsLessThanComparable<Value>::value)>
1340 inline bool operator<=(
1341     const Expected<Value, Error>& lhs,
1342     const Expected<Value, Error>& rhs) {
1343   return !(rhs < lhs);
1344 }
1345
1346 template <
1347     class Value,
1348     class Error FOLLY_REQUIRES_TRAILING(IsLessThanComparable<Value>::value)>
1349 inline bool operator>(
1350     const Expected<Value, Error>& lhs,
1351     const Expected<Value, Error>& rhs) {
1352   return rhs < lhs;
1353 }
1354
1355 template <
1356     class Value,
1357     class Error FOLLY_REQUIRES_TRAILING(IsLessThanComparable<Value>::value)>
1358 inline bool operator>=(
1359     const Expected<Value, Error>& lhs,
1360     const Expected<Value, Error>& rhs) {
1361   return !(lhs < rhs);
1362 }
1363
1364 /**
1365  * swap Expected values
1366  */
1367 template <class Error, class Value>
1368 void swap(Expected<Error, Value>& lhs, Expected<Value, Error>& rhs) noexcept(
1369     expected_detail::StrictAllOf<IsNothrowSwappable, Value, Error>::value) {
1370   lhs.swap(rhs);
1371 }
1372
1373 template <class Value, class Error>
1374 const Value* get_pointer(const Expected<Value, Error>& ex) noexcept {
1375   return ex.get_pointer();
1376 }
1377
1378 template <class Value, class Error>
1379 Value* get_pointer(Expected<Value, Error>& ex) noexcept {
1380   return ex.get_pointer();
1381 }
1382
1383 /**
1384  * For constructing an Expected object from a value, with the specified
1385  * Error type. Usage is as follows:
1386  *
1387  * enum MyErrorCode { BAD_ERROR, WORSE_ERROR };
1388  * Expected<int, MyErrorCode> myAPI() {
1389  *   int i = // ...;
1390  *   return i ? makeExpected<MyErrorCode>(i) : makeUnexpected(BAD_ERROR);
1391  * }
1392  */
1393 template <class Error, class Value>
1394 constexpr Expected<typename std::decay<Value>::type, Error> makeExpected(
1395     Value&& val) {
1396   return Expected<typename std::decay<Value>::type, Error>{
1397       in_place, static_cast<Value&&>(val)};
1398 }
1399
1400 // Suppress comparability of Optional<T> with T, despite implicit conversion.
1401 template <class Value, class Error>
1402 bool operator==(const Expected<Value, Error>&, const Value& other) = delete;
1403 template <class Value, class Error>
1404 bool operator!=(const Expected<Value, Error>&, const Value& other) = delete;
1405 template <class Value, class Error>
1406 bool operator<(const Expected<Value, Error>&, const Value& other) = delete;
1407 template <class Value, class Error>
1408 bool operator<=(const Expected<Value, Error>&, const Value& other) = delete;
1409 template <class Value, class Error>
1410 bool operator>=(const Expected<Value, Error>&, const Value& other) = delete;
1411 template <class Value, class Error>
1412 bool operator>(const Expected<Value, Error>&, const Value& other) = delete;
1413 template <class Value, class Error>
1414 bool operator==(const Value& other, const Expected<Value, Error>&) = delete;
1415 template <class Value, class Error>
1416 bool operator!=(const Value& other, const Expected<Value, Error>&) = delete;
1417 template <class Value, class Error>
1418 bool operator<(const Value& other, const Expected<Value, Error>&) = delete;
1419 template <class Value, class Error>
1420 bool operator<=(const Value& other, const Expected<Value, Error>&) = delete;
1421 template <class Value, class Error>
1422 bool operator>=(const Value& other, const Expected<Value, Error>&) = delete;
1423 template <class Value, class Error>
1424 bool operator>(const Value& other, const Expected<Value, Error>&) = delete;
1425
1426 } // namespace folly
1427
1428 #if defined(__GNUC__) && !defined(__clang__)
1429 #pragma GCC diagnostic pop
1430 #endif
1431
1432 #undef FOLLY_REQUIRES
1433 #undef FOLLY_REQUIRES_TRAILING
1434
1435 // Enable the use of folly::Expected with `co_await`
1436 // Inspired by https://github.com/toby-allsopp/coroutine_monad
1437 #if FOLLY_HAS_COROUTINES
1438 #include <experimental/coroutine>
1439
1440 namespace folly {
1441 namespace expected_detail {
1442 template <typename Value, typename Error>
1443 struct Promise;
1444
1445 template <typename Value, typename Error>
1446 struct PromiseReturn {
1447   Optional<Expected<Value, Error>> storage_;
1448   Promise<Value, Error>* promise_;
1449   /* implicit */ PromiseReturn(Promise<Value, Error>& promise) noexcept
1450       : promise_(&promise) {
1451     promise_->value_ = &storage_;
1452   }
1453   PromiseReturn(PromiseReturn&& that) noexcept
1454       : PromiseReturn{*that.promise_} {}
1455   ~PromiseReturn() {}
1456   /* implicit */ operator Expected<Value, Error>() & {
1457     return std::move(*storage_);
1458   }
1459 };
1460
1461 template <typename Value, typename Error>
1462 struct Promise {
1463   Optional<Expected<Value, Error>>* value_ = nullptr;
1464   Promise() = default;
1465   Promise(Promise const&) = delete;
1466   // This should work regardless of whether the compiler generates:
1467   //    folly::Expected<Value, Error> retobj{ p.get_return_object(); } // MSVC
1468   // or:
1469   //    auto retobj = p.get_return_object(); // clang
1470   PromiseReturn<Value, Error> get_return_object() noexcept {
1471     return *this;
1472   }
1473   std::experimental::suspend_never initial_suspend() const noexcept {
1474     return {};
1475   }
1476   std::experimental::suspend_never final_suspend() const {
1477     return {};
1478   }
1479   template <typename U>
1480   void return_value(U&& u) {
1481     value_->emplace(static_cast<U&&>(u));
1482   }
1483   void unhandled_exception() {
1484     // Technically, throwing from unhandled_exception is underspecified:
1485     // https://github.com/GorNishanov/CoroutineWording/issues/17
1486     throw;
1487   }
1488 };
1489
1490 template <typename Value, typename Error>
1491 struct Awaitable {
1492   Expected<Value, Error> o_;
1493
1494   explicit Awaitable(Expected<Value, Error> o) : o_(std::move(o)) {}
1495
1496   bool await_ready() const noexcept {
1497     return o_.hasValue();
1498   }
1499   Value await_resume() {
1500     return std::move(o_.value());
1501   }
1502
1503   // Explicitly only allow suspension into a Promise
1504   template <typename U>
1505   void await_suspend(std::experimental::coroutine_handle<Promise<U, Error>> h) {
1506     *h.promise().value_ = makeUnexpected(std::move(o_.error()));
1507     // Abort the rest of the coroutine. resume() is not going to be called
1508     h.destroy();
1509   }
1510 };
1511 } // namespace expected_detail
1512
1513 template <typename Value, typename Error>
1514 expected_detail::Awaitable<Value, Error>
1515 /* implicit */ operator co_await(Expected<Value, Error> o) {
1516   return expected_detail::Awaitable<Value, Error>{std::move(o)};
1517 }
1518 } // namespace folly
1519
1520 // This makes folly::Optional<Value> useable as a coroutine return type..
1521 FOLLY_NAMESPACE_STD_BEGIN
1522 namespace experimental {
1523 template <typename Value, typename Error, typename... Args>
1524 struct coroutine_traits<folly::Expected<Value, Error>, Args...> {
1525   using promise_type = folly::expected_detail::Promise<Value, Error>;
1526 };
1527 } // namespace experimental
1528 FOLLY_NAMESPACE_STD_END
1529 #endif // FOLLY_HAS_COROUTINES