File: pr95736.C

package info (click to toggle)
gcc-arm-none-eabi 15%3A14.2.rel1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,099,328 kB
  • sloc: cpp: 3,627,108; ansic: 2,571,498; ada: 834,230; f90: 235,082; makefile: 79,231; asm: 74,984; xml: 51,692; exp: 39,736; sh: 33,298; objc: 15,629; python: 15,069; fortran: 14,429; pascal: 7,003; awk: 5,070; perl: 3,106; ml: 285; lisp: 253; lex: 204; haskell: 135
file content (84 lines) | stat: -rw-r--r-- 2,006 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <iostream>
#include <exception>
#include <cassert>

#if __has_include("coroutine")
#include <coroutine>
namespace stdcoro = std;
#else
#include <experimental/coroutine>
namespace stdcoro = std::experimental;
#endif

struct footable : stdcoro::suspend_always {
	footable() noexcept = default;
	~footable() { assert(released); }
	footable(const footable&) = delete;

	using coro_handle = stdcoro::coroutine_handle<>;

	void await_suspend(coro_handle awaiter) noexcept {
		std::cout << "suspending to footable " << this << std::endl;
		assert(!handle);
		handle = awaiter;
	}
	void await_resume() noexcept {
		std::cout << "resuming from footable " << this << std::endl;
		assert(handle);
		handle = {};
	}

	void operator()() noexcept {
		std::cout << "operator() on " << this << std::endl;
		assert(handle);
		handle.resume();
		handle = {};
	}

	void release() noexcept { released = true; }
private:
	coro_handle handle;
	bool released = false;
};

struct footask {
	struct promise_type {
		using coro_handle = stdcoro::coroutine_handle<promise_type>;

		stdcoro::suspend_never initial_suspend() noexcept { return {}; }
		stdcoro::suspend_never final_suspend() noexcept { std::cout << "final suspend" << std::endl; return {}; }
		void unhandled_exception() {}
		void return_void() noexcept { std::cout << "coro returns" << std::endl; }

		footask get_return_object() { return footask{ coro_handle::from_promise(*this) }; }
	};

	footask(promise_type::coro_handle handle) : handle(handle) {}
	~footask() { assert(handle.done()); }

	promise_type::coro_handle handle;
};

struct bar {
	bar() = default;
	bar(const bar&) = delete;

	footable foo{};
	footask task = taskfun();

	footask taskfun() noexcept {
		std::cout << "coro begin" << std::endl;
		co_await foo;
		std::cout << "coro end" << std::endl;
	}
};

int main() {
	bar foobar;
	foobar.foo();
	assert(foobar.task.handle.done());
	std::cout << "releasing" << std::endl;
	foobar.foo.release();
	std::cout << "done" << std::endl;
	return 0;
}