17#if defined(__cpp_impl_coroutine) && __cpp_impl_coroutine >= 201902L
26#if defined(__has_include)
27# if __has_include(<version>)
32#if defined(__cpp_lib_generator) && __cpp_lib_generator >= 202207L
34# define THREADSCHEDULE_HAS_STD_GENERATOR 1
36# define THREADSCHEDULE_HAS_STD_GENERATOR 0
39namespace threadschedule
42#if THREADSCHEDULE_HAS_STD_GENERATOR
45using generator = std::generator<T>;
99 auto get_return_object() noexcept -> generator
101 return generator{std::coroutine_handle<promise_type>::from_promise(*
this)};
104 auto initial_suspend() noexcept -> std::suspend_always
109 auto final_suspend() noexcept -> std::suspend_always
114 auto yield_value(T
const& value) -> std::suspend_always
116 value_.emplace(value);
120 auto yield_value(T&& value)
noexcept(std::is_nothrow_move_constructible_v<T>) -> std::suspend_always
122 value_.emplace(std::move(value));
126 void return_void() noexcept
130 void unhandled_exception()
132 exception_ = std::current_exception();
135 void rethrow_if_exception()
138 std::rethrow_exception(exception_);
141 std::optional<T> value_{};
144 std::exception_ptr exception_{};
160 using iterator_category = std::input_iterator_tag;
161 using difference_type = std::ptrdiff_t;
162 using value_type = T;
163 using reference = T&;
166 iterator() noexcept = default;
168 explicit iterator(std::coroutine_handle<promise_type> h) noexcept : handle_(h)
172 auto operator++() -> iterator&
177 handle_.promise().rethrow_if_exception();
188 [[nodiscard]]
auto operator*() const -> T&
190 return *handle_.promise().value_;
193 [[nodiscard]]
auto operator->() const -> T*
195 return std::addressof(*handle_.promise().value_);
198 [[nodiscard]]
friend auto operator==(iterator
const& it, std::default_sentinel_t)
noexcept ->
bool
200 return !it.handle_ || it.handle_.done();
203 [[nodiscard]]
friend auto operator==(std::default_sentinel_t s, iterator
const& it)
noexcept ->
bool
208 [[nodiscard]]
friend auto operator!=(iterator
const& it, std::default_sentinel_t s)
noexcept ->
bool
213 [[nodiscard]]
friend auto operator!=(std::default_sentinel_t s, iterator
const& it)
noexcept ->
bool
219 std::coroutine_handle<promise_type> handle_{};
222 generator() noexcept = default;
224 generator(generator&& other) noexcept : handle_(std::exchange(other.handle_,
nullptr))
228 auto operator=(generator&& other)
noexcept -> generator&
233 handle_ = std::exchange(other.handle_,
nullptr);
243 generator(generator
const&) =
delete;
244 auto operator=(generator
const&) -> generator& =
delete;
246 [[nodiscard]]
auto begin() -> iterator
253 handle_.promise().rethrow_if_exception();
257 return iterator{handle_};
260 [[nodiscard]]
auto end() const noexcept -> std::default_sentinel_t
266 explicit generator(std::coroutine_handle<promise_type> h) noexcept : handle_(h)
279 std::coroutine_handle<promise_type> handle_{};