Iros
 
Loading...
Searching...
No Matches
generator.h
Go to the documentation of this file.
1#pragma once
2
9#include "di/util/coroutine.h"
10#include "di/util/exchange.h"
11#include "di/util/unreachable.h"
12
13namespace di::function {
14namespace detail {
15 template<typename Ref, typename Value>
17
18 template<typename Ref, typename Value>
20
21 template<typename Ref>
23
24 template<concepts::Reference Yield>
26 private:
27 struct FinalAwaiter {
28 auto await_ready() noexcept -> bool { return false; }
29 auto await_suspend(CoroutineHandle<>) noexcept -> CoroutineHandle<> { return noop_coroutine(); }
30 void await_resume() noexcept {}
31 };
32
33 public:
34 auto initial_suspend() noexcept { return SuspendAlways {}; }
35 auto final_suspend() noexcept { return FinalAwaiter {}; }
36
37 auto yield_value(Yield value) noexcept {
38 m_pointer = util::addressof(value);
39 return SuspendAlways {};
40 }
41
42 void await_transform() = delete;
43
44 void return_void() noexcept {}
45
47
48 private:
49 template<typename, typename>
50 friend class GeneratorIterator;
51
52 meta::AddPointer<Yield> m_pointer { nullptr };
53 };
54
55 template<typename Ref, typename Value>
57 : public container::IteratorBase<GeneratorIterator<Ref, Value>, InputIteratorTag, GeneratorValue<Ref, Value>,
58 ssize_t> {
59 private:
61
62 public:
63 GeneratorIterator(InPlace, Handle coroutine) : m_coroutine(coroutine) {}
64
65 GeneratorIterator(GeneratorIterator&& other) : m_coroutine(util::exchange(other.m_coroutine, {})) {}
66
68 m_coroutine = util::exchange(other.m_coroutine);
69 return *this;
70 }
71
72 auto operator*() const -> Ref {
73 DI_ASSERT(!m_coroutine.done());
74 return static_cast<Ref>(*m_coroutine.promise().m_pointer);
75 }
76
77 void advance_one() {
78 DI_ASSERT(!m_coroutine.done());
79 m_coroutine.resume();
80 }
81
82 private:
84 return a.m_coroutine.done();
85 }
86
87 Handle m_coroutine;
88 };
89}
90
91template<typename Ref, typename Value = void>
92class Generator : public container::ViewInterface<Generator<Ref, Value>> {
94
95 struct PromiseType : BasePromiseType {
96 auto get_return_object() noexcept -> Generator {
98 }
99 };
100
101public:
102 using promise_type = PromiseType;
103
104 Generator(Generator&& other) : m_coroutine(util::exchange(other.m_coroutine, {})) {}
105
107 if (m_coroutine) {
108 m_coroutine.destroy();
109 }
110 }
111
112 auto operator=(Generator other) -> Generator& {
113 util::swap(this->m_coroutine, other.m_coroutine);
114 return *this;
115 }
116
117 auto begin() {
118 DI_ASSERT(m_coroutine);
119 m_coroutine.resume();
121 m_coroutine.address()) };
122 }
123
124 auto end() const { return container::default_sentinel; }
125
126private:
127 explicit Generator(InPlace, CoroutineHandle<PromiseType> handle) : m_coroutine(handle) {}
128
129 CoroutineHandle<PromiseType> m_coroutine {};
130};
131}
132
133namespace di {
135}
#define DI_ASSERT(...)
Definition assert_bool.h:7
Definition view_interface.h:26
Definition generator.h:92
auto operator=(Generator other) -> Generator &
Definition generator.h:112
auto begin()
Definition generator.h:117
PromiseType promise_type
Definition generator.h:102
auto end() const
Definition generator.h:124
Generator(Generator &&other)
Definition generator.h:104
~Generator()
Definition generator.h:106
GeneratorIterator(InPlace, Handle coroutine)
Definition generator.h:63
friend auto operator==(GeneratorIterator const &a, container::DefaultSentinel) -> bool
Definition generator.h:83
auto operator=(GeneratorIterator &&other) -> GeneratorIterator &
Definition generator.h:67
auto operator*() const -> Ref
Definition generator.h:72
GeneratorIterator(GeneratorIterator &&other)
Definition generator.h:65
void advance_one()
Definition generator.h:77
void unhandled_exception()
Definition generator.h:46
void return_void() noexcept
Definition generator.h:44
auto initial_suspend() noexcept
Definition generator.h:34
friend class GeneratorIterator
Definition generator.h:50
auto yield_value(Yield value) noexcept
Definition generator.h:37
auto final_suspend() noexcept
Definition generator.h:35
constexpr auto default_sentinel
Definition default_sentinel.h:6
Definition bind_back.h:16
meta::Conditional< concepts::LanguageVoid< Value >, Ref &&, Ref > GeneratorReference
Definition generator.h:19
meta::Conditional< concepts::Reference< Ref >, Ref, Ref const & > GeneratorYield
Definition generator.h:22
meta::Conditional< concepts::LanguageVoid< Value >, meta::RemoveCVRef< Ref >, Value > GeneratorValue
Definition generator.h:16
Definition as_bool.h:8
constexpr auto value
Definition value.h:34
detail::ConditionalHelper< value, T, U >::Type Conditional
Definition core.h:88
RemoveCV< RemoveReference< T > > RemoveCVRef
Definition core.h:74
Type< detail::AddPointerHelper< T > > AddPointer
This is a helper template which will convert reference types into their corresponding pointer type,...
Definition language.h:427
Definition vocab.h:96
constexpr auto exchange(T &object, U &&new_value) -> T
Definition exchange.h:8
constexpr struct di::util::SwapFunction swap
void unreachable()
Definition unreachable.h:4
Definition zstring_parser.h:9
constexpr auto exchange(T &object, U &&new_value) -> T
Definition exchange.h:8
std::coroutine_handle< Promise > CoroutineHandle
Definition coroutine.h:164
constexpr auto in_place
Definition in_place.h:8
std::suspend_always SuspendAlways
Definition coroutine.h:169
Definition default_sentinel.h:4
Definition iterator_base.h:14
Definition value.h:12
Definition in_place.h:4