1#ifndef DED82BB9_7596_4598_B34D_B60883A4775D
2#define DED82BB9_7596_4598_B34D_B60883A4775D
42template<
typename Result>
43class [[nodiscard]]
generator :
public std::ranges::view_interface<generator<Result>> {
56 using value_type = std::remove_reference_t<Result>;
58 using reference_type = std::add_lvalue_reference_t<value_type>;
60 using pointer_type = std::add_pointer_t<value_type>;
71 using coroutine_handle = std::coroutine_handle<promise_type>;
84 [[nodiscard]]
constexpr auto initial_suspend()
const noexcept {
return std::suspend_always{}; }
95 [[nodiscard]]
constexpr auto final_suspend()
const noexcept {
return std::suspend_always{}; }
108 constexpr auto yield_value(std::add_const_t<reference_type> value)
noexcept
110 this->m_value = std::addressof(value);
111 return std::suspend_always{};
126 constexpr auto yield_value(std::add_rvalue_reference_t<std::remove_cvref_t<value_type>> value)
noexcept
135 this->m_value = std::addressof(value);
136 return std::suspend_always{};
151 constexpr void unhandled_exception()
noexcept { this->m_exception = std::current_exception(); }
158 constexpr void return_void()
const noexcept {}
167 [[nodiscard]] reference_type value()
const noexcept {
return static_cast<reference_type
>(*this->m_value); }
174 void await_transform() =
delete;
185 void rethrow_if_exception()
187 if (this->m_exception) {
188 std::rethrow_exception(std::move(this->m_exception));
194 pointer_type m_value =
nullptr;
196 std::exception_ptr m_exception =
nullptr;
237 using value_type = promise_type::value_type;
246 explicit iterator(std::coroutine_handle<promise_type> coroutine) noexcept : m_coroutine(coroutine) {}
269 [[nodiscard]] constexpr
bool operator==(const
iterator& other) const noexcept
271 return this->m_coroutine == other.m_coroutine ||
272 (!detail::is_good_handle(this->m_coroutine) && !detail::is_good_handle(other.m_coroutine));
288 if (detail::is_good_handle(this->m_coroutine)) [[likely]] {
289 this->m_coroutine.resume();
290 if (this->m_coroutine.done()) {
291 this->m_coroutine.promise().rethrow_if_exception();
323 if (detail::is_good_handle(this->m_coroutine)) [[likely]] {
324 return this->m_coroutine.promise().value();
332 std::coroutine_handle<promise_type> m_coroutine;
364 if (this->m_coroutine) {
365 this->m_coroutine.destroy();
384 if (
this != std::addressof(other)) {
385 if (this->m_coroutine) {
386 this->m_coroutine.destroy();
389 this->m_coroutine = std::exchange(other.m_coroutine,
nullptr);
472 std::coroutine_handle<promise_type> m_coroutine;
479 explicit generator(std::coroutine_handle<promise_type> coroutine) noexcept : m_coroutine(coroutine) {}
493 if (detail::is_good_handle(this->m_coroutine)) {
494 this->m_coroutine.resume();
495 if (this->m_coroutine.done()) {
496 this->m_coroutine.promise().rethrow_if_exception();
Exception thrown when accessing a result that is not available.
An input iterator that produces values of type Result.
std::ptrdiff_t difference_type
Difference between the addresses of any two elements in the controlled sequence.
promise_type::reference_type operator*() const
Dereferences the iterator to obtain the current value.
iterator & operator++()
Advances the iterator to the next value.
iterator() noexcept=default
Default constructor.
std::input_iterator_tag iterator_concept
The strongest iterator concept supported by the iterator.
void operator++(int)
Advances the iterator to the next value.
The promise type of the generator.
An synchronous generator that produces values of type Result.
generator() noexcept=default
Default constructor.
iterator begin() const
Returns a constant iterator to the current item of the generator.
constexpr iterator end() const noexcept
Returns a sentinel iterator that marks the end of the generator.
iterator cbegin() const
Returns a constant iterator to the current item of the generator.
generator & operator=(generator &&other) noexcept
Move assignment operator.
iterator begin()
Returns an iterator to the current item of the generator.
iterator cend() const noexcept
Returns a cinstant sentinel iterator.
Internal utility functions for coroutine handling.
Custom exception classes for coroutine handling.