Skip to content

Commit

Permalink
set_error CPO auto exception_ptr conversion
Browse files Browse the repository at this point in the history
 - set_error now uses as_exception_ptr to transform Errors to exception_ptr
 - rollback:
   - any_sender_of.hpp
   - async_scope.hpp
   - await_transform.hpp
 - cleanup tag_invocable/nothrow_tag_invocable concepts
 - file_coroutine_test does not used __FILE__ macro
 - sync_wait now requires only one set_error(exception_ptr) method
  • Loading branch information
Garcia6l20 committed Apr 21, 2021
1 parent aca13cb commit 532a343
Show file tree
Hide file tree
Showing 9 changed files with 39 additions and 43 deletions.
19 changes: 8 additions & 11 deletions examples/linux/file_coroutines_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,22 @@ int main() {
t.join();
};
sync_wait([&]() -> task<void> {
auto this_file = open_file_read_only(sched, filesystem::path{__FILE__});
auto output_file = open_file_write_only(
sched, filesystem::path{"file_coroutine_test_copy.cpp"});
std::array<std::byte, 32> buffer{};
auto file = open_file_write_only(
sched, filesystem::path{"file_coroutine_test.txt"});
constexpr char hello[]{"hello\n"};
size_t offset = 0;
while (size_t read_bytes = co_await async_read_some_at(
this_file, offset, as_writable_bytes(span{buffer}))) {
co_await async_write_some_at(
output_file, offset, as_bytes(span{buffer.data(), read_bytes}));
offset += read_bytes;
for (int ii = 0; ii < 42; ++ii) {
offset += co_await async_write_some_at(
file, offset, as_bytes(span{hello, sizeof(hello) - 1}));
}
std::printf("copied %zu bytes\n", offset);
std::printf("wrote %zu bytes\n", offset);
}());
return 0;
}
#else
# include <cstdio>
int main() {
printf("neither io_ring or coroutine support found\n");
printf("neither io_uring or coroutine support found\n");
return 0;
}
#endif
12 changes: 3 additions & 9 deletions include/unifex/any_sender_of.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@
#pragma once

#include <unifex/any_unique.hpp>
#include <unifex/as_exception_ptr.hpp>
#include <unifex/get_stop_token.hpp>
#include <unifex/inplace_stop_token.hpp>
#include <unifex/receiver_concepts.hpp>
#include <unifex/scheduler_concepts.hpp>
#include <unifex/sender_concepts.hpp>
#include <unifex/get_stop_token.hpp>
#include <unifex/inplace_stop_token.hpp>
#include <unifex/type_list.hpp>
#include <unifex/with_query_value.hpp>
#include <unifex/scheduler_concepts.hpp>

#include <unifex/detail/prologue.hpp>

Expand Down Expand Up @@ -71,11 +70,6 @@ struct _rec_ref<CPOs, Values...>::type
: _rec_ref_base<CPOs>::template type<Values...>(*op)
, stoken_(st) {}

template<typename Error>
void set_error(Error &&error) const noexcept {
unifex::set_error(*this, as_exception_ptr(std::forward<Error>(error)));
}

private:
friend inplace_stop_token tag_invoke(tag_t<get_stop_token>, const type& self) noexcept {
return self.stoken_;
Expand Down
4 changes: 2 additions & 2 deletions include/unifex/as_exception_ptr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace unifex
{
namespace _as_exception_ptr
{
inline const struct _fn {
inline constexpr struct _fn {
// forward std::exception_ptr
std::exception_ptr operator()(std::exception_ptr eptr) const noexcept {
return eptr;
Expand All @@ -51,7 +51,7 @@ namespace unifex
} as_exception_ptr{};

// default std::error_code -> std::exception_ptr conversion
std::exception_ptr
inline std::exception_ptr
tag_invoke(tag_t<as_exception_ptr>, std::error_code&& error) noexcept {
return make_exception_ptr(
std::system_error{std::forward<std::error_code>(error)});
Expand Down
4 changes: 1 addition & 3 deletions include/unifex/async_scope.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#pragma once

#include <unifex/config.hpp>
#include <unifex/as_exception_ptr.hpp>
#include <unifex/async_manual_reset_event.hpp>
#include <unifex/get_stop_token.hpp>
#include <unifex/inplace_stop_token.hpp>
Expand All @@ -41,8 +40,7 @@ namespace _async_scope {
struct async_scope;

struct _receiver_base {
template <typename Error>
void set_error(Error &&error) && noexcept {
[[noreturn]] void set_error(std::exception_ptr) noexcept {
std::terminate();
}

Expand Down
8 changes: 3 additions & 5 deletions include/unifex/await_transform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,12 @@
# error "Coroutine support is required to use <unifex/await_transform.hpp>"
#endif

#include <unifex/as_exception_ptr.hpp>
#include <unifex/async_trace.hpp>
#include <unifex/coroutine_concepts.hpp>
#include <unifex/manual_lifetime.hpp>
#include <unifex/receiver_concepts.hpp>
#include <unifex/sender_concepts.hpp>
#include <unifex/type_traits.hpp>
#include <unifex/manual_lifetime.hpp>

#include <cassert>
#include <exception>
Expand Down Expand Up @@ -108,9 +107,8 @@ struct _awaitable_base<Promise, Value>::type {
continuation_.resume();
}

template <typename Error>
void set_error(Error &&error) && noexcept {
unifex::activate_union_member(result_->exception_, as_exception_ptr(std::forward<Error>(error)));
void set_error(std::exception_ptr eptr) && noexcept {
unifex::activate_union_member(result_->exception_, std::move(eptr));
result_->state_ = _state::exception;
continuation_.resume();
}
Expand Down
14 changes: 13 additions & 1 deletion include/unifex/receiver_concepts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <unifex/type_traits.hpp>
#include <unifex/std_concepts.hpp>
#include <unifex/detail/unifex_fwd.hpp>
#include <unifex/as_exception_ptr.hpp>

#include <exception>
#include <type_traits>
Expand Down Expand Up @@ -116,14 +117,25 @@ namespace _rec_cpo {
_set_error_fn{}, (Receiver &&) r, (Error&&) error);
}
template(typename Receiver, typename Error)
(requires (!tag_invocable<_set_error_fn, Receiver, Error>))
(requires (!tag_invocable<_set_error_fn, Receiver, Error>) &&
(!tag_invocable<decltype(as_exception_ptr), Error>))
auto operator()(Receiver&& r, Error&& error) const noexcept
-> _result_t<Receiver, Error> {
static_assert(
noexcept(static_cast<Receiver&&>(r).set_error((Error &&) error)),
"receiver.set_error() method must be nothrow invocable");
return static_cast<Receiver&&>(r).set_error((Error&&) error);
}
template(typename Receiver, typename Error)
(requires (!tag_invocable<_set_error_fn, Receiver, Error>) &&
tag_invocable<decltype(as_exception_ptr), Error>)
auto operator()(Receiver&& r, Error&& error) const noexcept
-> _result_t<Receiver, std::exception_ptr> {
static_assert(
noexcept(static_cast<Receiver&&>(r).set_error(as_exception_ptr((Error&&) error))),
"receiver.set_error() method must be nothrow invocable");
return static_cast<Receiver&&>(r).set_error(as_exception_ptr((Error&&) error));
}
} set_error{};

inline const struct _set_done_fn {
Expand Down
5 changes: 2 additions & 3 deletions include/unifex/sync_wait.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,8 @@ struct _receiver {
signal_complete();
}

template <typename Error>
void set_error(Error &&e) && noexcept {
unifex::activate_union_member(promise_.exception_, as_exception_ptr(std::forward<Error>(e)));
void set_error(std::exception_ptr err) && noexcept {
unifex::activate_union_member(promise_.exception_, std::move(err));
promise_.state_ = promise<T>::state::error;
signal_complete();
}
Expand Down
5 changes: 2 additions & 3 deletions include/unifex/tag_invoke.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,11 @@ namespace unifex {

template <typename CPO, typename... Args>
UNIFEX_CONCEPT tag_invocable =
(sizeof(_tag_invoke::try_tag_invoke<CPO, Args...>(0)) ==
sizeof(_tag_invoke::yes_type));
(is_tag_invocable_v<CPO, Args...>);

template <typename CPO, typename... Args>
UNIFEX_CONCEPT nothrow_tag_invocable =
(tag_invocable<CPO, Args...> && is_nothrow_tag_invocable_v<CPO, Args...>);
(is_nothrow_tag_invocable_v<CPO, Args...>);

template <typename Fn>
using meta_tag_invoke_result =
Expand Down
11 changes: 5 additions & 6 deletions test/as_exception_ptr_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/

#include <unifex/as_exception_ptr.hpp>
#include <unifex/with_query_value.hpp>

#include <gtest/gtest.h>

Expand All @@ -32,12 +31,12 @@ TEST(as_exception_ptr, error_code) {

struct test_error {
int error_code;
};

std::exception_ptr tag_invoke(tag_t<as_exception_ptr>, test_error&& error) noexcept {
return std::make_exception_ptr(
std::runtime_error(std::to_string(std::forward<test_error>(error).error_code)));
}
friend std::exception_ptr tag_invoke(tag_t<as_exception_ptr>, test_error&& error) noexcept {
return std::make_exception_ptr(
std::runtime_error(std::to_string(std::forward<test_error>(error).error_code)));
}
};

TEST(as_exception_ptr, custom_error) {
try {
Expand Down

0 comments on commit 532a343

Please sign in to comment.