Py2Cpp 1.6.3; VERSION ${PROJECT_VERSION}
Loading...
Searching...
No Matches
gen.hpp
Go to the documentation of this file.
1
9#pragma once
10
11#include <coroutine>
12#include <exception>
13#include <iterator>
14#include <type_traits>
15#include <utility>
16
17namespace py {
18
30 template <typename T> class Generator {
31 public:
32 struct promise_type {
33 using value_type = std::remove_reference_t<T>;
34 using reference_type = std::conditional_t<std::is_reference_v<T>, T, T&>;
36
38
39 auto yield_value(std::remove_reference_t<T>& value) noexcept {
40 m_value = std::addressof(value);
41 return std::suspend_always{};
42 }
43
44 auto yield_value(std::remove_reference_t<T>&& value) noexcept {
45 m_value = std::addressof(value);
46 return std::suspend_always{};
47 }
48
49 auto initial_suspend() noexcept { return std::suspend_always{}; }
50 auto final_suspend() noexcept { return std::suspend_always{}; }
51 void return_void() noexcept {}
52 void unhandled_exception() noexcept { std::terminate(); }
53
54 auto get_return_object() noexcept {
55 return Generator{std::coroutine_handle<promise_type>::from_promise(*this)};
56 }
57 };
58
59 private:
60 using handle_type = std::coroutine_handle<promise_type>;
61 handle_type coro_{};
62
63 explicit Generator(handle_type coro) noexcept : coro_(coro) {}
64
65 public:
66 Generator() noexcept = default;
68 if (coro_) coro_.destroy();
69 }
70
71 Generator(Generator&& other) noexcept : coro_(std::exchange(other.coro_, {})) {}
72 Generator& operator=(Generator&& other) noexcept {
73 if (this != &other) {
74 if (coro_) coro_.destroy();
75 coro_ = std::exchange(other.coro_, {});
76 }
77 return *this;
78 }
79
80 Generator(const Generator&) = delete;
81 Generator& operator=(const Generator&) = delete;
82
83 class iterator {
84 handle_type coro_{};
85
86 public:
87 using iterator_category = std::input_iterator_tag;
88 using value_type = std::remove_reference_t<T>;
89 using difference_type = std::ptrdiff_t;
90 using reference = std::conditional_t<std::is_reference_v<T>, T, T&>;
91 using pointer = std::add_pointer_t<value_type>;
92
93 iterator() noexcept = default;
94 explicit iterator(handle_type coro) noexcept : coro_(coro) {}
95
97 coro_.resume();
98 if (coro_.done()) coro_ = {};
99 return *this;
100 }
101 void operator++(int) { ++*this; }
102
103 reference operator*() const noexcept {
104 return static_cast<reference>(*coro_.promise().m_value);
105 }
106
107 pointer operator->() const noexcept { return std::addressof(operator*()); }
108
109 bool operator==(const iterator& other) const noexcept { return coro_ == other.coro_; }
110 bool operator!=(const iterator& other) const noexcept { return !(*this == other); }
111 };
112
114 if (!coro_) return iterator{};
115 coro_.resume();
116 if (coro_.done()) return iterator{};
117 return iterator{coro_};
118 }
119
120 iterator end() noexcept { return iterator{}; }
121 };
122
123} // namespace py
Definition gen.hpp:83
iterator() noexcept=default
reference operator*() const noexcept
Definition gen.hpp:103
std::conditional_t< std::is_reference_v< T >, T, T & > reference
Definition gen.hpp:90
pointer operator->() const noexcept
Definition gen.hpp:107
std::add_pointer_t< value_type > pointer
Definition gen.hpp:91
bool operator==(const iterator &other) const noexcept
Definition gen.hpp:109
iterator & operator++()
Definition gen.hpp:96
void operator++(int)
Definition gen.hpp:101
bool operator!=(const iterator &other) const noexcept
Definition gen.hpp:110
std::input_iterator_tag iterator_category
Definition gen.hpp:87
std::ptrdiff_t difference_type
Definition gen.hpp:89
std::remove_reference_t< T > value_type
Definition gen.hpp:88
Minimal generator using C++20 coroutines.
Definition gen.hpp:30
Generator() noexcept=default
Generator & operator=(Generator &&other) noexcept
Definition gen.hpp:72
Generator(const Generator &)=delete
iterator begin()
Definition gen.hpp:113
Generator(Generator &&other) noexcept
Definition gen.hpp:71
Generator & operator=(const Generator &)=delete
iterator end() noexcept
Definition gen.hpp:120
Python-like utilities and data structures for C++.
Definition dict.hpp:18
Definition gen.hpp:32
std::conditional_t< std::is_reference_v< T >, T, T & > reference_type
Definition gen.hpp:34
pointer_type m_value
Definition gen.hpp:37
auto final_suspend() noexcept
Definition gen.hpp:50
auto get_return_object() noexcept
Definition gen.hpp:54
std::remove_reference_t< T > value_type
Definition gen.hpp:33
value_type * pointer_type
Definition gen.hpp:35
void unhandled_exception() noexcept
Definition gen.hpp:52
auto yield_value(std::remove_reference_t< T > &value) noexcept
Definition gen.hpp:39
auto initial_suspend() noexcept
Definition gen.hpp:49
auto yield_value(std::remove_reference_t< T > &&value) noexcept
Definition gen.hpp:44
void return_void() noexcept
Definition gen.hpp:51