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 
36 #include <cereal/macros.hpp>
38 
39 namespace cereal
40 {
41  // ######################################################################
43 
90  template <class T>
92  {
94 
95  static std::false_type load_and_construct(...)
96  { return std::false_type(); }
97  };
98 
99  // forward decl for construct
101  namespace memory_detail{ template <class Ar, class T> struct LoadAndConstructLoadWrapper; }
103 
105 
150  template <class T>
151  class construct
152  {
153  public:
155 
163  template <class ... Args>
164  void operator()( Args && ... args );
165  // implementation deferred due to reliance on cereal::access
166 
168 
173  {
174  if( !itsValid )
175  throw Exception("Object must be initialized prior to accessing members");
176 
177  return itsPtr;
178  }
179 
181 
188  T * ptr()
189  {
190  return operator->();
191  }
192 
193  private:
194  template <class A, class B> friend struct ::cereal::memory_detail::LoadAndConstructLoadWrapper;
195 
196  construct( T * p ) : itsPtr( p ), itsValid( false ) {}
197  construct( construct const & ) = delete;
198  construct & operator=( construct const & ) = delete;
199 
200  T * itsPtr;
201  bool itsValid;
202  };
203 
204  // ######################################################################
206 
223  class access
224  {
225  public:
226  // ####### Standard Serialization ########################################
227  template<class Archive, class T> inline
228  static auto member_serialize(Archive & ar, T & t) -> decltype(t.CEREAL_SERIALIZE_FUNCTION_NAME(ar))
229  { return t.CEREAL_SERIALIZE_FUNCTION_NAME(ar); }
230 
231  template<class Archive, class T> inline
232  static auto member_save(Archive & ar, T const & t) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar))
233  { return t.CEREAL_SAVE_FUNCTION_NAME(ar); }
234 
235  template<class Archive, class T> inline
236  static auto member_save_non_const(Archive & ar, T & t) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar))
237  { return t.CEREAL_SAVE_FUNCTION_NAME(ar); }
238 
239  template<class Archive, class T> inline
240  static auto member_load(Archive & ar, T & t) -> decltype(t.CEREAL_LOAD_FUNCTION_NAME(ar))
241  { return t.CEREAL_LOAD_FUNCTION_NAME(ar); }
242 
243  template<class Archive, class T> inline
244  static auto member_save_minimal(Archive const & ar, T const & t) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar))
245  { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar); }
246 
247  template<class Archive, class T> inline
248  static auto member_save_minimal_non_const(Archive const & ar, T & t) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar))
249  { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar); }
250 
251  template<class Archive, class T, class U> inline
252  static auto member_load_minimal(Archive const & ar, T & t, U && u) -> decltype(t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u)))
253  { return t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u)); }
254 
255  // ####### Versioned Serialization #######################################
256  template<class Archive, class T> inline
257  static auto member_serialize(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.CEREAL_SERIALIZE_FUNCTION_NAME(ar, version))
258  { return t.CEREAL_SERIALIZE_FUNCTION_NAME(ar, version); }
259 
260  template<class Archive, class T> inline
261  static auto member_save(Archive & ar, T const & t, const std::uint32_t version ) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar, version))
262  { return t.CEREAL_SAVE_FUNCTION_NAME(ar, version); }
263 
264  template<class Archive, class T> inline
265  static auto member_save_non_const(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar, version))
266  { return t.CEREAL_SAVE_FUNCTION_NAME(ar, version); }
267 
268  template<class Archive, class T> inline
269  static auto member_load(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.CEREAL_LOAD_FUNCTION_NAME(ar, version))
270  { return t.CEREAL_LOAD_FUNCTION_NAME(ar, version); }
271 
272  template<class Archive, class T> inline
273  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))
274  { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version); }
275 
276  template<class Archive, class T> inline
277  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))
278  { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version); }
279 
280  template<class Archive, class T, class U> inline
281  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))
282  { return t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u), version); }
283 
284  // ####### Other Functionality ##########################################
285  // for detecting inheritance from enable_shared_from_this
286  template <class T> inline
287  static auto shared_from_this(T & t) -> decltype(t.shared_from_this());
288 
289  // for placement new
290  template <class T, class ... Args> inline
291  static void construct( T *& ptr, Args && ... args )
292  {
293  new (ptr) T( std::forward<Args>( args )... );
294  }
295 
296  // for non-placement new with a default constructor
297  template <class T> inline
298  static T * construct()
299  {
300  return new T();
301  }
302 
303  template <class T> inline
304  static std::false_type load_and_construct(...)
305  { return std::false_type(); }
306 
307  template<class T, class Archive> inline
308  static auto load_and_construct(Archive & ar, ::cereal::construct<T> & construct) -> decltype(T::load_and_construct(ar, construct))
309  {
310  T::load_and_construct( ar, construct );
311  }
312  }; // end class access
313 
314  // ######################################################################
317 
319  enum class specialization
320  {
321  member_serialize,
322  member_load_save,
323  member_load_save_minimal,
324  non_member_serialize,
325  non_member_load_save,
326  non_member_load_save_minimal
327  };
328 
330 
383  template <class Archive, class T, specialization S>
384  struct specialize : public std::false_type {};
385 
387 
397  #define CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES( Type, Specialization ) \
398  namespace cereal { template <class Archive> struct specialize<Archive, Type, Specialization> {}; }
399 
401 
411  #define CEREAL_SPECIALIZE_FOR_ARCHIVE( Archive, Type, Specialization ) \
412  namespace cereal { template <> struct specialize<Archive, Type, Specialization> {}; }
413 
414  // ######################################################################
415  // Deferred Implementation, see construct for more information
416  template <class T> template <class ... Args> inline
417  void construct<T>::operator()( Args && ... args )
418  {
419  if( itsValid )
420  throw Exception("Attempting to construct an already initialized object");
421 
422  ::cereal::access::construct( itsPtr, std::forward<Args>( args )... );
423  itsValid = true;
424  }
425 } // namespace cereal
426 
427 #endif // CEREAL_ACCESS_HPP_
T * operator->()
Get a reference to the initialized underlying object.
Definition: access.hpp:172
specialization
Definition: access.hpp:319
Used to construct types with no default constructor.
Definition: access.hpp:151
static std::false_type load_and_construct(...)
Called by cereal if no default constructor exists to load and construct data simultaneously.
Definition: access.hpp:95
A class that allows cereal to load smart pointers to types that have no default constructor.
Definition: access.hpp:91
Internal helper functionality.
A class that can be made a friend to give cereal access to non public functions.
Definition: access.hpp:223
Definition: access.hpp:39
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:417
T * ptr()
Returns a raw pointer to the initialized underlying object.
Definition: access.hpp:188
A class used to disambiguate cases where cereal cannot detect a unique way of serializing a class...
Definition: access.hpp:384
An exception class thrown when things go wrong at runtime.
Definition: helpers.hpp:48