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 cereal 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 RANDOLPH VOORHIES OR SHANE GRANT 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 
43 namespace 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 
59  using size_type = uint64_t;
60 
61  // forward decls
62  class BinaryOutputArchive;
63  class BinaryInputArchive;
64 
65  // ######################################################################
66  namespace detail
67  {
68  struct NameValuePairCore {};
69  }
70 
72 
134  template <class T>
136  {
137  private:
138  // If we get passed an array, keep the type as is, otherwise store
139  // a reference if we were passed an l value reference, else copy the value
140  using Type = typename std::conditional<std::is_array<typename std::remove_reference<T>::type>::value,
141  typename std::remove_cv<T>::type,
142  typename std::conditional<std::is_lvalue_reference<T>::value,
143  T,
144  typename std::decay<T>::type>::type>::type;
145 
146  // prevent nested nvps
147  static_assert( !std::is_base_of<detail::NameValuePairCore, T>::value,
148  "Cannot pair a name to a NameValuePair" );
149 
150  NameValuePair & operator=( NameValuePair const & ) = delete;
151 
152  public:
154 
161  NameValuePair( char const * n, T && v ) : name(n), value(std::forward<T>(v)) {}
162 
163  char const * name;
164  Type value;
165  };
166 
168 
170  template<class Archive, class T> inline
171  typename
172  std::enable_if<std::is_same<Archive, ::cereal::BinaryInputArchive>::value ||
173  std::is_same<Archive, ::cereal::BinaryOutputArchive>::value,
174  T && >::type
175  make_nvp( const char *, T && value )
176  {
177  return std::forward<T>(value);
178  }
179 
181 
183  template<class Archive, class T> inline
184  typename
185  std::enable_if<!std::is_same<Archive, ::cereal::BinaryInputArchive>::value &&
186  !std::is_same<Archive, ::cereal::BinaryOutputArchive>::value,
187  NameValuePair<T> >::type
188  make_nvp( const char * name, T && value)
189  {
190  return {name, std::forward<T>(value)};
191  }
192 
194 
197  #define CEREAL_NVP_(name, value) ::cereal::make_nvp<Archive>(name, value)
198 
199  // ######################################################################
201 
206  template <class T>
207  struct BinaryData
208  {
211  using PT = typename std::conditional<std::is_const<typename std::remove_pointer<T>::type>::value,
212  const void *,
213  void *>::type;
214 
215  BinaryData( T && d, uint64_t s ) : data(std::forward<T>(d)), size(s) {}
216 
218  uint64_t size;
219  };
220 
221  // ######################################################################
222  namespace detail
223  {
224  // base classes for type checking
225  /* The rtti virtual function only exists to enable an archive to
226  be used in a polymorphic fashion, if necessary. See the
227  archive adapters for an example of this */
229  {
230  public:
231  OutputArchiveBase() = default;
233  OutputArchiveBase & operator=( OutputArchiveBase && ) CEREAL_NOEXCEPT { return *this; }
234  virtual ~OutputArchiveBase() CEREAL_NOEXCEPT = default;
235 
236  private:
237  virtual void rtti() {}
238  };
239 
241  {
242  public:
243  InputArchiveBase() = default;
245  InputArchiveBase & operator=( InputArchiveBase && ) CEREAL_NOEXCEPT { return *this; }
246  virtual ~InputArchiveBase() CEREAL_NOEXCEPT = default;
247 
248  private:
249  virtual void rtti() {}
250  };
251 
252  // forward decls for polymorphic support
253  template <class Archive, class T> struct polymorphic_serialization_support;
254  struct adl_tag;
255 
256  // used during saving pointers
257  static const int32_t msb_32bit = 0x80000000;
258  static const int32_t msb2_32bit = 0x40000000;
259  }
260 
261  // ######################################################################
263 
270  template <class T>
271  class SizeTag
272  {
273  private:
274  // Store a reference if passed an lvalue reference, otherwise
275  // make a copy of the data
276  using Type = typename std::conditional<std::is_lvalue_reference<T>::value,
277  T,
278  typename std::decay<T>::type>::type;
279 
280  SizeTag & operator=( SizeTag const & ) = delete;
281 
282  public:
283  SizeTag( T && sz ) : size(std::forward<T>(sz)) {}
284 
285  Type size;
286  };
287 
288  // ######################################################################
290 
309  template <class Key, class Value>
310  struct MapItem
311  {
312  using KeyType = typename std::conditional<
313  std::is_lvalue_reference<Key>::value,
314  Key,
315  typename std::decay<Key>::type>::type;
316 
317  using ValueType = typename std::conditional<
318  std::is_lvalue_reference<Value>::value,
319  Value,
320  typename std::decay<Value>::type>::type;
321 
323 
324  MapItem( Key && key_, Value && value_ ) : key(std::forward<Key>(key_)), value(std::forward<Value>(value_)) {}
325 
326  MapItem & operator=( MapItem const & ) = delete;
327 
328  KeyType key;
329  ValueType value;
330 
332  template <class Archive> inline
333  void CEREAL_SERIALIZE_FUNCTION_NAME(Archive & archive)
334  {
335  archive( make_nvp<Archive>("key", key),
336  make_nvp<Archive>("value", value) );
337  }
338  };
339 
341 
343  template <class KeyType, class ValueType> inline
344  MapItem<KeyType, ValueType> make_map_item(KeyType && key, ValueType && value)
345  {
346  return {std::forward<KeyType>(key), std::forward<ValueType>(value)};
347  }
348 
349  namespace detail
350  {
353 
354  namespace{ struct version_binding_tag {}; }
355 
356  // ######################################################################
358 
360  template <class T, class BindingTag = version_binding_tag> struct Version
361  {
362  static const std::uint32_t version = 0;
363  // we don't need to explicitly register these types since they
364  // always get a version number of 0
365  };
366 
368  struct Versions
369  {
370  std::unordered_map<std::size_t, std::uint32_t> mapping;
371 
372  std::uint32_t find( std::size_t hash, std::uint32_t version )
373  {
374  const auto result = mapping.emplace( hash, version );
375  return result.first->second;
376  }
377  }; // struct Versions
378  } // namespace detail
379 } // namespace cereal
380 
381 #endif // CEREAL_DETAILS_HELPERS_HPP_
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:188
PT data
pointer to beginning of data
Definition: helpers.hpp:217
A wrapper around size metadata.
Definition: helpers.hpp:271
Traits struct for NVPs.
Definition: helpers.hpp:68
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:344
A wrapper around a key and value for serializing data into maps.
Definition: helpers.hpp:310
Version information class.
Definition: helpers.hpp:360
typename std::conditional< std::is_const< typename std::remove_pointer< T >::type >::value, const void *, void * >::type PT
Definition: helpers.hpp:213
STL namespace.
NameValuePair(char const *n, T &&v)
Constructs a new NameValuePair.
Definition: helpers.hpp:161
An input archive designed to load data saved using BinaryOutputArchive.
Definition: binary.hpp:88
uint64_t size_type
The size type used by cereal.
Definition: helpers.hpp:59
Definition: access.hpp:40
For holding name value pairs.
Definition: helpers.hpp:135
Definition: polymorphic_impl.hpp:573
Preprocessor macros that can customise the cereal library.
void CEREAL_SERIALIZE_FUNCTION_NAME(Archive &archive)
Serialize the MapItem with the NVPs "key" and "value".
Definition: helpers.hpp:333
#define CEREAL_NOEXCEPT
Defines the CEREAL_NOEXCEPT macro to use instead of noexcept.
Definition: macros.hpp:116
A wrapper around data that can be serialized in a binary fashion.
Definition: helpers.hpp:207
Definition: helpers.hpp:228
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:175
uint64_t size
size in bytes
Definition: helpers.hpp:218
Definition: helpers.hpp:240
Holds all registered version information.
Definition: helpers.hpp:368
MapItem(Key &&key_, Value &&value_)
Construct a MapItem from a key and a value.
Definition: helpers.hpp:324
Internal polymorphism static object support.
An exception class thrown when things go wrong at runtime.
Definition: helpers.hpp:48
An output archive designed to save data in a compact binary representation.
Definition: binary.hpp:51