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