libcopp 2.3.1
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
coroutine_context.h
Go to the documentation of this file.
1// Copyright 2023 owent
2
3#pragma once
4
5#include <libcopp/utils/config/libcopp_build_features.h>
7
10
11#ifdef LIBCOPP_MACRO_USE_SEGMENTED_STACKS
12# define COROUTINE_CONTEXT_BASE_USING_BASE_SEGMENTED_STACKS(base_type) using base_type::caller_stack_;
13#else
14# define COROUTINE_CONTEXT_BASE_USING_BASE_SEGMENTED_STACKS(base_type)
15#endif
16
17#define COROUTINE_CONTEXT_BASE_USING_BASE(base_type) \
18 protected: \
19 using base_type::caller_; \
20 using base_type::callee_; \
21 using base_type::callee_stack_; \
22 COROUTINE_CONTEXT_BASE_USING_BASE_SEGMENTED_STACKS(base_type)
23
24LIBCOPP_COPP_NAMESPACE_BEGIN
29 public:
30 using ptr_type = LIBCOPP_COPP_NAMESPACE_ID::memory::intrusive_ptr<coroutine_context>;
34
35 // Compability with libcopp-1.x
36 using ptr_t = ptr_type;
40
41 private:
48#if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
49 using coroutine_context_base::unhandle_exception_;
50#endif
51
57
59
60 protected:
65#ifdef LIBCOPP_MACRO_USE_SEGMENTED_STACKS
66 stack_context caller_stack_;
67#endif
68
69 protected:
70 LIBCOPP_COPP_API coroutine_context() LIBCOPP_MACRO_NOEXCEPT;
71
72 public:
73 LIBCOPP_COPP_API ~coroutine_context();
74
75 private:
77 coroutine_context &operator=(const coroutine_context &) = delete;
79 coroutine_context &operator=(const coroutine_context &&) = delete;
80
81 public:
90 static LIBCOPP_COPP_API int create(coroutine_context *p, callback_type &&runner, const stack_context &callee_stack,
91 size_t coroutine_size, size_t private_buffer_size) LIBCOPP_MACRO_NOEXCEPT;
92
93 template <typename TRunner>
94 static LIBCOPP_COPP_API_HEAD_ONLY int create(coroutine_context *p, TRunner *runner, const stack_context &callee_stack,
95 size_t coroutine_size,
96 size_t private_buffer_size) LIBCOPP_MACRO_NOEXCEPT {
97 return create(
98 p, [runner](void *private_data) { return (*runner)(private_data); }, callee_stack, coroutine_size,
99 private_buffer_size);
100 }
101
108 LIBCOPP_COPP_API int start(void *priv_data = nullptr);
109
110#if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
117 LIBCOPP_COPP_API int start(std::exception_ptr &unhandled, void *priv_data = nullptr) LIBCOPP_MACRO_NOEXCEPT;
118#endif
119
126 LIBCOPP_COPP_API int resume(void *priv_data = nullptr);
127
128#if defined(LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR) && LIBCOPP_MACRO_ENABLE_STD_EXCEPTION_PTR
135 LIBCOPP_COPP_API int resume(std::exception_ptr &unhandled, void *priv_data = nullptr) LIBCOPP_MACRO_NOEXCEPT;
136#endif
137
143 LIBCOPP_COPP_API int yield(void **priv_data = nullptr) LIBCOPP_MACRO_NOEXCEPT;
144
153 template <class TAWAITABLE, class TERROR_TRANSFORM,
154 class = nostd::enable_if_t<stackful_inject_awaitable<nostd::remove_cvref_t<TAWAITABLE>>::value>>
155 LIBCOPP_COPP_API_HEAD_ONLY inline container_value_type<TAWAITABLE>
156 await_value(TAWAITABLE &&awaitable, TERROR_TRANSFORM &&error_transform) noexcept(
157 std::is_nothrow_copy_constructible<container_value_type<TAWAITABLE>>::value &&
158 noexcept(error_transform(COPP_EC_ARGS_ERROR))) {
159 return awaitable.inject_await(this, std::forward<TERROR_TRANSFORM>(error_transform));
160 }
161
170 template <class TAWAITABLE,
171 class = nostd::enable_if_t<stackful_inject_awaitable<nostd::remove_cvref_t<TAWAITABLE>>::value>>
172 LIBCOPP_COPP_API_HEAD_ONLY inline container_value_type<TAWAITABLE> await_value(TAWAITABLE &&awaitable) noexcept(
173 std::is_nothrow_copy_constructible<container_value_type<TAWAITABLE>>::value &&
175 return awaitable.inject_await(this, stackful_channel_error_transform<container_value_type<TAWAITABLE>>());
176 }
177};
178
179namespace this_coroutine {
185LIBCOPP_COPP_API coroutine_context *get_coroutine() LIBCOPP_MACRO_NOEXCEPT;
186
193template <typename Tc>
194LIBCOPP_COPP_API_HEAD_ONLY Tc *get() {
195 return static_cast<Tc *>(get_coroutine());
196}
197
203LIBCOPP_COPP_API int yield(void **priv_data = nullptr) LIBCOPP_MACRO_NOEXCEPT;
204} // namespace this_coroutine
205LIBCOPP_COPP_NAMESPACE_END
base type of all coroutine context
LIBCOPP_COPP_NAMESPACE_ID::util::lock::atomic_int_type< LIBCOPP_COPP_NAMESPACE_ID::util::lock::unsafe_int_type< int > > status_
std::function< int(void *)> callback_type
base type of all stackful coroutine context
LIBCOPP_COPP_NAMESPACE_ID::memory::intrusive_ptr< coroutine_context > ptr_type
LIBCOPP_COPP_API_HEAD_ONLY container_value_type< TAWAITABLE > await_value(TAWAITABLE &&awaitable, TERROR_TRANSFORM &&error_transform) noexcept(std::is_nothrow_copy_constructible< container_value_type< TAWAITABLE > >::value &&noexcept(error_transform(COPP_EC_ARGS_ERROR)))
Waits for the specified awaitable object to finish and retrieves its result.
LIBCOPP_COPP_API coroutine_context() LIBCOPP_MACRO_NOEXCEPT
coroutine_context_base::flag_type flag_type
fcontext::fcontext_t caller_
stack_context callee_stack_
LIBCOPP_COPP_API int start(void *priv_data=nullptr)
start coroutine
LIBCOPP_COPP_API int yield(void **priv_data=nullptr) LIBCOPP_MACRO_NOEXCEPT
yield coroutine
callback_type callback_t
LIBCOPP_COPP_API int resume(void *priv_data=nullptr)
resume coroutine
fcontext::fcontext_t callee_
coroutine_context_base::callback_type callback_type
static LIBCOPP_COPP_API int create(coroutine_context *p, callback_type &&runner, const stack_context &callee_stack, size_t coroutine_size, size_t private_buffer_size) LIBCOPP_MACRO_NOEXCEPT
create coroutine context at stack context callee_
LIBCOPP_COPP_API_HEAD_ONLY container_value_type< TAWAITABLE > await_value(TAWAITABLE &&awaitable) noexcept(std::is_nothrow_copy_constructible< container_value_type< TAWAITABLE > >::value &&noexcept(stackful_channel_error_transform< container_value_type< TAWAITABLE > >()(COPP_EC_ARGS_ERROR)))
Waits for the specified awaitable object to finish and retrieves its result.
coroutine_context_base::status_type status_type
@ COPP_EC_ARGS_ERROR
COPP_EC_ARGS_ERROR.
Definition errno.h:30
STL namespace.
LIBCOPP_COPP_API_HEAD_ONLY Tc * get()
get current coroutine and try to convert type
LIBCOPP_COPP_API int yield(void **priv_data=nullptr) LIBCOPP_MACRO_NOEXCEPT
yield current coroutine
LIBCOPP_COPP_API coroutine_context * get_coroutine() LIBCOPP_MACRO_NOEXCEPT
get current coroutine
typename nostd::remove_cvref_t< TCONTAINER >::value_type container_value_type
status of safe coroutine context base