//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___COROUTINE_COROUTINE_HANDLE_H
#define _LIBCPP___COROUTINE_COROUTINE_HANDLE_H

#include <__config>
#include <__debug>
#include <__functional/hash.h>
#include <__memory/addressof.h>
#include <compare>
#include <type_traits>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif

#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES)

_LIBCPP_BEGIN_NAMESPACE_STD

// [coroutine.handle]
template <class _Promise = void>
struct _LIBCPP_TEMPLATE_VIS coroutine_handle;

template <>
struct _LIBCPP_TEMPLATE_VIS coroutine_handle<void> {
public:
    // [coroutine.handle.con], construct/reset
    _LIBCPP_HIDE_FROM_ABI
    constexpr coroutine_handle() noexcept = default;

    _LIBCPP_HIDE_FROM_ABI
    constexpr coroutine_handle(nullptr_t) noexcept {}

    _LIBCPP_HIDE_FROM_ABI
    coroutine_handle& operator=(nullptr_t) noexcept {
        __handle_ = nullptr;
        return *this;
    }

    // [coroutine.handle.export.import], export/import
    _LIBCPP_HIDE_FROM_ABI
    constexpr void* address() const noexcept { return __handle_; }

    _LIBCPP_HIDE_FROM_ABI
    static constexpr coroutine_handle from_address(void* __addr) noexcept {
        coroutine_handle __tmp;
        __tmp.__handle_ = __addr;
        return __tmp;
    }

    // [coroutine.handle.observers], observers
    _LIBCPP_HIDE_FROM_ABI
    constexpr explicit operator bool() const noexcept {
        return __handle_ != nullptr;
    }

    _LIBCPP_HIDE_FROM_ABI
    bool done() const {
        _LIBCPP_ASSERT(__is_suspended(), "done() can be called only on suspended coroutines");
        return __builtin_coro_done(__handle_);
    }

    // [coroutine.handle.resumption], resumption
    _LIBCPP_HIDE_FROM_ABI
    void operator()() const { resume(); }

    _LIBCPP_HIDE_FROM_ABI
    void resume() const {
        _LIBCPP_ASSERT(__is_suspended(), "resume() can be called only on suspended coroutines");
        _LIBCPP_ASSERT(!done(), "resume() has undefined behavior when the coroutine is done");
        __builtin_coro_resume(__handle_);
    }

    _LIBCPP_HIDE_FROM_ABI
    void destroy() const {
        _LIBCPP_ASSERT(__is_suspended(), "destroy() can be called only on suspended coroutines");
        __builtin_coro_destroy(__handle_);
    }

private:
    bool __is_suspended() const {
        // FIXME actually implement a check for if the coro is suspended.
        return __handle_ != nullptr;
    }

    void* __handle_ = nullptr;
};

// [coroutine.handle.compare]
inline _LIBCPP_HIDE_FROM_ABI
constexpr bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
    return __x.address() == __y.address();
}
inline _LIBCPP_HIDE_FROM_ABI
constexpr strong_ordering operator<=>(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
    return compare_three_way()(__x.address(), __y.address());
}

template <class _Promise>
struct _LIBCPP_TEMPLATE_VIS coroutine_handle {
public:
    // [coroutine.handle.con], construct/reset
    _LIBCPP_HIDE_FROM_ABI
    constexpr coroutine_handle() noexcept = default;

    _LIBCPP_HIDE_FROM_ABI
    constexpr coroutine_handle(nullptr_t) noexcept {}

    _LIBCPP_HIDE_FROM_ABI
    static coroutine_handle from_promise(_Promise& __promise) {
        using _RawPromise = typename remove_cv<_Promise>::type;
        coroutine_handle __tmp;
        __tmp.__handle_ =
            __builtin_coro_promise(_VSTD::addressof(const_cast<_RawPromise&>(__promise)), alignof(_Promise), true);
        return __tmp;
    }

    _LIBCPP_HIDE_FROM_ABI
    coroutine_handle& operator=(nullptr_t) noexcept {
        __handle_ = nullptr;
        return *this;
    }

    // [coroutine.handle.export.import], export/import
    _LIBCPP_HIDE_FROM_ABI
    constexpr void* address() const noexcept { return __handle_; }

    _LIBCPP_HIDE_FROM_ABI
    static constexpr coroutine_handle from_address(void* __addr) noexcept {
        coroutine_handle __tmp;
        __tmp.__handle_ = __addr;
        return __tmp;
    }

    // [coroutine.handle.conv], conversion
    _LIBCPP_HIDE_FROM_ABI
    constexpr operator coroutine_handle<>() const noexcept {
        return coroutine_handle<>::from_address(address());
    }

    // [coroutine.handle.observers], observers
    _LIBCPP_HIDE_FROM_ABI
    constexpr explicit operator bool() const noexcept {
        return __handle_ != nullptr;
    }

    _LIBCPP_HIDE_FROM_ABI
    bool done() const {
        _LIBCPP_ASSERT(__is_suspended(), "done() can be called only on suspended coroutines");
        return __builtin_coro_done(__handle_);
    }

    // [coroutine.handle.resumption], resumption
    _LIBCPP_HIDE_FROM_ABI
    void operator()() const { resume(); }

    _LIBCPP_HIDE_FROM_ABI
    void resume() const {
        _LIBCPP_ASSERT(__is_suspended(), "resume() can be called only on suspended coroutines");
        _LIBCPP_ASSERT(!done(), "resume() has undefined behavior when the coroutine is done");
        __builtin_coro_resume(__handle_);
    }

    _LIBCPP_HIDE_FROM_ABI
    void destroy() const {
        _LIBCPP_ASSERT(__is_suspended(), "destroy() can be called only on suspended coroutines");
        __builtin_coro_destroy(__handle_);
    }

    // [coroutine.handle.promise], promise access
    _LIBCPP_HIDE_FROM_ABI
    _Promise& promise() const {
        return *static_cast<_Promise*>(__builtin_coro_promise(this->__handle_, alignof(_Promise), false));
    }

private:
    bool __is_suspended() const {
        // FIXME actually implement a check for if the coro is suspended.
        return __handle_ != nullptr;
    }
    void* __handle_ = nullptr;
};

// [coroutine.handle.hash]
template <class _Tp>
struct hash<coroutine_handle<_Tp>> {
    _LIBCPP_HIDE_FROM_ABI
    size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept { return hash<void*>()(__v.address()); }
};

_LIBCPP_END_NAMESPACE_STD

#endif // __LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_COROUTINES)

#endif // _LIBCPP___COROUTINE_COROUTINE_HANDLE_H
