mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 16:56:44 +08:00
Support value and error assignments in expected
This commit is contained in:
parent
95d5f25f84
commit
73a8da1b86
@ -34,6 +34,7 @@
|
||||
// Exlude this header when coroutines are not available
|
||||
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
||||
|
||||
#include <cassert>
|
||||
#include <experimental/coroutine>
|
||||
|
||||
#include <continuable/continuable-api.hpp>
|
||||
@ -47,20 +48,47 @@ namespace cti {
|
||||
namespace detail {
|
||||
namespace awaiting {
|
||||
namespace detail {
|
||||
struct void_guard_tag {};
|
||||
|
||||
template <typename T>
|
||||
struct result_trait {
|
||||
struct result_trait;
|
||||
template <>
|
||||
struct result_trait<traits::identity<void>> {
|
||||
using expected = util::expected<void_guard_tag>;
|
||||
|
||||
static auto wrap() {
|
||||
return expected(void_guard_tag{});
|
||||
}
|
||||
static void unwrap(expected&& e) {
|
||||
assert(e.is_value());
|
||||
(void)e;
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct result_trait<traits::identity<T>> {
|
||||
using expected = util::expected<T>;
|
||||
|
||||
static auto wrap(T arg) {
|
||||
return std::move(arg);
|
||||
}
|
||||
static void unwrap(expected&& e) {
|
||||
assert(e.is_value());
|
||||
(void)e;
|
||||
return std::move(e.get_value());
|
||||
}
|
||||
};
|
||||
template <typename... T>
|
||||
struct result_trait<traits::identity<T...>> {
|
||||
using expected = util::expected<std::tuple<T...>>;
|
||||
template <typename First, typename Second, typename... Rest>
|
||||
struct result_trait<traits::identity<First, Second, Rest...>> {
|
||||
using expected = util::expected<std::tuple<First, Second, Rest...>>;
|
||||
|
||||
static auto wrap(T... args) {
|
||||
return std::make_tuple(std::move(args)...);
|
||||
static auto wrap(First first, Second second, Rest... rest) {
|
||||
return std::make_tuple(std::move(first), std::move(second),
|
||||
std::move(rest)...);
|
||||
}
|
||||
static void unwrap(expected&& e) {
|
||||
assert(e.is_value());
|
||||
(void)e;
|
||||
return std::move(e.get_value());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -172,6 +172,15 @@ public:
|
||||
: expected(std::move(error), detail::slot_t::error) {
|
||||
}
|
||||
|
||||
expected& operator=(T value) {
|
||||
set_value(std::move(value));
|
||||
return *this;
|
||||
}
|
||||
expected& operator=(types::error_type error) {
|
||||
set_error(std::move(error));
|
||||
return *this;
|
||||
}
|
||||
|
||||
expected(expected const&) = default;
|
||||
expected(expected&& right) = default;
|
||||
expected& operator=(expected const&) = default;
|
||||
@ -190,6 +199,17 @@ public:
|
||||
return is_value();
|
||||
}
|
||||
|
||||
void set_value(T value) {
|
||||
weak_destroy();
|
||||
init(std::move(value));
|
||||
set(detail::slot_t::value);
|
||||
}
|
||||
void set_error(types::error_type error) {
|
||||
weak_destroy();
|
||||
init(std::move(error));
|
||||
set(detail::slot_t::error);
|
||||
}
|
||||
|
||||
T& get_value() noexcept {
|
||||
assert(is_value());
|
||||
return cast<T>();
|
||||
|
||||
@ -129,6 +129,27 @@ TYPED_TEST(expected_all_tests, is_move_assignable) {
|
||||
}
|
||||
}
|
||||
|
||||
TYPED_TEST(expected_all_tests, is_value_assignable) {
|
||||
{
|
||||
TypeParam e;
|
||||
e = this->supply(CANARY);
|
||||
|
||||
EXPECT_TRUE(bool(e));
|
||||
EXPECT_EQ(this->get(*e), CANARY);
|
||||
EXPECT_TRUE(e.is_value());
|
||||
EXPECT_FALSE(e.is_exception());
|
||||
}
|
||||
|
||||
{
|
||||
TypeParam e;
|
||||
e = error_type{};
|
||||
|
||||
EXPECT_FALSE(bool(e));
|
||||
EXPECT_FALSE(e.is_value());
|
||||
EXPECT_TRUE(e.is_exception());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(expected_copyable_tests, is_copy_constructible) {
|
||||
{
|
||||
copyable_type const e_old(CANARY);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user