Reputation: 12777
I've implemented a template<typename T> Serializer
that works on any trivially copyable object of type T
, just serializing sizeof(T)
bytes.
Then I've implemented a couple of (partial) specializations for other types of interest, like std::vector<T>
and std::bacis_string<T>
. For other types, I trigger a static_assert(is_trivially_copyable<T>::type, "Unsupported type");
.
This is not what I want, because I want to avoid serializing, for example, types with naked pointers, like:
struct C_style_vector{
size_t size;
int* ptr;
};
For such kind of types, I assume that the user will define an ad hoc specialization. Conversely, as far as now my Serializer
doesn't work with a type like this:
struct Simple_type{
double d;
std::vector<int> v;
};
even though every member of Simple_type
is serializable by my class.
So, how can I catch types with naked pointers? And how can I tell my serializer to serialize types composed only by serializable members, serializing it member by member?
Upvotes: 3
Views: 240
Reputation: 55897
It is not actually simple and cannot be done in C++, without some users additions, since there is no reflection in C++.
You can use something like boost::fusion, but user should use fusion sequences in this case. The best way is that uses boost::serialization I think, user MUST provide serialize/deserialize
functions for own types.
Example with fusion.
template<bool Value, typename Next, typename Last>
struct is_serializable_impl
{
private:
static const bool cvalue = !boost::is_pointer<
typename boost::remove_reference<
typename boost::fusion::result_of::deref<Next>::type>::type>::value;
public:
static const bool value = Value && is_serializable_impl<
cvalue, typename boost::fusion::result_of::next<Next>::type, Last>::value;
};
template<bool Value, typename Last>
struct is_serializable_impl<Value, Last, Last>
{
static const bool value = Value;
};
template<typename T>
struct is_serializable :
is_serializable_impl<true, typename boost::fusion::result_of::begin<T>::type,
typename boost::fusion::result_of::end<T>::type>
{
};
template<typename T, typename = void>
struct serializer;
template<typename T>
struct serializer<T,
typename boost::enable_if<typename
boost::fusion::traits::is_sequence<T>::type>::type>
{
static_assert(is_serializable<T>::value, "Not serializable");
};
Upvotes: 4