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