// -*-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.  */
#ifndef cm_optional
#define cm_optional

#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);
  optional& operator=(optional&& other) noexcept;

  template <
    typename U = T,
    typename = 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)>::type>
  optional& 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
{
}

template <typename T>
optional<T>::optional(const optional& other)
{
  *this = other;
}

template <typename T>
optional<T>::optional(optional&& other) noexcept
{
  *this = 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>
optional<T>& optional<T>::operator=(optional&& 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>
optional<T>& optional<T>::operator=(U&& v)
{
  if (this->has_value()) {
    this->value() = v;
  } else {
    this->emplace(std::forward<U>(v));
  }
  return *this;
}

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
}

#endif
