Commit 6ebea452 authored by Dominik Charousset's avatar Dominik Charousset

Streamline fold expression in the data_processor

parent 772bebef
...@@ -475,76 +475,43 @@ public: ...@@ -475,76 +475,43 @@ public:
return none; return none;
} }
static_assert(__cpp_fold_expressions, "C++ fold-expressions required"); #if defined(__cpp_fold_expressions) && defined(__cpp_if_constexpr)
#if __cpp_fold_expressions
template <class F> inline
error safe_callback_action(meta::save_callback_t<F> x) {
return Derived::reads_state ? x.fun() : none;
}
template <class F> inline
error load_callback_action(meta::load_callback_t<F> x) {
return Derived::writes_state ? x.fun() : none;
}
inline
error annotation_action(const meta::annotation&) {
return none;
}
template<typename T> inline
typename std::enable_if<is_allowed_unsafe_message_type<T>::value, error>::type
allowed_unsafe_message_type_action(const T&) {
return none;
}
template <class T> inline
typename std::enable_if<!meta::is_annotation<T>::value && !is_allowed_unsafe_message_type<T>::value, error>::type
action(T&& x) {
static_assert(Derived::reads_state || (!std::is_rvalue_reference<T&&>::value && !std::is_const<typename std::remove_reference<T>::type>::value), "a loading inspector requires mutable lvalue references");
return apply(deconst(x));
}
struct FoldLeft {
Derived& derived;
error err = none;
template<class F> inline
FoldLeft& operator<<(meta::save_callback_t<F> x) {
if (not err) err = derived.safe_callback_action(std::move(x));
return *this;
}
template<class F> inline
FoldLeft& operator<<(meta::load_callback_t<F> x) {
if (not err) err = derived.load_callback_action(std::move(x));
return *this;
}
inline
FoldLeft& operator<<(const meta::annotation& x) {
if (not err) err = derived.annotation_action(x);
return *this;
}
template<typename T> inline
typename std::enable_if<is_allowed_unsafe_message_type<T>::value, FoldLeft&>::type
operator<<(const T& x) {
if (not err) err = derived.allowed_unsafe_message_type_action(x);
return *this;
}
template<typename T> inline
typename std::enable_if<!meta::is_annotation<T>::value && !is_allowed_unsafe_message_type<T>::value, FoldLeft&>::type
operator<<(T&& x) {
if (not err) err = derived.action(std::forward<T>(x));
return *this;
}
};
template <class... Ts> inline template <class... Ts> inline
error operator()(Ts&&... xs) { error operator()(Ts&&... xs) {
return (FoldLeft{dref()} << ... << xs).err; error result;
auto f = [&result, this](auto&& x) {
using type = detail::decay_t<decltype(x)>;
if constexpr (meta::is_save_callback<type>::value) {
if constexpr (Derived::reads_state)
if (auto err = x.fun()) {
result = std::move(err);
return false;
}
} else if constexpr (meta::is_load_callback<type>::value) {
if constexpr (Derived::writes_state)
if (auto err = x.fun()) {
result = std::move(err);
return false;
}
} else if constexpr (meta::is_annotation<type>::value
|| is_allowed_unsafe_message_type<type>::value) {
// skip element
} else {
if (auto err = dref().apply(deconst(x))) {
result = std::move(err);
return false;
}
}
return true;
};
if ((f(std::forward<Ts>(xs)) && ...))
return none;
return result;
} }
#else // __cpp_fold_expressions #else // defined(__cpp_fold_expressions) && defined(__cpp_if_constexpr)
template <class F, class... Ts> template <class F, class... Ts>
error operator()(meta::save_callback_t<F> x, Ts&&... xs) { error operator()(meta::save_callback_t<F> x, Ts&&... xs) {
// TODO: use `if constexpr` when switching to C++17. // TODO: use `if constexpr` when switching to C++17.
...@@ -594,7 +561,8 @@ public: ...@@ -594,7 +561,8 @@ public:
return err; return err;
return dref()(std::forward<Ts>(xs)...); return dref()(std::forward<Ts>(xs)...);
} }
#endif // __cpp_fold_expressions
#endif // defined(__cpp_fold_expressions) && defined(__cpp_if_constexpr)
protected: protected:
virtual error apply_impl(int8_t&) = 0; virtual error apply_impl(int8_t&) = 0;
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#pragma once #pragma once
#include <type_traits>
#include "caf/meta/annotation.hpp" #include "caf/meta/annotation.hpp"
namespace caf { namespace caf {
...@@ -36,6 +38,12 @@ struct load_callback_t : annotation { ...@@ -36,6 +38,12 @@ struct load_callback_t : annotation {
F fun; F fun;
}; };
template <class T>
struct is_load_callback : std::false_type {};
template <class F>
struct is_load_callback<load_callback_t<F>> : std::true_type {};
/// Returns an annotation that allows inspectors to call /// Returns an annotation that allows inspectors to call
/// user-defined code after performing load operations. /// user-defined code after performing load operations.
template <class F> template <class F>
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#pragma once #pragma once
#include <type_traits>
#include "caf/meta/annotation.hpp" #include "caf/meta/annotation.hpp"
namespace caf { namespace caf {
...@@ -36,6 +38,12 @@ struct save_callback_t : annotation { ...@@ -36,6 +38,12 @@ struct save_callback_t : annotation {
F fun; F fun;
}; };
template <class T>
struct is_save_callback : std::false_type {};
template <class F>
struct is_save_callback<save_callback_t<F>> : std::true_type {};
/// Returns an annotation that allows inspectors to call /// Returns an annotation that allows inspectors to call
/// user-defined code after performing save operations. /// user-defined code after performing save operations.
template <class F> template <class F>
......
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