Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
works with void-returning awaitables
  • Loading branch information
ericniebler committed Aug 22, 2021
commit f489034d15096408e4a6926075b6443a571e0555
2 changes: 1 addition & 1 deletion examples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ CXXFLAGS=-I$(IDIR) -std=c++20 -stdlib=libc++

LIBS=-pthread

all: hello_world
all: hello_world hello_coro

execution: $(IDIR)/execution.hpp

Expand Down
26 changes: 19 additions & 7 deletions examples/task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,13 @@ struct task {
void await_resume() const noexcept {
}
};
struct promise_type {
struct _promise_base {
void return_value(T value) noexcept {
data_.template emplace<1>(std::move(value));
}
std::variant<std::monostate, T, std::exception_ptr> data_{};
};
struct promise_type : _promise_base {
task get_return_object() noexcept {
return task(coro::coroutine_handle<promise_type>::from_promise(*this));
}
Expand All @@ -47,12 +53,8 @@ struct task {
return {};
}
void unhandled_exception() noexcept {
data_.template emplace<2>(std::current_exception());
}
void return_value(T value) noexcept {
data_.template emplace<1>(std::move(value));
this->data_.template emplace<2>(std::current_exception());
}
std::variant<std::monostate, T, std::exception_ptr> data_{};
coro::coroutine_handle<> parent_{};
};

Expand All @@ -77,7 +79,8 @@ struct task {
T await_resume() const {
if (t.coro_.promise().data_.index() == 2)
std::rethrow_exception(std::get<2>(t.coro_.promise().data_));
return std::get<T>(t.coro_.promise().data_);
if constexpr (!std::is_void_v<T>)
return std::get<T>(t.coro_.promise().data_);
}
};

Expand All @@ -91,3 +94,12 @@ struct task {
{}
coro::coroutine_handle<promise_type> coro_;
};

template<>
struct task<void>::_promise_base {
struct _void {};
void return_void() noexcept {
data_.template emplace<1>(_void{});
}
std::variant<std::monostate, _void, std::exception_ptr> data_{};
};
4 changes: 2 additions & 2 deletions include/execution.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,9 @@ namespace std::execution {
// The 'co_yield' expression then invokes this lambda
// after the coroutine is suspended so that it is safe
// for the receiver to destroy the coroutine.
auto fn = [&](auto&&... result) {
auto fn = [&](auto&&... r) {
return [&] {
set_value((R&&) r, (__await_result_t<A>&&) result...);
set_value((R&&) r, (add_rvalue_reference_t<__await_result_t<A>>) r...);
};
};
if constexpr (is_void_v<__await_result_t<A>>)
Expand Down