Commit f34067a7 authored by Dominik Charousset's avatar Dominik Charousset

Support constructing maybes from error enums

parent 460560ab
...@@ -76,6 +76,16 @@ public: ...@@ -76,6 +76,16 @@ public:
cr_moved_value(value); cr_moved_value(value);
} }
/// Creates an instance representing an error
/// from an error condition enum.
template <class E,
class = typename std::enable_if<
std::is_error_condition_enum<E>::value
>::type>
maybe(E error_code_enum) {
cr_error(std::make_error_condition(error_code_enum));
}
/// Creates an empty instance. /// Creates an empty instance.
maybe() { maybe() {
cr_error(error_type{}); cr_error(error_type{});
...@@ -152,6 +162,14 @@ public: ...@@ -152,6 +162,14 @@ public:
return *this; return *this;
} }
template <class E,
class = typename std::enable_if<
std::is_error_condition_enum<E>::value
>::type>
maybe& operator=(E error_code_enum) {
return *this = std::make_error_condition(error_code_enum);
}
maybe& operator=(maybe&& other) { maybe& operator=(maybe&& other) {
return other ? *this = std::move(*other) : *this = std::move(other.error()); return other ? *this = std::move(*other) : *this = std::move(other.error());
} }
...@@ -381,6 +399,8 @@ bool operator!=(const none_t&, const maybe<T>& val) { ...@@ -381,6 +399,8 @@ bool operator!=(const none_t&, const maybe<T>& val) {
return ! val.empty(); return ! val.empty();
} }
// Represents a computation performing side effects only and
// optionally return a `std::error_condition`.
template <> template <>
class maybe<void> { class maybe<void> {
public: public:
...@@ -391,21 +411,22 @@ public: ...@@ -391,21 +411,22 @@ public:
using const_pointer = const type*; using const_pointer = const type*;
using error_type = std::error_condition; using error_type = std::error_condition;
maybe(const none_t& = none) { } maybe() = default;
maybe(error_type err) : error_{std::move(err)} { } maybe(const none_t&) {
// nop
}
maybe& operator=(const none_t&) { maybe(error_type err) : error_(std::move(err)) {
error_ = {}; // nop
return *this;
} }
maybe& operator=(const error_type& err) { maybe& operator=(const none_t&) {
error_ = err; error_.clear();
return *this; return *this;
} }
maybe& operator=(error_type&& err) { maybe& operator=(error_type err) {
error_ = std::move(err); error_ = std::move(err);
return *this; return *this;
} }
...@@ -448,14 +469,11 @@ public: ...@@ -448,14 +469,11 @@ public:
return &get(); return &get();
} }
/// Returns whether this objects holds neither a value nor an actual error.
bool empty() const { bool empty() const {
return ! error(); return ! error();
} }
/// Returns the error.
const error_type& error() const { const error_type& error() const {
CAF_ASSERT(! available());
return error_; return error_;
} }
......
...@@ -81,6 +81,18 @@ CAF_TEST(custom_type_engaged) { ...@@ -81,6 +81,18 @@ CAF_TEST(custom_type_engaged) {
CAF_CHECK(*j == obj); CAF_CHECK(*j == obj);
} }
CAF_TEST(error_construct_and_assign) {
auto f = []() -> maybe<int> {
return std::errc::invalid_argument;
};
auto val = f();
CAF_CHECK(! val && val.error() == std::errc::invalid_argument);
val = 42;
CAF_CHECK(val && *val == 42);
val = std::errc::state_not_recoverable;
CAF_CHECK(! val && val.error() == std::errc::state_not_recoverable);
}
CAF_TEST(maybe_void) { CAF_TEST(maybe_void) {
maybe<void> m; maybe<void> m;
CAF_CHECK(! m); CAF_CHECK(! m);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment