Commit 329f45ff authored by Dominik Charousset's avatar Dominik Charousset

Merge pull request #452 from actor-framework/topic/serialization-tweaks

Enhance serialization framework
parents a73e1f42 058d2a1a
......@@ -52,11 +52,21 @@ namespace detail {
// to enable both ADL and picking up existing boost code.
template <class Processor, class U>
void delegate_serialize(Processor& proc, U& x) {
auto delegate_serialize(Processor& proc, U& x)
-> decltype(serialize(proc, x, 0)) {
using namespace boost::serialization;
serialize(proc, x, 0);
}
// Calls `serialize(...)` without the unused version argument, which CAF
// ignores anyway.
template <class Processor, class U>
auto delegate_serialize(Processor& proc, U& x)
-> decltype(serialize(proc, x)) {
serialize(proc, x);
}
} // namespace detail
} // namespace caf
......
......@@ -258,66 +258,38 @@ struct is_tuple<std::tuple<Ts...>> : std::true_type { };
template <class F, class S>
struct is_tuple<std::pair<F, S>> : std::true_type { };
/// Checks whether `T` provides a free
/// `serialize(Processor&, T&, const unsigned int)` function.
template <class T>
struct has_free_serialize {
private:
// check for free function
template <class C,
class E = decltype(serialize(std::declval<serializer&>(),
std::declval<C&>(), 0))>
static bool sfinae_fun(C*) {
return true;
}
static void sfinae_fun(void*) {
// nop
}
using type = typename std::remove_const<T>::type;
using result_type = decltype(sfinae_fun(static_cast<type*>(nullptr)));
public:
static constexpr bool value = std::is_same<bool, result_type>::value;
};
/// Checks whether `T` provides a member
/// `T::serialize(Processor&, const unsigned int)` function.
template <class T>
struct has_member_serialize {
private:
// check for free function
template <class C,
class E = decltype(std::declval<C&>()
.serialize(std::declval<serializer&>(), 0))>
static bool sfinae_fun(C*) {
return true;
}
/// Checks whether `T` provides either a free function or a member function for
/// serialization. The following signatures are tested:
///
/// - `serialize(Processor&, T&, const unsigned int)`
/// - `serialize(Processor&, T&)`
/// - `T::serialize(Processor&, const unsigned int)`.
/// - `T::serialize(Processor&)`.
template <class T,
bool Ignore = std::is_pointer<T>::value
|| std::is_function<T>::value>
struct has_serialize {
template <class U>
static auto test(caf::serializer* sink, U* x)
-> decltype(serialize(*sink, *x, 0u), std::true_type());
static void sfinae_fun(void*) {
// nop
}
template <class U>
static auto test(caf::serializer* sink, U* x)
-> decltype(serialize(*sink, *x), std::true_type());
using type = typename std::remove_const<T>::type;
template <class U>
static auto test(caf::serializer* sink, U* x)
-> decltype(x->serialize(*sink, 0u), std::true_type());
using result_type = decltype(sfinae_fun(static_cast<type*>(nullptr)));
template <class U>
static auto test(caf::serializer* sink, U* x)
-> decltype(x->serialize(*sink), std::true_type());
public:
static constexpr bool value = std::is_same<bool, result_type>::value;
};
template <class>
static auto test(...) -> std::false_type;
/// Checks whether `T` provides either a free function
/// `serialize(Processor&, T&, const unsigned int)` or a member function
/// `T::serialize(Processor&, const unsigned int)`. If `T` is iterable,
/// then the template checks whether `T::value_type` is serializable.
template <class T,
bool Ignore = std::is_pointer<T>::value
|| std::is_function<T>::value>
struct has_serialize {
static constexpr bool value = has_free_serialize<T>::value
|| has_member_serialize<T>::value;
using type = decltype(test<T>(nullptr, nullptr));
static constexpr bool value = type::value;
};
template <class T>
......
......@@ -74,7 +74,7 @@ struct raw_struct {
};
template <class Processor>
void serialize(Processor& proc, raw_struct& x, const unsigned int) {
void serialize(Processor& proc, raw_struct& x) {
proc & x.str;
}
......
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