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