Commit 206d2012 authored by Dominik Charousset's avatar Dominik Charousset

Revert changes to error class to 0.17.1 state

The changes since the 0.17.1 release can result in deserialization
errors at runtime.
parent 4b9d37c1
......@@ -19,15 +19,17 @@
#pragma once
#include <cstdint>
#include <functional>
#include <utility>
#include "caf/atom.hpp"
#include "caf/detail/comparable.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/fwd.hpp"
#include "caf/meta/load_callback.hpp"
#include "caf/none.hpp"
#include "caf/meta/omittable_if_empty.hpp"
#include "caf/meta/type_name.hpp"
#include "caf/none.hpp"
#include "caf/detail/comparable.hpp"
namespace caf {
......@@ -88,6 +90,12 @@ using enable_if_has_make_error_t = typename std::enable_if<
/// rendering error messages via `actor_system::render(const error&)`.
class error : detail::comparable<error> {
public:
// -- member types -----------------------------------------------------------
using inspect_fun = std::function<
error(meta::type_name_t, uint8_t&, atom_value&, meta::omittable_if_empty_t,
message&)>;
// -- constructors, destructors, and assignment operators --------------------
error() noexcept;
......@@ -131,12 +139,12 @@ public:
const message& context() const noexcept;
/// Returns `*this != none`.
explicit operator bool() const noexcept {
inline explicit operator bool() const noexcept {
return data_ != nullptr;
}
/// Returns `*this == none`.
bool operator!() const noexcept {
inline bool operator!() const noexcept {
return data_ == nullptr;
}
......@@ -146,14 +154,6 @@ public:
// -- modifiers --------------------------------------------------------------
/// Returns the category-specific error code, whereas `0` means "no error".
/// @pre `*this != none`
uint8_t& code() noexcept;
/// Returns the category of this error.
/// @pre `*this != none`
atom_value& category() noexcept;
/// Returns context information to this error.
/// @pre `*this != none`
message& context() noexcept;
......@@ -161,74 +161,45 @@ public:
/// Sets the error code to 0.
void clear() noexcept;
/// Assigns new code and category to this error.
void assign(uint8_t code, atom_value category);
/// Assigns new code, category and context to this error.
void assign(uint8_t code, atom_value category, message context);
// -- static convenience functions -------------------------------------------
/// @cond PRIVATE
static error eval() {
static inline error eval() {
return none;
}
template <class F, class... Fs>
static error eval(F&& f, Fs&&... fs) {
if (auto err = f())
return err;
return eval(std::forward<Fs>(fs)...);
auto x = f();
return x ? x : eval(std::forward<Fs>(fs)...);
}
/// @endcond
// -- nested classes ---------------------------------------------------------
struct data;
// -- friend functions -------------------------------------------------------
struct inspect_helper {
uint8_t code;
error& err;
};
template <class Inspector>
friend typename Inspector::result_type inspect(Inspector& f, error& x) {
auto fun = [&](meta::type_name_t x0, uint8_t& x1, atom_value& x2,
meta::omittable_if_empty_t x3,
message& x4) -> error { return f(x0, x1, x2, x3, x4); };
return x.apply(fun);
}
private:
// -- member variables -------------------------------------------------------
// -- inspection support -----------------------------------------------------
data* data_;
};
error apply(const inspect_fun& f);
// -- operators and free functions ---------------------------------------------
// -- nested classes ---------------------------------------------------------
/// @relates error
template <class Inspector>
detail::enable_if_t<Inspector::reads_state, typename Inspector::result_type>
inspect(Inspector& f, const error& x) {
if (x)
return f(meta::type_name("error"), x.code(), x.category(),
meta::omittable_if_empty(), x.context());
return f(meta::type_name("error"), uint8_t{0});
}
struct data;
template <class Inspector>
detail::enable_if_t<Inspector::writes_state, typename Inspector::result_type>
inspect(Inspector& f, error::inspect_helper& x) {
if (x.code == 0) {
x.err.clear();
return f();
}
x.err.assign(x.code, atom(""));
return f(x.err.category(), x.err.context());
}
// -- member variables -------------------------------------------------------
/// @relates error
template <class Inspector>
detail::enable_if_t<Inspector::writes_state, typename Inspector::result_type>
inspect(Inspector& f, error& x) {
error::inspect_helper helper{0, x};
return f(helper.code, helper);
}
data* data_;
};
/// @relates error
std::string to_string(const error& x);
......
......@@ -18,11 +18,11 @@
#include "caf/error.hpp"
#include <utility>
#include "caf/config.hpp"
#include "caf/deep_to_string.hpp"
#include "caf/make_message.hpp"
#include "caf/deserializer.hpp"
#include "caf/message.hpp"
#include "caf/serializer.hpp"
namespace caf {
......@@ -55,11 +55,8 @@ error& error::operator=(error&& x) noexcept {
return *this;
}
error::error(const error& x) {
if (x)
data_ = new data(*x.data_);
else
data_ = nullptr;
error::error(const error& x) : data_(x ? new data(*x.data_) : nullptr) {
// nop
}
error& error::operator=(const error& x) {
......@@ -76,7 +73,8 @@ error& error::operator=(const error& x) {
return *this;
}
error::error(uint8_t x, atom_value y) : error(x, y, make_message()) {
error::error(uint8_t x, atom_value y)
: data_(x != 0 ? new data{x, y, none} : nullptr) {
// nop
}
......@@ -141,16 +139,6 @@ int error::compare(uint8_t x, atom_value y) const noexcept {
// -- modifiers --------------------------------------------------------------
uint8_t& error::code() noexcept {
CAF_ASSERT(data_ != nullptr);
return data_->code;
}
atom_value& error::category() noexcept {
CAF_ASSERT(data_ != nullptr);
return data_->category;
}
message& error::context() noexcept {
CAF_ASSERT(data_ != nullptr);
return data_->context;
......@@ -163,27 +151,25 @@ void error::clear() noexcept {
}
}
void error::assign(uint8_t code, atom_value category) {
return assign(code, category, make_message());
}
// -- inspection support -----------------------------------------------------
void error::assign(uint8_t code, atom_value category, message context) {
if (data_ == nullptr) {
data_ = new data{code, category, std::move(context)};
} else {
data_->code = code;
data_->category = category;
data_->context = std::move(context);
}
error error::apply(const inspect_fun& f) {
data tmp{0, atom(""), message{}};
data& ref = data_ != nullptr ? *data_ : tmp;
auto result = f(meta::type_name("error"), ref.code, ref.category,
meta::omittable_if_empty(), ref.context);
if (ref.code == 0)
clear();
else if (&tmp == &ref)
data_ = new data(std::move(tmp));
return result;
}
// -- operators and free functions ---------------------------------------------
std::string to_string(const error& x) {
if (!x)
return "none";
deep_to_string_t f;
return inspect(f, x);
return deep_to_string(meta::type_name("error"), x.code(), x.category(),
meta::omittable_if_empty(), x.context());
}
} // namespace caf
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