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

/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst 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(optional const& 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=(optional const& 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);

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

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

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

  T&& value() &&;
  T const&& 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(optional const& 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=(optional const& 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==(optional<T> const& lhs, optional<U> const& rhs)
{
  if (lhs.has_value()) {
    return rhs.has_value() && *lhs == *rhs;
  }
  return !rhs.has_value();
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

template <typename T>
T const&& 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>
T const& 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
}
