// -*-c++-*-
// vim: set ft=cpp:

/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#pragma once

#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
#  define CMake_HAVE_CXX_OPTIONAL
#endif

#if defined(CMake_HAVE_CXX_OPTIONAL)
#  include <optional> // IWYU pragma: export
#else
#  include <memory>

#  include <cm/utility>
#endif

namespace cm {

#if defined(CMake_HAVE_CXX_OPTIONAL)

using std::nullopt_t;
using std::nullopt;
using std::optional;
using std::bad_optional_access;
using std::make_optional;

#else

class bad_optional_access : public std::exception
{
  using std::exception::exception;
};

struct nullopt_t
{
  explicit constexpr nullopt_t(int) {}
};

constexpr nullopt_t nullopt{ 0 };

template <typename T>
class optional
{
public:
  using value_type = T;

  optional() noexcept = default;
  optional(nullopt_t) noexcept;
  optional(const optional& other);
  optional(optional&& other) noexcept;

  template <typename... Args>
  explicit optional(cm::in_place_t, Args&&... args);

  template <
    typename U = T,
    typename = typename std::enable_if<
      std::is_constructible<T, U&&>::value &&
      !std::is_same<typename std::decay<U>::type, cm::in_place_t>::value &&
      !std::is_same<typename std::decay<U>::type,
                    cm::optional<T>>::value>::type>
  optional(U&& v);

  ~optional();

  optional& operator=(nullopt_t) noexcept;
  optional& operator=(const optional& other);

  template <typename U = T>
  typename std::enable_if<std::is_constructible<T, U&&>::value &&
                            std::is_assignable<T&, U&&>::value,
                          optional&>::type
  operator=(optional<U>&& other) noexcept;

  template <typename U = T>
  typename std::enable_if<
    !std::is_same<typename std::decay<U>::type, cm::optional<T>>::value &&
      std::is_constructible<T, U&&>::value &&
      std::is_assignable<T&, U&&>::value &&
      (!std::is_scalar<T>::value ||
       !std::is_same<typename std::decay<U>::type, T>::value),
    optional&>::type
  operator=(U&& v);

  const T* operator->() const;
  T* operator->();
  const T& operator*() const&;
  T& operator*() &;
  const T&& operator*() const&&;
  T&& operator*() &&;

  explicit operator bool() const noexcept;
  bool has_value() const noexcept;

  T& value() &;
  const T& value() const&;

  T&& value() &&;
  const T&& value() const&&;

  template <typename U>
  T value_or(U&& default_value) const&;

  template <typename U>
  T value_or(U&& default_value) &&;

  void swap(optional& other) noexcept;
  void reset() noexcept;

  template <typename... Args>
  T& emplace(Args&&... args);

private:
  bool _has_value = false;
  std::allocator<T> _allocator;
  union _mem_union
  {
    T value;

    // Explicit constructor and destructor is required to make this work
    _mem_union() noexcept {}
    ~_mem_union() noexcept {}
  } _mem;
};

template <typename T>
optional<typename std::decay<T>::type> make_optional(T&& value)
{
  return optional<typename std::decay<T>::type>(std::forward<T>(value));
}

template <typename T, class... Args>
optional<T> make_optional(Args&&... args)
{
  return optional<T>(in_place, std::forward<Args>(args)...);
}

template <typename T>
optional<T>::optional(nullopt_t) noexcept
  : optional()
{
}

template <typename T>
optional<T>::optional(const optional& other)
{
  if (other.has_value()) {
    this->emplace(*other);
  }
}

template <typename T>
optional<T>::optional(optional&& other) noexcept
{
  if (other.has_value()) {
    this->emplace(std::move(*other));
  }
}

template <typename T>
template <typename... Args>
optional<T>::optional(cm::in_place_t, Args&&... args)
{
  this->emplace(std::forward<Args>(args)...);
}

template <typename T>
template <typename U, typename>
optional<T>::optional(U&& v)
{
  this->emplace(std::forward<U>(v));
}

template <typename T>
optional<T>::~optional()
{
  this->reset();
}

template <typename T>
optional<T>& optional<T>::operator=(nullopt_t) noexcept
{
  this->reset();
  return *this;
}

template <typename T>
optional<T>& optional<T>::operator=(const optional& other)
{
  if (other.has_value()) {
    if (this->has_value()) {
      this->value() = *other;
    } else {
      this->emplace(*other);
    }
  } else {
    this->reset();
  }
  return *this;
}

template <typename T>
template <typename U>
typename std::enable_if<std::is_constructible<T, U&&>::value &&
                          std::is_assignable<T&, U&&>::value,
                        optional<T>&>::type
optional<T>::operator=(optional<U>&& other) noexcept
{
  if (other.has_value()) {
    if (this->has_value()) {
      this->value() = std::move(*other);
    } else {
      this->emplace(std::move(*other));
    }
  } else {
    this->reset();
  }
  return *this;
}

template <typename T>
template <typename U>
typename std::enable_if<
  !std::is_same<typename std::decay<U>::type, cm::optional<T>>::value &&
    std::is_constructible<T, U&&>::value &&
    std::is_assignable<T&, U&&>::value &&
    (!std::is_scalar<T>::value ||
     !std::is_same<typename std::decay<U>::type, T>::value),
  optional<T>&>::type
optional<T>::operator=(U&& v)
{
  if (this->has_value()) {
    this->value() = v;
  } else {
    this->emplace(std::forward<U>(v));
  }
  return *this;
}

template <typename T, typename U>
bool operator==(const optional<T>& lhs, const optional<U>& rhs)
{
  if (lhs.has_value()) {
    return rhs.has_value() && *lhs == *rhs;
  }
  return !rhs.has_value();
}

template <typename T, typename U>
bool operator!=(const optional<T>& lhs, const optional<U>& rhs)
{
  if (lhs.has_value()) {
    return !rhs.has_value() || *lhs != *rhs;
  }
  return rhs.has_value();
}

template <typename T, typename U>
bool operator<(const optional<T>& lhs, const optional<U>& rhs)
{
  if (rhs.has_value()) {
    return !lhs.has_value() || *lhs < *rhs;
  }
  return false;
}

template <typename T, typename U>
bool operator<=(const optional<T>& lhs, const optional<U>& rhs)
{
  if (!lhs.has_value()) {
    return true;
  }
  if (rhs.has_value()) {
    return *lhs <= *rhs;
  }
  return false;
}

template <typename T, typename U>
bool operator>(const optional<T>& lhs, const optional<U>& rhs)
{
  if (lhs.has_value()) {
    return !rhs.has_value() || *lhs > *rhs;
  }
  return false;
}

template <typename T, typename U>
bool operator>=(const optional<T>& lhs, const optional<U>& rhs)
{
  if (!rhs.has_value()) {
    return true;
  }
  if (lhs.has_value()) {
    return *lhs >= *rhs;
  }
  return false;
}

template <typename T>
bool operator==(const optional<T>& opt, nullopt_t) noexcept
{
  return !opt.has_value();
}

template <typename T>
bool operator!=(const optional<T>& opt, nullopt_t) noexcept
{
  return opt.has_value();
}

template <typename T>
bool operator<(const optional<T>& opt, nullopt_t) noexcept
{
  return false;
}

template <typename T>
bool operator<=(const optional<T>& opt, nullopt_t) noexcept
{
  return !opt.has_value();
}

template <typename T>
bool operator>(const optional<T>& opt, nullopt_t) noexcept
{
  return opt.has_value();
}

template <typename T>
bool operator>=(const optional<T>& opt, nullopt_t) noexcept
{
  return true;
}

template <typename T>
bool operator==(nullopt_t, const optional<T>& opt) noexcept
{
  return !opt.has_value();
}

template <typename T>
bool operator!=(nullopt_t, const optional<T>& opt) noexcept
{
  return opt.has_value();
}

template <typename T>
bool operator<(nullopt_t, const optional<T>& opt) noexcept
{
  return opt.has_value();
}

template <typename T>
bool operator<=(nullopt_t, const optional<T>& opt) noexcept
{
  return true;
}

template <typename T>
bool operator>(nullopt_t, const optional<T>& opt) noexcept
{
  return false;
}

template <typename T>
bool operator>=(nullopt_t, const optional<T>& opt) noexcept
{
  return !opt.has_value();
}

template <typename T, typename U>
bool operator==(const optional<T>& opt, const U& value)
{
  return opt.has_value() && *opt == value;
}

template <typename T, typename U>
bool operator!=(const optional<T>& opt, const U& value)
{
  return !opt.has_value() || *opt != value;
}

template <typename T, typename U>
bool operator<(const optional<T>& opt, const U& value)
{
  return !opt.has_value() || *opt < value;
}

template <typename T, typename U>
bool operator<=(const optional<T>& opt, const U& value)
{
  return !opt.has_value() || *opt <= value;
}

template <typename T, typename U>
bool operator>(const optional<T>& opt, const U& value)
{
  return opt.has_value() && *opt > value;
}

template <typename T, typename U>
bool operator>=(const optional<T>& opt, const U& value)
{
  return opt.has_value() && *opt >= value;
}

template <typename T, typename U>
bool operator==(const T& value, const optional<U>& opt)
{
  return opt.has_value() && value == *opt;
}

template <typename T, typename U>
bool operator!=(const T& value, const optional<U>& opt)
{
  return !opt.has_value() || value != *opt;
}

template <typename T, typename U>
bool operator<(const T& value, const optional<U>& opt)
{
  return opt.has_value() && value < *opt;
}

template <typename T, typename U>
bool operator<=(const T& value, const optional<U>& opt)
{
  return opt.has_value() && value <= *opt;
}

template <typename T, typename U>
bool operator>(const T& value, const optional<U>& opt)
{
  return !opt.has_value() || value > *opt;
}

template <typename T, typename U>
bool operator>=(const T& value, const optional<U>& opt)
{
  return !opt.has_value() || value >= *opt;
}

template <typename T>
const T* optional<T>::operator->() const
{
  return &**this;
}

template <typename T>
T* optional<T>::operator->()
{
  return &**this;
}

template <typename T>
const T& optional<T>::operator*() const&
{
  return this->_mem.value;
}

template <typename T>
T& optional<T>::operator*() &
{
  return this->_mem.value;
}

template <typename T>
const T&& optional<T>::operator*() const&&
{
  return std::move(**this);
}

template <typename T>
T&& optional<T>::operator*() &&
{
  return std::move(**this);
}

template <typename T>
bool optional<T>::has_value() const noexcept
{
  return this->_has_value;
}

template <typename T>
optional<T>::operator bool() const noexcept
{
  return this->has_value();
}

template <typename T>
T& optional<T>::value() &
{
  if (!this->has_value()) {
    throw cm::bad_optional_access{};
  }
  return **this;
}

template <typename T>
const T& optional<T>::value() const&
{
  if (!this->has_value()) {
    throw cm::bad_optional_access{};
  }
  return **this;
}

template <typename T>
template <typename U>
T optional<T>::value_or(U&& default_value) const&
{
  return bool(*this) ? **this : static_cast<T>(std::forward<U>(default_value));
}

template <typename T>
template <typename U>
T optional<T>::value_or(U&& default_value) &&
{
  return bool(*this) ? std::move(**this)
                     : static_cast<T>(std::forward<U>(default_value));
}

template <typename T>
void optional<T>::swap(optional& other) noexcept
{
  if (this->has_value()) {
    if (other.has_value()) {
      using std::swap;
      swap(**this, *other);
    } else {
      other.emplace(std::move(**this));
      this->reset();
    }
  } else if (other.has_value()) {
    this->emplace(std::move(*other));
    other.reset();
  }
}

template <typename T>
void optional<T>::reset() noexcept
{
  if (this->has_value()) {
    this->_has_value = false;
    std::allocator_traits<std::allocator<T>>::destroy(this->_allocator,
                                                      &**this);
  }
}

template <typename T>
template <typename... Args>
T& optional<T>::emplace(Args&&... args)
{
  this->reset();
  std::allocator_traits<std::allocator<T>>::construct(
    this->_allocator, &**this, std::forward<Args>(args)...);
  this->_has_value = true;
  return this->value();
}

#endif
}
