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 the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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"
38 #include "cereal/specialize.hpp"
40 
41 namespace cereal
42 {
43  // ######################################################################
45 
107  template <class T>
109  { };
110 
111  // forward decl for construct
113  namespace memory_detail{ template <class Ar, class T> struct LoadAndConstructLoadWrapper; }
114  namespace boost_variant_detail{ template <class Ar, class T> struct LoadAndConstructLoadWrapper; }
116 
118 
163  template <class T>
164  class construct
165  {
166  public:
168 
176  template <class ... Args>
177  void operator()( Args && ... args );
178  // implementation deferred due to reliance on cereal::access
179 
181 
186  {
187  if( !itsValid )
188  throw Exception("Object must be initialized prior to accessing members");
189 
190  return itsPtr;
191  }
192 
194 
201  T * ptr()
202  {
203  return operator->();
204  }
205 
206  private:
207  template <class Ar, class TT> friend struct ::cereal::memory_detail::LoadAndConstructLoadWrapper;
208  template <class Ar, class TT> friend struct ::cereal::boost_variant_detail::LoadAndConstructLoadWrapper;
209 
210  construct( T * p ) : itsPtr( p ), itsEnableSharedRestoreFunction( [](){} ), itsValid( false ) {}
211  construct( T * p, std::function<void()> enableSharedFunc ) : // g++4.7 ice with default lambda to std func
212  itsPtr( p ), itsEnableSharedRestoreFunction( enableSharedFunc ), itsValid( false ) {}
213  construct( construct const & ) = delete;
214  construct & operator=( construct const & ) = delete;
215 
216  T * itsPtr;
217  std::function<void()> itsEnableSharedRestoreFunction;
218  bool itsValid;
219  };
220 
221  // ######################################################################
223 
240  class access
241  {
242  public:
243  // ####### Standard Serialization ########################################
244  template<class Archive, class T> inline
245  static auto member_serialize(Archive & ar, T & t) -> decltype(t.CEREAL_SERIALIZE_FUNCTION_NAME(ar))
246  { return t.CEREAL_SERIALIZE_FUNCTION_NAME(ar); }
247 
248  template<class Archive, class T> inline
249  static auto member_save(Archive & ar, T const & t) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar))
250  { return t.CEREAL_SAVE_FUNCTION_NAME(ar); }
251 
252  template<class Archive, class T> inline
253  static auto member_save_non_const(Archive & ar, T & t) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar))
254  { return t.CEREAL_SAVE_FUNCTION_NAME(ar); }
255 
256  template<class Archive, class T> inline
257  static auto member_load(Archive & ar, T & t) -> decltype(t.CEREAL_LOAD_FUNCTION_NAME(ar))
258  { return t.CEREAL_LOAD_FUNCTION_NAME(ar); }
259 
260  template<class Archive, class T> inline
261  static auto member_save_minimal(Archive const & ar, T const & t) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar))
262  { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar); }
263 
264  template<class Archive, class T> inline
265  static auto member_save_minimal_non_const(Archive const & ar, T & t) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar))
266  { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar); }
267 
268  template<class Archive, class T, class U> inline
269  static auto member_load_minimal(Archive const & ar, T & t, U && u) -> decltype(t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u)))
270  { return t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u)); }
271 
272  // ####### Versioned Serialization #######################################
273  template<class Archive, class T> inline
274  static auto member_serialize(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.CEREAL_SERIALIZE_FUNCTION_NAME(ar, version))
275  { return t.CEREAL_SERIALIZE_FUNCTION_NAME(ar, version); }
276 
277  template<class Archive, class T> inline
278  static auto member_save(Archive & ar, T const & t, const std::uint32_t version ) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar, version))
279  { return t.CEREAL_SAVE_FUNCTION_NAME(ar, version); }
280 
281  template<class Archive, class T> inline
282  static auto member_save_non_const(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar, version))
283  { return t.CEREAL_SAVE_FUNCTION_NAME(ar, version); }
284 
285  template<class Archive, class T> inline
286  static auto member_load(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.CEREAL_LOAD_FUNCTION_NAME(ar, version))
287  { return t.CEREAL_LOAD_FUNCTION_NAME(ar, version); }
288 
289  template<class Archive, class T> inline
290  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))
291  { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version); }
292 
293  template<class Archive, class T> inline
294  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))
295  { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version); }
296 
297  template<class Archive, class T, class U> inline
298  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))
299  { return t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u), version); }
300 
301  // ####### Other Functionality ##########################################
302  // for detecting inheritance from enable_shared_from_this
303  template <class T> inline
304  static auto shared_from_this(T & t) -> decltype(t.shared_from_this());
305 
306  // for placement new
307  template <class T, class ... Args> inline
308  static void construct( T *& ptr, Args && ... args )
309  {
310  new (ptr) T( std::forward<Args>( args )... );
311  }
312 
313  // for non-placement new with a default constructor
314  template <class T> inline
315  static T * construct()
316  {
317  return new T();
318  }
319 
320  template <class T> inline
321  static std::false_type load_and_construct(...)
322  { return std::false_type(); }
323 
324  template<class T, class Archive> inline
325  static auto load_and_construct(Archive & ar, ::cereal::construct<T> & construct) -> decltype(T::load_and_construct(ar, construct))
326  {
327  T::load_and_construct( ar, construct );
328  }
329 
330  template<class T, class Archive> inline
331  static auto load_and_construct(Archive & ar, ::cereal::construct<T> & construct, const std::uint32_t version) -> decltype(T::load_and_construct(ar, construct, version))
332  {
333  T::load_and_construct( ar, construct, version );
334  }
335  }; // end class access
336 
337  // ######################################################################
338  // Deferred Implementation, see construct for more information
339  template <class T> template <class ... Args> inline
340  void construct<T>::operator()( Args && ... args )
341  {
342  if( itsValid )
343  throw Exception("Attempting to construct an already initialized object");
344 
345  ::cereal::access::construct( itsPtr, std::forward<Args>( args )... );
346  itsEnableSharedRestoreFunction();
347  itsValid = true;
348  }
349 } // namespace cereal
350 
351 #endif // CEREAL_ACCESS_HPP_
cereal::construct
Used to construct types with no default constructor.
Definition: access.hpp:164
cereal::LoadAndConstruct
A class that allows cereal to load smart pointers to types that have no default constructor.
Definition: access.hpp:108
helpers.hpp
Internal helper functionality.
specialize.hpp
Serialization disambiguation.
macros.hpp
Preprocessor macros that can customise the cereal library.
cereal::construct::ptr
T * ptr()
Returns a raw pointer to the initialized underlying object.
Definition: access.hpp:201
cereal::construct::operator->
T * operator->()
Get a reference to the initialized underlying object.
Definition: access.hpp:185
cereal::Exception
An exception class thrown when things go wrong at runtime.
Definition: helpers.hpp:48
cereal::construct::operator()
void operator()(Args &&... args)
Construct and initialize the type T with the given arguments.
Definition: access.hpp:340
cereal::access
A class that can be made a friend to give cereal access to non public functions.
Definition: access.hpp:240