mlpack: src/mlpack/core/data/serialization_shim.hpp Source File
serialization_shim.hpp
Go to the documentation of this file.
1 
18 #ifndef mlpack_CORE_UTIL_SERIALIZATION_SHIM_HPP
19 #define mlpack_CORE_UTIL_SERIALIZATION_SHIM_HPP
20 
22 #include <boost/serialization/serialization.hpp>
23 #include <boost/archive/xml_oarchive.hpp>
24 
25 namespace mlpack {
26 namespace data {
27 
28 // This gives us a HasSerializeCheck<T, U> type (where U is a function pointer)
29 // we can use with SFINAE to catch when a type has a Serialize() function.
30 HAS_MEM_FUNC(Serialize, HasSerializeCheck);
31 
32 // Don't call this with a non-class. HasSerializeFunction::value is true if the
33 // type T has a static or non-static Serialize() function.
34 template<typename T>
36 {
37  static const bool value =
38  // Non-static version.
39  HasSerializeCheck<T, void(T::*)(boost::archive::xml_oarchive&,
40  const unsigned int)>::value ||
41  // Static version.
42  HasSerializeCheck<T, void(*)(boost::archive::xml_oarchive&,
43  const unsigned int)>::value;
44 };
45 
46 template<typename T>
48 {
49  // We have to handle the case where T isn't a class...
50  typedef char yes[1];
51  typedef char no [2];
52  template<typename U, typename V, typename W> struct check;
53  template<typename U> static yes& chk( // This matches classes.
54  check<U,
55  typename boost::enable_if<boost::is_class<U>>::type*,
56  typename boost::enable_if<HasSerializeFunction<U>>::type*>*);
57  template<typename > static no& chk(...); // This matches non-classes.
58 
59  static const bool value = (sizeof(chk<T>(0)) == sizeof(yes));
60 };
61 
62 // Declare the shims we need.
63 template<typename T> struct FirstShim;
64 template<typename T> struct FirstArrayShim;
65 template<typename T> struct FirstNormalArrayShim;
66 template<typename T> struct SecondShim;
67 template<typename T> struct SecondArrayShim;
68 template<typename T> struct SecondNormalArrayShim;
69 template<typename T> struct PointerShim;
70 
94 template<typename T>
96  T& t,
97  const std::string& name,
98  typename boost::enable_if<HasSerialize<T>>::type* = 0)
99 {
100  return FirstShim<T>(t, name);
101 }
102 
124 template<typename T>
125 inline
126 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
127 const // Imitate the boost::serialization make_nvp() function.
128 #endif
129 boost::serialization::nvp<T> CreateNVP(
130  T& t,
131  const std::string& name,
132  typename boost::disable_if<HasSerialize<T>>::type* = 0,
133  typename boost::disable_if<boost::is_pointer<T>>::type* = 0)
134 {
135  return boost::serialization::make_nvp(name.c_str(), t);
136 }
137 
159 template<typename T>
160 inline
161 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
162 const
163 #endif
164 boost::serialization::nvp<PointerShim<T>*> CreateNVP(
165  T*& t,
166  const std::string& name,
167  typename boost::enable_if<HasSerialize<T>>::type* = 0)
168 {
169  return boost::serialization::make_nvp(name.c_str(),
170  reinterpret_cast<PointerShim<T>*&>(t));
171 }
172 
194 template<typename T>
195 inline
196 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
197 const
198 #endif
199 boost::serialization::nvp<T*> CreateNVP(
200  T*& t,
201  const std::string& name,
202  typename boost::disable_if<HasSerialize<T>>::type* = 0)
203 {
204  return boost::serialization::make_nvp(name.c_str(), t);
205 }
206 
214 template<typename T>
216  T* t,
217  const size_t len,
218  const std::string& name,
219  typename boost::enable_if<HasSerialize<T>>::type* = 0)
220 {
221  return FirstArrayShim<T>(t, len, name);
222 }
223 
231 template<typename T>
233  T* t,
234  const size_t len,
235  const std::string& name,
236  typename boost::disable_if<HasSerialize<T>>::type* = 0)
237 {
238  return FirstNormalArrayShim<T>(t, len, name);
239 }
240 
246 template<typename T>
247 struct FirstShim
248 {
250  FirstShim(T& t, const std::string& name) : t(t), name(name) { }
251 
252  T& t;
253  const std::string& name;
254 };
255 
261 template<typename T>
262 struct FirstArrayShim
263 {
265  FirstArrayShim(T* t, const size_t len, const std::string& name) :
266  t(t), len(len), name(name) { }
267 
268  T* t;
269  const size_t len;
270  const std::string& name;
271 };
272 
278 template<typename T>
280 {
282  FirstNormalArrayShim(T* t, const size_t len, const std::string& name) :
283  t(t), len(len), name(name) { }
284 
285  T* t;
286  const size_t len;
287  const std::string& name;
288 };
289 
295 template<typename T>
296 struct SecondShim
297 {
299  SecondShim(T& t) : t(t) { }
300 
302  template<typename Archive>
303  void serialize(Archive& ar, const unsigned int version)
304  {
305  t.Serialize(ar, version);
306  }
307 
308  T& t;
309 };
310 
316 template<typename T>
317 struct SecondArrayShim
318 {
320  SecondArrayShim(T* t, const size_t len) : t(t), len(len) { }
321 
323  template<typename Archive>
324  void serialize(Archive& ar, const unsigned int /* version */)
325  {
326  // Serialize each element, using the shims we already have.
327  for (size_t i = 0; i < len; ++i)
328  ar & CreateNVP(t[i], "item");
329  }
330 
331  T* t;
332  const size_t len;
333 };
334 
339 template<typename T>
341 {
343  SecondNormalArrayShim(T* t, const size_t len) : t(t), len(len) { }
344 
346  template<typename Archive>
347  void serialize(Archive& ar, const unsigned int /* version */)
348  {
349  ar & boost::serialization::make_array(t, len);
350  }
351 
352  T* t;
353  const size_t len;
354 };
355 
361 template<typename T>
362 struct PointerShim : public T { };
363 
371 template<typename Archive, typename T>
372 Archive& operator<<(Archive& ar, FirstShim<T> t)
373 {
374  SecondShim<T> sh(t.t);
375  return (ar << boost::serialization::make_nvp(t.name.c_str(), sh));
376 }
377 
385 template<typename Archive, typename T>
386 Archive& operator&(Archive& ar, FirstShim<T> t)
387 {
388  SecondShim<T> sh(t.t);
389  return (ar & boost::serialization::make_nvp(t.name.c_str(), sh));
390 }
391 
399 template<typename Archive, typename T>
400 Archive& operator>>(Archive& ar, FirstShim<T> t)
401 {
402  SecondShim<T> sh(t.t);
403  return (ar >> boost::serialization::make_nvp(t.name.c_str(), sh));
404 }
405 
413 template<typename Archive, typename T>
414 Archive& operator<<(Archive& ar, FirstArrayShim<T> t)
415 {
416  SecondArrayShim<T> sh(t.t, t.len);
417  return (ar << boost::serialization::make_nvp(t.name.c_str(), sh));
418 }
419 
427 template<typename Archive, typename T>
428 Archive& operator&(Archive& ar, FirstArrayShim<T> t)
429 {
430  SecondArrayShim<T> sh(t.t, t.len);
431  return (ar & boost::serialization::make_nvp(t.name.c_str(), sh));
432 }
433 
441 template<typename Archive, typename T>
442 Archive& operator>>(Archive& ar, FirstArrayShim<T> t)
443 {
444  SecondArrayShim<T> sh(t.t, t.len);
445  return (ar >> boost::serialization::make_nvp(t.name.c_str(), sh));
446 }
447 
455 template<typename Archive, typename T>
456 Archive& operator<<(Archive& ar, FirstNormalArrayShim<T> t)
457 {
458  SecondNormalArrayShim<T> sh(t.t, t.len);
459  return (ar << boost::serialization::make_nvp(t.name.c_str(), sh));
460 }
461 
469 template<typename Archive, typename T>
470 Archive& operator&(Archive& ar, FirstNormalArrayShim<T> t)
471 {
472  SecondNormalArrayShim<T> sh(t.t, t.len);
473  return (ar & boost::serialization::make_nvp(t.name.c_str(), sh));
474 }
475 
483 template<typename Archive, typename T>
484 Archive& operator>>(Archive& ar, FirstNormalArrayShim<T> t)
485 {
486  SecondNormalArrayShim<T> sh(t.t, t.len);
487  return (ar >> boost::serialization::make_nvp(t.name.c_str(), sh));
488 }
489 
490 } // namespace data
491 } // namespace mlpack
492 
493 namespace boost {
494 namespace serialization {
495 
500 template<typename Archive, typename T>
501 inline void serialize(Archive& ar,
503  const BOOST_PFTO unsigned int version)
504 {
505  T* tptr = reinterpret_cast<T*>(&t);
506  tptr->Serialize(ar, version);
507 }
508 
509 } // namespace serialization
510 } // namespace boost
511 
512 #endif
FirstShim(T &t, const std::string &name)
Construct the first shim with the given object and name.
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...
Linear algebra utility functions, generally performed on matrices or vectors.
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.
FirstArrayShim(T *t, const size_t len, const std::string &name)
Construct the first shim with the given objects, length, and name.
Archive & operator&(Archive &ar, FirstShim< T > t)
Catch when we call operator& with a FirstShim object.
SecondShim(T &t)
Construct the second shim. The name isn&#39;t necessary for this shim.
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...
A shim for objects in an array which do not have a Serialize() function.
A first shim for arrays without a Serialize() method.
SecondNormalArrayShim(T *t, const size_t len)
Construct the shim.
A first shim for arrays.
void serialize(Archive &ar, const unsigned int)
A wrapper for make_array().
Archive & operator>>(Archive &ar, FirstShim< T > t)
Catch when we call operator>> with a FirstShim object.
HAS_MEM_FUNC(Serialize, HasSerializeCheck)
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 Serialize() for each element.
SecondArrayShim(T *t, const size_t len)
Construct the shim.
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.
The second shim: wrap the call to Serialize() inside of a serialize() function, so that an archive ty...
#define BOOST_PFTO
Definition: prereqs.hpp:72
void serialize(Archive &ar, const unsigned int version)
A wrapper for t.Serialize().