/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * 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.
 */

#pragma once

#include <algorithm>
#include <initializer_list>
#include <type_traits>
#include <utility>
#include <variant>

// android::base::expected is an Android implementation of the std::expected
// proposal.
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0323r7.html
//
// Usage:
// using android::base::expected;
// using android::base::unexpected;
//
// expected<double,std::string> safe_divide(double i, double j) {
//   if (j == 0) return unexpected("divide by zero");
//   else return i / j;
// }
//
// void test() {
//   auto q = safe_divide(10, 0);
//   if (q) { printf("%f\n", q.value()); }
//   else { printf("%s\n", q.error().c_str()); }
// }
//
// When the proposal becomes part of the standard and is implemented by
// libcxx, this will be removed and android::base::expected will be
// type alias to std::expected.
//

namespace android {
namespace base {

// Synopsis
template<class T, class E>
    class expected;

template<class E>
    class unexpected;
template<class E>
  unexpected(E) -> unexpected<E>;

template<class E>
   class bad_expected_access;

template<>
   class bad_expected_access<void>;

struct unexpect_t {
   explicit unexpect_t() = default;
};
inline constexpr unexpect_t unexpect{};

// macros for SFINAE
#define _ENABLE_IF(...) \
  , std::enable_if_t<(__VA_ARGS__)>* = nullptr

// Define NODISCARD_EXPECTED to prevent expected<T,E> from being
// ignored when used as a return value. This is off by default.
#ifdef NODISCARD_EXPECTED
#define _NODISCARD_ [[nodiscard]]
#else
#define _NODISCARD_
#endif

namespace {
template< class T >
struct remove_cvref {
  typedef std::remove_cv_t<std::remove_reference_t<T>> type;
};
template< class T >
using remove_cvref_t = typename remove_cvref<T>::type;
} // namespace

// Class expected
template<class T, class E>
class _NODISCARD_ expected {
 public:
  using value_type = T;
  using error_type = E;
  using unexpected_type = unexpected<E>;

  template<class U>
  using rebind = expected<U, error_type>;

  // constructors
  constexpr expected() = default;
  constexpr expected(const expected& rhs) = default;
  constexpr expected(expected&& rhs) noexcept = default;

  template<class U, class G _ENABLE_IF(
    std::is_constructible_v<T, const U&> &&
    std::is_constructible_v<E, const G&> &&
    !std::is_constructible_v<T, expected<U, G>&> &&
    !std::is_constructible_v<T, expected<U, G>&&> &&
    !std::is_constructible_v<T, const expected<U, G>&> &&
    !std::is_constructible_v<T, const expected<U, G>&&> &&
    !std::is_convertible_v<expected<U, G>&, T> &&
    !std::is_convertible_v<expected<U, G>&&, T> &&
    !std::is_convertible_v<const expected<U, G>&, T> &&
    !std::is_convertible_v<const expected<U, G>&&, T> &&
    !(!std::is_convertible_v<const U&, T> ||
     !std::is_convertible_v<const G&, E>) /* non-explicit */
  )>
  constexpr expected(const expected<U, G>& rhs) {
    if (rhs.has_value()) var_ = rhs.value();
    else var_ = unexpected(rhs.error());
  }

  template<class U, class G _ENABLE_IF(
    std::is_constructible_v<T, const U&> &&
    std::is_constructible_v<E, const G&> &&
    !std::is_constructible_v<T, expected<U, G>&> &&
    !std::is_constructible_v<T, expected<U, G>&&> &&
    !std::is_constructible_v<T, const expected<U, G>&> &&
    !std::is_constructible_v<T, const expected<U, G>&&> &&
    !std::is_convertible_v<expected<U, G>&, T> &&
    !std::is_convertible_v<expected<U, G>&&, T> &&
    !std::is_convertible_v<const expected<U, G>&, T> &&
    !std::is_convertible_v<const expected<U, G>&&, T> &&
    (!std::is_convertible_v<const U&, T> ||
     !std::is_convertible_v<const G&, E>) /* explicit */
  )>
  constexpr explicit expected(const expected<U, G>& rhs) {
    if (rhs.has_value()) var_ = rhs.value();
    else var_ = unexpected(rhs.error());
  }

  template<class U, class G _ENABLE_IF(
    std::is_constructible_v<T, const U&> &&
    std::is_constructible_v<E, const G&> &&
    !std::is_constructible_v<T, expected<U, G>&> &&
    !std::is_constructible_v<T, expected<U, G>&&> &&
    !std::is_constructible_v<T, const expected<U, G>&> &&
    !std::is_constructible_v<T, const expected<U, G>&&> &&
    !std::is_convertible_v<expected<U, G>&, T> &&
    !std::is_convertible_v<expected<U, G>&&, T> &&
    !std::is_convertible_v<const expected<U, G>&, T> &&
    !std::is_convertible_v<const expected<U, G>&&, T> &&
    !(!std::is_convertible_v<const U&, T> ||
     !std::is_convertible_v<const G&, E>) /* non-explicit */
  )>
  constexpr expected(expected<U, G>&& rhs) {
    if (rhs.has_value()) var_ = std::move(rhs.value());
    else var_ = unexpected(std::move(rhs.error()));
  }

  template<class U, class G _ENABLE_IF(
    std::is_constructible_v<T, const U&> &&
    std::is_constructible_v<E, const G&> &&
    !std::is_constructible_v<T, expected<U, G>&> &&
    !std::is_constructible_v<T, expected<U, G>&&> &&
    !std::is_constructible_v<T, const expected<U, G>&> &&
    !std::is_constructible_v<T, const expected<U, G>&&> &&
    !std::is_convertible_v<expected<U, G>&, T> &&
    !std::is_convertible_v<expected<U, G>&&, T> &&
    !std::is_convertible_v<const expected<U, G>&, T> &&
    !std::is_convertible_v<const expected<U, G>&&, T> &&
    (!std::is_convertible_v<const U&, T> ||
     !std::is_convertible_v<const G&, E>) /* explicit */
  )>
  constexpr explicit expected(expected<U, G>&& rhs) {
    if (rhs.has_value()) var_ = std::move(rhs.value());
    else var_ = unexpected(std::move(rhs.error()));
  }

  template<class U = T _ENABLE_IF(
    std::is_constructible_v<T, U&&> &&
    !std::is_same_v<remove_cvref_t<U>, std::in_place_t> &&
    !std::is_same_v<expected<T, E>, remove_cvref_t<U>> &&
    !std::is_same_v<unexpected<E>, remove_cvref_t<U>> &&
    std::is_convertible_v<U&&,T> /* non-explicit */
  )>
  constexpr expected(U&& v)
  : var_(std::in_place_index<0>, std::forward<U>(v)) {}

  template<class U = T _ENABLE_IF(
    std::is_constructible_v<T, U&&> &&
    !std::is_same_v<remove_cvref_t<U>, std::in_place_t> &&
    !std::is_same_v<expected<T, E>, remove_cvref_t<U>> &&
    !std::is_same_v<unexpected<E>, remove_cvref_t<U>> &&
    !std::is_convertible_v<U&&,T> /* explicit */
  )>
  constexpr explicit expected(U&& v)
  : var_(std::in_place_index<0>, T(std::forward<U>(v))) {}

  template<class G = E _ENABLE_IF(
    std::is_constructible_v<E, const G&> &&
    std::is_convertible_v<const G&, E> /* non-explicit */
  )>
  constexpr expected(const unexpected<G>& e)
  : var_(std::in_place_index<1>, e.value()) {}

  template<class G = E _ENABLE_IF(
    std::is_constructible_v<E, const G&> &&
    !std::is_convertible_v<const G&, E> /* explicit */
  )>
  constexpr explicit expected(const unexpected<G>& e)
  : var_(std::in_place_index<1>, E(e.value())) {}

  template<class G = E _ENABLE_IF(
    std::is_constructible_v<E, G&&> &&
    std::is_convertible_v<G&&, E> /* non-explicit */
  )>
  constexpr expected(unexpected<G>&& e)
  : var_(std::in_place_index<1>, std::move(e.value())) {}

  template<class G = E _ENABLE_IF(
    std::is_constructible_v<E, G&&> &&
    !std::is_convertible_v<G&&, E> /* explicit */
  )>
  constexpr explicit expected(unexpected<G>&& e)
  : var_(std::in_place_index<1>, E(std::move(e.value()))) {}

  template<class... Args _ENABLE_IF(
    std::is_constructible_v<T, Args&&...>
  )>
  constexpr explicit expected(std::in_place_t, Args&&... args)
  : var_(std::in_place_index<0>, std::forward<Args>(args)...) {}

  template<class U, class... Args _ENABLE_IF(
    std::is_constructible_v<T, std::initializer_list<U>&, Args...>
  )>
  constexpr explicit expected(std::in_place_t, std::initializer_list<U> il, Args&&... args)
  : var_(std::in_place_index<0>, il, std::forward<Args>(args)...) {}

  template<class... Args _ENABLE_IF(
    std::is_constructible_v<E, Args...>
  )>
  constexpr explicit expected(unexpect_t, Args&&... args)
  : var_(unexpected_type(std::forward<Args>(args)...)) {}

  template<class U, class... Args _ENABLE_IF(
    std::is_constructible_v<E, std::initializer_list<U>&, Args...>
  )>
  constexpr explicit expected(unexpect_t, std::initializer_list<U> il, Args&&... args)
  : var_(unexpected_type(il, std::forward<Args>(args)...)) {}

  // destructor
  ~expected() = default;

  // assignment
  // Note: SFNAIE doesn't work here because assignment operator should be
  // non-template. We could workaround this by defining a templated parent class
  // having the assignment operator. This incomplete implementation however
  // doesn't allow us to copy assign expected<T,E> even when T is non-copy
  // assignable. The copy assignment will fail by the underlying std::variant
  // anyway though the error message won't be clear.
  expected& operator=(const expected& rhs) = default;

  // Note for SFNAIE above applies to here as well
  expected& operator=(expected&& rhs) = default;

  template<class U = T _ENABLE_IF(
    !std::is_void_v<T> &&
    !std::is_same_v<expected<T,E>, remove_cvref_t<U>> &&
    !std::conjunction_v<std::is_scalar<T>, std::is_same<T, std::decay_t<U>>> &&
    std::is_constructible_v<T,U> &&
    std::is_assignable_v<T&,U> &&
    std::is_nothrow_move_constructible_v<E>
  )>
  expected& operator=(U&& rhs) {
    var_ = T(std::forward<U>(rhs));
    return *this;
  }

  template<class G = E>
  expected& operator=(const unexpected<G>& rhs) {
    var_ = rhs;
    return *this;
  }

  template<class G = E _ENABLE_IF(
    std::is_nothrow_move_constructible_v<G> &&
    std::is_move_assignable_v<G>
  )>
  expected& operator=(unexpected<G>&& rhs) {
    var_ = std::move(rhs);
    return *this;
  }

  // modifiers
  template<class... Args _ENABLE_IF(
    std::is_nothrow_constructible_v<T, Args...>
  )>
  T& emplace(Args&&... args) {
    expected(std::in_place, std::forward<Args>(args)...).swap(*this);
    return value();
  }

  template<class U, class... Args _ENABLE_IF(
    std::is_nothrow_constructible_v<T, std::initializer_list<U>&, Args...>
  )>
  T& emplace(std::initializer_list<U> il, Args&&... args) {
    expected(std::in_place, il, std::forward<Args>(args)...).swap(*this);
    return value();
  }

  // swap
  template<typename U = T, typename = std::enable_if_t<(
    std::is_swappable_v<U> &&
    std::is_swappable_v<E> &&
    (std::is_move_constructible_v<U> ||
     std::is_move_constructible_v<E>))>>
  void swap(expected& rhs) noexcept(
    std::is_nothrow_move_constructible_v<T> &&
    std::is_nothrow_swappable_v<T> &&
    std::is_nothrow_move_constructible_v<E> &&
    std::is_nothrow_swappable_v<E>) {
    var_.swap(rhs.var_);
  }

  // observers
  constexpr const T* operator->() const { return std::addressof(value()); }
  constexpr T* operator->() { return std::addressof(value()); }
  constexpr const T& operator*() const& { return value(); }
  constexpr T& operator*() & { return value(); }
  constexpr const T&& operator*() const&& { return std::move(std::get<T>(var_)); }
  constexpr T&& operator*() && { return std::move(std::get<T>(var_)); }

  constexpr explicit operator bool() const noexcept { return has_value(); }
  constexpr bool has_value() const noexcept { return var_.index() == 0; }

  constexpr const T& value() const& { return std::get<T>(var_); }
  constexpr T& value() & { return std::get<T>(var_); }
  constexpr const T&& value() const&& { return std::move(std::get<T>(var_)); }
  constexpr T&& value() && { return std::move(std::get<T>(var_)); }

  constexpr const E& error() const& { return std::get<unexpected_type>(var_).value(); }
  constexpr E& error() & { return std::get<unexpected_type>(var_).value(); }
  constexpr const E&& error() const&& { return std::move(std::get<unexpected_type>(var_)).value(); }
  constexpr E&& error() && { return std::move(std::get<unexpected_type>(var_)).value(); }

  template<class U _ENABLE_IF(
    std::is_copy_constructible_v<T> &&
    std::is_convertible_v<U, T>
  )>
  constexpr T value_or(U&& v) const& {
    if (has_value()) return value();
    else return static_cast<T>(std::forward<U>(v));
  }

  template<class U _ENABLE_IF(
    std::is_move_constructible_v<T> &&
    std::is_convertible_v<U, T>
  )>
  constexpr T value_or(U&& v) && {
    if (has_value()) return std::move(value());
    else return static_cast<T>(std::forward<U>(v));
  }

  // expected equality operators
  template<class T1, class E1, class T2, class E2>
  friend constexpr bool operator==(const expected<T1, E1>& x, const expected<T2, E2>& y);
  template<class T1, class E1, class T2, class E2>
  friend constexpr bool operator!=(const expected<T1, E1>& x, const expected<T2, E2>& y);

  // comparison with T
  template<class T1, class E1, class T2>
  friend constexpr bool operator==(const expected<T1, E1>&, const T2&);
  template<class T1, class E1, class T2>
  friend constexpr bool operator==(const T2&, const expected<T1, E1>&);
  template<class T1, class E1, class T2>
  friend constexpr bool operator!=(const expected<T1, E1>&, const T2&);
  template<class T1, class E1, class T2>
  friend constexpr bool operator!=(const T2&, const expected<T1, E1>&);

  // Comparison with unexpected<E>
  template<class T1, class E1, class E2>
  friend constexpr bool operator==(const expected<T1, E1>&, const unexpected<E2>&);
  template<class T1, class E1, class E2>
  friend constexpr bool operator==(const unexpected<E2>&, const expected<T1, E1>&);
  template<class T1, class E1, class E2>
  friend constexpr bool operator!=(const expected<T1, E1>&, const unexpected<E2>&);
  template<class T1, class E1, class E2>
  friend constexpr bool operator!=(const unexpected<E2>&, const expected<T1, E1>&);

  // Specialized algorithms
  template<class T1, class E1>
  friend void swap(expected<T1, E1>&, expected<T1, E1>&) noexcept;

 private:
  std::variant<value_type, unexpected_type> var_;
};

template<class T1, class E1, class T2, class E2>
constexpr bool operator==(const expected<T1, E1>& x, const expected<T2, E2>& y) {
  if (x.has_value() != y.has_value()) {
    return false;
  } else if (!x.has_value()) {
    return x.error() == y.error();
  } else {
    return *x == *y;
  }
}

template<class T1, class E1, class T2, class E2>
constexpr bool operator!=(const expected<T1, E1>& x, const expected<T2, E2>& y) {
  return !(x == y);
}

// comparison with T
template<class T1, class E1, class T2>
constexpr bool operator==(const expected<T1, E1>& x, const T2& y) {
  return x.has_value() && (*x == y);
}
template<class T1, class E1, class T2>
constexpr bool operator==(const T2& x, const expected<T1, E1>& y) {
  return y.has_value() && (x == *y);
}
template<class T1, class E1, class T2>
constexpr bool operator!=(const expected<T1, E1>& x, const T2& y) {
  return !x.has_value() || (*x != y);
}
template<class T1, class E1, class T2>
constexpr bool operator!=(const T2& x, const expected<T1, E1>& y) {
  return !y.has_value() || (x != *y);
}

// Comparison with unexpected<E>
template<class T1, class E1, class E2>
constexpr bool operator==(const expected<T1, E1>& x, const unexpected<E2>& y) {
  return !x.has_value() && (x.error() == y.value());
}
template<class T1, class E1, class E2>
constexpr bool operator==(const unexpected<E2>& x, const expected<T1, E1>& y) {
  return !y.has_value() && (x.value() == y.error());
}
template<class T1, class E1, class E2>
constexpr bool operator!=(const expected<T1, E1>& x, const unexpected<E2>& y) {
  return x.has_value() || (x.error() != y.value());
}
template<class T1, class E1, class E2>
constexpr bool operator!=(const unexpected<E2>& x, const expected<T1, E1>& y) {
  return y.has_value() || (x.value() != y.error());
}

template<class E>
class _NODISCARD_ expected<void, E> {
 public:
  using value_type = void;
  using error_type = E;
  using unexpected_type = unexpected<E>;

  // constructors
  constexpr expected() = default;
  constexpr expected(const expected& rhs) = default;
  constexpr expected(expected&& rhs) noexcept = default;

  template<class U, class G _ENABLE_IF(
    std::is_void_v<U> &&
    std::is_convertible_v<const G&, E> /* non-explicit */
  )>
  constexpr expected(const expected<U, G>& rhs) {
    if (!rhs.has_value()) var_ = unexpected(rhs.error());
  }

  template<class U, class G _ENABLE_IF(
    std::is_void_v<U> &&
    !std::is_convertible_v<const G&, E> /* explicit */
  )>
  constexpr explicit expected(const expected<U, G>& rhs) {
    if (!rhs.has_value()) var_ = unexpected(rhs.error());
  }

  template<class U, class G _ENABLE_IF(
    std::is_void_v<U> &&
    std::is_convertible_v<const G&&, E> /* non-explicit */
  )>
  constexpr expected(expected<U, G>&& rhs) {
    if (!rhs.has_value()) var_ = unexpected(std::move(rhs.error()));
  }

  template<class U, class G _ENABLE_IF(
    std::is_void_v<U> &&
    !std::is_convertible_v<const G&&, E> /* explicit */
  )>
  constexpr explicit expected(expected<U, G>&& rhs) {
    if (!rhs.has_value()) var_ = unexpected(std::move(rhs.error()));
  }

  template<class G = E _ENABLE_IF(
    std::is_constructible_v<E, const G&> &&
    std::is_convertible_v<const G&, E> /* non-explicit */
  )>
  constexpr expected(const unexpected<G>& e)
  : var_(std::in_place_index<1>, e.value()) {}

  template<class G = E _ENABLE_IF(
    std::is_constructible_v<E, const G&> &&
    !std::is_convertible_v<const G&, E> /* explicit */
  )>
  constexpr explicit expected(const unexpected<G>& e)
  : var_(std::in_place_index<1>, E(e.value())) {}

  template<class G = E _ENABLE_IF(
    std::is_constructible_v<E, G&&> &&
    std::is_convertible_v<G&&, E> /* non-explicit */
  )>
  constexpr expected(unexpected<G>&& e)
  : var_(std::in_place_index<1>, std::move(e.value())) {}

  template<class G = E _ENABLE_IF(
    std::is_constructible_v<E, G&&> &&
    !std::is_convertible_v<G&&, E> /* explicit */
  )>
  constexpr explicit expected(unexpected<G>&& e)
  : var_(std::in_place_index<1>, E(std::move(e.value()))) {}

  template<class... Args _ENABLE_IF(
    sizeof...(Args) == 0
  )>
  constexpr explicit expected(std::in_place_t, Args&&...) {}

  template<class... Args _ENABLE_IF(
    std::is_constructible_v<E, Args...>
  )>
  constexpr explicit expected(unexpect_t, Args&&... args)
  : var_(unexpected_type(std::forward<Args>(args)...)) {}

  template<class U, class... Args _ENABLE_IF(
    std::is_constructible_v<E, std::initializer_list<U>&, Args...>
  )>
  constexpr explicit expected(unexpect_t, std::initializer_list<U> il, Args&&... args)
  : var_(unexpected_type(il, std::forward<Args>(args)...)) {}

  // destructor
  ~expected() = default;

  // assignment
  // Note: SFNAIE doesn't work here because assignment operator should be
  // non-template. We could workaround this by defining a templated parent class
  // having the assignment operator. This incomplete implementation however
  // doesn't allow us to copy assign expected<T,E> even when T is non-copy
  // assignable. The copy assignment will fail by the underlying std::variant
  // anyway though the error message won't be clear.
  expected& operator=(const expected& rhs) = default;

  // Note for SFNAIE above applies to here as well
  expected& operator=(expected&& rhs) = default;

  template<class G = E>
  expected& operator=(const unexpected<G>& rhs) {
    var_ = rhs;
    return *this;
  }

  template<class G = E _ENABLE_IF(
    std::is_nothrow_move_constructible_v<G> &&
    std::is_move_assignable_v<G>
  )>
  expected& operator=(unexpected<G>&& rhs) {
    var_ = std::move(rhs);
    return *this;
  }

  // modifiers
  void emplace() {
    var_ = std::monostate();
  }

  // swap
  template<typename = std::enable_if_t<
    std::is_swappable_v<E>>
  >
  void swap(expected& rhs) noexcept(std::is_nothrow_move_constructible_v<E>) {
    var_.swap(rhs.var_);
  }

  // observers
  constexpr explicit operator bool() const noexcept { return has_value(); }
  constexpr bool has_value() const noexcept { return var_.index() == 0; }

  constexpr void value() const& { if (!has_value()) std::get<0>(var_); }

  constexpr const E& error() const& { return std::get<unexpected_type>(var_).value(); }
  constexpr E& error() & { return std::get<unexpected_type>(var_).value(); }
  constexpr const E&& error() const&& { return std::move(std::get<unexpected_type>(var_)).value(); }
  constexpr E&& error() && { return std::move(std::get<unexpected_type>(var_)).value(); }

  // expected equality operators
  template<class E1, class E2>
  friend constexpr bool operator==(const expected<void, E1>& x, const expected<void, E2>& y);

  // Specialized algorithms
  template<class T1, class E1>
  friend void swap(expected<T1, E1>&, expected<T1, E1>&) noexcept;

 private:
  std::variant<std::monostate, unexpected_type> var_;
};

template<class E1, class E2>
constexpr bool operator==(const expected<void, E1>& x, const expected<void, E2>& y) {
  if (x.has_value() != y.has_value()) {
    return false;
  } else if (!x.has_value()) {
    return x.error() == y.error();
  } else {
    return true;
  }
}

template<class T1, class E1, class E2>
constexpr bool operator==(const expected<T1, E1>& x, const expected<void, E2>& y) {
  if (x.has_value() != y.has_value()) {
    return false;
  } else if (!x.has_value()) {
    return x.error() == y.error();
  } else {
    return false;
  }
}

template<class E1, class T2, class E2>
constexpr bool operator==(const expected<void, E1>& x, const expected<T2, E2>& y) {
  if (x.has_value() != y.has_value()) {
    return false;
  } else if (!x.has_value()) {
    return x.error() == y.error();
  } else {
    return false;
  }
}

template<class E>
class unexpected {
 public:
  // constructors
  constexpr unexpected(const unexpected&) = default;
  constexpr unexpected(unexpected&&) = default;

  template<class Err = E _ENABLE_IF(
    std::is_constructible_v<E, Err> &&
    !std::is_same_v<remove_cvref_t<E>, std::in_place_t> &&
    !std::is_same_v<remove_cvref_t<E>, unexpected>
  )>
  constexpr unexpected(Err&& e)
  : val_(std::forward<Err>(e)) {}

  template<class U, class... Args _ENABLE_IF(
    std::is_constructible_v<E, std::initializer_list<U>&, Args...>
  )>
  constexpr explicit unexpected(std::in_place_t, std::initializer_list<U> il, Args&&... args)
  : val_(il, std::forward<Args>(args)...) {}

  template<class Err _ENABLE_IF(
    std::is_constructible_v<E, Err> &&
    !std::is_constructible_v<E, unexpected<Err>&> &&
    !std::is_constructible_v<E, unexpected<Err>> &&
    !std::is_constructible_v<E, const unexpected<Err>&> &&
    !std::is_constructible_v<E, const unexpected<Err>> &&
    !std::is_convertible_v<unexpected<Err>&, E> &&
    !std::is_convertible_v<unexpected<Err>, E> &&
    !std::is_convertible_v<const unexpected<Err>&, E> &&
    !std::is_convertible_v<const unexpected<Err>, E> &&
    std::is_convertible_v<Err, E> /* non-explicit */
  )>
  constexpr unexpected(const unexpected<Err>& rhs)
  : val_(rhs.value()) {}

  template<class Err _ENABLE_IF(
    std::is_constructible_v<E, Err> &&
    !std::is_constructible_v<E, unexpected<Err>&> &&
    !std::is_constructible_v<E, unexpected<Err>> &&
    !std::is_constructible_v<E, const unexpected<Err>&> &&
    !std::is_constructible_v<E, const unexpected<Err>> &&
    !std::is_convertible_v<unexpected<Err>&, E> &&
    !std::is_convertible_v<unexpected<Err>, E> &&
    !std::is_convertible_v<const unexpected<Err>&, E> &&
    !std::is_convertible_v<const unexpected<Err>, E> &&
    !std::is_convertible_v<Err, E> /* explicit */
  )>
  constexpr explicit unexpected(const unexpected<Err>& rhs)
  : val_(E(rhs.value())) {}

  template<class Err _ENABLE_IF(
    std::is_constructible_v<E, Err> &&
    !std::is_constructible_v<E, unexpected<Err>&> &&
    !std::is_constructible_v<E, unexpected<Err>> &&
    !std::is_constructible_v<E, const unexpected<Err>&> &&
    !std::is_constructible_v<E, const unexpected<Err>> &&
    !std::is_convertible_v<unexpected<Err>&, E> &&
    !std::is_convertible_v<unexpected<Err>, E> &&
    !std::is_convertible_v<const unexpected<Err>&, E> &&
    !std::is_convertible_v<const unexpected<Err>, E> &&
    std::is_convertible_v<Err, E> /* non-explicit */
  )>
  constexpr unexpected(unexpected<Err>&& rhs)
  : val_(std::move(rhs.value())) {}

  template<class Err _ENABLE_IF(
    std::is_constructible_v<E, Err> &&
    !std::is_constructible_v<E, unexpected<Err>&> &&
    !std::is_constructible_v<E, unexpected<Err>> &&
    !std::is_constructible_v<E, const unexpected<Err>&> &&
    !std::is_constructible_v<E, const unexpected<Err>> &&
    !std::is_convertible_v<unexpected<Err>&, E> &&
    !std::is_convertible_v<unexpected<Err>, E> &&
    !std::is_convertible_v<const unexpected<Err>&, E> &&
    !std::is_convertible_v<const unexpected<Err>, E> &&
    !std::is_convertible_v<Err, E> /* explicit */
  )>
  constexpr explicit unexpected(unexpected<Err>&& rhs)
  : val_(E(std::move(rhs.value()))) {}

  // assignment
  constexpr unexpected& operator=(const unexpected&) = default;
  constexpr unexpected& operator=(unexpected&&) = default;
  template<class Err = E>
  constexpr unexpected& operator=(const unexpected<Err>& rhs) {
    val_ = rhs.value();
    return *this;
  }
  template<class Err = E>
  constexpr unexpected& operator=(unexpected<Err>&& rhs) {
    val_ = std::forward<E>(rhs.value());
    return *this;
  }

  // observer
  constexpr const E& value() const& noexcept { return val_; }
  constexpr E& value() & noexcept { return val_; }
  constexpr const E&& value() const&& noexcept { return std::move(val_); }
  constexpr E&& value() && noexcept { return std::move(val_); }

  void swap(unexpected& other) noexcept(std::is_nothrow_swappable_v<E>) {
    std::swap(val_, other.val_);
  }

  template<class E1, class E2>
  friend constexpr bool
  operator==(const unexpected<E1>& e1, const unexpected<E2>& e2);
  template<class E1, class E2>
  friend constexpr bool
  operator!=(const unexpected<E1>& e1, const unexpected<E2>& e2);

  template<class E1>
  friend void swap(unexpected<E1>& x, unexpected<E1>& y) noexcept(noexcept(x.swap(y)));

 private:
  E val_;
};

template<class E1, class E2>
constexpr bool
operator==(const unexpected<E1>& e1, const unexpected<E2>& e2) {
  return e1.value() == e2.value();
}

template<class E1, class E2>
constexpr bool
operator!=(const unexpected<E1>& e1, const unexpected<E2>& e2) {
  return e1.value() != e2.value();
}

template<class E1>
void swap(unexpected<E1>& x, unexpected<E1>& y) noexcept(noexcept(x.swap(y))) {
  x.swap(y);
}

// TODO: bad_expected_access class

#undef _ENABLE_IF
#undef _NODISCARD_

}  // namespace base
}  // namespace android
