File indexing completed on 2026-05-03 08:13:17
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef _LIBCPP___COROUTINE_COROUTINE_HANDLE_H
0010 #define _LIBCPP___COROUTINE_COROUTINE_HANDLE_H
0011
0012 #include <__assert>
0013 #include <__config>
0014 #include <__cstddef/nullptr_t.h>
0015 #include <__cstddef/size_t.h>
0016 #include <__functional/hash.h>
0017 #include <__memory/addressof.h>
0018 #include <__type_traits/remove_cv.h>
0019 #include <compare>
0020
0021 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0022 # pragma GCC system_header
0023 #endif
0024
0025 #if _LIBCPP_STD_VER >= 20
0026
0027 _LIBCPP_BEGIN_NAMESPACE_STD
0028
0029
0030 template <class _Promise = void>
0031 struct _LIBCPP_TEMPLATE_VIS coroutine_handle;
0032
0033 template <>
0034 struct _LIBCPP_TEMPLATE_VIS coroutine_handle<void> {
0035 public:
0036
0037 constexpr coroutine_handle() noexcept = default;
0038
0039 _LIBCPP_HIDE_FROM_ABI constexpr coroutine_handle(nullptr_t) noexcept {}
0040
0041 _LIBCPP_HIDE_FROM_ABI coroutine_handle& operator=(nullptr_t) noexcept {
0042 __handle_ = nullptr;
0043 return *this;
0044 }
0045
0046
0047 _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
0048
0049 _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept {
0050 coroutine_handle __tmp;
0051 __tmp.__handle_ = __addr;
0052 return __tmp;
0053 }
0054
0055
0056 _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __handle_ != nullptr; }
0057
0058 _LIBCPP_HIDE_FROM_ABI bool done() const {
0059 _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "done() can be called only on suspended coroutines");
0060 return __builtin_coro_done(__handle_);
0061 }
0062
0063
0064 _LIBCPP_HIDE_FROM_ABI void operator()() const { resume(); }
0065
0066 _LIBCPP_HIDE_FROM_ABI void resume() const {
0067 _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "resume() can be called only on suspended coroutines");
0068 _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(!done(), "resume() has undefined behavior when the coroutine is done");
0069 __builtin_coro_resume(__handle_);
0070 }
0071
0072 _LIBCPP_HIDE_FROM_ABI void destroy() const {
0073 _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "destroy() can be called only on suspended coroutines");
0074 __builtin_coro_destroy(__handle_);
0075 }
0076
0077 private:
0078 _LIBCPP_HIDE_FROM_ABI bool __is_suspended() const {
0079
0080 return __handle_ != nullptr;
0081 }
0082
0083 void* __handle_ = nullptr;
0084 };
0085
0086
0087 inline _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
0088 return __x.address() == __y.address();
0089 }
0090 inline _LIBCPP_HIDE_FROM_ABI constexpr strong_ordering
0091 operator<=>(coroutine_handle<> __x, coroutine_handle<> __y) noexcept {
0092 return compare_three_way()(__x.address(), __y.address());
0093 }
0094
0095 template <class _Promise>
0096 struct _LIBCPP_TEMPLATE_VIS coroutine_handle {
0097 public:
0098
0099 constexpr coroutine_handle() noexcept = default;
0100
0101 _LIBCPP_HIDE_FROM_ABI constexpr coroutine_handle(nullptr_t) noexcept {}
0102
0103 _LIBCPP_HIDE_FROM_ABI static coroutine_handle from_promise(_Promise& __promise) {
0104 using _RawPromise = __remove_cv_t<_Promise>;
0105 coroutine_handle __tmp;
0106 __tmp.__handle_ =
0107 __builtin_coro_promise(std::addressof(const_cast<_RawPromise&>(__promise)), alignof(_Promise), true);
0108 return __tmp;
0109 }
0110
0111 _LIBCPP_HIDE_FROM_ABI coroutine_handle& operator=(nullptr_t) noexcept {
0112 __handle_ = nullptr;
0113 return *this;
0114 }
0115
0116
0117 _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; }
0118
0119 _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept {
0120 coroutine_handle __tmp;
0121 __tmp.__handle_ = __addr;
0122 return __tmp;
0123 }
0124
0125
0126 _LIBCPP_HIDE_FROM_ABI constexpr operator coroutine_handle<>() const noexcept {
0127 return coroutine_handle<>::from_address(address());
0128 }
0129
0130
0131 _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __handle_ != nullptr; }
0132
0133 _LIBCPP_HIDE_FROM_ABI bool done() const {
0134 _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "done() can be called only on suspended coroutines");
0135 return __builtin_coro_done(__handle_);
0136 }
0137
0138
0139 _LIBCPP_HIDE_FROM_ABI void operator()() const { resume(); }
0140
0141 _LIBCPP_HIDE_FROM_ABI void resume() const {
0142 _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "resume() can be called only on suspended coroutines");
0143 _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(!done(), "resume() has undefined behavior when the coroutine is done");
0144 __builtin_coro_resume(__handle_);
0145 }
0146
0147 _LIBCPP_HIDE_FROM_ABI void destroy() const {
0148 _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "destroy() can be called only on suspended coroutines");
0149 __builtin_coro_destroy(__handle_);
0150 }
0151
0152
0153 _LIBCPP_HIDE_FROM_ABI _Promise& promise() const {
0154 return *static_cast<_Promise*>(__builtin_coro_promise(this->__handle_, alignof(_Promise), false));
0155 }
0156
0157 private:
0158 _LIBCPP_HIDE_FROM_ABI bool __is_suspended() const {
0159
0160 return __handle_ != nullptr;
0161 }
0162 void* __handle_ = nullptr;
0163 };
0164
0165
0166 template <class _Tp>
0167 struct hash<coroutine_handle<_Tp>> {
0168 _LIBCPP_HIDE_FROM_ABI size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept {
0169 return hash<void*>()(__v.address());
0170 }
0171 };
0172
0173 _LIBCPP_END_NAMESPACE_STD
0174
0175 #endif
0176
0177 #endif