examples

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

coroutine_owner.hpp (1193B)


      1 #pragma once
      2 
      3 #include <coroutine> // coroutine_handle
      4 #include <utility> // exchange
      5 
      6 template <typename T = void>
      7 struct [[nodiscard]] coroutine_owner
      8 {
      9 	coroutine_owner() = default;
     10 
     11 	explicit coroutine_owner(std::coroutine_handle<T> h)
     12 	:	h{h}
     13 	{}
     14 
     15 	coroutine_owner(coroutine_owner const&) = delete;
     16 	coroutine_owner& operator =(coroutine_owner const&) = delete;
     17 
     18 	coroutine_owner(coroutine_owner&& old)
     19 	:   h{old.release()}
     20 	{};
     21 
     22 	coroutine_owner& operator =(coroutine_owner&& old)
     23 	{
     24 		reset(old.release());
     25 		return *this;
     26 	}
     27 
     28 	~coroutine_owner()
     29 	{
     30 		if (h)
     31 			h.destroy();
     32 	}
     33 
     34 	explicit operator bool() const
     35 	{
     36 		return !!h;
     37 	}
     38 
     39 	std::coroutine_handle<T> release()
     40 	{
     41 		return std::exchange(h, {});
     42 	}
     43 
     44 	void reset(std::coroutine_handle<T> v = {})
     45 	{
     46 		coroutine_owner{std::exchange(h, v)};
     47 	}
     48 
     49 	template <typename Self>
     50 	auto* operator ->(this Self&& self)
     51 	{
     52 		return &self.h;
     53 	}
     54 
     55 	template <typename Self>
     56 	auto& operator *(this Self&& self)
     57 	{
     58 		return self.h;
     59 	}
     60 
     61 private:
     62 	std::coroutine_handle<T> h;
     63 };
     64 
     65 template <typename T, typename U = T>
     66 coroutine_owner<U> make_coroutine_owner(T& promise)
     67 {
     68 	return coroutine_owner<U>{std::coroutine_handle<T>::from_promise(promise)};
     69 }