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
41namespace 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>
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_
A class that can be made a friend to give cereal access to non public functions.
Definition: access.hpp:241
Used to construct types with no default constructor.
Definition: access.hpp:165
T * ptr()
Returns a raw pointer to the initialized underlying object.
Definition: access.hpp:201
void operator()(Args &&... args)
Construct and initialize the type T with the given arguments.
Definition: access.hpp:340
T * operator->()
Get a reference to the initialized underlying object.
Definition: access.hpp:185
Internal helper functionality.
Preprocessor macros that can customise the cereal library.
Serialization disambiguation.
An exception class thrown when things go wrong at runtime.
Definition: helpers.hpp:49
A class that allows cereal to load smart pointers to types that have no default constructor.
Definition: access.hpp:109