/*
 * Copyright 2017 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Like folly::Optional, but can store a value *or* and error.
 *
 * @author Eric Niebler (eniebler@fb.com)
 */

#pragma once

#include <cstddef>
#include <initializer_list>
#include <new>
#include <stdexcept>
#include <type_traits>
#include <utility>

#include <folly/Likely.h>
#include <folly/Portability.h>
#include <folly/Preprocessor.h>
#include <folly/Traits.h>
#include <folly/Unit.h>
#include <folly/Utility.h>

#define FOLLY_EXPECTED_ID(X) FB_CONCATENATE(FB_CONCATENATE(Folly, X), __LINE__)

#define FOLLY_REQUIRES_IMPL(...)                                            \
  bool FOLLY_EXPECTED_ID(Requires) = false,                                 \
       typename std::enable_if<                                             \
           (FOLLY_EXPECTED_ID(Requires) || static_cast<bool>(__VA_ARGS__)), \
           int>::type = 0

#define FOLLY_REQUIRES_TRAILING(...) , FOLLY_REQUIRES_IMPL(__VA_ARGS__)

#define FOLLY_REQUIRES(...) template <FOLLY_REQUIRES_IMPL(__VA_ARGS__)>

/**
 * gcc-4.7 warns about use of uninitialized memory around the use of storage_
 * even though this is explicitly initialized at each point.
 */
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif // __GNUC__

namespace folly {

/**
 * Forward declarations
 */
template <class Error>
class Unexpected;

template <class Error>
constexpr Unexpected<typename std::decay<Error>::type> makeUnexpected(Error&&);

template <class Value, class Error>
class Expected;

template <class Error, class Value>
constexpr Expected<typename std::decay<Value>::type, Error> makeExpected(
    Value&&);

/**
 * Alias for an Expected type's assiciated value_type
 */
template <class Expected>
using ExpectedValueType =
    typename std::remove_reference<Expected>::type::value_type;

/**
 * Alias for an Expected type's assiciated error_type
 */
template <class Expected>
using ExpectedErrorType =
    typename std::remove_reference<Expected>::type::error_type;

// Details...
namespace expected_detail {
#ifdef _MSC_VER
// MSVC 2015 can't handle the StrictConjunction, so we have
// to use std::conjunction instead.
template <template <class...> class Trait, class... Ts>
using StrictAllOf = std::conjunction<Trait<Ts>...>;
#else
template <template <class...> class Trait, class... Ts>
using StrictAllOf = StrictConjunction<Trait<Ts>...>;
#endif

template <class T>
using IsCopyable = StrictConjunction<
    std::is_copy_constructible<T>,
    std::is_copy_assignable<T>>;

template <class T>
using IsMovable = StrictConjunction<
    std::is_move_constructible<T>,
    std::is_move_assignable<T>>;

template <class T>
using IsNothrowCopyable = StrictConjunction<
    std::is_nothrow_copy_constructible<T>,
    std::is_nothrow_copy_assignable<T>>;

template <class T>
using IsNothrowMovable = StrictConjunction<
    std::is_nothrow_move_constructible<T>,
    std::is_nothrow_move_assignable<T>>;

template <class From, class To>
using IsConvertible = StrictConjunction<
    std::is_constructible<To, From>,
    std::is_assignable<To&, From>>;

template <class T, class U>
auto doEmplaceAssign(int, T& t, U&& u) -> decltype(void(t = (U &&)u)) {
  t = (U &&)u;
}

template <class T, class U>
auto doEmplaceAssign(long, T& t, U&& u) -> decltype(void(T((U &&)u))) {
  t.~T();
  ::new ((void*)std::addressof(t)) T((U &&)u);
}

template <class T, class... Us>
auto doEmplaceAssign(int, T& t, Us&&... us)
    -> decltype(void(t = T((Us &&)us...))) {
  t = T((Us &&)us...);
}

template <class T, class... Us>
auto doEmplaceAssign(long, T& t, Us&&... us)
    -> decltype(void(T((Us &&)us...))) {
  t.~T();
  ::new ((void*)std::addressof(t)) T((Us &&)us...);
}

struct EmptyTag {};
struct ValueTag {};
struct ErrorTag {};
enum class Which : unsigned char { eEmpty, eValue, eError };
enum class StorageType { ePODStruct, ePODUnion, eUnion };

template <class Value, class Error>
constexpr StorageType getStorageType() {
  return StrictAllOf<IsTriviallyCopyable, Value, Error>::value
      ? (sizeof(std::pair<Value, Error>) <= sizeof(void * [2]) &&
                 StrictAllOf<std::is_trivial, Value, Error>::value
             ? StorageType::ePODStruct
             : StorageType::ePODUnion)
      : StorageType::eUnion;
}

template <
    class Value,
    class Error,
    StorageType = expected_detail::getStorageType<Value, Error>()> // ePODUnion
struct ExpectedStorage {
  using value_type = Value;
  using error_type = Error;
  union {
    Value value_;
    Error error_;
    char ch_;
  };
  Which which_;

  template <class E = Error, class = decltype(E{})>
  constexpr ExpectedStorage() noexcept(noexcept(E{}))
      : error_{}, which_(Which::eError) {}
  explicit constexpr ExpectedStorage(EmptyTag) noexcept
      : ch_{}, which_(Which::eEmpty) {}
  template <class... Vs>
  explicit constexpr ExpectedStorage(ValueTag, Vs&&... vs) noexcept(
      noexcept(Value(static_cast<Vs&&>(vs)...)))
      : value_(static_cast<Vs&&>(vs)...), which_(Which::eValue) {}
  template <class... Es>
  explicit constexpr ExpectedStorage(ErrorTag, Es&&... es) noexcept(
      noexcept(Error(static_cast<Es&&>(es)...)))
      : error_(static_cast<Es&&>(es)...), which_(Which::eError) {}
  void clear() noexcept {}
  static constexpr bool uninitializedByException() noexcept {
    // Although which_ may temporarily be eEmpty during construction, it
    // is always either eValue or eError for a fully-constructed Expected.
    return false;
  }
  template <class... Vs>
  void assignValue(Vs&&... vs) {
    expected_detail::doEmplaceAssign(0, value_, static_cast<Vs&&>(vs)...);
    which_ = Which::eValue;
  }
  template <class... Es>
  void assignError(Es&&... es) {
    expected_detail::doEmplaceAssign(0, error_, static_cast<Es&&>(es)...);
    which_ = Which::eError;
  }
  template <class Other>
  void assign(Other&& that) {
    switch (that.which_) {
      case Which::eValue:
        this->assignValue(static_cast<Other&&>(that).value());
        break;
      case Which::eError:
        this->assignError(static_cast<Other&&>(that).error());
        break;
      default:
        this->clear();
        break;
    }
  }
  Value& value() & {
    return value_;
  }
  const Value& value() const& {
    return value_;
  }
  Value&& value() && {
    return std::move(value_);
  }
  // TODO (t17322426): remove when VS2015 support is deprecated
  // VS2015 static analyzer incorrectly flags these as unreachable in certain
  // circumstances. VS2017 does not have this problem on the same code.
  FOLLY_PUSH_WARNING
  FOLLY_MSVC_DISABLE_WARNING(4702) // unreachable code
  Error& error() & {
    return error_;
  }
  const Error& error() const& {
    return error_;
  }
  Error&& error() && {
    return std::move(error_);
  }
  FOLLY_POP_WARNING
};

template <class Value, class Error>
struct ExpectedUnion {
  union {
    Value value_;
    Error error_;
    char ch_{};
  };
  Which which_ = Which::eEmpty;

  explicit constexpr ExpectedUnion(EmptyTag) noexcept {}
  template <class... Vs>
  explicit constexpr ExpectedUnion(ValueTag, Vs&&... vs) noexcept(
      noexcept(Value(static_cast<Vs&&>(vs)...)))
      : value_(static_cast<Vs&&>(vs)...), which_(Which::eValue) {}
  template <class... Es>
  explicit constexpr ExpectedUnion(ErrorTag, Es&&... es) noexcept(
      noexcept(Error(static_cast<Es&&>(es)...)))
      : error_(static_cast<Es&&>(es)...), which_(Which::eError) {}
  ExpectedUnion(const ExpectedUnion&) {}
  ExpectedUnion(ExpectedUnion&&) noexcept {}
  ExpectedUnion& operator=(const ExpectedUnion&) {
    return *this;
  }
  ExpectedUnion& operator=(ExpectedUnion&&) noexcept {
    return *this;
  }
  ~ExpectedUnion() {}
  Value& value() & {
    return value_;
  }
  const Value& value() const& {
    return value_;
  }
  Value&& value() && {
    return std::move(value_);
  }
  Error& error() & {
    return error_;
  }
  const Error& error() const& {
    return error_;
  }
  Error&& error() && {
    return std::move(error_);
  }
};

template <class Derived, bool, bool Noexcept>
struct CopyConstructible {
  constexpr CopyConstructible() = default;
  CopyConstructible(const CopyConstructible& that) noexcept(Noexcept) {
    static_cast<Derived*>(this)->assign(static_cast<const Derived&>(that));
  }
  constexpr CopyConstructible(CopyConstructible&&) = default;
  CopyConstructible& operator=(const CopyConstructible&) = default;
  CopyConstructible& operator=(CopyConstructible&&) = default;
};

template <class Derived, bool Noexcept>
struct CopyConstructible<Derived, false, Noexcept> {
  constexpr CopyConstructible() = default;
  CopyConstructible(const CopyConstructible&) = delete;
  constexpr CopyConstructible(CopyConstructible&&) = default;
  CopyConstructible& operator=(const CopyConstructible&) = default;
  CopyConstructible& operator=(CopyConstructible&&) = default;
};

template <class Derived, bool, bool Noexcept>
struct MoveConstructible {
  constexpr MoveConstructible() = default;
  constexpr MoveConstructible(const MoveConstructible&) = default;
  MoveConstructible(MoveConstructible&& that) noexcept(Noexcept) {
    static_cast<Derived*>(this)->assign(std::move(static_cast<Derived&>(that)));
  }
  MoveConstructible& operator=(const MoveConstructible&) = default;
  MoveConstructible& operator=(MoveConstructible&&) = default;
};

template <class Derived, bool Noexcept>
struct MoveConstructible<Derived, false, Noexcept> {
  constexpr MoveConstructible() = default;
  constexpr MoveConstructible(const MoveConstructible&) = default;
  MoveConstructible(MoveConstructible&&) = delete;
  MoveConstructible& operator=(const MoveConstructible&) = default;
  MoveConstructible& operator=(MoveConstructible&&) = default;
};

template <class Derived, bool, bool Noexcept>
struct CopyAssignable {
  constexpr CopyAssignable() = default;
  constexpr CopyAssignable(const CopyAssignable&) = default;
  constexpr CopyAssignable(CopyAssignable&&) = default;
  CopyAssignable& operator=(const CopyAssignable& that) noexcept(Noexcept) {
    static_cast<Derived*>(this)->assign(static_cast<const Derived&>(that));
    return *this;
  }
  CopyAssignable& operator=(CopyAssignable&&) = default;
};

template <class Derived, bool Noexcept>
struct CopyAssignable<Derived, false, Noexcept> {
  constexpr CopyAssignable() = default;
  constexpr CopyAssignable(const CopyAssignable&) = default;
  constexpr CopyAssignable(CopyAssignable&&) = default;
  CopyAssignable& operator=(const CopyAssignable&) = delete;
  CopyAssignable& operator=(CopyAssignable&&) = default;
};

template <class Derived, bool, bool Noexcept>
struct MoveAssignable {
  constexpr MoveAssignable() = default;
  constexpr MoveAssignable(const MoveAssignable&) = default;
  constexpr MoveAssignable(MoveAssignable&&) = default;
  MoveAssignable& operator=(const MoveAssignable&) = default;
  MoveAssignable& operator=(MoveAssignable&& that) noexcept(Noexcept) {
    static_cast<Derived*>(this)->assign(std::move(static_cast<Derived&>(that)));
    return *this;
  }
};

template <class Derived, bool Noexcept>
struct MoveAssignable<Derived, false, Noexcept> {
  constexpr MoveAssignable() = default;
  constexpr MoveAssignable(const MoveAssignable&) = default;
  constexpr MoveAssignable(MoveAssignable&&) = default;
  MoveAssignable& operator=(const MoveAssignable&) = default;
  MoveAssignable& operator=(MoveAssignable&& that) = delete;
};

template <class Value, class Error>
struct ExpectedStorage<Value, Error, StorageType::eUnion>
    : ExpectedUnion<Value, Error>,
      CopyConstructible<
          ExpectedStorage<Value, Error, StorageType::eUnion>,
          StrictAllOf<std::is_copy_constructible, Value, Error>::value,
          StrictAllOf<std::is_nothrow_copy_constructible, Value, Error>::value>,
      MoveConstructible<
          ExpectedStorage<Value, Error, StorageType::eUnion>,
          StrictAllOf<std::is_move_constructible, Value, Error>::value,
          StrictAllOf<std::is_nothrow_move_constructible, Value, Error>::value>,
      CopyAssignable<
          ExpectedStorage<Value, Error, StorageType::eUnion>,
          StrictAllOf<IsCopyable, Value, Error>::value,
          StrictAllOf<IsNothrowCopyable, Value, Error>::value>,
      MoveAssignable<
          ExpectedStorage<Value, Error, StorageType::eUnion>,
          StrictAllOf<IsMovable, Value, Error>::value,
          StrictAllOf<IsNothrowMovable, Value, Error>::value> {
  using value_type = Value;
  using error_type = Error;
  using Base = ExpectedUnion<Value, Error>;
  template <class E = Error, class = decltype(E{})>
  constexpr ExpectedStorage() noexcept(noexcept(E{})) : Base{ErrorTag{}} {}
  ExpectedStorage(const ExpectedStorage&) = default;
  ExpectedStorage(ExpectedStorage&&) = default;
  ExpectedStorage& operator=(const ExpectedStorage&) = default;
  ExpectedStorage& operator=(ExpectedStorage&&) = default;
  using ExpectedUnion<Value, Error>::ExpectedUnion;
  ~ExpectedStorage() {
    clear();
  }
  void clear() noexcept {
    switch (this->which_) {
      case Which::eValue:
        this->value().~Value();
        break;
      case Which::eError:
        this->error().~Error();
        break;
      default:
        break;
    }
    this->which_ = Which::eEmpty;
  }
  bool uninitializedByException() const noexcept {
    return this->which_ == Which::eEmpty;
  }
  template <class... Vs>
  void assignValue(Vs&&... vs) {
    if (this->which_ == Which::eValue) {
      expected_detail::doEmplaceAssign(
          0, this->value(), static_cast<Vs&&>(vs)...);
    } else {
      this->clear();
      ::new ((void*)std::addressof(this->value()))
          Value(static_cast<Vs&&>(vs)...);
      this->which_ = Which::eValue;
    }
  }
  template <class... Es>
  void assignError(Es&&... es) {
    if (this->which_ == Which::eError) {
      expected_detail::doEmplaceAssign(
          0, this->error(), static_cast<Es&&>(es)...);
    } else {
      this->clear();
      ::new ((void*)std::addressof(this->error()))
          Error(static_cast<Es&&>(es)...);
      this->which_ = Which::eError;
    }
  }
  bool isSelfAssign(const ExpectedStorage* that) const {
    return this == that;
  }
  constexpr bool isSelfAssign(const void*) const {
    return false;
  }
  template <class Other>
  void assign(Other&& that) {
    if (isSelfAssign(&that))
      return;
    switch (that.which_) {
      case Which::eValue:
        this->assignValue(static_cast<Other&&>(that).value());
        break;
      case Which::eError:
        this->assignError(static_cast<Other&&>(that).error());
        break;
      default:
        this->clear();
        break;
    }
  }
};

// For small (pointer-sized) trivial types, a struct is faster than a union.
template <class Value, class Error>
struct ExpectedStorage<Value, Error, StorageType::ePODStruct> {
  using value_type = Value;
  using error_type = Error;
  Which which_;
  Error error_;
  Value value_;

  constexpr ExpectedStorage() noexcept
      : which_(Which::eError), error_{}, value_{} {}
  explicit constexpr ExpectedStorage(EmptyTag) noexcept
      : which_(Which::eEmpty), error_{}, value_{} {}
  template <class... Vs>
  explicit constexpr ExpectedStorage(ValueTag, Vs&&... vs) noexcept(
      noexcept(Value(static_cast<Vs&&>(vs)...)))
      : which_(Which::eValue), error_{}, value_(static_cast<Vs&&>(vs)...) {}
  template <class... Es>
  explicit constexpr ExpectedStorage(ErrorTag, Es&&... es) noexcept(
      noexcept(Error(static_cast<Es&&>(es)...)))
      : which_(Which::eError), error_(static_cast<Es&&>(es)...), value_{} {}
  void clear() noexcept {}
  constexpr static bool uninitializedByException() noexcept {
    return false;
  }
  template <class... Vs>
  void assignValue(Vs&&... vs) {
    expected_detail::doEmplaceAssign(0, value_, static_cast<Vs&&>(vs)...);
    which_ = Which::eValue;
  }
  template <class... Es>
  void assignError(Es&&... es) {
    expected_detail::doEmplaceAssign(0, error_, static_cast<Es&&>(es)...);
    which_ = Which::eError;
  }
  template <class Other>
  void assign(Other&& that) {
    switch (that.which_) {
      case Which::eValue:
        this->assignValue(static_cast<Other&&>(that).value());
        break;
      case Which::eError:
        this->assignError(static_cast<Other&&>(that).error());
        break;
      default:
        this->clear();
        break;
    }
  }
  Value& value() & {
    return value_;
  }
  const Value& value() const& {
    return value_;
  }
  Value&& value() && {
    return std::move(value_);
  }
  // TODO (t17322426): remove when VS2015 support is deprecated
  // VS2015 static analyzer incorrectly flags these as unreachable in certain
  // circumstances. VS2017 does not have this problem on the same code.
  FOLLY_PUSH_WARNING
  FOLLY_MSVC_DISABLE_WARNING(4702) // unreachable code
  Error& error() & {
    return error_;
  }
  const Error& error() const& {
    return error_;
  }
  Error&& error() && {
    return std::move(error_);
  }
  FOLLY_POP_WARNING
};

namespace expected_detail_ExpectedHelper {
// Tricky hack so that Expected::then can handle lambdas that return void
template <class T>
inline T&& operator,(T&& t, Unit) noexcept {
  return static_cast<T&&>(t);
}

struct ExpectedHelper {
  template <class Error, class T>
  static constexpr Expected<T, Error> return_(T t) {
    return folly::makeExpected<Error>(t);
  }
  template <
      class Error,
      class T,
      class U FOLLY_REQUIRES_TRAILING(
          expected_detail::IsConvertible<U&&, Error>::value)>
  static constexpr Expected<T, Error> return_(Expected<T, U> t) {
    return t;
  }

  template <class This>
  static typename std::decay<This>::type then_(This&& ex) {
    return static_cast<This&&>(ex);
  }

  FOLLY_PUSH_WARNING
  // Don't warn about not using the overloaded comma operator.
  FOLLY_MSVC_DISABLE_WARNING(4913)
  template <
      class This,
      class Fn,
      class... Fns,
      class E = ExpectedErrorType<This>,
      class T = ExpectedHelper>
  static auto then_(This&& ex, Fn&& fn, Fns&&... fns) -> decltype(T::then_(
      T::template return_<E>(
          (std::declval<Fn>()(std::declval<This>().value()), unit)),
      std::declval<Fns>()...)) {
    if (LIKELY(ex.which_ == expected_detail::Which::eValue))
      return T::then_(
          T::template return_<E>(
              // Uses the comma operator defined above IFF the lambda
              // returns non-void.
              (static_cast<Fn&&>(fn)(static_cast<This&&>(ex).value()), unit)),
          static_cast<Fns&&>(fns)...);
    return makeUnexpected(static_cast<This&&>(ex).error());
  }

  template <
      class This,
      class Yes,
      class No,
      class Ret = decltype(std::declval<Yes>()(std::declval<This>().value())),
      class Err = decltype(std::declval<No>()(std::declval<This>().error()))
          FOLLY_REQUIRES_TRAILING(!std::is_void<Err>::value)>
  static Ret thenOrThrow_(This&& ex, Yes&& yes, No&& no) {
    if (LIKELY(ex.which_ == expected_detail::Which::eValue))
      return Ret(static_cast<Yes&&>(yes)(static_cast<This&&>(ex).value()));
    throw static_cast<No&&>(no)(static_cast<This&&>(ex).error());
  }

  template <
      class This,
      class Yes,
      class No,
      class Ret = decltype(std::declval<Yes>()(std::declval<This>().value())),
      class Err = decltype(std::declval<No>()(std::declval<This&>().error()))
          FOLLY_REQUIRES_TRAILING(std::is_void<Err>::value)>
  static Ret thenOrThrow_(This&& ex, Yes&& yes, No&& no) {
    if (LIKELY(ex.which_ == expected_detail::Which::eValue))
      return Ret(static_cast<Yes&&>(yes)(static_cast<This&&>(ex).value()));
    static_cast<No&&>(no)(ex.error());
    throw typename Unexpected<ExpectedErrorType<This>>::MakeBadExpectedAccess()(
        static_cast<This&&>(ex).error());
  }
  FOLLY_POP_WARNING
};
}
/* using override */ using expected_detail_ExpectedHelper::ExpectedHelper;

struct UnexpectedTag {};

} // namespace expected_detail

using unexpected_t =
    expected_detail::UnexpectedTag (&)(expected_detail::UnexpectedTag);

inline expected_detail::UnexpectedTag unexpected(
    expected_detail::UnexpectedTag = {}) {
  return {};
}

/**
 * An exception type thrown by Expected on catastrophic logic errors.
 */
class BadExpectedAccess : public std::logic_error {
 public:
  BadExpectedAccess() : std::logic_error("bad Expected access") {}
};

/**
 * Unexpected - a helper type used to disambiguate the construction of
 * Expected objects in the error state.
 */
template <class Error>
class Unexpected final {
  template <class E>
  friend class Unexpected;
  template <class V, class E>
  friend class Expected;
  friend struct expected_detail::ExpectedHelper;

 public:
  /**
   * Unexpected::BadExpectedAccess - An exception type thrown by Expected
   * when the user tries to access the nested value but the Expected object is
   * actually storing an error code.
   */
  class BadExpectedAccess : public folly::BadExpectedAccess {
   public:
    explicit BadExpectedAccess(Error err)
        : folly::BadExpectedAccess{}, error_(std::move(err)) {}
    /**
     * The error code that was held by the Expected object when the user
     * erroneously requested the value.
     */
    Error error() const {
      return error_;
    }

   private:
    Error error_;
  };

  /**
   * Constructors
   */
  Unexpected() = default;
  Unexpected(const Unexpected&) = default;
  Unexpected(Unexpected&&) = default;
  Unexpected& operator=(const Unexpected&) = default;
  Unexpected& operator=(Unexpected&&) = default;
  constexpr /* implicit */ Unexpected(const Error& err) : error_(err) {}
  constexpr /* implicit */ Unexpected(Error&& err) : error_(std::move(err)) {}

  template <class Other FOLLY_REQUIRES_TRAILING(
      std::is_constructible<Error, Other&&>::value)>
  constexpr /* implicit */ Unexpected(Unexpected<Other> that)
      : error_(std::move(that.error())) {}

  /**
   * Assignment
   */
  template <class Other FOLLY_REQUIRES_TRAILING(
      std::is_assignable<Error&, Other&&>::value)>
  Unexpected& operator=(Unexpected<Other> that) {
    error_ = std::move(that.error());
  }

  /**
   * Observers
   */
  Error& error() & {
    return error_;
  }
  const Error& error() const& {
    return error_;
  }
  Error&& error() && {
    return std::move(error_);
  }

 private:
  struct MakeBadExpectedAccess {
    template <class E>
    BadExpectedAccess operator()(E&& err) const {
      return BadExpectedAccess(static_cast<E&&>(err));
    }
  };

  Error error_;
};

template <
    class Error FOLLY_REQUIRES_TRAILING(IsEqualityComparable<Error>::value)>
inline bool operator==(
    const Unexpected<Error>& lhs,
    const Unexpected<Error>& rhs) {
  return lhs.error() == rhs.error();
}

template <
    class Error FOLLY_REQUIRES_TRAILING(IsEqualityComparable<Error>::value)>
inline bool operator!=(
    const Unexpected<Error>& lhs,
    const Unexpected<Error>& rhs) {
  return !(lhs == rhs);
}

/**
 * For constructing an Unexpected object from an error code. Unexpected objects
 * are implicitly convertible to Expected object in the error state. Usage is
 * as follows:
 *
 * enum class MyErrorCode { BAD_ERROR, WORSE_ERROR };
 * Expected<int, MyErrorCode> myAPI() {
 *   int i = // ...;
 *   return i ? makeExpected<MyErrorCode>(i)
 *            : makeUnexpected(MyErrorCode::BAD_ERROR);
 * }
 */
template <class Error>
constexpr Unexpected<typename std::decay<Error>::type> makeUnexpected(
    Error&& err) {
  return Unexpected<typename std::decay<Error>::type>{
      static_cast<Error&&>(err)};
}

/**
 * Expected - For holding a value or an error. Useful as an alternative to
 * exceptions, for APIs where throwing on failure would be too expensive.
 *
 * Expected<Value, Error> is a variant over the types Value and Error.
 *
 * Expected does not offer support for references. Use
 * Expected<std::reference_wrapper<T>, Error> if your API needs to return a
 * reference or an error.
 *
 * Expected offers a continuation-based interface to reduce the boilerplate
 * of checking error codes. The Expected::then member function takes a lambda
 * that is to execute should the Expected object contain a value. The return
 * value of the lambda is wrapped in an Expected and returned. If the lambda is
 * not executed because the Expected contains an error, the error is returned
 * immediately in a new Expected object.
 *
 * Expected<int, Error> funcTheFirst();
 * Expected<std::string, Error> funcTheSecond() {
 *   return funcTheFirst().then([](int i) { return std::to_string(i); });
 * }
 *
 * The above line of code could more verbosely written as:
 *
 * Expected<std::string, Error> funcTheSecond() {
 *   if (auto ex = funcTheFirst()) {
 *     return std::to_string(*ex);
 *   }
 *   return makeUnexpected(ex.error());
 * }
 *
 * Continuations can chain, like:
 *
 * Expected<D, Error> maybeD = someFunc()
 *     .then([](A a){return B(a);})
 *     .then([](B b){return C(b);})
 *     .then([](C c){return D(c);});
 *
 * To avoid the redundant error checking that would happen if a call at the
 * front of the chain returns an error, these call chains can be collaped into
 * a single call to .then:
 *
 * Expected<D, Error> maybeD = someFunc()
 *     .then([](A a){return B(a);},
 *           [](B b){return C(b);},
 *           [](C c){return D(c);});
 *
 * The result of .then() is wrapped into Expected< ~, Error > if it isn't
 * of that form already. Consider the following code:
 *
 * extern Expected<std::string, Error> readLineFromIO();
 * extern Expected<int, Error> parseInt(std::string);
 * extern int increment(int);
 *
 * Expected<int, Error> x = readLineFromIO().then(parseInt).then(increment);
 *
 * From the code above, we see that .then() works both with functions that
 * return an Expected< ~, Error > (like parseInt) and with ones that return
 * a plain value (like increment). In the case of parseInt, .then() returns
 * the result of parseInt as-is. In the case of increment, it wraps the int
 * that increment returns into an Expected< int, Error >.
 *
 * Sometimes when using a continuation you would prefer an exception to be
 * thrown for a value-less Expected. For that you can use .thenOrThrow, as
 * follows:
 *
 * B b = someFunc()
 *     .thenOrThrow([](A a){return B(a);});
 *
 * The above call to thenOrThrow will invoke the lambda if the Expected returned
 * by someFunc() contains a value. Otherwise, it will throw an exception of type
 * Unexpected<Error>::BadExpectedAccess. If you prefer it throw an exception of
 * a different type, you can pass a second lambda to thenOrThrow:
 *
 * B b = someFunc()
 *     .thenOrThrow([](A a){return B(a);},
 *                  [](Error e) {throw MyException(e);});
 *
 * Like C++17's std::variant, Expected offers the almost-never-empty guarantee;
 * that is, an Expected<Value, Error> almost always contains either a Value or
 * and Error. Partially-formed Expected objects occur when an assignment to
 * an Expected object that would change the type of the contained object (Value-
 * to-Error or vice versa) throws. Trying to access either the contained value
 * or error object causes Expected to throw folly::BadExpectedAccess.
 *
 * Expected models OptionalPointee, so calling 'get_pointer(ex)' will return a
 * pointer to nullptr if the 'ex' is in the error state, and a pointer to the
 * value otherwise:
 *
 *  Expected<int, Error> maybeInt = ...;
 *  if (int* v = get_pointer(maybeInt)) {
 *    cout << *v << endl;
 *  }
 */
template <class Value, class Error>
class Expected final : expected_detail::ExpectedStorage<Value, Error> {
  template <class, class>
  friend class Expected;
  template <class, class, expected_detail::StorageType>
  friend struct expected_detail::ExpectedStorage;
  friend struct expected_detail::ExpectedHelper;
  using Base = expected_detail::ExpectedStorage<Value, Error>;
  using MakeBadExpectedAccess =
      typename Unexpected<Error>::MakeBadExpectedAccess;
  Base& base() & {
    return *this;
  }
  const Base& base() const& {
    return *this;
  }
  Base&& base() && {
    return std::move(*this);
  }

 public:
  using value_type = Value;
  using error_type = Error;
  using IsTriviallyCopyable = typename expected_detail::
      StrictAllOf<IsTriviallyCopyable, Value, Error>::type;

  template <class U>
  using rebind = Expected<U, Error>;

  static_assert(
      !std::is_reference<Value>::value,
      "Expected may not be used with reference types");
  static_assert(
      !std::is_abstract<Value>::value,
      "Expected may not be used with abstract types");

  /*
   * Constructors
   */
  template <class B = Base, class = decltype(B{})>
  Expected() noexcept(noexcept(B{})) : Base{} {}
  Expected(const Expected& that) = default;
  Expected(Expected&& that) = default;

  template <
      class V,
      class E FOLLY_REQUIRES_TRAILING(
          !std::is_same<Expected<V, E>, Expected>::value &&
          std::is_constructible<Value, V&&>::value &&
          std::is_constructible<Error, E&&>::value)>
  Expected(Expected<V, E> that) : Base{expected_detail::EmptyTag{}} {
    *this = std::move(that);
  }

  FOLLY_REQUIRES(std::is_copy_constructible<Value>::value)
  constexpr /* implicit */ Expected(const Value& val) noexcept(
      noexcept(Value(val)))
      : Base{expected_detail::ValueTag{}, val} {}

  FOLLY_REQUIRES(std::is_move_constructible<Value>::value)
  constexpr /* implicit */ Expected(Value&& val) noexcept(
      noexcept(Value(std::move(val))))
      : Base{expected_detail::ValueTag{}, std::move(val)} {}

  template <class T FOLLY_REQUIRES_TRAILING(
      std::is_convertible<T, Value>::value &&
      !std::is_convertible<T, Error>::value)>
  constexpr /* implicit */ Expected(T&& val) noexcept(
      noexcept(Value(static_cast<T&&>(val))))
      : Base{expected_detail::ValueTag{}, static_cast<T&&>(val)} {}

  template <class... Ts FOLLY_REQUIRES_TRAILING(
      std::is_constructible<Value, Ts&&...>::value)>
  explicit constexpr Expected(in_place_t, Ts&&... ts) noexcept(
      noexcept(Value(std::declval<Ts>()...)))
      : Base{expected_detail::ValueTag{}, static_cast<Ts&&>(ts)...} {}

  template <
      class U,
      class... Ts FOLLY_REQUIRES_TRAILING(
          std::is_constructible<Value, std::initializer_list<U>&, Ts&&...>::
              value)>
  explicit constexpr Expected(
      in_place_t,
      std::initializer_list<U> il,
      Ts&&... ts) noexcept(noexcept(Value(std::declval<Ts>()...)))
      : Base{expected_detail::ValueTag{}, il, static_cast<Ts&&>(ts)...} {}

  // If overload resolution selects one of these deleted functions, that
  // means you need to use makeUnexpected
  /* implicit */ Expected(const Error&) = delete;
  /* implicit */ Expected(Error&&) = delete;

  FOLLY_REQUIRES(std::is_copy_constructible<Error>::value)
  constexpr Expected(unexpected_t, const Error& err) noexcept(
      noexcept(Error(err)))
      : Base{expected_detail::ErrorTag{}, err} {}

  FOLLY_REQUIRES(std::is_move_constructible<Error>::value)
  constexpr Expected(unexpected_t, Error&& err) noexcept(
      noexcept(Error(std::move(err))))
      : Base{expected_detail::ErrorTag{}, std::move(err)} {}

  FOLLY_REQUIRES(std::is_copy_constructible<Error>::value)
  constexpr /* implicit */ Expected(const Unexpected<Error>& err) noexcept(
      noexcept(Error(err.error())))
      : Base{expected_detail::ErrorTag{}, err.error()} {}

  FOLLY_REQUIRES(std::is_move_constructible<Error>::value)
  constexpr /* implicit */ Expected(Unexpected<Error>&& err) noexcept(
      noexcept(Error(std::move(err.error()))))
      : Base{expected_detail::ErrorTag{}, std::move(err.error())} {}

  /*
   * Assignment operators
   */
  Expected& operator=(const Expected& that) = default;
  Expected& operator=(Expected&& that) = default;

  template <
      class V,
      class E FOLLY_REQUIRES_TRAILING(
          !std::is_same<Expected<V, E>, Expected>::value &&
          expected_detail::IsConvertible<V&&, Value>::value &&
          expected_detail::IsConvertible<E&&, Error>::value)>
  Expected& operator=(Expected<V, E> that) {
    this->assign(std::move(that));
    return *this;
  }

  FOLLY_REQUIRES(expected_detail::IsCopyable<Value>::value)
  Expected& operator=(const Value& val) noexcept(
      expected_detail::IsNothrowCopyable<Value>::value) {
    this->assignValue(val);
    return *this;
  }

  FOLLY_REQUIRES(expected_detail::IsMovable<Value>::value)
  Expected& operator=(Value&& val) noexcept(
      expected_detail::IsNothrowMovable<Value>::value) {
    this->assignValue(std::move(val));
    return *this;
  }

  template <class T FOLLY_REQUIRES_TRAILING(
      std::is_convertible<T, Value>::value &&
      !std::is_convertible<T, Error>::value)>
  Expected& operator=(T&& val) {
    this->assignValue(static_cast<T&&>(val));
    return *this;
  }

  FOLLY_REQUIRES(expected_detail::IsCopyable<Error>::value)
  Expected& operator=(const Unexpected<Error>& err) noexcept(
      expected_detail::IsNothrowCopyable<Error>::value) {
    this->assignError(err.error());
    return *this;
  }

  FOLLY_REQUIRES(expected_detail::IsMovable<Error>::value)
  Expected& operator=(Unexpected<Error>&& err) noexcept(
      expected_detail::IsNothrowMovable<Error>::value) {
    this->assignError(std::move(err.error()));
    return *this;
  }

  template <class... Ts FOLLY_REQUIRES_TRAILING(
      std::is_constructible<Value, Ts&&...>::value)>
  void emplace(Ts&&... ts) {
    this->assignValue(static_cast<Ts&&>(ts)...);
  }

  /**
   * swap
   */
  void swap(Expected& that) noexcept(
      expected_detail::StrictAllOf<IsNothrowSwappable, Value, Error>::value) {
    if (this->uninitializedByException() || that.uninitializedByException())
      throw BadExpectedAccess();
    using std::swap;
    if (*this) {
      if (that) {
        swap(this->value_, that.value_);
      } else {
        Error e(std::move(that.error_));
        that.assignValue(std::move(this->value_));
        this->assignError(std::move(e));
      }
    } else {
      if (!that) {
        swap(this->error_, that.error_);
      } else {
        Error e(std::move(this->error_));
        this->assignValue(std::move(that.value_));
        that.assignError(std::move(e));
      }
    }
  }

  // If overload resolution selects one of these deleted functions, that
  // means you need to use makeUnexpected
  /* implicit */ Expected& operator=(const Error&) = delete;
  /* implicit */ Expected& operator=(Error&&) = delete;

  /**
   * Relational Operators
   */
  template <class Val, class Err>
  friend typename std::enable_if<IsEqualityComparable<Val>::value, bool>::type
  operator==(const Expected<Val, Err>& lhs, const Expected<Val, Err>& rhs);
  template <class Val, class Err>
  friend typename std::enable_if<IsLessThanComparable<Val>::value, bool>::type
  operator<(const Expected<Val, Err>& lhs, const Expected<Val, Err>& rhs);

  /*
   * Accessors
   */
  constexpr bool hasValue() const noexcept {
    return expected_detail::Which::eValue == this->which_;
  }

  constexpr bool hasError() const noexcept {
    return expected_detail::Which::eError == this->which_;
  }

  using Base::uninitializedByException;

  const Value& value() const& {
    requireValue();
    return this->Base::value();
  }

  Value& value() & {
    requireValue();
    return this->Base::value();
  }

  Value&& value() && {
    requireValue();
    return std::move(this->Base::value());
  }

  const Error& error() const& {
    requireError();
    return this->Base::error();
  }

  Error& error() & {
    requireError();
    return this->Base::error();
  }

  Error&& error() && {
    requireError();
    return std::move(this->Base::error());
  }

  // Return a copy of the value if set, or a given default if not.
  template <class U>
  Value value_or(U&& dflt) const& {
    if (LIKELY(this->which_ == expected_detail::Which::eValue)) {
      return this->value_;
    }
    return static_cast<U&&>(dflt);
  }

  template <class U>
  Value value_or(U&& dflt) && {
    if (LIKELY(this->which_ == expected_detail::Which::eValue)) {
      return std::move(this->value_);
    }
    return static_cast<U&&>(dflt);
  }

  explicit constexpr operator bool() const noexcept {
    return hasValue();
  }

  const Value& operator*() const& {
    return this->value();
  }

  Value& operator*() & {
    return this->value();
  }

  Value&& operator*() && {
    return std::move(this->value());
  }

  const Value* operator->() const {
    return std::addressof(this->value());
  }

  Value* operator->() {
    return std::addressof(this->value());
  }

  const Value* get_pointer() const& noexcept {
    return hasValue() ? std::addressof(this->value_) : nullptr;
  }

  Value* get_pointer() & noexcept {
    return hasValue() ? std::addressof(this->value_) : nullptr;
  }

  Value* get_pointer() && = delete;

  /**
   * then
   */
  template <class... Fns FOLLY_REQUIRES_TRAILING(sizeof...(Fns) >= 1)>
  auto then(Fns&&... fns) const& -> decltype(
      expected_detail::ExpectedHelper::then_(
          std::declval<const Base&>(),
          std::declval<Fns>()...)) {
    if (this->uninitializedByException())
      throw BadExpectedAccess();
    return expected_detail::ExpectedHelper::then_(
        base(), static_cast<Fns&&>(fns)...);
  }

  template <class... Fns FOLLY_REQUIRES_TRAILING(sizeof...(Fns) >= 1)>
  auto then(Fns&&... fns) & -> decltype(expected_detail::ExpectedHelper::then_(
      std::declval<Base&>(),
      std::declval<Fns>()...)) {
    if (this->uninitializedByException())
      throw BadExpectedAccess();
    return expected_detail::ExpectedHelper::then_(
        base(), static_cast<Fns&&>(fns)...);
  }

  template <class... Fns FOLLY_REQUIRES_TRAILING(sizeof...(Fns) >= 1)>
  auto then(Fns&&... fns) && -> decltype(expected_detail::ExpectedHelper::then_(
      std::declval<Base&&>(),
      std::declval<Fns>()...)) {
    if (this->uninitializedByException())
      throw BadExpectedAccess();
    return expected_detail::ExpectedHelper::then_(
        std::move(base()), static_cast<Fns&&>(fns)...);
  }

  /**
   * thenOrThrow
   */
  template <class Yes, class No = MakeBadExpectedAccess>
  auto thenOrThrow(Yes&& yes, No&& no = No{}) const& -> decltype(
      std::declval<Yes>()(std::declval<const Value&>())) {
    using Ret = decltype(std::declval<Yes>()(std::declval<const Value&>()));
    if (this->uninitializedByException())
      throw BadExpectedAccess();
    return Ret(expected_detail::ExpectedHelper::thenOrThrow_(
        base(), static_cast<Yes&&>(yes), static_cast<No&&>(no)));
  }

  template <class Yes, class No = MakeBadExpectedAccess>
  auto thenOrThrow(Yes&& yes, No&& no = No{}) & -> decltype(
      std::declval<Yes>()(std::declval<Value&>())) {
    using Ret = decltype(std::declval<Yes>()(std::declval<Value&>()));
    if (this->uninitializedByException())
      throw BadExpectedAccess();
    return Ret(expected_detail::ExpectedHelper::thenOrThrow_(
        base(), static_cast<Yes&&>(yes), static_cast<No&&>(no)));
  }

  template <class Yes, class No = MakeBadExpectedAccess>
  auto thenOrThrow(Yes&& yes, No&& no = No{}) && -> decltype(
      std::declval<Yes>()(std::declval<Value&&>())) {
    using Ret = decltype(std::declval<Yes>()(std::declval<Value&&>()));
    if (this->uninitializedByException())
      throw BadExpectedAccess();
    return Ret(expected_detail::ExpectedHelper::thenOrThrow_(
        std::move(base()), static_cast<Yes&&>(yes), static_cast<No&&>(no)));
  }

 private:
  void requireValue() const {
    if (UNLIKELY(!hasValue())) {
      if (LIKELY(hasError()))
        throw typename Unexpected<Error>::BadExpectedAccess(this->error_);
      throw BadExpectedAccess();
    }
  }

  void requireError() const {
    if (UNLIKELY(!hasError())) {
      throw BadExpectedAccess();
    }
  }

  expected_detail::Which which() const noexcept {
    return this->which_;
  }
};

template <class Value, class Error>
inline typename std::enable_if<IsEqualityComparable<Value>::value, bool>::type
operator==(
    const Expected<Value, Error>& lhs,
    const Expected<Value, Error>& rhs) {
  if (UNLIKELY(lhs.which_ != rhs.which_))
    return UNLIKELY(lhs.uninitializedByException()) ? false
                                                    : throw BadExpectedAccess();
  if (UNLIKELY(lhs.uninitializedByException()))
    throw BadExpectedAccess();
  if (UNLIKELY(lhs.hasError()))
    return true; // All error states are considered equal
  return lhs.value_ == rhs.value_;
}

template <
    class Value,
    class Error FOLLY_REQUIRES_TRAILING(IsEqualityComparable<Value>::value)>
inline bool operator!=(
    const Expected<Value, Error>& lhs,
    const Expected<Value, Error>& rhs) {
  return !(rhs == lhs);
}

template <class Value, class Error>
inline typename std::enable_if<IsLessThanComparable<Value>::value, bool>::type
operator<(
    const Expected<Value, Error>& lhs,
    const Expected<Value, Error>& rhs) {
  if (UNLIKELY(
          lhs.uninitializedByException() || rhs.uninitializedByException()))
    throw BadExpectedAccess();
  if (UNLIKELY(lhs.hasError()))
    return !rhs.hasError();
  if (UNLIKELY(rhs.hasError()))
    return false;
  return lhs.value_ < rhs.value_;
}

template <
    class Value,
    class Error FOLLY_REQUIRES_TRAILING(IsLessThanComparable<Value>::value)>
inline bool operator<=(
    const Expected<Value, Error>& lhs,
    const Expected<Value, Error>& rhs) {
  return !(rhs < lhs);
}

template <
    class Value,
    class Error FOLLY_REQUIRES_TRAILING(IsLessThanComparable<Value>::value)>
inline bool operator>(
    const Expected<Value, Error>& lhs,
    const Expected<Value, Error>& rhs) {
  return rhs < lhs;
}

template <
    class Value,
    class Error FOLLY_REQUIRES_TRAILING(IsLessThanComparable<Value>::value)>
inline bool operator>=(
    const Expected<Value, Error>& lhs,
    const Expected<Value, Error>& rhs) {
  return !(lhs < rhs);
}

/**
 * swap Expected values
 */
template <class Error, class Value>
void swap(Expected<Error, Value>& lhs, Expected<Value, Error>& rhs) noexcept(
    expected_detail::StrictAllOf<IsNothrowSwappable, Value, Error>::value) {
  lhs.swap(rhs);
}

template <class Value, class Error>
const Value* get_pointer(const Expected<Value, Error>& ex) noexcept {
  return ex.get_pointer();
}

template <class Value, class Error>
Value* get_pointer(Expected<Value, Error>& ex) noexcept {
  return ex.get_pointer();
}

/**
 * For constructing an Expected object from a value, with the specified
 * Error type. Usage is as follows:
 *
 * enum MyErrorCode { BAD_ERROR, WORSE_ERROR };
 * Expected<int, MyErrorCode> myAPI() {
 *   int i = // ...;
 *   return i ? makeExpected<MyErrorCode>(i) : makeUnexpected(BAD_ERROR);
 * }
 */
template <class Error, class Value>
constexpr Expected<typename std::decay<Value>::type, Error> makeExpected(
    Value&& val) {
  return Expected<typename std::decay<Value>::type, Error>{
      in_place, static_cast<Value&&>(val)};
}

// Suppress comparability of Optional<T> with T, despite implicit conversion.
template <class Value, class Error>
bool operator==(const Expected<Value, Error>&, const Value& other) = delete;
template <class Value, class Error>
bool operator!=(const Expected<Value, Error>&, const Value& other) = delete;
template <class Value, class Error>
bool operator<(const Expected<Value, Error>&, const Value& other) = delete;
template <class Value, class Error>
bool operator<=(const Expected<Value, Error>&, const Value& other) = delete;
template <class Value, class Error>
bool operator>=(const Expected<Value, Error>&, const Value& other) = delete;
template <class Value, class Error>
bool operator>(const Expected<Value, Error>&, const Value& other) = delete;
template <class Value, class Error>
bool operator==(const Value& other, const Expected<Value, Error>&) = delete;
template <class Value, class Error>
bool operator!=(const Value& other, const Expected<Value, Error>&) = delete;
template <class Value, class Error>
bool operator<(const Value& other, const Expected<Value, Error>&) = delete;
template <class Value, class Error>
bool operator<=(const Value& other, const Expected<Value, Error>&) = delete;
template <class Value, class Error>
bool operator>=(const Value& other, const Expected<Value, Error>&) = delete;
template <class Value, class Error>
bool operator>(const Value& other, const Expected<Value, Error>&) = delete;

} // namespace folly

#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif

#undef FOLLY_REQUIRES
#undef FOLLY_REQUIRES_TRAILING
