TGViewer
C++ - Reddit C++ - Reddit @r_cpp · 230 subscribers
Post #25209 14
you don't need external access to the data members and just want to benefit from RAII, you can convert the class to a coroutine that suspends itself right before ending:

class scope {
public:
struct promise_type {
scope get_return_object() noexcept {
return scope { std::coroutine_handle<promise_type>::from_promise(*this) };
}
std::suspend_never initial_suspend() noexcept { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void return_void() noexcept {}
void unhandled_exception() { std::terminate(); }
};

...

~scope() {
if (!this->handle) return;
this->handle.destroy();
this->handle = {};
}

private:
explicit scope(std::coroutine_handle<promise_type> h) noexcept : handle(h) {}
std::coroutine_handle<promise_type> handle {};
};

scope gpio_uart_forwarder() {
auto gpio_in = peripheral::gpio {};
auto gpio_out = peripheral::gpio {};
auto uart = peripheral::uart {};

auto gpio_to_uart = evt::callback { gpio_in.on_change, [&](bool high) {
uart.write(high ? '1' : '0');
} };

auto uart_to_gpio = evt::callback { uart.on_char, [&](char c) {
if (c == '1') gpio_out.set(1);
else if (c == '0') gpio_out.set(0);
} };

// All local variables remain alive until coroutine is destroyed
co_await std::suspend_always();
// Can't rely on final_suspend because stack is already destroyed by then
// But we need a co_ statement anyway to turn it into a coroutine
}

scope my_gpio_uart_forwarder = gpio_uart_forwarder();

Far from perfect, but it reduces us to a single heap allocation plus the minimal overhead of launching the coroutine, no matter how many callbacks we define.

Maybe the best part is it can be used *within* an existing class too, preserving standard object RAII:

struct gpio_uart_forwarder {
peripheral::gpio gpio_in {};
peripheral::gpio gpio_out {};
peripheral::uart uart {};

scope callbacks = [&] -> scope {
auto gpio_to_uart = evt::callback { gpio_in.on_change, [&](bool high) {
uart.write(high ? '1' : '0');
} };

auto uart_to_gpio = evt::callback { uart.on_char, [&](char c) {
if (c == '1') gpio_out.set(1);
else if (c == '0') gpio_out.set(0);
} };
co_await std::suspend_always();
}();
}



https://redd.it/1tg6mzu
@r_cpp
Reddit From the cpp community on Reddit Explore this post and more from the cpp community
More from @r_cpp
  1. Oct 3, 2026C++ Show and Tell - October 2026 Use this thread to share anything you've written in C++.…
  2. Oct 3, 2026C++ future at Adobe So if anyone was still curious what happened to Hylo, or where Adobe s…
  3. Oct 3, 2026C++ Jobs - Q4 2026 Rules For Individuals --------------------- * **Don't** create top-leve…
  4. Sep 29, 2026Boost.Graph 1.95 will be C++17 Dear Boost.Graph community, In two release cycles (Boost re…
  5. Sep 26, 2026Token Sequence Injection & Modern Macros: The Most Game-Changing Compile-Time Feature in C…
  6. Sep 25, 2026myStringStream.str("") Considered Harmful Under C++20 I was recently looking at some (rath…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →