uLib-0.2
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Serializable.h
Go to the documentation of this file.
1 /*//////////////////////////////////////////////////////////////////////////////
2 // CMT Cosmic Muon Tomography project //////////////////////////////////////////
4 
5  Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
6  All rights reserved
7 
8  Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
9 
10  ------------------------------------------------------------------
11  This library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU Lesser General Public
13  License as published by the Free Software Foundation; either
14  version 3.0 of the License, or (at your option) any later version.
15 
16  This library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  Lesser General Public License for more details.
20 
21  You should have received a copy of the GNU Lesser General Public
22  License along with this library.
23 
25 
26 
27 
28 #ifndef U_SERIALIZABLE_H
29 #define U_SERIALIZABLE_H
30 
31 /* Serialization:
32 
33 
34 
35 TODO:
36 * Problema nella serializzazione delle properties in test_archive
37 * implementare human readable make_hrp ... non riesco..
38 
39 */
40 
41 
42 
43 
44 #include <boost/serialization/access.hpp>
45 #include <boost/serialization/export.hpp>
46 
47 #include <boost/mpl/for_each.hpp>
48 #include <boost/mpl/remove_if.hpp>
49 #include <boost/serialization/nvp.hpp>
50 
51 //#include <boost/archive/xml_iarchive.hpp>
52 //#include <boost/archive/xml_oarchive.hpp>
53 //#include <boost/archive/text_iarchive.hpp>
54 //#include <boost/archive/text_oarchive.hpp>
55 //#include "boost/archive/polymorphic_iarchive.hpp"
56 //#include "boost/archive/polymorphic_oarchive.hpp"
57 
58 #include <boost/preprocessor/comma_if.hpp>
59 #include <boost/preprocessor/repeat.hpp>
60 #include <boost/preprocessor/inc.hpp>
61 #include <boost/preprocessor/cat.hpp>
62 #include <boost/preprocessor/tuple/to_seq.hpp>
63 
64 
65 #include "Core/Mpl.h"
66 #include "Core/ObjectProps.h"
67 #include "Core/Archives.h"
68 #include "Core/Export.h"
69 
70 
71 
75 // BOOST SERIALIZATION ADD-ON
76 
77 namespace boost {
78 namespace serialization {
79 
80 // ACCESS 2 //
81 template <class T> struct access2 {};
82 
83 
84 // NON FUNZIONA ... SISTEMARE !!!! // ------------------------------------------
85 template<class T>
86 class hrp :
87  public wrapper_traits<const hrp< T > >
88 {
89  const char *m_name;
90  T *m_value;
91  std::string *m_str;
92 
93 public:
94  explicit hrp(const char * name_, T &t) :
95  m_str(new std::string),
96  m_name(name_), m_value(&t) {}
97 
98  const char * name() const {
99  return this->m_name;
100  }
101 
102 
103  template<class Archivex>
104  void save( Archivex & ar, const unsigned int /* file_version */) const {
106  // std::stringstream ss;
107  // uLib::Archive::hrt_oarchive har(ss);
108  // har << make_nvp(m_name,*m_value);
109  // // (*m_str) = ss.str();
111  }
112  template<class Archivex>
113  void load( Archivex & ar, const unsigned int /* file_version */) {
114 // ar.operator>>(value());
115  }
116  BOOST_SERIALIZATION_SPLIT_MEMBER()
117 };
118 
119 
120 template<class T>
121 inline
122 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
123 const
124 #endif
125 hrp< T > make_hrp(const char * name, T & t){
126  return hrp< T >(name, t);
127 }
128 
129 #define HRP(name) \
130  boost::serialization::make_hrp(BOOST_PP_STRINGIZE(name), name)
131 
132 
133 } // serialization
134 } // boost
135 
136 
137 
138 
139 
140 
150 // ULIB SERIALIZATION
151 
152 namespace uLib {
153 
154 
155 
156 #define _AR_OP(r,data,elem) data&BOOST_SERIALIZATION_BASE_OBJECT_NVP(elem);
157 
158 #define NVP(data) BOOST_SERIALIZATION_NVP(data)
159 
163 // SERIALIZTION MACROS //
164 
165 // !!! WARNING !!! INTRUSIVE SERIALIZATION IS ACTUALLY NOT WORKING FEATURE
166 // SO LEAVE ULIB_CFG_INTRUSIVE_SERIALIZATION NOT DEFINED
167 
168 #ifdef ULIB_CFG_INTRUSIVE_SERIALIZATION_OBJECT
169 # define ULIB_SERIALIZABLE_OBJECT _ULIB_DETAIL_INTRUSIVE_SERIALIZABLE_OBJECT
170 # define ULIB_SERIALIZE_OBJECT(_Ob,...) _ULIB_DETAIL_INTRUSIVE_SERIALIZE_OBJECT(_Ob,__VA_ARGS__)
171 # define _AR_(_name) _ULIB_DETAIL_INTRUSIVE_AR_(_name)
172 #else
173 # define ULIB_SERIALIZABLE(_Ob) _ULIB_DETAIL_UNINTRUSIVE_SERIALIZABLE(_Ob) \
174  ULIB_CLASS_EXPORT_KEY(_Ob)
175 # define ULIB_SERIALIZE(_Ob,...) _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE(_Ob)
176 # define ULIB_SERIALIZE_DERIVED(_Ob,...) _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_DERIVED(_Ob,__VA_ARGS__)
177 # define ULIB_SERIALIZABLE_OBJECT(_Ob) _ULIB_DETAIL_UNINTRUSIVE_SERIALIZABLE_OBJECT(_Ob) \
178  ULIB_CLASS_EXPORT_OBJECT_KEY(_Ob)
179 # define ULIB_SERIALIZE_OBJECT(_Ob,...) _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_OBJECT(_Ob,__VA_ARGS__)
180 # define ULIB_SERIALIZE_OBJECT_PROPS(_Ob) _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_PROPS(_Ob)
181 # define AR(_name) _ULIB_DETAIL_UNINTRUSIVE_AR_(_name)
182 # define HR(_name) _ULIB_DETAIL_UNINTRUSIVE_AR_(_name)
183 #endif
184 
185 
186 #define ULIB_SERIALIZE_ACCESS \
187  friend class boost::serialization::access; \
188  template <class T> friend class boost::serialization::access2;
189 
190 #define ULIB_CLASS_EXPORT_KEY(_FullNamespaceClass) \
191  BOOST_CLASS_EXPORT_KEY(_FullNamespaceClass)
192 
193 #define ULIB_CLASS_EXPORT_OBJECT_KEY(_FullNamespaceClass) \
194  BOOST_CLASS_EXPORT_KEY(_FullNamespaceClass) \
195  BOOST_CLASS_EXPORT_KEY(_FullNamespaceClass::ObjectProps) \
196  BOOST_CLASS_EXPORT_KEY(uLib::ObjectPropsImpl<_FullNamespaceClass>)
197 
198 
199 #define _SERIALIZE_IMPL_SEQ \
200  (uLib::Archive::text_iarchive) \
201  (uLib::Archive::text_oarchive) \
202  (uLib::Archive::hrt_iarchive) \
203  (uLib::Archive::hrt_oarchive) \
204  (uLib::Archive::xml_iarchive) \
205  (uLib::Archive::xml_oarchive) \
206  (uLib::Archive::log_archive)
207 
208 
210 #define _ULIB_DETAIL_SPECIALIZE_IS_VIRTUAL_BASE(_Base,_Derived) namespace boost{ template<> struct is_virtual_base_of<_Base,_Derived>: public boost::mpl::true_ {}; }
211 #define _ULIB_DETAIL_SPECIALIZE_IS_VIRTUAL_BASE_OP(r,data,elem) _ULIB_DETAIL_SPECIALIZE_IS_VIRTUAL_BASE(elem,data)
212 
213 
214 
221 // INTRUSIVE SERIALIZATION ( NOT WORKING YET !! ) //
222 
223 #define _ULIB_DETAIL_INTRUSIVE_AR_(name) ar & BOOST_SERIALIZATION_NVP(name);
224 
225 #define _ULIB_DETAIL_INTRUSIVE_SERIALIZE_FUNC(Class,Archive) \
226  template void Class::serialize(Archive &ar,const unsigned int);
227 
228 #define _ULIB_DETAIL_INTRUSIVE_SERIALIZE_FUNC_OP(r,data,elem) _ULIB_DETAIL_INTRUSIVE_SERIALIZE_FUNC(data,elem);
229 
230 #define _ULIB_DETAIL_INTRUSIVE_SERIALIZABLE_OBJECT \
231  typedef boost::mpl::bool_<true> serializable; \
232  typedef boost::mpl::remove_if< TypeList, IsUnSerializable >::type SerilizableTypeList; \
233  void PrintSerializableListId() { boost::mpl::for_each<SerilizableTypeList>(PrintTypeId()); } \
234  template <class ArchiveT> void serialize(ArchiveT &ar,const unsigned int version); \
235  template <class ArchiveT> void serialize_parents(ArchiveT &ar,const unsigned int version); \
236  template <class ArchiveT> void save_override(ArchiveT &ar,const unsigned int version);
237 
238 #define _ULIB_DETAIL_INTRUSIVE_SERIALIZE_OBJECT(_Ob,...) \
239  template <class ArchiveT> void _Ob::serialize(ArchiveT &ar, const unsigned int version) { \
240  boost::serialization::void_cast_register<_Ob,_Ob::BaseClass>(static_cast<_Ob *>(NULL),static_cast<_Ob::BaseClass *>(NULL)); \
241  _Ob::serialize_parents(ar,version); \
242  _Ob::save_override(ar,version); }\
243  template <class ArchiveT> void _Ob::serialize_parents(ArchiveT &ar, const unsigned int v) { \
244  BOOST_PP_SEQ_FOR_EACH(_AR_OP,ar,BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__))); } \
245  BOOST_PP_SEQ_FOR_EACH(_ULIB_DETAIL_INTRUSIVE_SERIALIZE_FUNC_OP,_Ob,_SERIALIZE_IMPL_SEQ)\
246  BOOST_PP_SEQ_FOR_EACH(_ULIB_DETAIL_SPECIALIZE_IS_VIRTUAL_BASE_OP,_Ob,BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__))) \
247  ULIB_CLASS_EXPORT_IMPLEMENT(_Ob) \
248  namespace boost { \
249  namespace serialization { \
250  template<class ArchiveT> inline void load_construct_data(ArchiveT & ar, _Ob *o, const unsigned int file_version) \
251  { ::new(o)_Ob(); o->init_parameters(); } }}\
252  template <class ArchiveT> void _Ob::save_override(ArchiveT &ar, const unsigned int version)
253 
254 
255 
262 // UNINTRUSIVE SERIALIZATION
263 
264 #define _UNAR_OP(r,data,elem) ar&boost::serialization::make_nvp(BOOST_PP_STRINGIZE(elem),boost::serialization::base_object<elem>(ob));
265 
266 #define _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_FUNC(Class,Archive) \
267  template void boost::serialization::serialize(Archive &ar, Class &ob, const unsigned int i);
268 
269 #define _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_FUNC_OP(r,data,elem) _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_FUNC(data,elem)
270 
271 
272 // NOTE: becouse of BOOST_PP_VARIADIC_SIZE issue of some boost macro has two
273 // different implementation
274 
275 #define _ULIB_DETAIL_UNINTRUSIVE_SERIALIZABLE(_Ob) \
276  namespace boost { namespace serialization { \
277  template <class ArchiveT> void serialize (ArchiveT &ar, _Ob &ob, const unsigned int version); \
278  template <class ArchiveT> void serialize_parents (ArchiveT &ar, _Ob &ob, const unsigned int version); \
279  template <> struct access2< _Ob > { template <class ArchiveT> static void save_override (ArchiveT &ar, _Ob &ob, const unsigned int version); }; }}
280 
281 #define _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE(_Ob) \
282  namespace boost { namespace serialization { \
283  template <class ArchiveT> void serialize_parents(ArchiveT &ar, _Ob &ob, const unsigned int v) {} \
284  template <class ArchiveT> void serialize (ArchiveT &ar, _Ob &ob, const unsigned int version) { \
285  serialize_parents(ar,ob,version); \
286  access2< _Ob >::save_override(ar,ob,version); } }}\
287  ULIB_CLASS_EXPORT_IMPLEMENT(_Ob) \
288  BOOST_PP_SEQ_FOR_EACH(_ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_FUNC_OP,_Ob,_SERIALIZE_IMPL_SEQ)\
289  template <class ArchiveT> void boost::serialization::access2< _Ob >::save_override(ArchiveT &ar, _Ob &ob, const unsigned int version)
290 
291 #define _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_DERIVED(_Ob,...) \
292  namespace boost { namespace serialization { \
293  template <class ArchiveT> void serialize_parents(ArchiveT &ar, _Ob &ob, const unsigned int v) { \
294  BOOST_PP_IF(BOOST_PP_VARIADIC_SIZE((__VA_ARGS__)),BOOST_PP_SEQ_FOR_EACH(_UNAR_OP,ob,BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__)));,) } \
295  template <class ArchiveT> void serialize (ArchiveT &ar, _Ob &ob, const unsigned int version) { \
296  serialize_parents(ar,ob,version); \
297  access2< _Ob >::save_override (ar,ob,version); } }}\
298  ULIB_CLASS_EXPORT_IMPLEMENT(_Ob) \
299  BOOST_PP_SEQ_FOR_EACH(_ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_FUNC_OP,_Ob,_SERIALIZE_IMPL_SEQ) \
300  BOOST_PP_SEQ_FOR_EACH(_ULIB_DETAIL_SPECIALIZE_IS_VIRTUAL_BASE_OP,_Ob,BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__))) \
301  template <class ArchiveT> void boost::serialization::access2< _Ob >::save_override(ArchiveT &ar, _Ob &ob, const unsigned int version)
302 
303 
304 #define _ULIB_DETAIL_UNINTRUSIVE_SERIALIZABLE_OBJECT(_Ob) \
305  namespace boost { namespace serialization { \
306  template <class ArchiveT> void serialize (ArchiveT &ar, _Ob &ob, const unsigned int version); \
307  template <class ArchiveT> void serialize_parents (ArchiveT &ar, _Ob &ob, const unsigned int version); \
308  template <> struct access2< _Ob > { template <class ArchiveT> static void save_override (ArchiveT &ar, _Ob &ob, const unsigned int version); }; \
309  template <class ArchiveT> void serialize (ArchiveT &ar, class _Ob::ObjectProps &ob, const unsigned int version); \
310  template <class ArchiveT> void save_override (ArchiveT &ar, class _Ob::ObjectProps &ob, const unsigned int version); }}
311 
312 #define _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_OBJECT(_Ob,...) \
313  namespace boost { namespace serialization { \
314  template <class ArchiveT> void serialize_parents(ArchiveT &ar, _Ob &ob, const unsigned int v) { \
315  /* PP serialize */ BOOST_PP_SEQ_FOR_EACH(_UNAR_OP,ob,BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__))); \
316  /* MPL serialize */ /*uLib::mpl::for_each<_Ob::BaseList>(uLib::detail::Serializable::serialize_baseobject<_Ob,ArchiveT>(ob,ar) );*/ } \
317  template<class ArchiveT> inline void load_construct_data(ArchiveT & ar, _Ob *ob, const unsigned int file_version) { \
318  ::new(ob)_Ob(); uLib::detail::ObjectProps::initializer::init_object(ob); } \
319  template <class ArchiveT> void serialize (ArchiveT &ar, _Ob &ob, const unsigned int version) { \
320  void_cast_register<_Ob,_Ob::BaseClass>(static_cast<_Ob *>(NULL),static_cast<_Ob::BaseClass *>(NULL)); /*fix*/ \
321  serialize_parents(ar,ob,version); \
322  access2< _Ob >::save_override (ar,ob,version); } }}\
323  ULIB_CLASS_EXPORT_IMPLEMENT(_Ob) \
324  BOOST_PP_SEQ_FOR_EACH(_ULIB_DETAIL_SPECIALIZE_IS_VIRTUAL_BASE_OP,_Ob,BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__))) \
325  BOOST_PP_SEQ_FOR_EACH(_ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_FUNC_OP,_Ob,_SERIALIZE_IMPL_SEQ)\
326  template <class ArchiveT> void boost::serialization::access2< _Ob >::save_override(ArchiveT &ar, _Ob &ob, const unsigned int version)
327 
328 #define _ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_PROPS(_Ob) \
329  namespace boost { namespace serialization { \
330  template <class ArchiveT> void serialize (ArchiveT &ar, _Ob::ObjectProps &ob, const unsigned int version) { \
331  save_override (ar,ob,version); } }}\
332  BOOST_PP_SEQ_FOR_EACH(_ULIB_DETAIL_UNINTRUSIVE_SERIALIZE_FUNC_OP,_Ob::ObjectProps,_SERIALIZE_IMPL_SEQ)\
333  ULIB_CLASS_EXPORT_IMPLEMENT(_Ob::ObjectProps) \
334  ULIB_CLASS_EXPORT_IMPLEMENT(uLib::ObjectPropsImpl<_Ob>) \
335  template <class ArchiveT> void boost::serialization::save_override(ArchiveT &ar, _Ob::ObjectProps &ob, const unsigned int version)
336 
337 
338 #define _ULIB_DETAIL_UNINTRUSIVE_AR_(name) boost::serialization::make_nvp(BOOST_PP_STRINGIZE(name),ob.name)
339 
340 
341 
342 
343 
344 
345 
346 
347 
351 
352 
353 
354 namespace detail {
355 
356 struct Serializable {
357 
363  template <class T>
364  struct serializable_trait : mpl::bool_<false> {};
365 
369  template <class T>
370  struct IsA : serializable_trait<T> {};
371 
372  template <class ThisClass, class Archive>
374  ThisClass & m_object;
375  Archive & m_ar;
376  serialize_baseobject(ThisClass &o, Archive &ar) : m_object(o), m_ar(ar) {}
377  template <class T> void operator()(T &o) {
378  m_ar & boost::serialization::make_nvp(
379  typeid(T).name() ,
380  boost::serialization::base_object<T>(m_object));
381  }
382  };
383 
384 
385 };
386 
387 
388 } // detail
389 
390 
391 
392 
393 
394 struct Serializable {
396  template <class T> friend class boost::serialization::access2;
397  virtual ~Serializable() {}
398 protected:
399 };
400 
401 
402 
403 
404 
405 } // uLib
406 
407 
408 
409 
410 
411 
412 #endif // U_SERIALIZABLE_H
const char * name() const
Definition: Serializable.h:98
serialize_baseobject(ThisClass &o, Archive &ar)
Definition: Serializable.h:376
Definition: Serializable.h:370
void operator()(T &o)
Definition: Serializable.h:377
Definition: Serializable.h:81
Definition: Serializable.h:356
const hrp< T > make_hrp(const char *name, T &t)
Definition: Serializable.h:125
Archive & m_ar
Definition: Serializable.h:375
virtual ~Serializable()
Definition: Serializable.h:397
void save(Archivex &ar, const unsigned int) const
Definition: Serializable.h:104
void load(Archivex &ar, const unsigned int)
Definition: Serializable.h:113
Definition: Serializable.h:394
friend class boost::serialization::access
Definition: Serializable.h:395
hrp(const char *name_, T &t)
Definition: Serializable.h:94
ThisClass & m_object
Definition: Serializable.h:374
Definition: Archives.h:87