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