1 #ifndef SERIALIZE_META_HH
2 #define SERIALIZE_META_HH
12 #include <type_traits>
35 template<
typename TUPLE>
37 DoInstantiate<std::tuple_size<TUPLE>::value, TUPLE> inst;
42 template<
int I,
typename TUPLE>
struct DoInstantiate;
43 template<
typename TUPLE>
struct DoInstantiate<0, TUPLE> {
45 return make_unique<T>();
48 template<
typename TUPLE>
struct DoInstantiate<1, TUPLE> {
50 return make_unique<T>(std::get<0>(args));
53 template<
typename TUPLE>
struct DoInstantiate<2, TUPLE> {
55 return make_unique<T>(
56 std::get<0>(args), std::get<1>(args));
59 template<
typename TUPLE>
struct DoInstantiate<3, TUPLE> {
61 return make_unique<T>(
62 std::get<0>(args), std::get<1>(args),
87 template<
typename T>
struct PolymorphicConstructorArgs;
92 template<
typename T>
struct PolymorphicBaseClass;
96 typedef typename PolymorphicConstructorArgs<Base>::type
TUPLEIn;
99 return std::make_tuple();
104 typedef typename PolymorphicConstructorArgs<Base>::type
TUPLEIn;
105 typedef typename PolymorphicConstructorArgs<Derived>::type
TUPLEOut;
107 "constructor argument types must match");
127 :
if_<std::is_same<std::tuple<>,
128 typename PolymorphicConstructorArgs<Derived>::type>,
129 MapConstrArgsEmpty<Base>,
130 MapConstrArgsCopy<Base, Derived>> {};
138 template<
typename Base>
struct BaseClassName;
144 virtual void save(Archive& ar,
const void* p)
const = 0;
151 virtual void*
load(Archive& ar,
unsigned id,
const void* args)
const = 0;
158 virtual void init(Archive& ar,
void* t,
unsigned id)
const = 0;
161 template<
typename Archive,
typename T>
169 virtual void save(Archive& ar,
const void* v)
const
171 typedef typename PolymorphicBaseClass<T>::type BaseType;
172 auto base =
static_cast<const BaseType*
>(v);
173 auto tp =
static_cast<const T*
>(base);
175 saver(ar, *tp,
true, name,
true);
181 template<
typename Archive,
typename T>
185 virtual void*
load(Archive& ar,
unsigned id,
const void* args)
const
187 typedef typename PolymorphicBaseClass<T>::type BaseType;
188 typedef typename PolymorphicConstructorArgs<BaseType>::type TUPLEIn;
189 typedef typename PolymorphicConstructorArgs<T>::type TUPLEOut;
190 auto& argsIn = *
static_cast<const TUPLEIn*
>(args);
192 TUPLEOut argsOut = mapArgs(argsIn);
194 return loader(ar,
id, argsOut);
198 void polyInitError(
const char* expected,
const char* actual);
199 template<
typename Archive,
typename T>
203 virtual void init(Archive& ar,
void* v,
unsigned id)
const
205 typedef typename PolymorphicBaseClass<T>::type BaseType;
206 auto base =
static_cast<BaseType*
>(v);
207 if (
unlikely(dynamic_cast<T*>(base) != static_cast<T*>(base))) {
210 auto t =
static_cast<T*
>(base);
212 loader(ar, *t, std::make_tuple(),
id);
217 template<
typename Archive>
226 "must be a polymorphic type");
228 "can't be an abstract type");
229 registerHelper(
typeid(T),
233 template<
typename T>
static void save(Archive& ar, T* t)
235 save(ar, t,
typeid(*t));
237 template<
typename T>
static void save(
const char* tag, Archive& ar, T& t)
239 save(tag, ar, &t,
typeid(t));
245 void registerHelper(
const std::type_info& type,
247 static void save(Archive& ar,
const void* t,
248 const std::type_info& typeInfo);
249 static void save(
const char* tag, Archive& ar,
const void* t,
250 const std::type_info& typeInfo);
252 std::map<TypeInfo, std::unique_ptr<PolymorphicSaverBase<Archive>>>
256 template<
typename Archive>
265 "must be a polymorphic type");
267 "can't be an abstract type");
272 static void*
load(Archive& ar,
unsigned id,
const void* args);
284 template<
typename Archive>
293 "must be a polymorphic type");
295 "can't be an abstract type");
300 static void init(
const char* tag, Archive& ar,
void* t);
319 template registerClass<T>(name);
327 template registerClass<T>(name);
335 template registerClass<T>(name);
339 #define REGISTER_CONSTRUCTOR_ARGS_0(C) \
340 template<> struct PolymorphicConstructorArgs<C> \
341 { typedef std::tuple<> type; };
343 #define REGISTER_CONSTRUCTOR_ARGS_1(C,T1) \
344 template<> struct PolymorphicConstructorArgs<C> \
345 { typedef std::tuple<T1> type; };
347 #define REGISTER_CONSTRUCTOR_ARGS_2(C,T1,T2) \
348 template<> struct PolymorphicConstructorArgs<C> \
349 { typedef std::tuple<T1,T2> type; };
351 #define REGISTER_CONSTRUCTOR_ARGS_3(C,T1,T2,T3) \
352 template<> struct PolymorphicConstructorArgs<C> \
353 { typedef std::tuple<T1,T2,T3> type; };
355 class MemInputArchive;
356 class MemOutputArchive;
357 class XmlInputArchive;
358 class XmlOutputArchive;
368 #define REGISTER_POLYMORPHIC_CLASS_HELPER(B,C,N) \
369 static_assert(std::is_base_of<B,C>::value, "must be base and sub class"); \
370 static RegisterLoaderHelper<MemInputArchive, C> registerHelper3##C(N); \
371 static RegisterSaverHelper <MemOutputArchive, C> registerHelper4##C(N); \
372 static RegisterLoaderHelper<XmlInputArchive, C> registerHelper5##C(N); \
373 static RegisterSaverHelper <XmlOutputArchive, C> registerHelper6##C(N); \
374 template<> struct PolymorphicBaseClass<C> { typedef B type; };
376 #define REGISTER_POLYMORPHIC_INITIALIZER_HELPER(B,C,N) \
377 static_assert(std::is_base_of<B,C>::value, "must be base and sub class"); \
378 static RegisterInitializerHelper<MemInputArchive, C> registerHelper3##C(N); \
379 static RegisterSaverHelper <MemOutputArchive, C> registerHelper4##C(N); \
380 static RegisterInitializerHelper<XmlInputArchive, C> registerHelper5##C(N); \
381 static RegisterSaverHelper <XmlOutputArchive, C> registerHelper6##C(N); \
382 template<> struct PolymorphicBaseClass<C> { typedef B type; };
384 #define REGISTER_BASE_NAME_HELPER(B,N) \
385 template<> struct BaseClassName<B> \
386 { static const char* getName() { static const char* name = N; return name; } };
391 #define REGISTER_POLYMORPHIC_CLASS(BASE,CLASS,NAME) \
392 REGISTER_POLYMORPHIC_CLASS_HELPER(BASE,CLASS,NAME) \
393 REGISTER_CONSTRUCTOR_ARGS_0(CLASS)
395 #define REGISTER_POLYMORPHIC_CLASS_1(BASE,CLASS,NAME,TYPE1) \
396 REGISTER_POLYMORPHIC_CLASS_HELPER(BASE,CLASS,NAME) \
397 REGISTER_CONSTRUCTOR_ARGS_1(CLASS,TYPE1)
399 #define REGISTER_POLYMORPHIC_CLASS_2(BASE,CLASS,NAME,TYPE1,TYPE2) \
400 REGISTER_POLYMORPHIC_CLASS_HELPER(BASE,CLASS,NAME) \
401 REGISTER_CONSTRUCTOR_ARGS_2(CLASS,TYPE1,TYPE2)
403 #define REGISTER_POLYMORPHIC_CLASS_3(BASE,CLASS,NAME,TYPE1,TYPE2,TYPE3) \
404 REGISTER_POLYMORPHIC_CLASS_HELPER(BASE,CLASS,NAME) \
405 REGISTER_CONSTRUCTOR_ARGS_3(CLASS,TYPE1,TYPE2,TYPE3)
407 #define REGISTER_BASE_CLASS(CLASS,NAME) \
408 REGISTER_BASE_NAME_HELPER(CLASS,NAME) \
409 REGISTER_CONSTRUCTOR_ARGS_0(CLASS)
411 #define REGISTER_BASE_CLASS_1(CLASS,NAME,TYPE1) \
412 REGISTER_BASE_NAME_HELPER(CLASS,NAME) \
413 REGISTER_CONSTRUCTOR_ARGS_1(CLASS,TYPE1)
415 #define REGISTER_BASE_CLASS_2(CLASS,NAME,TYPE1,TYPE2) \
416 REGISTER_BASE_NAME_HELPER(CLASS,NAME) \
417 REGISTER_CONSTRUCTOR_ARGS_2(CLASS,TYPE1,TYPE2)
419 #define REGISTER_BASE_CLASS_3(CLASS,NAME,TYPE1,TYPE2,TYPE3) \
420 REGISTER_BASE_NAME_HELPER(CLASS,NAME) \
421 REGISTER_CONSTRUCTOR_ARGS_3(CLASS,TYPE1,TYPE2,TYPE3)
424 #define REGISTER_POLYMORPHIC_INITIALIZER(BASE,CLASS,NAME) \
425 REGISTER_POLYMORPHIC_INITIALIZER_HELPER(BASE,CLASS,NAME)
446 static const unsigned value = 1;
448 #define SERIALIZE_CLASS_VERSION(CLASS, VERSION) \
449 template<> struct SerializeClassVersion<CLASS> \
451 static const unsigned value = VERSION; \