1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
template <typename T>
RecursiveGenerator<T>::Promise::Promise() noexcept
:
d_parentOrLeaf(this),
d_root(this)
{}
template <typename T>
inline auto RecursiveGenerator<T>::Promise::get_return_object() noexcept
{
return RecursiveGenerator<T>{ *this };
}
template <typename T>
inline void RecursiveGenerator<T>::Promise::unhandled_exception() noexcept
{
d_exception = std::current_exception();
}
template <typename T>
std::suspend_always RecursiveGenerator<T>::Promise::yield_value(T &value)
noexcept
{
d_value = std::addressof(value);
return {};
}
template <typename T>
std::suspend_always RecursiveGenerator<T>::Promise::yield_value(T &&value)
noexcept
{
d_value = std::addressof(value);
return {};
}
template <typename T>
inline auto
RecursiveGenerator<T>::Promise::yield_value(RecursiveGenerator &&generator)
noexcept
{
return yield_value(generator);
}
template <typename T>
auto RecursiveGenerator<T>::Promise::yield_value(
RecursiveGenerator &generator) noexcept
{
if (generator.d_promise != nullptr)
{
d_root->d_parentOrLeaf = generator.d_promise;
generator.d_promise->d_root = d_root;
generator.d_promise->d_parentOrLeaf = this;
generator.d_promise->resume();
if (!generator.d_promise->is_complete())
return Awaitable{ generator.d_promise };
d_root->d_parentOrLeaf = this;
}
return Awaitable{ 0 };
}
template <typename T>
inline void RecursiveGenerator<T>::Promise::destroy() noexcept
{
Handle::from_promise(*this).destroy();
}
template <typename T>
void RecursiveGenerator<T>::Promise::throw_if_exception()
{
if (d_exception != nullptr)
std::rethrow_exception(std::move(d_exception));
}
template <typename T>
inline bool RecursiveGenerator<T>::Promise::is_complete() noexcept
{
return Handle::from_promise(*this).done();
}
template <typename T>
inline T &RecursiveGenerator<T>::Promise::value() noexcept
{
return *(d_parentOrLeaf->d_value);
}
template <typename T>
void RecursiveGenerator<T>::Promise::pull() noexcept
{
d_parentOrLeaf->resume();
while (d_parentOrLeaf != this && d_parentOrLeaf->is_complete())
{
d_parentOrLeaf = d_parentOrLeaf->d_parentOrLeaf;
d_parentOrLeaf->resume();
}
}
template <typename T>
inline void RecursiveGenerator<T>::Promise::resume() noexcept
{
Handle::from_promise(*this).resume();
}
template <typename T>
inline RecursiveGenerator<T>::Promise::Awaitable::Awaitable(
Promise *childPromise)
:
d_childPromise(childPromise)
{}
template <typename T>
inline bool RecursiveGenerator<T>::Promise::Awaitable::await_ready() noexcept
{
return this->d_childPromise == 0;
}
template <typename T>
inline void RecursiveGenerator<T>::Promise::Awaitable::await_suspend(Handle)
noexcept
{}
template <typename T>
inline void RecursiveGenerator<T>::Promise::Awaitable::await_resume()
{
if (this->d_childPromise != 0)
this->d_childPromise->throw_if_exception();
}
|