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