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 */
228  class OutputArchiveBase { private: virtual void rtti(){} };
229  class InputArchiveBase { private: virtual void rtti(){} };
230 
231  // forward decls for polymorphic support
232  template <class Archive, class T> struct polymorphic_serialization_support;
233  struct adl_tag;
234 
235  // used during saving pointers
236  static const int32_t msb_32bit = 0x80000000;
237  static const int32_t msb2_32bit = 0x40000000;
238  }
239 
240  // ######################################################################
242 
249  template <class T>
250  class SizeTag
251  {
252  private:
253  // Store a reference if passed an lvalue reference, otherwise
254  // make a copy of the data
255  using Type = typename std::conditional<std::is_lvalue_reference<T>::value,
256  T,
257  typename std::decay<T>::type>::type;
258 
259  SizeTag & operator=( SizeTag const & ) = delete;
260 
261  public:
262  SizeTag( T && sz ) : size(std::forward<T>(sz)) {}
263 
264  Type size;
265  };
266 
267  // ######################################################################
269 
288  template <class Key, class Value>
289  struct MapItem
290  {
291  using KeyType = typename std::conditional<
292  std::is_lvalue_reference<Key>::value,
293  Key,
294  typename std::decay<Key>::type>::type;
295 
296  using ValueType = typename std::conditional<
297  std::is_lvalue_reference<Value>::value,
298  Value,
299  typename std::decay<Value>::type>::type;
300 
302 
303  MapItem( Key && key_, Value && value_ ) : key(std::forward<Key>(key_)), value(std::forward<Value>(value_)) {}
304 
305  MapItem & operator=( MapItem const & ) = delete;
306 
307  KeyType key;
308  ValueType value;
309 
311  template <class Archive> inline
312  void CEREAL_SERIALIZE_FUNCTION_NAME(Archive & archive)
313  {
314  archive( make_nvp<Archive>("key", key),
315  make_nvp<Archive>("value", value) );
316  }
317  };
318 
320 
322  template <class KeyType, class ValueType> inline
323  MapItem<KeyType, ValueType> make_map_item(KeyType && key, ValueType && value)
324  {
325  return {std::forward<KeyType>(key), std::forward<ValueType>(value)};
326  }
327 
328  namespace detail
329  {
332 
333  namespace{ struct version_binding_tag {}; }
334 
335  // ######################################################################
337 
339  template <class T, class BindingTag = version_binding_tag> struct Version
340  {
341  static const std::uint32_t version = 0;
342  // we don't need to explicitly register these types since they
343  // always get a version number of 0
344  };
345 
347  struct Versions
348  {
349  std::unordered_map<std::size_t, std::uint32_t> mapping;
350 
351  std::uint32_t find( std::size_t hash, std::uint32_t version )
352  {
353  const auto result = mapping.emplace( hash, version );
354  return result.first->second;
355  }
356  }; // struct Versions
357  } // namespace detail
358 } // namespace cereal
359 
360 #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:250
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:323
A wrapper around a key and value for serializing data into maps.
Definition: helpers.hpp:289
Version information class.
Definition: helpers.hpp:339
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:86
uint64_t size_type
The size type used by cereal.
Definition: helpers.hpp:59
Definition: access.hpp:39
For holding name value pairs.
Definition: helpers.hpp:135
Definition: polymorphic_impl.hpp:322
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:312
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:229
Holds all registered version information.
Definition: helpers.hpp:347
MapItem(Key &&key_, Value &&value_)
Construct a MapItem from a key and a value.
Definition: helpers.hpp:303
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