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