Make use of expected in await

This commit is contained in:
Denis Blank 2017-11-30 07:11:23 +01:00
parent 3d6bb4d8a7
commit b4332b66c5
3 changed files with 71 additions and 23 deletions

View File

@ -37,13 +37,38 @@
#include <experimental/coroutine>
#include <continuable/continuable-api.hpp>
// #include <continuable/detail/expected.hpp>
#include <continuable/detail/expected.hpp>
#include <continuable/detail/features.hpp>
#include <continuable/detail/traits.hpp>
#include <continuable/detail/types.hpp>
#include <continuable/detail/util.hpp>
namespace cti {
namespace detail {
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
using std::experimental::coroutine_handle;
@ -51,11 +76,13 @@ using std::experimental::coroutine_handle;
/// for waiting on a continuable in a stackless coroutine.
template <typename Continuable>
class awaitable {
using trait_t = detail::result_trait<Continuable>;
/// The continuable which is invoked upon suspension
Continuable continuable_;
/// A cache which is used to pass the result of the continuation
/// to the
// util::expected<int /*TODO*/> cache_;
/// to the coroutine.
typename trait_t::expected result_;
public:
/// Since continuables are evaluated lazily we are not
@ -68,16 +95,20 @@ public:
// TODO Convert this to an r-value function once possible
void await_suspend(coroutine_handle<> h) {
// Forward every result to the current awaitable
std::move(continuable_).flow([h, this](auto&&... args) {
resolve();
h.resume();
});
std::move(continuable_)
.flow([h, this](auto&&... args) {
resolve(std::forward<decltype(args)>(args)...);
h.resume();
})
.done();
}
void await_resume() {
// if ec throw
// return n;
// return
if (result_) {
return result_.get_value();
} else {
throw result_.get_error();
}
}
private:

View File

@ -181,7 +181,7 @@ public:
assert(!is_empty());
return slot_ == detail::slot_t::value;
}
bool is_error() const noexcept {
bool is_exception() const noexcept {
assert(!is_empty());
return slot_ == detail::slot_t::error;
}
@ -189,14 +189,30 @@ public:
explicit constexpr operator bool() const noexcept {
return is_value();
}
T& operator*() noexcept {
T& get_value() noexcept {
assert(is_value());
return cast<T>();
}
T const& operator*() const noexcept {
T const& get_value() const noexcept {
assert(is_value());
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:
template <typename V>

View File

@ -22,6 +22,7 @@
**/
#include <memory>
#include <utility>
#include <continuable/detail/expected.hpp>
#include <continuable/detail/types.hpp>
@ -70,7 +71,7 @@ TYPED_TEST(expected_all_tests, can_carry_errors) {
EXPECT_TRUE(bool(e));
EXPECT_EQ(this->get(*e), CANARY);
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(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_EQ(this->get(*e), CANARY);
EXPECT_TRUE(e.is_value());
EXPECT_FALSE(e.is_error());
EXPECT_FALSE(e.is_exception());
}
{
TypeParam e(TypeParam(error_type{}));
EXPECT_FALSE(bool(e));
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_EQ(this->get(*e), CANARY);
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(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_EQ(*e, CANARY);
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(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_EQ(*e, CANARY);
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(e.is_value());
EXPECT_TRUE(e.is_error());
EXPECT_TRUE(e.is_exception());
}
}