11#include <memory_resource>
13#include "../macros.hpp"
14#include "debugger.hpp"
16hi_export_module(hikogui.utility.generator);
18hi_export
namespace hi::inline
v1 {
35 static_assert(not std::is_reference_v<value_type>);
36 static_assert(not std::is_const_v<value_type>);
42 return generator{handle_type::from_promise(*
this)};
45 value_type
const& value()
const noexcept
51 static std::suspend_never initial_suspend()
noexcept
56 static std::suspend_always final_suspend()
noexcept
61 std::suspend_always yield_value(value_type
const& value)
noexcept
67 std::suspend_always yield_value(value_type&& value)
noexcept
73 void return_void()
noexcept {}
76 void await_transform() =
delete;
78 void unhandled_exception()
noexcept
85 if (
auto ptr = std::exchange(_exception,
nullptr)) {
91 std::optional<value_type> _value = {};
95 using handle_type = std::coroutine_handle<promise_type>;
99 value_proxy(value_type
const& value) noexcept : _value(value) {}
101 value_type
const& operator*()
const noexcept
114 using difference_type = ptrdiff_t;
115 using value_type = std::decay_t<value_type>;
116 using pointer = value_type
const *;
117 using reference = value_type
const&;
120 explicit const_iterator(handle_type coroutine) : _coroutine{coroutine}
122 _coroutine.promise().rethrow();
129 hi_axiom(not at_end());
131 _coroutine.promise().rethrow();
137 auto tmp =
value_proxy(_coroutine.promise().value());
138 hi_axiom(not at_end());
140 _coroutine.promise().rethrow();
146 decltype(
auto)
operator*()
const
148 hi_axiom(not at_end());
149 return _coroutine.promise().value();
152 pointer *operator->() const noexcept
154 hi_axiom(not at_end());
158 [[nodiscard]]
bool at_end() const noexcept
160 return not _coroutine or _coroutine.done();
165 [[nodiscard]]
bool operator==(std::default_sentinel_t)
const noexcept
171 handle_type _coroutine;
174 explicit generator(handle_type coroutine) : _coroutine(coroutine) {}
176 generator() =
default;
180 _coroutine.destroy();
184 generator(
const generator&) =
delete;
185 generator& operator=(
const generator&) =
delete;
187 generator(generator&& other) noexcept : _coroutine{std::exchange(
other._coroutine, {})} {}
189 generator& operator=(generator&& other)
noexcept
191 hi_return_on_self_assignment(other);
193 _coroutine.destroy();
195 _coroutine = std::exchange(
other._coroutine, {});
215 std::default_sentinel_t
end()
const
222 std::default_sentinel_t
cend()
const
228 handle_type _coroutine;
234 using value_type = T&;
240 return generator{handle_type::from_promise(*
this)};
243 value_type value()
const noexcept
245 hi_axiom(_value !=
nullptr);
250 static std::suspend_never initial_suspend()
noexcept
255 static std::suspend_always final_suspend()
noexcept
260 std::suspend_always yield_value(value_type value)
noexcept
266 void return_void()
noexcept {}
269 void await_transform() =
delete;
271 void unhandled_exception()
noexcept
278 if (
auto ptr = std::exchange(_exception,
nullptr)) {
284 std::remove_reference_t<value_type> *_value =
nullptr;
288 using handle_type = std::coroutine_handle<promise_type>;
292 value_proxy(value_type value) noexcept : _value(
std::addressof(value)) {}
294 value_type operator*()
const noexcept
300 std::remove_reference_t<value_type> *_value;
305 class const_iterator {
307 using difference_type = ptrdiff_t;
308 using value_type = std::decay_t<value_type>;
309 using pointer = value_type
const *;
310 using reference = value_type
const&;
313 explicit const_iterator(handle_type coroutine) : _coroutine{coroutine} {}
319 hi_axiom(not at_end());
321 _coroutine.promise().rethrow();
325 value_proxy operator++(
int)
327 auto tmp = value_proxy(_coroutine.promise().value());
328 hi_axiom(not at_end());
330 _coroutine.promise().rethrow();
336 decltype(
auto)
operator*()
const
338 hi_axiom(not at_end());
339 return _coroutine.promise().value();
342 pointer *operator->() const noexcept
344 hi_axiom(not at_end());
348 [[nodiscard]]
bool at_end() const noexcept
350 return not _coroutine or _coroutine.done();
355 [[nodiscard]]
bool operator==(std::default_sentinel_t)
const noexcept
361 handle_type _coroutine;
364 explicit generator(handle_type coroutine) : _coroutine(coroutine) {}
366 generator() =
default;
370 _coroutine.destroy();
374 generator(
const generator&) =
delete;
375 generator& operator=(
const generator&) =
delete;
377 generator(generator&& other) noexcept : _coroutine{std::exchange(
other._coroutine, {})} {}
379 generator& operator=(generator&& other)
noexcept
381 hi_return_on_self_assignment(other);
383 _coroutine.destroy();
385 _coroutine = std::exchange(
other._coroutine, {});
393 return const_iterator{_coroutine};
400 return const_iterator{_coroutine};
405 std::default_sentinel_t
end()
const
412 std::default_sentinel_t
cend()
const
418 handle_type _coroutine;
@ other
The gui_event does not have associated data.
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
A return value for a generator-function.
Definition generator.hpp:31
std::default_sentinel_t end() const
Return a sentinel for the iterator.
Definition generator.hpp:215
const_iterator cbegin() const
Start the generator-function and return an iterator.
Definition generator.hpp:208
std::default_sentinel_t cend() const
Return a sentinel for the iterator.
Definition generator.hpp:222
const_iterator begin() const
Start the generator-function and return an iterator.
Definition generator.hpp:201
Definition generator.hpp:38
Definition generator.hpp:97
A forward iterator which iterates through values co_yieled by the generator-function.
Definition generator.hpp:112
const_iterator & operator++()
Resume the generator-function.
Definition generator.hpp:127
bool operator==(std::default_sentinel_t) const noexcept
Check if the generator-function has finished.
Definition generator.hpp:165
std::default_sentinel_t cend() const
Return a sentinel for the iterator.
Definition generator.hpp:412
std::default_sentinel_t end() const
Return a sentinel for the iterator.
Definition generator.hpp:405
const_iterator begin() const
Start the generator-function and return an iterator.
Definition generator.hpp:391
const_iterator cbegin() const
Start the generator-function and return an iterator.
Definition generator.hpp:398
bool operator==(std::default_sentinel_t) const noexcept
Check if the generator-function has finished.
Definition generator.hpp:355
const_iterator & operator++()
Resume the generator-function.
Definition generator.hpp:317
T current_exception(T... args)
T rethrow_exception(T... args)