mirror of
https://github.com/Naios/continuable.git
synced 2026-02-07 02:09:46 +08:00
Make use of expected in await
This commit is contained in:
parent
3d6bb4d8a7
commit
b4332b66c5
@ -37,13 +37,38 @@
|
|||||||
#include <experimental/coroutine>
|
#include <experimental/coroutine>
|
||||||
|
|
||||||
#include <continuable/continuable-api.hpp>
|
#include <continuable/continuable-api.hpp>
|
||||||
// #include <continuable/detail/expected.hpp>
|
#include <continuable/detail/expected.hpp>
|
||||||
#include <continuable/detail/features.hpp>
|
#include <continuable/detail/features.hpp>
|
||||||
|
#include <continuable/detail/traits.hpp>
|
||||||
#include <continuable/detail/types.hpp>
|
#include <continuable/detail/types.hpp>
|
||||||
|
#include <continuable/detail/util.hpp>
|
||||||
|
|
||||||
namespace cti {
|
namespace cti {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
namespace awaiting {
|
namespace awaiting {
|
||||||
|
namespace detail {
|
||||||
|
template <typename T>
|
||||||
|
struct result_trait {
|
||||||
|
using expected = util::expected<T>;
|
||||||
|
|
||||||
|
static auto wrap(T arg) {
|
||||||
|
return std::move(arg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <typename... T>
|
||||||
|
struct result_trait<traits::identity<T...>> {
|
||||||
|
using expected = util::expected<std::tuple<T...>>;
|
||||||
|
|
||||||
|
static auto wrap(T... args) {
|
||||||
|
return std::make_tuple(std::move(args)...);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Continuable>
|
||||||
|
using result_storage_of_t =
|
||||||
|
result_trait<decltype(hint_of(traits::identity_of<Continuable>()))>;
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
/// We import the coroutine handle in our namespace
|
/// We import the coroutine handle in our namespace
|
||||||
using std::experimental::coroutine_handle;
|
using std::experimental::coroutine_handle;
|
||||||
|
|
||||||
@ -51,11 +76,13 @@ using std::experimental::coroutine_handle;
|
|||||||
/// for waiting on a continuable in a stackless coroutine.
|
/// for waiting on a continuable in a stackless coroutine.
|
||||||
template <typename Continuable>
|
template <typename Continuable>
|
||||||
class awaitable {
|
class awaitable {
|
||||||
|
using trait_t = detail::result_trait<Continuable>;
|
||||||
|
|
||||||
/// The continuable which is invoked upon suspension
|
/// The continuable which is invoked upon suspension
|
||||||
Continuable continuable_;
|
Continuable continuable_;
|
||||||
/// A cache which is used to pass the result of the continuation
|
/// A cache which is used to pass the result of the continuation
|
||||||
/// to the
|
/// to the coroutine.
|
||||||
// util::expected<int /*TODO*/> cache_;
|
typename trait_t::expected result_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Since continuables are evaluated lazily we are not
|
/// Since continuables are evaluated lazily we are not
|
||||||
@ -68,16 +95,20 @@ public:
|
|||||||
// TODO Convert this to an r-value function once possible
|
// TODO Convert this to an r-value function once possible
|
||||||
void await_suspend(coroutine_handle<> h) {
|
void await_suspend(coroutine_handle<> h) {
|
||||||
// Forward every result to the current awaitable
|
// Forward every result to the current awaitable
|
||||||
std::move(continuable_).flow([h, this](auto&&... args) {
|
std::move(continuable_)
|
||||||
resolve();
|
.flow([h, this](auto&&... args) {
|
||||||
h.resume();
|
resolve(std::forward<decltype(args)>(args)...);
|
||||||
});
|
h.resume();
|
||||||
|
})
|
||||||
|
.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
void await_resume() {
|
void await_resume() {
|
||||||
// if ec throw
|
if (result_) {
|
||||||
// return n;
|
return result_.get_value();
|
||||||
// return
|
} else {
|
||||||
|
throw result_.get_error();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -181,7 +181,7 @@ public:
|
|||||||
assert(!is_empty());
|
assert(!is_empty());
|
||||||
return slot_ == detail::slot_t::value;
|
return slot_ == detail::slot_t::value;
|
||||||
}
|
}
|
||||||
bool is_error() const noexcept {
|
bool is_exception() const noexcept {
|
||||||
assert(!is_empty());
|
assert(!is_empty());
|
||||||
return slot_ == detail::slot_t::error;
|
return slot_ == detail::slot_t::error;
|
||||||
}
|
}
|
||||||
@ -189,14 +189,30 @@ public:
|
|||||||
explicit constexpr operator bool() const noexcept {
|
explicit constexpr operator bool() const noexcept {
|
||||||
return is_value();
|
return is_value();
|
||||||
}
|
}
|
||||||
T& operator*() noexcept {
|
|
||||||
|
T& get_value() noexcept {
|
||||||
assert(is_value());
|
assert(is_value());
|
||||||
return cast<T>();
|
return cast<T>();
|
||||||
}
|
}
|
||||||
T const& operator*() const noexcept {
|
T const& get_value() const noexcept {
|
||||||
assert(is_value());
|
assert(is_value());
|
||||||
return cast<T>();
|
return cast<T>();
|
||||||
}
|
}
|
||||||
|
T& get_exception() noexcept {
|
||||||
|
assert(is_exception());
|
||||||
|
return cast<types::error_type>();
|
||||||
|
}
|
||||||
|
T const& get_exception() const noexcept {
|
||||||
|
assert(is_exception());
|
||||||
|
return cast<types::error_type>();
|
||||||
|
}
|
||||||
|
|
||||||
|
T& operator*() noexcept {
|
||||||
|
return get_value();
|
||||||
|
}
|
||||||
|
T const& operator*() const noexcept {
|
||||||
|
return get_value();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename V>
|
template <typename V>
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include <continuable/detail/expected.hpp>
|
#include <continuable/detail/expected.hpp>
|
||||||
#include <continuable/detail/types.hpp>
|
#include <continuable/detail/types.hpp>
|
||||||
@ -70,7 +71,7 @@ TYPED_TEST(expected_all_tests, can_carry_errors) {
|
|||||||
EXPECT_TRUE(bool(e));
|
EXPECT_TRUE(bool(e));
|
||||||
EXPECT_EQ(this->get(*e), CANARY);
|
EXPECT_EQ(this->get(*e), CANARY);
|
||||||
EXPECT_TRUE(e.is_value());
|
EXPECT_TRUE(e.is_value());
|
||||||
EXPECT_FALSE(e.is_error());
|
EXPECT_FALSE(e.is_exception());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -78,7 +79,7 @@ TYPED_TEST(expected_all_tests, can_carry_errors) {
|
|||||||
|
|
||||||
EXPECT_FALSE(bool(e));
|
EXPECT_FALSE(bool(e));
|
||||||
EXPECT_FALSE(e.is_value());
|
EXPECT_FALSE(e.is_value());
|
||||||
EXPECT_TRUE(e.is_error());
|
EXPECT_TRUE(e.is_exception());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,14 +95,14 @@ TYPED_TEST(expected_all_tests, is_move_constructible) {
|
|||||||
EXPECT_TRUE(bool(e));
|
EXPECT_TRUE(bool(e));
|
||||||
EXPECT_EQ(this->get(*e), CANARY);
|
EXPECT_EQ(this->get(*e), CANARY);
|
||||||
EXPECT_TRUE(e.is_value());
|
EXPECT_TRUE(e.is_value());
|
||||||
EXPECT_FALSE(e.is_error());
|
EXPECT_FALSE(e.is_exception());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
TypeParam e(TypeParam(error_type{}));
|
TypeParam e(TypeParam(error_type{}));
|
||||||
EXPECT_FALSE(bool(e));
|
EXPECT_FALSE(bool(e));
|
||||||
EXPECT_FALSE(e.is_value());
|
EXPECT_FALSE(e.is_value());
|
||||||
EXPECT_TRUE(e.is_error());
|
EXPECT_TRUE(e.is_exception());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +115,7 @@ TYPED_TEST(expected_all_tests, is_move_assignable) {
|
|||||||
EXPECT_TRUE(bool(e));
|
EXPECT_TRUE(bool(e));
|
||||||
EXPECT_EQ(this->get(*e), CANARY);
|
EXPECT_EQ(this->get(*e), CANARY);
|
||||||
EXPECT_TRUE(e.is_value());
|
EXPECT_TRUE(e.is_value());
|
||||||
EXPECT_FALSE(e.is_error());
|
EXPECT_FALSE(e.is_exception());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -124,7 +125,7 @@ TYPED_TEST(expected_all_tests, is_move_assignable) {
|
|||||||
|
|
||||||
EXPECT_FALSE(bool(e));
|
EXPECT_FALSE(bool(e));
|
||||||
EXPECT_FALSE(e.is_value());
|
EXPECT_FALSE(e.is_value());
|
||||||
EXPECT_TRUE(e.is_error());
|
EXPECT_TRUE(e.is_exception());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +137,7 @@ TEST(expected_copyable_tests, is_copy_constructible) {
|
|||||||
EXPECT_TRUE(bool(e));
|
EXPECT_TRUE(bool(e));
|
||||||
EXPECT_EQ(*e, CANARY);
|
EXPECT_EQ(*e, CANARY);
|
||||||
EXPECT_TRUE(e.is_value());
|
EXPECT_TRUE(e.is_value());
|
||||||
EXPECT_FALSE(e.is_error());
|
EXPECT_FALSE(e.is_exception());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -145,7 +146,7 @@ TEST(expected_copyable_tests, is_copy_constructible) {
|
|||||||
|
|
||||||
EXPECT_FALSE(bool(e));
|
EXPECT_FALSE(bool(e));
|
||||||
EXPECT_FALSE(e.is_value());
|
EXPECT_FALSE(e.is_value());
|
||||||
EXPECT_TRUE(e.is_error());
|
EXPECT_TRUE(e.is_exception());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +159,7 @@ TEST(expected_copyable_tests, is_copy_assignable) {
|
|||||||
EXPECT_TRUE(bool(e));
|
EXPECT_TRUE(bool(e));
|
||||||
EXPECT_EQ(*e, CANARY);
|
EXPECT_EQ(*e, CANARY);
|
||||||
EXPECT_TRUE(e.is_value());
|
EXPECT_TRUE(e.is_value());
|
||||||
EXPECT_FALSE(e.is_error());
|
EXPECT_FALSE(e.is_exception());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -168,6 +169,6 @@ TEST(expected_copyable_tests, is_copy_assignable) {
|
|||||||
|
|
||||||
EXPECT_FALSE(bool(e));
|
EXPECT_FALSE(bool(e));
|
||||||
EXPECT_FALSE(e.is_value());
|
EXPECT_FALSE(e.is_value());
|
||||||
EXPECT_TRUE(e.is_error());
|
EXPECT_TRUE(e.is_exception());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user