Skip to content

Commit 3a5a227

Browse files
committed
added an example with coroutine stackoverflow
1 parent 65d1ff5 commit 3a5a227

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

examples/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
list(
77
APPEND
88
EXAMPLES
9+
stackoverflow
910
inspect
1011
playground
1112
sender-demo

examples/stackoverflow.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include <beman/execution/execution.hpp>
2+
#include <coroutine>
3+
#include <iostream>
4+
#include <type_traits>
5+
#include <utility>
6+
7+
namespace ex = beman::execution;
8+
9+
struct task {
10+
using sender_concept = ex::sender_t;
11+
using completion_signatures = ex::completion_signatures<ex::set_value_t()>;
12+
13+
struct base {
14+
virtual void complete_value() noexcept = 0;
15+
};
16+
17+
struct promise_type {
18+
struct final_awaiter {
19+
base* data;
20+
bool await_ready() noexcept { return false; }
21+
auto await_suspend(auto h) noexcept {
22+
std::cout << "final_awaiter\n";
23+
this->data->complete_value();
24+
std::cout << "completed\n";
25+
};
26+
void await_resume() noexcept {}
27+
};
28+
std::suspend_always initial_suspend() const noexcept { return {}; }
29+
final_awaiter final_suspend() const noexcept { return {this->data}; }
30+
void unhandled_exception() const noexcept {}
31+
std::coroutine_handle<> unhandled_stopped() { return std::coroutine_handle<>(); }
32+
auto return_void() {}
33+
auto get_return_object() { return task{std::coroutine_handle<promise_type>::from_promise(*this)}; }
34+
template <::beman::execution::sender Sender>
35+
auto await_transform(Sender&& sender) noexcept {
36+
return ::beman::execution::as_awaitable(::std::forward<Sender>(sender), *this);
37+
}
38+
39+
base* data{};
40+
};
41+
42+
template <ex::receiver R>
43+
struct state : base {
44+
45+
using operation_state_concept = ex::operation_state_t;
46+
std::remove_cvref_t<R> r;
47+
std::coroutine_handle<promise_type> handle;
48+
49+
state(auto&& r, auto&& h) : r(std::forward<R>(r)), handle(std::move(h)) {}
50+
void start() & noexcept {
51+
this->handle.promise().data = this;
52+
this->handle.resume();
53+
}
54+
void complete_value() noexcept override { ex::set_value(std::move(this->r)); }
55+
};
56+
57+
std::coroutine_handle<promise_type> handle;
58+
59+
template <ex::receiver R>
60+
auto connect(R&& r) && {
61+
return state<R>(std::forward<R>(r), std::move(this->handle));
62+
}
63+
};
64+
65+
int main(int ac, char*[]) {
66+
static_assert(ex::sender<task>);
67+
ex::sync_wait([](int n) -> task {
68+
for (int i{}; i < n; ++i) {
69+
std::cout << "await=" << (co_await ex::just(i)) << "\n";
70+
}
71+
co_return;
72+
}(ac < 2 ? 3 : 30000));
73+
}

0 commit comments

Comments
 (0)