//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <future>
#include <string>

_LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS

class _LIBCPP_HIDDEN __future_error_category : public __do_message {
public:
  virtual const char* name() const noexcept;
  virtual string message(int ev) const;
};

const char* __future_error_category::name() const noexcept { return "future"; }

_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wswitch")
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wswitch")

string __future_error_category::message(int ev) const {
  switch (static_cast<future_errc>(ev)) {
  case future_errc(0): // For backwards compatibility with C++11 (LWG 2056)
  case future_errc::broken_promise:
    return string("The associated promise has been destructed prior "
                  "to the associated state becoming ready.");
  case future_errc::future_already_retrieved:
    return string("The future has already been retrieved from "
                  "the promise or packaged_task.");
  case future_errc::promise_already_satisfied:
    return string("The state of the promise has already been set.");
  case future_errc::no_state:
    return string("Operation not permitted on an object without "
                  "an associated state.");
  }
  return string("unspecified future_errc value\n");
}

_LIBCPP_DIAGNOSTIC_POP

const error_category& future_category() noexcept {
  union AvoidDestroyingFutureCategory {
    __future_error_category future_error_category;
    constexpr explicit AvoidDestroyingFutureCategory() : future_error_category() {}
    ~AvoidDestroyingFutureCategory() {}
  };
  // Use no-destroy since this removes the function local static guard variable.
  _LIBCPP_NO_DESTROY constinit static AvoidDestroyingFutureCategory helper;
  return helper.future_error_category;
}

future_error::future_error(error_code __ec) : logic_error(__ec.message()), __ec_(__ec) {}

future_error::~future_error() noexcept {}

void __assoc_sub_state::__on_zero_shared() noexcept { delete this; }

void __assoc_sub_state::set_value() {
  unique_lock<mutex> __lk(__mut_);
  if (__has_value())
    std::__throw_future_error(future_errc::promise_already_satisfied);
  __state_ |= __constructed | ready;
  __cv_.notify_all();
}

void __assoc_sub_state::set_value_at_thread_exit() {
  unique_lock<mutex> __lk(__mut_);
  if (__has_value())
    std::__throw_future_error(future_errc::promise_already_satisfied);
  __state_ |= __constructed;
  __thread_local_data()->__make_ready_at_thread_exit(this);
}

void __assoc_sub_state::set_exception(exception_ptr __p) {
  unique_lock<mutex> __lk(__mut_);
  if (__has_value())
    std::__throw_future_error(future_errc::promise_already_satisfied);
  __exception_ = __p;
  __state_ |= ready;
  __cv_.notify_all();
}

void __assoc_sub_state::set_exception_at_thread_exit(exception_ptr __p) {
  unique_lock<mutex> __lk(__mut_);
  if (__has_value())
    std::__throw_future_error(future_errc::promise_already_satisfied);
  __exception_ = __p;
  __thread_local_data()->__make_ready_at_thread_exit(this);
}

void __assoc_sub_state::__make_ready() {
  unique_lock<mutex> __lk(__mut_);
  __state_ |= ready;
  __cv_.notify_all();
}

void __assoc_sub_state::copy() {
  unique_lock<mutex> __lk(__mut_);
  __sub_wait(__lk);
  if (__exception_ != nullptr)
    rethrow_exception(__exception_);
}

void __assoc_sub_state::wait() {
  unique_lock<mutex> __lk(__mut_);
  __sub_wait(__lk);
}

void __assoc_sub_state::__sub_wait(unique_lock<mutex>& __lk) {
  if (!__is_ready()) {
    if (__state_ & static_cast<unsigned>(deferred)) {
      __state_ &= ~static_cast<unsigned>(deferred);
      __lk.unlock();
      __execute();
    } else
      while (!__is_ready())
        __cv_.wait(__lk);
  }
}

void __assoc_sub_state::__execute() { std::__throw_future_error(future_errc::no_state); }

future<void>::future(__assoc_sub_state* __state) : __state_(__state) { __state_->__attach_future(); }

future<void>::~future() {
  if (__state_)
    __state_->__release_shared();
}

void future<void>::get() {
  unique_ptr<__shared_count, __release_shared_count> __(__state_);
  __assoc_sub_state* __s = __state_;
  __state_               = nullptr;
  __s->copy();
}

promise<void>::promise() : __state_(new __assoc_sub_state) {}

promise<void>::~promise() {
  if (__state_) {
#if _LIBCPP_HAS_EXCEPTIONS
    if (!__state_->__has_value() && __state_->use_count() > 1)
      __state_->set_exception(make_exception_ptr(future_error(future_errc::broken_promise)));
#endif // _LIBCPP_HAS_EXCEPTIONS
    __state_->__release_shared();
  }
}

future<void> promise<void>::get_future() {
  if (__state_ == nullptr)
    std::__throw_future_error(future_errc::no_state);
  return future<void>(__state_);
}

void promise<void>::set_value() {
  if (__state_ == nullptr)
    std::__throw_future_error(future_errc::no_state);
  __state_->set_value();
}

void promise<void>::set_exception(exception_ptr __p) {
  if (__state_ == nullptr)
    std::__throw_future_error(future_errc::no_state);
  __state_->set_exception(__p);
}

void promise<void>::set_value_at_thread_exit() {
  if (__state_ == nullptr)
    std::__throw_future_error(future_errc::no_state);
  __state_->set_value_at_thread_exit();
}

void promise<void>::set_exception_at_thread_exit(exception_ptr __p) {
  if (__state_ == nullptr)
    std::__throw_future_error(future_errc::no_state);
  __state_->set_exception_at_thread_exit(__p);
}

shared_future<void>::~shared_future() {
  if (__state_)
    __state_->__release_shared();
}

shared_future<void>& shared_future<void>::operator=(const shared_future& __rhs) {
  if (__rhs.__state_)
    __rhs.__state_->__add_shared();
  if (__state_)
    __state_->__release_shared();
  __state_ = __rhs.__state_;
  return *this;
}

_LIBCPP_END_EXPLICIT_ABI_ANNOTATIONS
_LIBCPP_END_NAMESPACE_STD
