// Copyright 2019 Google LLC
//
// 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
//
//     https://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.

#ifndef dap_optional_h
#define dap_optional_h

#include <assert.h>
#include <type_traits>
#include <utility>  // std::move

namespace dap {

// optional holds an 'optional' contained value.
// This is similar to C++17's std::optional.
template <typename T>
class optional {
  template <typename U>
  using IsConvertibleToT =
      typename std::enable_if<std::is_convertible<U, T>::value>::type;

 public:
  using value_type = T;

  // constructors
  inline optional() = default;
  inline optional(const optional& other);
  inline optional(optional&& other);
  template <typename U>
  inline optional(const optional<U>& other);
  template <typename U>
  inline optional(optional<U>&& other);
  template <typename U = value_type, typename = IsConvertibleToT<U>>
  inline optional(U&& value);

  // value() returns the contained value.
  // If the optional does not contain a value, then value() will assert.
  inline T& value();
  inline const T& value() const;

  // value() returns the contained value, or defaultValue if the optional does
  // not contain a value.
  inline T& value(const T& defaultValue);
  inline const T& value(const T& defaultValue) const;

  // operator bool() returns true if the optional contains a value.
  inline explicit operator bool() const noexcept;

  // has_value() returns true if the optional contains a value.
  inline bool has_value() const;

  // assignment
  inline optional& operator=(const optional& other);
  inline optional& operator=(optional&& other) noexcept;
  template <typename U = T, typename = IsConvertibleToT<U>>
  inline optional& operator=(U&& value);
  template <typename U>
  inline optional& operator=(const optional<U>& other);
  template <typename U>
  inline optional& operator=(optional<U>&& other);

  // value access
  inline const T* operator->() const;
  inline T* operator->();
  inline const T& operator*() const;
  inline T& operator*();

 private:
  T val = {};
  bool set = false;
};

template <typename T>
optional<T>::optional(const optional& other) : val(other.val), set(other.set) {}

template <typename T>
optional<T>::optional(optional&& other)
    : val(std::move(other.val)), set(other.set) {}

template <typename T>
template <typename U>
optional<T>::optional(const optional<U>& other) : set(other.has_value()) {
  if (set) {
    val = static_cast<T>(other.value());
  }
}

template <typename T>
template <typename U>
optional<T>::optional(optional<U>&& other) : set(other.has_value()) {
  if (set) {
    val = static_cast<T>(std::move(other.value()));
  }
}

template <typename T>
template <typename U /*= T*/, typename>
optional<T>::optional(U&& value) : val(std::move(value)), set(true) {}

template <typename T>
T& optional<T>::value() {
  assert(set);
  return val;
}

template <typename T>
const T& optional<T>::value() const {
  assert(set);
  return val;
}

template <typename T>
T& optional<T>::value(const T& defaultValue) {
  if (!has_value()) {
    return defaultValue;
  }
  return val;
}

template <typename T>
const T& optional<T>::value(const T& defaultValue) const {
  if (!has_value()) {
    return defaultValue;
  }
  return val;
}

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

template <typename T>
bool optional<T>::has_value() const {
  return set;
}

template <typename T>
optional<T>& optional<T>::operator=(const optional& other) {
  val = other.val;
  set = other.set;
  return *this;
}

template <typename T>
optional<T>& optional<T>::operator=(optional&& other) noexcept {
  val = std::move(other.val);
  set = other.set;
  return *this;
}

template <typename T>
template <typename U /* = T */, typename>
optional<T>& optional<T>::operator=(U&& value) {
  val = std::move(value);
  set = true;
  return *this;
}

template <typename T>
template <typename U>
optional<T>& optional<T>::operator=(const optional<U>& other) {
  val = other.val;
  set = other.set;
  return *this;
}

template <typename T>
template <typename U>
optional<T>& optional<T>::operator=(optional<U>&& other) {
  val = std::move(other.val);
  set = other.set;
  return *this;
}

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

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

template <typename T>
const T& optional<T>::operator*() const {
  assert(set);
  return val;
}

template <typename T>
T& optional<T>::operator*() {
  assert(set);
  return val;
}

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

template <class T, class U>
inline bool operator!=(const optional<T>& lhs, const optional<U>& rhs) {
  return !(lhs == rhs);
}

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

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

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

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

}  // namespace dap

#endif  // dap_optional_h
