forked from OctaForge/libostd
make value-returning no-argument coroutines iterable
This commit is contained in:
parent
64d92743e4
commit
7ba1f9265b
|
@ -4,7 +4,7 @@
|
||||||
using namespace ostd;
|
using namespace ostd;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
generator<int> g = [](auto yield) {
|
coroutine<int()> g = [](auto yield) {
|
||||||
yield(5);
|
yield(5);
|
||||||
yield(10);
|
yield(10);
|
||||||
yield(15);
|
yield(15);
|
||||||
|
@ -13,8 +13,8 @@ int main() {
|
||||||
};
|
};
|
||||||
|
|
||||||
writeln("generator test");
|
writeln("generator test");
|
||||||
for (int i: g) {
|
for (int i: g.iter()) {
|
||||||
writeln("generated: ", i);
|
writefln("generated: %s", i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -181,6 +181,9 @@ inline void swap(coroutine_context &a, coroutine_context &b) {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct coroutine;
|
struct coroutine;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct coroutine_range;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
/* like reference_wrapper but for any value */
|
/* like reference_wrapper but for any value */
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -345,6 +348,8 @@ namespace detail {
|
||||||
/* yield takes a value but doesn't return any args */
|
/* yield takes a value but doesn't return any args */
|
||||||
template<typename R>
|
template<typename R>
|
||||||
struct coro_base<R> {
|
struct coro_base<R> {
|
||||||
|
coroutine_range<R> iter();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
coro_base(void (*callp)(void *), size_t ss):
|
coro_base(void (*callp)(void *), size_t ss):
|
||||||
p_ctx(ss, callp, this)
|
p_ctx(ss, callp, this)
|
||||||
|
@ -554,29 +559,27 @@ inline void swap(coroutine<R(A...)> &a, coroutine<R(A...)> &b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct generator: input_range<generator<T>> {
|
struct coroutine_range: input_range<coroutine_range<T>> {
|
||||||
using range_category = input_range_tag;
|
using range_category = input_range_tag;
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
using reference = T &;
|
using reference = T &;
|
||||||
using size_type = size_t;
|
using size_type = size_t;
|
||||||
using difference_type = stream_off_t;
|
using difference_type = stream_off_t;
|
||||||
|
|
||||||
generator() = default;
|
coroutine_range() = delete;
|
||||||
|
coroutine_range(coroutine<T()> &c): p_coro(&c) {
|
||||||
template<typename F>
|
|
||||||
generator(F &&func, size_t ss = COROUTINE_DEFAULT_STACK_SIZE):
|
|
||||||
p_ptr(new coroutine<T()>{std::forward<F>(func), ss})
|
|
||||||
{
|
|
||||||
pop_front();
|
pop_front();
|
||||||
}
|
}
|
||||||
|
coroutine_range(coroutine_range const &r):
|
||||||
|
p_coro(r.p_coro), p_item(r.p_item) {}
|
||||||
|
|
||||||
bool empty() const {
|
bool empty() const {
|
||||||
return !p_item;
|
return !p_item;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_front() {
|
void pop_front() {
|
||||||
if (*p_ptr) {
|
if (*p_coro) {
|
||||||
p_item = (*p_ptr)();
|
p_item = (*p_coro)();
|
||||||
} else {
|
} else {
|
||||||
p_item = std::nullopt;
|
p_item = std::nullopt;
|
||||||
}
|
}
|
||||||
|
@ -586,14 +589,21 @@ struct generator: input_range<generator<T>> {
|
||||||
return p_item.value();
|
return p_item.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool equals_front(generator const &g) {
|
bool equals_front(coroutine_range const &g) {
|
||||||
return p_ptr == g.p_ptr;
|
return p_coro == g.p_coro;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<coroutine<T()>> p_ptr;
|
coroutine<T()> *p_coro;
|
||||||
mutable std::optional<T> p_item;
|
mutable std::optional<T> p_item;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template<typename R>
|
||||||
|
coroutine_range<R> coro_base<R>::iter() {
|
||||||
|
return coroutine_range<R>{static_cast<coroutine<R()> &>(*this)};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace ostd */
|
} /* namespace ostd */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue