mirror of
https://github.com/Naios/continuable.git
synced 2025-12-07 01:06: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
|
// Exlude this header when coroutines are not available
|
||||||
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
#ifdef CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <experimental/coroutine>
|
#include <experimental/coroutine>
|
||||||
|
|
||||||
#include <continuable/continuable-api.hpp>
|
#include <continuable/continuable-api.hpp>
|
||||||
@ -47,20 +48,47 @@ namespace cti {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
namespace awaiting {
|
namespace awaiting {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
struct void_guard_tag {};
|
||||||
|
|
||||||
template <typename T>
|
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>;
|
using expected = util::expected<T>;
|
||||||
|
|
||||||
static auto wrap(T arg) {
|
static auto wrap(T arg) {
|
||||||
return std::move(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>
|
template <typename First, typename Second, typename... Rest>
|
||||||
struct result_trait<traits::identity<T...>> {
|
struct result_trait<traits::identity<First, Second, Rest...>> {
|
||||||
using expected = util::expected<std::tuple<T...>>;
|
using expected = util::expected<std::tuple<First, Second, Rest...>>;
|
||||||
|
|
||||||
static auto wrap(T... args) {
|
static auto wrap(First first, Second second, Rest... rest) {
|
||||||
return std::make_tuple(std::move(args)...);
|
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(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 const&) = default;
|
||||||
expected(expected&& right) = default;
|
expected(expected&& right) = default;
|
||||||
expected& operator=(expected const&) = default;
|
expected& operator=(expected const&) = default;
|
||||||
@ -190,6 +199,17 @@ public:
|
|||||||
return is_value();
|
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 {
|
T& get_value() noexcept {
|
||||||
assert(is_value());
|
assert(is_value());
|
||||||
return cast<T>();
|
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) {
|
TEST(expected_copyable_tests, is_copy_constructible) {
|
||||||
{
|
{
|
||||||
copyable_type const e_old(CANARY);
|
copyable_type const e_old(CANARY);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user