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