diff --git a/include/continuable/detail/awaiting.hpp b/include/continuable/detail/awaiting.hpp
index 5db87ce..2bf78e8 100644
--- a/include/continuable/detail/awaiting.hpp
+++ b/include/continuable/detail/awaiting.hpp
@@ -54,7 +54,7 @@ class awaitable {
Continuable continuable_;
/// A cache which is used to pass the result of the continuation
/// to the
- expected::expected cache_;
+ util::expected cache_;
public:
/// Since continuables are evaluated lazily we are not
diff --git a/include/continuable/detail/expected.hpp b/include/continuable/detail/expected.hpp
index 6b02524..ac0245f 100644
--- a/include/continuable/detail/expected.hpp
+++ b/include/continuable/detail/expected.hpp
@@ -31,6 +31,7 @@
#ifndef CONTINUABLE_DETAIL_EXPECTED_HPP_INCLUDED__
#define CONTINUABLE_DETAIL_EXPECTED_HPP_INCLUDED__
+#include
#include
#include
#include
@@ -55,25 +56,25 @@ template
struct expected_copy_base {
constexpr expected_copy_base() = default;
- expected_copy_base(expected_copy_base const&) = default;
- explicit expected_copy_base(expected_copy_base&& right)
+ expected_copy_base(expected_copy_base&&) = default;
+ explicit expected_copy_base(expected_copy_base const& right)
// TODO noexcept(Base::is_nothrow_move_constructible)
{
Base& me = *static_cast(this);
- Base& other = *static_cast(&right);
+ Base const& other = *static_cast(&right);
other.visit([&](auto&& value) {
// ...
me.init(std::move(value));
});
- set(other.get());
+ me.set(other.get());
}
- expected_copy_base& operator=(expected_copy_base const&) = default;
- expected_copy_base& operator=(expected_copy_base&& right)
+ expected_copy_base& operator=(expected_copy_base&&) = default;
+ expected_copy_base& operator=(expected_copy_base const& right)
// TODO noexcept(Base::is_nothrow_move_constructible)
{
Base& me = *static_cast(this);
- Base& other = *static_cast(&right);
+ Base const& other = *static_cast(&right);
me.weak_destroy();
@@ -81,7 +82,7 @@ struct expected_copy_base {
// ...
me.init(std::move(value));
});
- set(other.get());
+ me.set(other.get());
return *this;
}
};
@@ -98,19 +99,19 @@ template
struct expected_move_base {
constexpr expected_move_base() = default;
- expected_move_base(expected_move_base&&) = default;
- explicit expected_move_base(expected_move_base const& right) {
+ expected_move_base(expected_move_base const&) = default;
+ explicit expected_move_base(expected_move_base&& right) {
Base& me = *static_cast(this);
- Base const& other = *static_cast(&right);
+ Base& other = *static_cast(&right);
other.visit([&](auto&& value) {
// ...
me.init(std::move(value));
});
- set(other.consume());
+ me.set(other.consume());
}
- expected_move_base& operator=(expected_move_base&&) = default;
- expected_move_base& operator=(expected_move_base const& right) {
+ expected_move_base& operator=(expected_move_base const&) = default;
+ expected_move_base& operator=(expected_move_base&& right) {
Base& me = *static_cast(this);
Base const& other = *static_cast(&right);
@@ -120,7 +121,7 @@ struct expected_move_base {
// ...
me.init(std::move(value));
});
- set(other.consume());
+ me.set(other.consume());
return *this;
}
};
@@ -137,9 +138,11 @@ class expected
std::is_copy_constructible::value> {
template
- friend class expected_move_base;
+ friend class expected;
+ template
+ friend struct detail::expected_move_base;
template
- friend class expected_copy_base;
+ friend struct detail::expected_copy_base;
detail::storage_of_t storage_;
detail::slot_t slot_ = detail::slot_t::empty;
@@ -152,6 +155,8 @@ class expected
}
public:
+ expected() = default;
+
explicit expected(T value) //
: expected(std::move(value), detail::slot_t::value) {
}
@@ -165,25 +170,30 @@ public:
expected& operator=(expected&& right) = default;
bool is_value() const noexcept {
+ assert(!is_empty());
return slot_ == detail::slot_t::value;
}
bool is_error() const noexcept {
+ assert(!is_empty());
return slot_ == detail::slot_t::error;
}
-protected:
- bool is_empty() const noexcept {
- return slot_ == detail::slot_t::empty;
+ explicit constexpr operator bool() const noexcept {
+ return is_value();
+ }
+ T& operator*() const noexcept {
+ assert(!is_value());
+ return cast();
}
+private:
template
void visit(V&& visitor) {
switch (slot_) {
case detail::slot_t::value:
- return std::forward(visitor)(static_cast(&storage_));
+ return std::forward(visitor)(cast());
case detail::slot_t::error:
- return std::forward(visitor)(
- static_cast(&storage_));
+ return std::forward(visitor)(cast());
default:
// We don't visit when there is no value
break;
@@ -193,20 +203,33 @@ protected:
void visit(V&& visitor) const {
switch (slot_) {
case detail::slot_t::value:
- return std::forward(visitor)(static_cast(&storage_));
+ return std::forward(visitor)(cast());
case detail::slot_t::error:
- return std::forward(visitor)(
- static_cast(&storage_));
+ return std::forward(visitor)(cast());
default:
// We don't visit when there is no value
break;
}
}
+ bool is_empty() const noexcept {
+ return slot_ == detail::slot_t::empty;
+ }
+
template
- void init(V&& value, detail::slot_t const slot) {
- assert(is(slot_t::empty));
- set(slot);
+ V& cast() noexcept {
+ assert(!is_empty());
+ return *reinterpret_cast(&storage_);
+ }
+ template
+ V const& cast() const noexcept {
+ assert(!is_empty());
+ return *reinterpret_cast(&storage_);
+ }
+
+ template
+ void init(V&& value) {
+ assert(is_empty());
using type = std::decay_t;
auto storage = &storage_;
new (storage) type(std::forward(value));
@@ -237,7 +260,7 @@ protected:
void set(detail::slot_t const slot) {
slot_ = slot;
}
- detail::slot_t consume(detail::slot_t slot) {
+ detail::slot_t consume() {
auto const current = get();
destroy();
return current;
diff --git a/test/unit-test/test-continuable-await.cpp b/test/unit-test/test-continuable-await.cpp
index 70afb14..2d9c964 100644
--- a/test/unit-test/test-continuable-await.cpp
+++ b/test/unit-test/test-continuable-await.cpp
@@ -66,7 +66,7 @@ auto mk() {
void teststhh() {
auto c = mk();
- co_await std::move(c);
+ // co_await std::move(c);
}
#endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE
diff --git a/test/unit-test/test-continuable-expected.cpp b/test/unit-test/test-continuable-expected.cpp
index 9926db0..1eabc2e 100644
--- a/test/unit-test/test-continuable-expected.cpp
+++ b/test/unit-test/test-continuable-expected.cpp
@@ -23,11 +23,21 @@
#include "test-continuable.hpp"
-using cti::detail::util::expected;
using cti::detail::types::error_type;
+using cti::detail::util::expected;
TEST(expected_tests, can_carry_errors) {
- expected e(1);
+ {
+ expected e(1);
+ EXPECT_TRUE(bool(e));
+ EXPECT_TRUE(e.is_value());
+ EXPECT_FALSE(e.is_error());
+ }
- auto i = e;
+ {
+ expected e(error_type{});
+ EXPECT_FALSE(bool(e));
+ EXPECT_FALSE(e.is_value());
+ EXPECT_TRUE(e.is_error());
+ }
}