cereal
A C++11 library for serialization
access.hpp
Go to the documentation of this file.
1 
3 /*
4  Copyright (c) 2014, Randolph Voorhies, Shane Grant
5  All rights reserved.
6 
7  Redistribution and use in source and binary forms, with or without
8  modification, are permitted provided that the following conditions are met:
9  * Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11  * Redistributions in binary form must reproduce the above copyright
12  notice, this list of conditions and the following disclaimer in the
13  documentation and/or other materials provided with the distribution.
14  * Neither the name of cereal nor the
15  names of its contributors may be used to endorse or promote products
16  derived from this software without specific prior written permission.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES OR SHANE GRANT BE LIABLE FOR ANY
22  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 #ifndef CEREAL_ACCESS_HPP_
30 #define CEREAL_ACCESS_HPP_
31 
32 #include <type_traits>
33 #include <iostream>
34 #include <cstdint>
35 #include <functional>
36 
37 #include "cereal/macros.hpp"
39 
40 namespace cereal
41 {
42  // ######################################################################
44 
106  template <class T>
108  { };
109 
110  // forward decl for construct
112  namespace memory_detail{ template <class Ar, class T> struct LoadAndConstructLoadWrapper; }
114 
116 
161  template <class T>
162  class construct
163  {
164  public:
166 
174  template <class ... Args>
175  void operator()( Args && ... args );
176  // implementation deferred due to reliance on cereal::access
177 
179 
184  {
185  if( !itsValid )
186  throw Exception("Object must be initialized prior to accessing members");
187 
188  return itsPtr;
189  }
190 
192 
199  T * ptr()
200  {
201  return operator->();
202  }
203 
204  private:
205  template <class A, class B> friend struct ::cereal::memory_detail::LoadAndConstructLoadWrapper;
206 
207  construct( T * p ) : itsPtr( p ), itsEnableSharedRestoreFunction( [](){} ), itsValid( false ) {}
208  construct( T * p, std::function<void()> enableSharedFunc ) : // g++4.7 ice with default lambda to std func
209  itsPtr( p ), itsEnableSharedRestoreFunction( enableSharedFunc ), itsValid( false ) {}
210  construct( construct const & ) = delete;
211  construct & operator=( construct const & ) = delete;
212 
213  T * itsPtr;
214  std::function<void()> itsEnableSharedRestoreFunction;
215  bool itsValid;
216  };
217 
218  // ######################################################################
220 
237  class access
238  {
239  public:
240  // ####### Standard Serialization ########################################
241  template<class Archive, class T> inline
242  static auto member_serialize(Archive & ar, T & t) -> decltype(t.CEREAL_SERIALIZE_FUNCTION_NAME(ar))
243  { return t.CEREAL_SERIALIZE_FUNCTION_NAME(ar); }
244 
245  template<class Archive, class T> inline
246  static auto member_save(Archive & ar, T const & t) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar))
247  { return t.CEREAL_SAVE_FUNCTION_NAME(ar); }
248 
249  template<class Archive, class T> inline
250  static auto member_save_non_const(Archive & ar, T & t) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar))
251  { return t.CEREAL_SAVE_FUNCTION_NAME(ar); }
252 
253  template<class Archive, class T> inline
254  static auto member_load(Archive & ar, T & t) -> decltype(t.CEREAL_LOAD_FUNCTION_NAME(ar))
255  { return t.CEREAL_LOAD_FUNCTION_NAME(ar); }
256 
257  template<class Archive, class T> inline
258  static auto member_save_minimal(Archive const & ar, T const & t) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar))
259  { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar); }
260 
261  template<class Archive, class T> inline
262  static auto member_save_minimal_non_const(Archive const & ar, T & t) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar))
263  { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar); }
264 
265  template<class Archive, class T, class U> inline
266  static auto member_load_minimal(Archive const & ar, T & t, U && u) -> decltype(t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u)))
267  { return t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u)); }
268 
269  // ####### Versioned Serialization #######################################
270  template<class Archive, class T> inline
271  static auto member_serialize(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.CEREAL_SERIALIZE_FUNCTION_NAME(ar, version))
272  { return t.CEREAL_SERIALIZE_FUNCTION_NAME(ar, version); }
273 
274  template<class Archive, class T> inline
275  static auto member_save(Archive & ar, T const & t, const std::uint32_t version ) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar, version))
276  { return t.CEREAL_SAVE_FUNCTION_NAME(ar, version); }
277 
278  template<class Archive, class T> inline
279  static auto member_save_non_const(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar, version))
280  { return t.CEREAL_SAVE_FUNCTION_NAME(ar, version); }
281 
282  template<class Archive, class T> inline
283  static auto member_load(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.CEREAL_LOAD_FUNCTION_NAME(ar, version))
284  { return t.CEREAL_LOAD_FUNCTION_NAME(ar, version); }
285 
286  template<class Archive, class T> inline
287  static auto member_save_minimal(Archive const & ar, T const & t, const std::uint32_t version) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version))
288  { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version); }
289 
290  template<class Archive, class T> inline
291  static auto member_save_minimal_non_const(Archive const & ar, T & t, const std::uint32_t version) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version))
292  { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version); }
293 
294  template<class Archive, class T, class U> inline
295  static auto member_load_minimal(Archive const & ar, T & t, U && u, const std::uint32_t version) -> decltype(t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u), version))
296  { return t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u), version); }
297 
298  // ####### Other Functionality ##########################################
299  // for detecting inheritance from enable_shared_from_this
300  template <class T> inline
301  static auto shared_from_this(T & t) -> decltype(t.shared_from_this());
302 
303  // for placement new
304  template <class T, class ... Args> inline
305  static void construct( T *& ptr, Args && ... args )
306  {
307  new (ptr) T( std::forward<Args>( args )... );
308  }
309 
310  // for non-placement new with a default constructor
311  template <class T> inline
312  static T * construct()
313  {
314  return new T();
315  }
316 
317  template <class T> inline
318  static std::false_type load_and_construct(...)
319  { return std::false_type(); }
320 
321  template<class T, class Archive> inline
322  static auto load_and_construct(Archive & ar, ::cereal::construct<T> & construct) -> decltype(T::load_and_construct(ar, construct))
323  {
324  T::load_and_construct( ar, construct );
325  }
326 
327  template<class T, class Archive> inline
328  static auto load_and_construct(Archive & ar, ::cereal::construct<T> & construct, const std::uint32_t version) -> decltype(T::load_and_construct(ar, construct, version))
329  {
330  T::load_and_construct( ar, construct, version );
331  }
332  }; // end class access
333 
334  // ######################################################################
337 
339  enum class specialization
340  {
341  member_serialize,
342  member_load_save,
343  member_load_save_minimal,
344  non_member_serialize,
345  non_member_load_save,
346  non_member_load_save_minimal
347  };
348 
350 
403  template <class Archive, class T, specialization S>
404  struct specialize : public std::false_type {};
405 
407 
417  #define CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES( Type, Specialization ) \
418  namespace cereal { template <class Archive> struct specialize<Archive, Type, Specialization> {}; }
419 
421 
431  #define CEREAL_SPECIALIZE_FOR_ARCHIVE( Archive, Type, Specialization ) \
432  namespace cereal { template <> struct specialize<Archive, Type, Specialization> {}; }
433 
434  // ######################################################################
435  // Deferred Implementation, see construct for more information
436  template <class T> template <class ... Args> inline
437  void construct<T>::operator()( Args && ... args )
438  {
439  if( itsValid )
440  throw Exception("Attempting to construct an already initialized object");
441 
442  ::cereal::access::construct( itsPtr, std::forward<Args>( args )... );
443  itsEnableSharedRestoreFunction();
444  itsValid = true;
445  }
446 } // namespace cereal
447 
448 #endif // CEREAL_ACCESS_HPP_
T * operator->()
Get a reference to the initialized underlying object.
Definition: access.hpp:183
specialization
Definition: access.hpp:339
Used to construct types with no default constructor.
Definition: access.hpp:162
A class that allows cereal to load smart pointers to types that have no default constructor.
Definition: access.hpp:107
Internal helper functionality.
A class that can be made a friend to give cereal access to non public functions.
Definition: access.hpp:237
Definition: access.hpp:40
Preprocessor macros that can customise the cereal library.
void operator()(Args &&...args)
Construct and initialize the type T with the given arguments.
Definition: access.hpp:437
T * ptr()
Returns a raw pointer to the initialized underlying object.
Definition: access.hpp:199
A class used to disambiguate cases where cereal cannot detect a unique way of serializing a class...
Definition: access.hpp:404
An exception class thrown when things go wrong at runtime.
Definition: helpers.hpp:48