mlpack  2.2.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
serialization_shim.hpp
Go to the documentation of this file.
1 
16 #ifndef MLPACK_CORE_UTIL_SERIALIZATION_SHIM_HPP
17 #define MLPACK_CORE_UTIL_SERIALIZATION_SHIM_HPP
18 
20 #include <boost/serialization/serialization.hpp>
21 #include <boost/archive/xml_oarchive.hpp>
22 
23 namespace mlpack {
24 namespace data {
25 
26 // This gives us a HasSerializeCheck<T, U> type (where U is a function pointer)
27 // we can use with SFINAE to catch when a type has a Serialize() function.
28 HAS_MEM_FUNC(Serialize, HasSerializeCheck);
29 
30 // Don't call this with a non-class. HasSerializeFunction::value is true if the
31 // type T has a static or non-static Serialize() function.
32 template<typename T>
34 {
35  static const bool value =
36  // Non-static version.
37  HasSerializeCheck<T, void(T::*)(boost::archive::xml_oarchive&,
38  const unsigned int)>::value ||
39  // Static version.
40  HasSerializeCheck<T, void(*)(boost::archive::xml_oarchive&,
41  const unsigned int)>::value;
42 };
43 
44 template<typename T>
46 {
47  // We have to handle the case where T isn't a class...
48  typedef char yes[1];
49  typedef char no [2];
50  template<typename U, typename V, typename W> struct check;
51  template<typename U> static yes& chk( // This matches classes.
52  check<U,
53  typename boost::enable_if<boost::is_class<U>>::type*,
54  typename boost::enable_if<HasSerializeFunction<U>>::type*>*);
55  template<typename > static no& chk(...); // This matches non-classes.
56 
57  static const bool value = (sizeof(chk<T>(0)) == sizeof(yes));
58 };
59 
60 // Declare the shims we need.
61 template<typename T> struct FirstShim;
62 template<typename T> struct FirstArrayShim;
63 template<typename T> struct FirstNormalArrayShim;
64 template<typename T> struct SecondShim;
65 template<typename T> struct SecondArrayShim;
66 template<typename T> struct SecondNormalArrayShim;
67 template<typename T> struct PointerShim;
68 
92 template<typename T>
94  T& t,
95  const std::string& name,
96  typename boost::enable_if<HasSerialize<T>>::type* = 0)
97 {
98  return FirstShim<T>(t, name);
99 }
100 
122 template<typename T>
123 inline
124 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
125 const // Imitate the boost::serialization make_nvp() function.
126 #endif
127 boost::serialization::nvp<T> CreateNVP(
128  T& t,
129  const std::string& name,
130  typename boost::disable_if<HasSerialize<T>>::type* = 0,
131  typename boost::disable_if<boost::is_pointer<T>>::type* = 0)
132 {
133  return boost::serialization::make_nvp(name.c_str(), t);
134 }
135 
157 template<typename T>
158 inline
159 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
160 const
161 #endif
162 boost::serialization::nvp<PointerShim<T>*> CreateNVP(
163  T*& t,
164  const std::string& name,
165  typename boost::enable_if<HasSerialize<T>>::type* = 0)
166 {
167  return boost::serialization::make_nvp(name.c_str(),
168  reinterpret_cast<PointerShim<T>*&>(t));
169 }
170 
192 template<typename T>
193 inline
194 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
195 const
196 #endif
197 boost::serialization::nvp<T*> CreateNVP(
198  T*& t,
199  const std::string& name,
200  typename boost::disable_if<HasSerialize<T>>::type* = 0)
201 {
202  return boost::serialization::make_nvp(name.c_str(), t);
203 }
204 
212 template<typename T>
214  T* t,
215  const size_t len,
216  const std::string& name,
217  typename boost::enable_if<HasSerialize<T>>::type* = 0)
218 {
219  return FirstArrayShim<T>(t, len, name);
220 }
221 
229 template<typename T>
231  T* t,
232  const size_t len,
233  const std::string& name,
234  typename boost::disable_if<HasSerialize<T>>::type* = 0)
235 {
236  return FirstNormalArrayShim<T>(t, len, name);
237 }
238 
244 template<typename T>
245 struct FirstShim
246 {
248  FirstShim(T& t, const std::string& name) : t(t), name(name) { }
249 
250  T& t;
251  const std::string& name;
252 };
253 
259 template<typename T>
260 struct FirstArrayShim
261 {
263  FirstArrayShim(T* t, const size_t len, const std::string& name) :
264  t(t), len(len), name(name) { }
265 
266  T* t;
267  const size_t len;
268  const std::string& name;
269 };
270 
276 template<typename T>
278 {
280  FirstNormalArrayShim(T* t, const size_t len, const std::string& name) :
281  t(t), len(len), name(name) { }
282 
283  T* t;
284  const size_t len;
285  const std::string& name;
286 };
287 
293 template<typename T>
294 struct SecondShim
295 {
297  SecondShim(T& t) : t(t) { }
298 
300  template<typename Archive>
301  void serialize(Archive& ar, const unsigned int version)
302  {
303  t.Serialize(ar, version);
304  }
305 
306  T& t;
307 };
308 
314 template<typename T>
315 struct SecondArrayShim
316 {
318  SecondArrayShim(T* t, const size_t len) : t(t), len(len) { }
319 
321  template<typename Archive>
322  void serialize(Archive& ar, const unsigned int /* version */)
323  {
324  // Serialize each element, using the shims we already have.
325  for (size_t i = 0; i < len; ++i)
326  ar & CreateNVP(t[i], "item");
327  }
328 
329  T* t;
330  const size_t len;
331 };
332 
337 template<typename T>
339 {
341  SecondNormalArrayShim(T* t, const size_t len) : t(t), len(len) { }
342 
344  template<typename Archive>
345  void serialize(Archive& ar, const unsigned int /* version */)
346  {
347  ar & boost::serialization::make_array(t, len);
348  }
349 
350  T* t;
351  const size_t len;
352 };
353 
359 template<typename T>
360 struct PointerShim : public T { };
361 
369 template<typename Archive, typename T>
370 Archive& operator<<(Archive& ar, FirstShim<T> t)
371 {
372  SecondShim<T> sh(t.t);
373  return (ar << boost::serialization::make_nvp(t.name.c_str(), sh));
374 }
375 
383 template<typename Archive, typename T>
384 Archive& operator&(Archive& ar, FirstShim<T> t)
385 {
386  SecondShim<T> sh(t.t);
387  return (ar & boost::serialization::make_nvp(t.name.c_str(), sh));
388 }
389 
397 template<typename Archive, typename T>
398 Archive& operator>>(Archive& ar, FirstShim<T> t)
399 {
400  SecondShim<T> sh(t.t);
401  return (ar >> boost::serialization::make_nvp(t.name.c_str(), sh));
402 }
403 
411 template<typename Archive, typename T>
412 Archive& operator<<(Archive& ar, FirstArrayShim<T> t)
413 {
414  SecondArrayShim<T> sh(t.t, t.len);
415  return (ar << boost::serialization::make_nvp(t.name.c_str(), sh));
416 }
417 
425 template<typename Archive, typename T>
426 Archive& operator&(Archive& ar, FirstArrayShim<T> t)
427 {
428  SecondArrayShim<T> sh(t.t, t.len);
429  return (ar & boost::serialization::make_nvp(t.name.c_str(), sh));
430 }
431 
439 template<typename Archive, typename T>
440 Archive& operator>>(Archive& ar, FirstArrayShim<T> t)
441 {
442  SecondArrayShim<T> sh(t.t, t.len);
443  return (ar >> boost::serialization::make_nvp(t.name.c_str(), sh));
444 }
445 
453 template<typename Archive, typename T>
454 Archive& operator<<(Archive& ar, FirstNormalArrayShim<T> t)
455 {
456  SecondNormalArrayShim<T> sh(t.t, t.len);
457  return (ar << boost::serialization::make_nvp(t.name.c_str(), sh));
458 }
459 
467 template<typename Archive, typename T>
468 Archive& operator&(Archive& ar, FirstNormalArrayShim<T> t)
469 {
470  SecondNormalArrayShim<T> sh(t.t, t.len);
471  return (ar & boost::serialization::make_nvp(t.name.c_str(), sh));
472 }
473 
481 template<typename Archive, typename T>
482 Archive& operator>>(Archive& ar, FirstNormalArrayShim<T> t)
483 {
484  SecondNormalArrayShim<T> sh(t.t, t.len);
485  return (ar >> boost::serialization::make_nvp(t.name.c_str(), sh));
486 }
487 
488 } // namespace data
489 } // namespace mlpack
490 
491 namespace boost {
492 namespace serialization {
493 
498 template<typename Archive, typename T>
499 inline void serialize(Archive& ar,
501  const BOOST_PFTO unsigned int version)
502 {
503  T* tptr = reinterpret_cast<T*>(&t);
504  tptr->Serialize(ar, version);
505 }
506 
507 } // namespace serialization
508 } // namespace boost
509 
510 #endif
FirstArrayShim< T > CreateArrayNVP(T *t, const size_t len, const std::string &name, typename boost::enable_if< HasSerialize< T >>::type *=0)
Call this function to produce a name-value pair for an array; this is similar to boost::serialization...
FirstShim(T &t, const std::string &name)
Construct the first shim with the given object and name.
SecondShim(T &t)
Construct the second shim. The name isn&#39;t necessary for this shim.
FirstShim< T > CreateNVP(T &t, const std::string &name, typename boost::enable_if< HasSerialize< T >>::type *=0)
Call this function to produce a name-value pair; this is similar to BOOST_SERIALIZATION_NVP(), but should be used for types that have a Serialize() function (or contain a type that has a Serialize() function) instead of a serialize() function.
void serialize(Archive &ar, const unsigned int)
A wrapper for Serialize() for each element.
Archive & operator&(Archive &ar, FirstShim< T > t)
Catch when we call operator&amp; with a FirstShim object.
void serialize(Archive &ar, mlpack::data::PointerShim< T > &t, const BOOST_PFTO unsigned int version)
Catch a call to serialize() with a PointerShim, and call the Serialize() function directly...
SecondArrayShim(T *t, const size_t len)
Construct the shim.
A shim for objects in an array which do not have a Serialize() function.
FirstArrayShim(T *t, const size_t len, const std::string &name)
Construct the first shim with the given objects, length, and name.
A first shim for arrays without a Serialize() method.
FirstNormalArrayShim(T *t, const size_t len, const std::string &name)
Construct the first shim with the given objects, length, and name.
void serialize(Archive &ar, const unsigned int)
A wrapper for make_array().
A first shim for arrays.
Archive & operator>>(Archive &ar, FirstShim< T > t)
Catch when we call operator&gt;&gt; with a FirstShim object.
static yes & chk(check< U, typename boost::enable_if< boost::is_class< U >>::type *, typename boost::enable_if< HasSerializeFunction< U >>::type * > *)
SecondNormalArrayShim(T *t, const size_t len)
Construct the shim.
HAS_MEM_FUNC(Serialize, HasSerializeCheck)
A shim for objects in an array; this is basically like the SecondShim, but for arrays that hold objec...
The first shim: simply holds the object and its name.
void serialize(Archive &ar, const unsigned int version)
A wrapper for t.Serialize().
The second shim: wrap the call to Serialize() inside of a serialize() function, so that an archive ty...
#define BOOST_PFTO
Definition: prereqs.hpp:73