step20
Loading...
Searching...
No Matches
generator.hpp
Go to the documentation of this file.
1// Andrew Naplavkov
2
3#ifndef STEP20_GENERATOR_HPP
4#define STEP20_GENERATOR_HPP
5
6#include <coroutine>
7#include <iterator>
8#include <memory>
9#include <optional>
10
11namespace step20 {
12
13inline auto co_destroy = [](void* address) {
14 std::coroutine_handle<>::from_address(address).destroy();
15};
16
18template <std::movable T>
19struct generator : private std::unique_ptr<void, decltype(co_destroy)> {
20 struct promise_type : std::optional<T> {
21 std::suspend_never initial_suspend() { return {}; }
22 void await_transform() = delete;
23 void return_void() {}
24 void unhandled_exception() { throw; }
25 std::suspend_always final_suspend() noexcept { return {}; }
26
27 std::suspend_always yield_value(T value)
28 {
29 this->emplace(std::move(value));
30 return {};
31 }
32
34 {
35 auto result = generator{};
36 result.reset(handle::from_promise(*this).address());
37 return result;
38 }
39 };
40
41 using handle = std::coroutine_handle<promise_type>;
42
43 struct iterator : private handle {
44 using iterator_category = std::input_iterator_tag;
45 using difference_type = std::ptrdiff_t;
46 using value_type = T;
47 using reference = const T&;
48 explicit iterator(handle coro) : handle{coro} {}
49 reference operator*() const { return *this->promise(); }
50 bool operator==(std::default_sentinel_t) const { return this->done(); }
51 void operator++(int) { this->resume(); }
52
54 {
55 this->resume();
56 return *this;
57 }
58 };
59
60 auto begin() const { return iterator{handle::from_address(get())}; }
61 auto end() const { return std::default_sentinel; }
62};
63
64} // namespace step20
65
66#endif // STEP20_GENERATOR_HPP
Definition edit_distance.hpp:11
auto co_destroy
Definition generator.hpp:13
Definition generator.hpp:43
iterator(handle coro)
Definition generator.hpp:48
T value_type
Definition generator.hpp:46
std::ptrdiff_t difference_type
Definition generator.hpp:45
iterator & operator++()
Definition generator.hpp:53
const T & reference
Definition generator.hpp:47
std::input_iterator_tag iterator_category
Definition generator.hpp:44
reference operator*() const
Definition generator.hpp:49
bool operator==(std::default_sentinel_t) const
Definition generator.hpp:50
void operator++(int)
Definition generator.hpp:51
Definition generator.hpp:20
generator get_return_object()
Definition generator.hpp:33
void unhandled_exception()
Definition generator.hpp:24
std::suspend_never initial_suspend()
Definition generator.hpp:21
void return_void()
Definition generator.hpp:23
std::suspend_always final_suspend() noexcept
Definition generator.hpp:25
std::suspend_always yield_value(T value)
Definition generator.hpp:27
Definition generator.hpp:19
auto begin() const
Definition generator.hpp:60
auto end() const
Definition generator.hpp:61
std::coroutine_handle< promise_type > handle
Definition generator.hpp:41