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