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

Streamline fold expression in the data_processor

parent 772bebef
......@@ -475,76 +475,43 @@ public:
return none;
}
static_assert(__cpp_fold_expressions, "C++ fold-expressions required");
#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;
}
};
#if defined(__cpp_fold_expressions) && defined(__cpp_if_constexpr)
template <class... Ts> inline
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>
error operator()(meta::save_callback_t<F> x, Ts&&... xs) {
// TODO: use `if constexpr` when switching to C++17.
......@@ -594,7 +561,8 @@ public:
return err;
return dref()(std::forward<Ts>(xs)...);
}
#endif // __cpp_fold_expressions
#endif // defined(__cpp_fold_expressions) && defined(__cpp_if_constexpr)
protected:
virtual error apply_impl(int8_t&) = 0;
......
......@@ -18,6 +18,8 @@
#pragma once
#include <type_traits>
#include "caf/meta/annotation.hpp"
namespace caf {
......@@ -36,6 +38,12 @@ struct load_callback_t : annotation {
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
/// user-defined code after performing load operations.
template <class F>
......
......@@ -18,6 +18,8 @@
#pragma once
#include <type_traits>
#include "caf/meta/annotation.hpp"
namespace caf {
......@@ -36,6 +38,12 @@ struct save_callback_t : annotation {
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
/// user-defined code after performing save operations.
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