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 }