cereal
A C++11 library for serialization
helpers.hpp
Go to the documentation of this file.
1
4/*
5 Copyright (c) 2014, Randolph Voorhies, Shane Grant
6 All rights reserved.
7
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 * Neither the name of the copyright holder nor the
16 names of its contributors may be used to endorse or promote products
17 derived from this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
23 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*/
30#ifndef CEREAL_DETAILS_HELPERS_HPP_
31#define CEREAL_DETAILS_HELPERS_HPP_
32
33#include <type_traits>
34#include <cstdint>
35#include <utility>
36#include <memory>
37#include <unordered_map>
38#include <stdexcept>
39
40#include "cereal/macros.hpp"
42
43namespace cereal
44{
45 // ######################################################################
47
48 struct Exception : public std::runtime_error
49 {
50 explicit Exception( const std::string & what_ ) : std::runtime_error(what_) {}
51 explicit Exception( const char * what_ ) : std::runtime_error(what_) {}
52 };
53
54 // ######################################################################
56
62
63 // forward decls
66
67 // ######################################################################
68 namespace detail
69 {
71 struct DeferredDataCore {};
72 }
73
74 // ######################################################################
76
138 template <class T>
140 {
141 private:
142 // If we get passed an array, keep the type as is, otherwise store
143 // a reference if we were passed an l value reference, else copy the value
144 using Type = typename std::conditional<std::is_array<typename std::remove_reference<T>::type>::value,
145 typename std::remove_cv<T>::type,
146 typename std::conditional<std::is_lvalue_reference<T>::value,
147 T,
148 typename std::decay<T>::type>::type>::type;
149
150 // prevent nested nvps
151 static_assert( !std::is_base_of<detail::NameValuePairCore, T>::value,
152 "Cannot pair a name to a NameValuePair" );
153
154 NameValuePair & operator=( NameValuePair const & ) = delete;
155
156 public:
158
165 NameValuePair( char const * n, T && v ) : name(n), value(std::forward<T>(v)) {}
166
167 char const * name;
168 Type value;
169 };
170
172
174 template<class Archive, class T> inline
175 typename
176 std::enable_if<std::is_same<Archive, ::cereal::BinaryInputArchive>::value ||
177 std::is_same<Archive, ::cereal::BinaryOutputArchive>::value,
178 T && >::type
179 make_nvp( const char *, T && value )
180 {
181 return std::forward<T>(value);
182 }
183
185
187 template<class Archive, class T> inline
188 typename
189 std::enable_if<!std::is_same<Archive, ::cereal::BinaryInputArchive>::value &&
190 !std::is_same<Archive, ::cereal::BinaryOutputArchive>::value,
191 NameValuePair<T> >::type
192 make_nvp( const char * name, T && value)
193 {
194 return {name, std::forward<T>(value)};
195 }
196
198
201 #define CEREAL_NVP_(name, value) ::cereal::make_nvp<Archive>(name, value)
202
203 // ######################################################################
205
210 template <class T>
212 {
215 using PT = typename std::conditional<std::is_const<typename std::remove_pointer<typename std::remove_reference<T>::type>::type>::value,
216 const void *,
217 void *>::type;
218
219 BinaryData( T && d, uint64_t s ) : data(std::forward<T>(d)), size(s) {}
220
222 uint64_t size;
223 };
224
225 // ######################################################################
227
231 template <class T>
233 {
234 private:
235 // If we get passed an array, keep the type as is, otherwise store
236 // a reference if we were passed an l value reference, else copy the value
237 using Type = typename std::conditional<std::is_array<typename std::remove_reference<T>::type>::value,
238 typename std::remove_cv<T>::type,
239 typename std::conditional<std::is_lvalue_reference<T>::value,
240 T,
241 typename std::decay<T>::type>::type>::type;
242
243 // prevent nested nvps
244 static_assert( !std::is_base_of<detail::DeferredDataCore, T>::value,
245 "Cannot defer DeferredData" );
246
247 DeferredData & operator=( DeferredData const & ) = delete;
248
249 public:
251
257 DeferredData( T && v ) : value(std::forward<T>(v)) {}
258
259 Type value;
260 };
261
262 // ######################################################################
263 namespace detail
264 {
265 // base classes for type checking
266 /* The rtti virtual function only exists to enable an archive to
267 be used in a polymorphic fashion, if necessary. See the
268 archive adapters for an example of this */
270 {
271 public:
272 OutputArchiveBase() = default;
274 OutputArchiveBase & operator=( OutputArchiveBase && ) CEREAL_NOEXCEPT { return *this; }
275 virtual ~OutputArchiveBase() CEREAL_NOEXCEPT = default;
276
277 private:
278 virtual void rtti() {}
279 };
280
282 {
283 public:
284 InputArchiveBase() = default;
286 InputArchiveBase & operator=( InputArchiveBase && ) CEREAL_NOEXCEPT { return *this; }
287 virtual ~InputArchiveBase() CEREAL_NOEXCEPT = default;
288
289 private:
290 virtual void rtti() {}
291 };
292
293 // forward decls for polymorphic support
294 template <class Archive, class T> struct polymorphic_serialization_support;
295 struct adl_tag;
296
297 // used during saving pointers
298 static const uint32_t msb_32bit = 0x80000000;
299 static const int32_t msb2_32bit = 0x40000000;
300 }
301
302 // ######################################################################
304
311 template <class T>
313 {
314 private:
315 // Store a reference if passed an lvalue reference, otherwise
316 // make a copy of the data
317 using Type = typename std::conditional<std::is_lvalue_reference<T>::value,
318 T,
319 typename std::decay<T>::type>::type;
320
321 SizeTag & operator=( SizeTag const & ) = delete;
322
323 public:
324 SizeTag( T && sz ) : size(std::forward<T>(sz)) {}
325
326 Type size;
327 };
328
329 // ######################################################################
331
350 template <class Key, class Value>
351 struct MapItem
352 {
353 using KeyType = typename std::conditional<
354 std::is_lvalue_reference<Key>::value,
355 Key,
356 typename std::decay<Key>::type>::type;
357
358 using ValueType = typename std::conditional<
359 std::is_lvalue_reference<Value>::value,
360 Value,
361 typename std::decay<Value>::type>::type;
362
364
365 MapItem( Key && key_, Value && value_ ) : key(std::forward<Key>(key_)), value(std::forward<Value>(value_)) {}
366
367 MapItem & operator=( MapItem const & ) = delete;
368
369 KeyType key;
370 ValueType value;
371
373 template <class Archive> inline
374 void CEREAL_SERIALIZE_FUNCTION_NAME(Archive & archive)
375 {
376 archive( make_nvp<Archive>("key", key),
377 make_nvp<Archive>("value", value) );
378 }
379 };
380
382
384 template <class KeyType, class ValueType> inline
385 MapItem<KeyType, ValueType> make_map_item(KeyType && key, ValueType && value)
386 {
387 return {std::forward<KeyType>(key), std::forward<ValueType>(value)};
388 }
389
390 namespace detail
391 {
394
395 namespace{ struct version_binding_tag {}; }
396
397 // ######################################################################
399
401 template <class T, class BindingTag = version_binding_tag> struct Version
402 {
403 static const std::uint32_t version = 0;
404 // we don't need to explicitly register these types since they
405 // always get a version number of 0
406 };
407
409 struct Versions
410 {
411 std::unordered_map<std::size_t, std::uint32_t> mapping;
412
413 std::uint32_t find( std::size_t hash, std::uint32_t version )
414 {
415 const auto result = mapping.emplace( hash, version );
416 return result.first->second;
417 }
418 }; // struct Versions
419 } // namespace detail
420} // namespace cereal
421
422#endif // CEREAL_DETAILS_HELPERS_HPP_
An input archive designed to load data saved using BinaryOutputArchive.
Definition: binary.hpp:89
An output archive designed to save data in a compact binary representation.
Definition: binary.hpp:52
A wrapper around data that should be serialized after all non-deferred data.
Definition: helpers.hpp:233
DeferredData(T &&v)
Constructs a new NameValuePair.
Definition: helpers.hpp:257
For holding name value pairs.
Definition: helpers.hpp:140
std::enable_if<!std::is_same< Archive,::cereal::BinaryInputArchive >::value &&!std::is_same< Archive,::cereal::BinaryOutputArchive >::value, NameValuePair< T > >::type make_nvp(const char *name, T &&value)
A specialization of make_nvp<> that actually creates an nvp for non-binary archives.
Definition: helpers.hpp:192
std::enable_if< std::is_same< Archive,::cereal::BinaryInputArchive >::value||std::is_same< Archive,::cereal::BinaryOutputArchive >::value, T && >::type make_nvp(const char *, T &&value)
A specialization of make_nvp<> that simply forwards the value for binary archives.
Definition: helpers.hpp:179
NameValuePair(char const *n, T &&v)
Constructs a new NameValuePair.
Definition: helpers.hpp:165
A wrapper around size metadata.
Definition: helpers.hpp:313
Definition: helpers.hpp:282
Definition: helpers.hpp:270
MapItem< KeyType, ValueType > make_map_item(KeyType &&key, ValueType &&value)
Create a MapItem so that human readable archives will group keys and values together.
Definition: helpers.hpp:385
CEREAL_SIZE_TYPE size_type
The size type used by cereal.
Definition: helpers.hpp:61
Preprocessor macros that can customise the cereal library.
#define CEREAL_SIZE_TYPE
Determines the data type used for size_type.
Definition: macros.hpp:70
#define CEREAL_NOEXCEPT
Defines the CEREAL_NOEXCEPT macro to use instead of noexcept.
Definition: macros.hpp:130
Internal polymorphism static object support.
A wrapper around data that can be serialized in a binary fashion.
Definition: helpers.hpp:212
PT data
pointer to beginning of data
Definition: helpers.hpp:221
typename std::conditional< std::is_const< typename std::remove_pointer< typename std::remove_reference< T >::type >::type >::value, const void *, void * >::type PT
Definition: helpers.hpp:217
uint64_t size
size in bytes
Definition: helpers.hpp:222
An exception class thrown when things go wrong at runtime.
Definition: helpers.hpp:49
A wrapper around a key and value for serializing data into maps.
Definition: helpers.hpp:352
MapItem(Key &&key_, Value &&value_)
Construct a MapItem from a key and a value.
Definition: helpers.hpp:365
void CEREAL_SERIALIZE_FUNCTION_NAME(Archive &archive)
Serialize the MapItem with the NVPs "key" and "value".
Definition: helpers.hpp:374
Traits struct for DeferredData.
Definition: helpers.hpp:71
Traits struct for NVPs.
Definition: helpers.hpp:70
Version information class.
Definition: helpers.hpp:402
Holds all registered version information.
Definition: helpers.hpp:410
Definition: polymorphic_impl.hpp:696
Definition: polymorphic_impl.hpp:747