examples

Toy examples in single C files.
git clone git://henryandlizzy.uk/examples
Log | Files | Refs

coro-throwing.cpp (1840B)


      1 #include "coroutine_owner.hpp"
      2 
      3 #include <stdexcept>
      4 #include <utility>
      5 #include <iostream>
      6 
      7 struct coro
      8 {
      9 	struct promise_type
     10 	{
     11 		coro get_return_object() { return {*this}; }
     12 		std::suspend_never initial_suspend() { return {}; }
     13 		std::suspend_always final_suspend() noexcept { return {}; }
     14 		void unhandled_exception() noexcept { e = std::current_exception(); }
     15 		void return_void() noexcept {}
     16 		std::exception_ptr e;
     17 	};
     18 
     19 	coroutine_owner<promise_type> h;
     20 
     21 	void result()
     22 	{
     23 		if (not *h)
     24 			throw std::logic_error("cannot get result() from empty coroutine");
     25 		else if (not h->done())
     26 			throw std::logic_error("cannot get result() from unfinished coroutine");
     27 		else if (auto e = std::exchange(h->promise().e, {}))
     28 			std::rethrow_exception(e);
     29 		std::cerr << "coroutine finished successfully.\n";
     30 	}
     31 
     32 	coro() = default;
     33 	coro(promise_type& p)
     34 	:   h{std::coroutine_handle<promise_type>::from_promise(p)}
     35 	{}
     36 	~coro()
     37 	{
     38 		cancel();
     39 	}
     40 	void cancel() noexcept
     41 	{
     42 		if (auto x = std::exchange(h, {}); *x)
     43 			if (auto& e = x->promise().e)
     44 				try
     45 				{
     46 					std::rethrow_exception(e);
     47 				} catch (std::exception const& e)
     48 				{
     49 					std::cerr << "Dropped exception: '" << e.what() << "'\n";
     50 				} catch (...) {
     51 					std::cerr << "Dropped exception\n";
     52 				}
     53 	}
     54 	coro(coro const&) = delete;
     55 	coro& operator =(coro const&) = delete;
     56 	coro(coro&& old)
     57 	:   h{std::move(old.h)}
     58 	{}
     59 	coro& operator =(coro&& old)
     60 	{
     61 		cancel();
     62 		h = std::exchange(old.h, {});
     63 		return *this;
     64 	}
     65 };
     66 
     67 coro mycoro(bool success)
     68 {
     69 	if (success)
     70 		co_return;
     71 	throw std::runtime_error("hi");
     72 }
     73 
     74 int main() try
     75 {
     76 	auto a = mycoro(true);
     77 	a.result();
     78 	a = mycoro(false);
     79 	auto c = mycoro(false);
     80 	auto c2 = std::move(c);
     81 	a = std::move(c2);
     82 	a.result();
     83 }
     84 catch (std::exception const& e)
     85 {
     86 	std::cerr << "Caught exception: '" << e.what() << "'\n";
     87 	return 1;
     88 }