-
Notifications
You must be signed in to change notification settings - Fork 0
/
Serialize.h
139 lines (108 loc) · 4.44 KB
/
Serialize.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
* File: Serialize.h
* Author: michal
*
* Created on March 1, 2016, 2:25 AM
*/
#ifndef SERIALIZE_H
#define SERIALIZE_H
#include "Stream.h"
#include "Memberwise.h"
#include <type_traits>
template <class Format>
struct serialization_purpose {};
template <class Format>
struct deserialization_purpose {};
namespace Serialize
{
struct no_member_serialize {};
}
template <class Type, class Format> struct member_list<Type, serialization_purpose<Format>> : member_ptr_list<>, Serialize::no_member_serialize {};
template <class Type, class Format> struct member_list<Type, deserialization_purpose<Format>> : member_list<Type, serialization_purpose<Format>> {};
namespace Serialize
{
template <class Format>
struct ISerializable
{
virtual void serialize(IOutputStream &out) const=0;
};
template <class Format>
struct IDeserializable
{
virtual void deserialize(IInputStream &in)=0;
};
template <class Format, class T>
struct is_serializable : std::is_base_of<ISerializable<Format>, T> {};
template <class Format, class T>
struct is_deserializable : std::is_base_of<ISerializable<Format>, T> {};
template <class Format, class Type>
struct is_memberwise_serializable : std::integral_constant<bool, !std::is_base_of<no_member_serialize, member_list<Type, serialization_purpose<Format>>>::value> {};
template <class Format, class Type>
struct is_memberwise_deserializable : std::integral_constant<bool, !std::is_base_of<no_member_serialize, member_list<Type, deserialization_purpose<Format>>>::value> {};
// Default serializers must be implemented per format
template <class Format, class T>
struct DefaultSerializer;
template <class Format, class T>
struct DefaultDeserializer;
// Generic serialization follows the inference path:
// - if type implements ISerializable/IDeserializable - use it
// - if type defines a member list for serialization purpose with this format - use it
// - otherwise, use a "DefaultSerializer".
// All of the above can be cut short by specializing Serializer for given type/format pair.
template <class Format, class T, bool IsMemberwise = is_memberwise_serializable<Format, T>::value>
struct SerializerCheckMemberwise : DefaultDeserializer<Format, T> {};
template <class Format, class T, bool IsMemberwise = is_memberwise_deserializable<Format, T>::value>
struct DeserializerCheckMemberwise : DefaultDeserializer<Format, T> {};
template <class Format, class T, bool IsSerializable = is_serializable<Format, T>::value>
struct SerializerCheckInterface : SerializerCheckMemberwise<Format, T> {};
template <class Format, class T, bool IsDeserializable = is_deserializable<Format, T>::value>
struct DeserializerCheckInterface : DeserializerCheckMemberwise<Format, T> {};
template <class Format, class T>
struct GenericSerializer : SerializerCheckInterface<Format, T> {};
template <class Format, class T>
struct GenericDeserializer : DeserializerCheckInterface<Format, T> {};
template <class Format, class T>
struct SerializerCheckInterface<Format, T, true>
{
void serialize(IOutputStream &out, const T &object)
{
object.serialize(out);
}
};
template <class Format, class T>
struct DeserializerCheckInterface<Format, T, true>
{
void deserialize(IInputStream &in, T &object)
{
object.deserialize(in);
}
};
template <class Format, class T>
struct Serializer : GenericSerializer<Format, T> {};
template <class Format, class T>
struct Deserializer : GenericSerializer<Format, T> {};
template <class Format, class T>
Serializer<Format, T> GetSerializer(const T &data)
{
return Serializer<Format, T>();
}
template <class Format, class T>
Deserializer<Format, T> GetDeserializer(T &data)
{
return Deserializer<Format, T>();
}
template <class Format, class T>
FormattedOStream<Format> operator<<(FormattedOStream<Format> os, const T &data)
{
GetSerializer<Format>(data).serialize(os, data);
return os;
}
template <class Format, class T>
FormattedIStream<Format> operator>>(FormattedIStream<Format> is, T &data)
{
GetDeserializer<Format>(data).deserialize(is, data);
return is;
}
};
#include "MemberwiseSerializer.h"
#endif /* SERIALIZE_H */