1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___COROUTINE_NOOP_COROUTINE_HANDLE_H
10 #define _LIBCPP___COROUTINE_NOOP_COROUTINE_HANDLE_H
13 #include <__coroutine/coroutine_handle.h>
15 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16 # pragma GCC system_header
19 #if _LIBCPP_STD_VER >= 20
21 _LIBCPP_BEGIN_NAMESPACE_STD
23 #if __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC)
26 // [coroutine.promise.noop]
27 struct noop_coroutine_promise
{};
29 // [coroutine.handle.noop]
31 struct _LIBCPP_TEMPLATE_VIS coroutine_handle
<noop_coroutine_promise
> {
33 // [coroutine.handle.noop.conv], conversion
35 constexpr operator coroutine_handle
<>() const noexcept
{
36 return coroutine_handle
<>::from_address(address());
39 // [coroutine.handle.noop.observers], observers
41 constexpr explicit operator bool() const noexcept
{ return true; }
43 constexpr bool done() const noexcept
{ return false; }
45 // [coroutine.handle.noop.resumption], resumption
47 constexpr void operator()() const noexcept
{}
49 constexpr void resume() const noexcept
{}
51 constexpr void destroy() const noexcept
{}
53 // [coroutine.handle.noop.promise], promise access
55 noop_coroutine_promise
& promise() const noexcept
{
56 return *static_cast<noop_coroutine_promise
*>(
57 __builtin_coro_promise(this->__handle_
, alignof(noop_coroutine_promise
), false));
60 // [coroutine.handle.noop.address], address
62 constexpr void* address() const noexcept
{ return __handle_
; }
66 friend coroutine_handle
<noop_coroutine_promise
> noop_coroutine() noexcept
;
68 #if __has_builtin(__builtin_coro_noop)
69 _LIBCPP_HIDE_FROM_ABI
coroutine_handle() noexcept
{
70 this->__handle_
= __builtin_coro_noop();
73 void* __handle_
= nullptr;
75 #elif defined(_LIBCPP_COMPILER_GCC)
76 // GCC doesn't implement __builtin_coro_noop().
77 // Construct the coroutine frame manually instead.
78 struct __noop_coroutine_frame_ty_
{
79 static void __dummy_resume_destroy_func() { }
81 void (*__resume_
)() = __dummy_resume_destroy_func
;
82 void (*__destroy_
)() = __dummy_resume_destroy_func
;
83 struct noop_coroutine_promise __promise_
;
86 static __noop_coroutine_frame_ty_ __noop_coroutine_frame_
;
88 void* __handle_
= &__noop_coroutine_frame_
;
90 _LIBCPP_HIDE_FROM_ABI
coroutine_handle() noexcept
= default;
92 #endif // __has_builtin(__builtin_coro_noop)
95 using noop_coroutine_handle
= coroutine_handle
<noop_coroutine_promise
>;
97 #if defined(_LIBCPP_COMPILER_GCC)
98 inline noop_coroutine_handle::__noop_coroutine_frame_ty_
99 noop_coroutine_handle::__noop_coroutine_frame_
{};
102 // [coroutine.noop.coroutine]
103 inline _LIBCPP_HIDE_FROM_ABI
104 noop_coroutine_handle
noop_coroutine() noexcept
{ return noop_coroutine_handle(); }
106 #endif // __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC)
108 _LIBCPP_END_NAMESPACE_STD
110 #endif // __LIBCPP_STD_VER >= 20
112 #endif // _LIBCPP___COROUTINE_NOOP_COROUTINE_HANDLE_H