git repos / blockattack-game

blame: source/code/Libs/include/cereal/details/helpers.hpp

normal view · raw

7a956470 sago007 2016-02-14 17:09 1
/*! \file helpers.hpp
7a956470 sago007 2016-02-14 17:09 2
    \brief Internal helper functionality
7a956470 sago007 2016-02-14 17:09 3
    \ingroup Internal */
7a956470 sago007 2016-02-14 17:09 4
/*
7a956470 sago007 2016-02-14 17:09 5
  Copyright (c) 2014, Randolph Voorhies, Shane Grant
7a956470 sago007 2016-02-14 17:09 6
  All rights reserved.
7a956470 sago007 2016-02-14 17:09 7
7a956470 sago007 2016-02-14 17:09 8
  Redistribution and use in source and binary forms, with or without
7a956470 sago007 2016-02-14 17:09 9
  modification, are permitted provided that the following conditions are met:
7a956470 sago007 2016-02-14 17:09 10
      * Redistributions of source code must retain the above copyright
7a956470 sago007 2016-02-14 17:09 11
        notice, this list of conditions and the following disclaimer.
7a956470 sago007 2016-02-14 17:09 12
      * Redistributions in binary form must reproduce the above copyright
7a956470 sago007 2016-02-14 17:09 13
        notice, this list of conditions and the following disclaimer in the
7a956470 sago007 2016-02-14 17:09 14
        documentation and/or other materials provided with the distribution.
7a956470 sago007 2016-02-14 17:09 15
      * Neither the name of cereal nor the
7a956470 sago007 2016-02-14 17:09 16
        names of its contributors may be used to endorse or promote products
7a956470 sago007 2016-02-14 17:09 17
        derived from this software without specific prior written permission.
7a956470 sago007 2016-02-14 17:09 18
7a956470 sago007 2016-02-14 17:09 19
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
7a956470 sago007 2016-02-14 17:09 20
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7a956470 sago007 2016-02-14 17:09 21
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
7a956470 sago007 2016-02-14 17:09 22
  DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES OR SHANE GRANT BE LIABLE FOR ANY
7a956470 sago007 2016-02-14 17:09 23
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7a956470 sago007 2016-02-14 17:09 24
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
7a956470 sago007 2016-02-14 17:09 25
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
7a956470 sago007 2016-02-14 17:09 26
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7a956470 sago007 2016-02-14 17:09 27
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
7a956470 sago007 2016-02-14 17:09 28
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7a956470 sago007 2016-02-14 17:09 29
*/
7a956470 sago007 2016-02-14 17:09 30
#ifndef CEREAL_DETAILS_HELPERS_HPP_
7a956470 sago007 2016-02-14 17:09 31
#define CEREAL_DETAILS_HELPERS_HPP_
7a956470 sago007 2016-02-14 17:09 32
7a956470 sago007 2016-02-14 17:09 33
#include <type_traits>
7a956470 sago007 2016-02-14 17:09 34
#include <cstdint>
7a956470 sago007 2016-02-14 17:09 35
#include <utility>
7a956470 sago007 2016-02-14 17:09 36
#include <memory>
7a956470 sago007 2016-02-14 17:09 37
#include <unordered_map>
7a956470 sago007 2016-02-14 17:09 38
#include <stdexcept>
7a956470 sago007 2016-02-14 17:09 39
7a956470 sago007 2016-02-14 17:09 40
#include <cereal/macros.hpp>
7a956470 sago007 2016-02-14 17:09 41
#include <cereal/details/static_object.hpp>
7a956470 sago007 2016-02-14 17:09 42
7a956470 sago007 2016-02-14 17:09 43
namespace cereal
7a956470 sago007 2016-02-14 17:09 44
{
7a956470 sago007 2016-02-14 17:09 45
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 46
  //! An exception class thrown when things go wrong at runtime
7a956470 sago007 2016-02-14 17:09 47
  /*! @ingroup Utility */
7a956470 sago007 2016-02-14 17:09 48
  struct Exception : public std::runtime_error
7a956470 sago007 2016-02-14 17:09 49
  {
7a956470 sago007 2016-02-14 17:09 50
    explicit Exception( const std::string & what_ ) : std::runtime_error(what_) {}
7a956470 sago007 2016-02-14 17:09 51
    explicit Exception( const char * what_ ) : std::runtime_error(what_) {}
7a956470 sago007 2016-02-14 17:09 52
  };
7a956470 sago007 2016-02-14 17:09 53
7a956470 sago007 2016-02-14 17:09 54
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 55
  //! The size type used by cereal
7a956470 sago007 2016-02-14 17:09 56
  /*! To ensure compatability between 32, 64, etc bit machines, we need to use
7a956470 sago007 2016-02-14 17:09 57
      a fixed size type instead of size_t, which may vary from machine to
7a956470 sago007 2016-02-14 17:09 58
      machine. */
7a956470 sago007 2016-02-14 17:09 59
  using size_type = uint64_t;
7a956470 sago007 2016-02-14 17:09 60
7a956470 sago007 2016-02-14 17:09 61
  // forward decls
7a956470 sago007 2016-02-14 17:09 62
  class BinaryOutputArchive;
7a956470 sago007 2016-02-14 17:09 63
  class BinaryInputArchive;
7a956470 sago007 2016-02-14 17:09 64
7a956470 sago007 2016-02-14 17:09 65
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 66
  namespace detail
7a956470 sago007 2016-02-14 17:09 67
  {
7a956470 sago007 2016-02-14 17:09 68
    struct NameValuePairCore {}; //!< Traits struct for NVPs
7a956470 sago007 2016-02-14 17:09 69
  }
7a956470 sago007 2016-02-14 17:09 70
7a956470 sago007 2016-02-14 17:09 71
  //! For holding name value pairs
7a956470 sago007 2016-02-14 17:09 72
  /*! This pairs a name (some string) with some value such that an archive
7a956470 sago007 2016-02-14 17:09 73
      can potentially take advantage of the pairing.
7a956470 sago007 2016-02-14 17:09 74
7a956470 sago007 2016-02-14 17:09 75
      In serialization functions, NameValuePairs are usually created like so:
7a956470 sago007 2016-02-14 17:09 76
      @code{.cpp}
7a956470 sago007 2016-02-14 17:09 77
      struct MyStruct
7a956470 sago007 2016-02-14 17:09 78
      {
7a956470 sago007 2016-02-14 17:09 79
        int a, b, c, d, e;
7a956470 sago007 2016-02-14 17:09 80
7a956470 sago007 2016-02-14 17:09 81
        template<class Archive>
7a956470 sago007 2016-02-14 17:09 82
        void serialize(Archive & archive)
7a956470 sago007 2016-02-14 17:09 83
        {
7a956470 sago007 2016-02-14 17:09 84
          archive( CEREAL_NVP(a),
7a956470 sago007 2016-02-14 17:09 85
                   CEREAL_NVP(b),
7a956470 sago007 2016-02-14 17:09 86
                   CEREAL_NVP(c),
7a956470 sago007 2016-02-14 17:09 87
                   CEREAL_NVP(d),
7a956470 sago007 2016-02-14 17:09 88
                   CEREAL_NVP(e) );
7a956470 sago007 2016-02-14 17:09 89
        }
7a956470 sago007 2016-02-14 17:09 90
      };
7a956470 sago007 2016-02-14 17:09 91
      @endcode
7a956470 sago007 2016-02-14 17:09 92
7a956470 sago007 2016-02-14 17:09 93
      Alternatively, you can give you data members custom names like so:
7a956470 sago007 2016-02-14 17:09 94
      @code{.cpp}
7a956470 sago007 2016-02-14 17:09 95
      struct MyStruct
7a956470 sago007 2016-02-14 17:09 96
      {
7a956470 sago007 2016-02-14 17:09 97
        int a, b, my_embarrassing_variable_name, d, e;
7a956470 sago007 2016-02-14 17:09 98
7a956470 sago007 2016-02-14 17:09 99
        template<class Archive>
7a956470 sago007 2016-02-14 17:09 100
        void serialize(Archive & archive)
7a956470 sago007 2016-02-14 17:09 101
        {
7a956470 sago007 2016-02-14 17:09 102
          archive( CEREAL_NVP(a),
7a956470 sago007 2016-02-14 17:09 103
                   CEREAL_NVP(b),
7a956470 sago007 2016-02-14 17:09 104
                   cereal::make_nvp("var", my_embarrassing_variable_name) );
7a956470 sago007 2016-02-14 17:09 105
                   CEREAL_NVP(d),
7a956470 sago007 2016-02-14 17:09 106
                   CEREAL_NVP(e) );
7a956470 sago007 2016-02-14 17:09 107
        }
7a956470 sago007 2016-02-14 17:09 108
      };
7a956470 sago007 2016-02-14 17:09 109
      @endcode
7a956470 sago007 2016-02-14 17:09 110
7a956470 sago007 2016-02-14 17:09 111
      There is a slight amount of overhead to creating NameValuePairs, so there
7a956470 sago007 2016-02-14 17:09 112
      is a third method which will elide the names when they are not used by
7a956470 sago007 2016-02-14 17:09 113
      the Archive:
7a956470 sago007 2016-02-14 17:09 114
7a956470 sago007 2016-02-14 17:09 115
      @code{.cpp}
7a956470 sago007 2016-02-14 17:09 116
      struct MyStruct
7a956470 sago007 2016-02-14 17:09 117
      {
7a956470 sago007 2016-02-14 17:09 118
        int a, b;
7a956470 sago007 2016-02-14 17:09 119
7a956470 sago007 2016-02-14 17:09 120
        template<class Archive>
7a956470 sago007 2016-02-14 17:09 121
        void serialize(Archive & archive)
7a956470 sago007 2016-02-14 17:09 122
        {
7a956470 sago007 2016-02-14 17:09 123
          archive( cereal::make_nvp<Archive>(a),
7a956470 sago007 2016-02-14 17:09 124
                   cereal::make_nvp<Archive>(b) );
7a956470 sago007 2016-02-14 17:09 125
        }
7a956470 sago007 2016-02-14 17:09 126
      };
7a956470 sago007 2016-02-14 17:09 127
      @endcode
7a956470 sago007 2016-02-14 17:09 128
7a956470 sago007 2016-02-14 17:09 129
      This third method is generally only used when providing generic type
7a956470 sago007 2016-02-14 17:09 130
      support.  Users writing their own serialize functions will normally
7a956470 sago007 2016-02-14 17:09 131
      explicitly control whether they want to use NVPs or not.
7a956470 sago007 2016-02-14 17:09 132
7a956470 sago007 2016-02-14 17:09 133
      @internal */
7a956470 sago007 2016-02-14 17:09 134
  template <class T>
7a956470 sago007 2016-02-14 17:09 135
  class NameValuePair : detail::NameValuePairCore
7a956470 sago007 2016-02-14 17:09 136
  {
7a956470 sago007 2016-02-14 17:09 137
    private:
7a956470 sago007 2016-02-14 17:09 138
      // If we get passed an array, keep the type as is, otherwise store
7a956470 sago007 2016-02-14 17:09 139
      // a reference if we were passed an l value reference, else copy the value
7a956470 sago007 2016-02-14 17:09 140
      using Type = typename std::conditional<std::is_array<typename std::remove_reference<T>::type>::value,
7a956470 sago007 2016-02-14 17:09 141
                                             typename std::remove_cv<T>::type,
7a956470 sago007 2016-02-14 17:09 142
                                             typename std::conditional<std::is_lvalue_reference<T>::value,
7a956470 sago007 2016-02-14 17:09 143
                                                                       T,
7a956470 sago007 2016-02-14 17:09 144
                                                                       typename std::decay<T>::type>::type>::type;
7a956470 sago007 2016-02-14 17:09 145
7a956470 sago007 2016-02-14 17:09 146
      // prevent nested nvps
7a956470 sago007 2016-02-14 17:09 147
      static_assert( !std::is_base_of<detail::NameValuePairCore, T>::value,
7a956470 sago007 2016-02-14 17:09 148
                     "Cannot pair a name to a NameValuePair" );
7a956470 sago007 2016-02-14 17:09 149
7a956470 sago007 2016-02-14 17:09 150
      NameValuePair & operator=( NameValuePair const & ) = delete;
7a956470 sago007 2016-02-14 17:09 151
7a956470 sago007 2016-02-14 17:09 152
    public:
7a956470 sago007 2016-02-14 17:09 153
      //! Constructs a new NameValuePair
7a956470 sago007 2016-02-14 17:09 154
      /*! @param n The name of the pair
7a956470 sago007 2016-02-14 17:09 155
          @param v The value to pair.  Ideally this should be an l-value reference so that
7a956470 sago007 2016-02-14 17:09 156
                   the value can be both loaded and saved to.  If you pass an r-value reference,
7a956470 sago007 2016-02-14 17:09 157
                   the NameValuePair will store a copy of it instead of a reference.  Thus you should
7a956470 sago007 2016-02-14 17:09 158
                   only pass r-values in cases where this makes sense, such as the result of some
7a956470 sago007 2016-02-14 17:09 159
                   size() call.
7a956470 sago007 2016-02-14 17:09 160
          @internal */
7a956470 sago007 2016-02-14 17:09 161
      NameValuePair( char const * n, T && v ) : name(n), value(std::forward<T>(v)) {}
7a956470 sago007 2016-02-14 17:09 162
7a956470 sago007 2016-02-14 17:09 163
      char const * name;
7a956470 sago007 2016-02-14 17:09 164
      Type value;
7a956470 sago007 2016-02-14 17:09 165
  };
7a956470 sago007 2016-02-14 17:09 166
7a956470 sago007 2016-02-14 17:09 167
  //! A specialization of make_nvp<> that simply forwards the value for binary archives
7a956470 sago007 2016-02-14 17:09 168
  /*! @relates NameValuePair
7a956470 sago007 2016-02-14 17:09 169
      @internal */
7a956470 sago007 2016-02-14 17:09 170
  template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 171
  typename
7a956470 sago007 2016-02-14 17:09 172
  std::enable_if<std::is_same<Archive, ::cereal::BinaryInputArchive>::value ||
7a956470 sago007 2016-02-14 17:09 173
                 std::is_same<Archive, ::cereal::BinaryOutputArchive>::value,
7a956470 sago007 2016-02-14 17:09 174
  T && >::type
7a956470 sago007 2016-02-14 17:09 175
  make_nvp( const char *, T && value )
7a956470 sago007 2016-02-14 17:09 176
  {
7a956470 sago007 2016-02-14 17:09 177
    return std::forward<T>(value);
7a956470 sago007 2016-02-14 17:09 178
  }
7a956470 sago007 2016-02-14 17:09 179
7a956470 sago007 2016-02-14 17:09 180
  //! A specialization of make_nvp<> that actually creates an nvp for non-binary archives
7a956470 sago007 2016-02-14 17:09 181
  /*! @relates NameValuePair
7a956470 sago007 2016-02-14 17:09 182
      @internal */
7a956470 sago007 2016-02-14 17:09 183
  template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 184
  typename
7a956470 sago007 2016-02-14 17:09 185
  std::enable_if<!std::is_same<Archive, ::cereal::BinaryInputArchive>::value &&
7a956470 sago007 2016-02-14 17:09 186
                 !std::is_same<Archive, ::cereal::BinaryOutputArchive>::value,
7a956470 sago007 2016-02-14 17:09 187
  NameValuePair<T> >::type
7a956470 sago007 2016-02-14 17:09 188
  make_nvp( const char * name, T && value)
7a956470 sago007 2016-02-14 17:09 189
  {
7a956470 sago007 2016-02-14 17:09 190
    return {name, std::forward<T>(value)};
7a956470 sago007 2016-02-14 17:09 191
  }
7a956470 sago007 2016-02-14 17:09 192
7a956470 sago007 2016-02-14 17:09 193
  //! Convenience for creating a templated NVP
7a956470 sago007 2016-02-14 17:09 194
  /*! For use in inteneral generic typing functions which have an
7a956470 sago007 2016-02-14 17:09 195
      Archive type declared
7a956470 sago007 2016-02-14 17:09 196
      @internal */
7a956470 sago007 2016-02-14 17:09 197
  #define CEREAL_NVP_(name, value) ::cereal::make_nvp<Archive>(name, value)
7a956470 sago007 2016-02-14 17:09 198
7a956470 sago007 2016-02-14 17:09 199
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 200
  //! A wrapper around data that can be serialized in a binary fashion
7a956470 sago007 2016-02-14 17:09 201
  /*! This class is used to demarcate data that can safely be serialized
7a956470 sago007 2016-02-14 17:09 202
      as a binary chunk of data.  Individual archives can then choose how
7a956470 sago007 2016-02-14 17:09 203
      best represent this during serialization.
7a956470 sago007 2016-02-14 17:09 204
7a956470 sago007 2016-02-14 17:09 205
      @internal */
7a956470 sago007 2016-02-14 17:09 206
  template <class T>
7a956470 sago007 2016-02-14 17:09 207
  struct BinaryData
7a956470 sago007 2016-02-14 17:09 208
  {
7a956470 sago007 2016-02-14 17:09 209
    //! Internally store the pointer as a void *, keeping const if created with
7a956470 sago007 2016-02-14 17:09 210
    //! a const pointer
7a956470 sago007 2016-02-14 17:09 211
    using PT = typename std::conditional<std::is_const<typename std::remove_pointer<T>::type>::value,
7a956470 sago007 2016-02-14 17:09 212
                                         const void *,
7a956470 sago007 2016-02-14 17:09 213
                                         void *>::type;
7a956470 sago007 2016-02-14 17:09 214
7a956470 sago007 2016-02-14 17:09 215
    BinaryData( T && d, uint64_t s ) : data(std::forward<T>(d)), size(s) {}
7a956470 sago007 2016-02-14 17:09 216
7a956470 sago007 2016-02-14 17:09 217
    PT data;       //!< pointer to beginning of data
7a956470 sago007 2016-02-14 17:09 218
    uint64_t size; //!< size in bytes
7a956470 sago007 2016-02-14 17:09 219
  };
7a956470 sago007 2016-02-14 17:09 220
7a956470 sago007 2016-02-14 17:09 221
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 222
  namespace detail
7a956470 sago007 2016-02-14 17:09 223
  {
7a956470 sago007 2016-02-14 17:09 224
    // base classes for type checking
7a956470 sago007 2016-02-14 17:09 225
    /* The rtti virtual function only exists to enable an archive to
7a956470 sago007 2016-02-14 17:09 226
       be used in a polymorphic fashion, if necessary.  See the
7a956470 sago007 2016-02-14 17:09 227
       archive adapters for an example of this */
7a956470 sago007 2016-02-14 17:09 228
    class OutputArchiveBase { private: virtual void rtti(){} };
7a956470 sago007 2016-02-14 17:09 229
    class InputArchiveBase { private: virtual void rtti(){} };
7a956470 sago007 2016-02-14 17:09 230
7a956470 sago007 2016-02-14 17:09 231
    // forward decls for polymorphic support
7a956470 sago007 2016-02-14 17:09 232
    template <class Archive, class T> struct polymorphic_serialization_support;
7a956470 sago007 2016-02-14 17:09 233
    struct adl_tag;
7a956470 sago007 2016-02-14 17:09 234
7a956470 sago007 2016-02-14 17:09 235
    // used during saving pointers
7a956470 sago007 2016-02-14 17:09 236
    static const int32_t msb_32bit  = 0x80000000;
7a956470 sago007 2016-02-14 17:09 237
    static const int32_t msb2_32bit = 0x40000000;
7a956470 sago007 2016-02-14 17:09 238
  }
7a956470 sago007 2016-02-14 17:09 239
7a956470 sago007 2016-02-14 17:09 240
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 241
  //! A wrapper around size metadata
7a956470 sago007 2016-02-14 17:09 242
  /*! This class provides a way for archives to have more flexibility over how
7a956470 sago007 2016-02-14 17:09 243
      they choose to serialize size metadata for containers.  For some archive
7a956470 sago007 2016-02-14 17:09 244
      types, the size may be implicitly encoded in the output (e.g. JSON) and
7a956470 sago007 2016-02-14 17:09 245
      not need an explicit entry.  Specializing serialize or load/save for
7a956470 sago007 2016-02-14 17:09 246
      your archive and SizeTags allows you to choose what happens.
7a956470 sago007 2016-02-14 17:09 247
7a956470 sago007 2016-02-14 17:09 248
      @internal */
7a956470 sago007 2016-02-14 17:09 249
  template <class T>
7a956470 sago007 2016-02-14 17:09 250
  class SizeTag
7a956470 sago007 2016-02-14 17:09 251
  {
7a956470 sago007 2016-02-14 17:09 252
    private:
7a956470 sago007 2016-02-14 17:09 253
      // Store a reference if passed an lvalue reference, otherwise
7a956470 sago007 2016-02-14 17:09 254
      // make a copy of the data
7a956470 sago007 2016-02-14 17:09 255
      using Type = typename std::conditional<std::is_lvalue_reference<T>::value,
7a956470 sago007 2016-02-14 17:09 256
                                             T,
7a956470 sago007 2016-02-14 17:09 257
                                             typename std::decay<T>::type>::type;
7a956470 sago007 2016-02-14 17:09 258
7a956470 sago007 2016-02-14 17:09 259
      SizeTag & operator=( SizeTag const & ) = delete;
7a956470 sago007 2016-02-14 17:09 260
7a956470 sago007 2016-02-14 17:09 261
    public:
7a956470 sago007 2016-02-14 17:09 262
      SizeTag( T && sz ) : size(std::forward<T>(sz)) {}
7a956470 sago007 2016-02-14 17:09 263
7a956470 sago007 2016-02-14 17:09 264
      Type size;
7a956470 sago007 2016-02-14 17:09 265
  };
7a956470 sago007 2016-02-14 17:09 266
7a956470 sago007 2016-02-14 17:09 267
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 268
  //! A wrapper around a key and value for serializing data into maps.
7a956470 sago007 2016-02-14 17:09 269
  /*! This class just provides a grouping of keys and values into a struct for
7a956470 sago007 2016-02-14 17:09 270
      human readable archives. For example, XML archives will use this wrapper
7a956470 sago007 2016-02-14 17:09 271
      to write maps like so:
7a956470 sago007 2016-02-14 17:09 272
7a956470 sago007 2016-02-14 17:09 273
      @code{.xml}
7a956470 sago007 2016-02-14 17:09 274
      <mymap>
7a956470 sago007 2016-02-14 17:09 275
        <item0>
7a956470 sago007 2016-02-14 17:09 276
          <key>MyFirstKey</key>
7a956470 sago007 2016-02-14 17:09 277
          <value>MyFirstValue</value>
7a956470 sago007 2016-02-14 17:09 278
        </item0>
7a956470 sago007 2016-02-14 17:09 279
        <item1>
7a956470 sago007 2016-02-14 17:09 280
          <key>MySecondKey</key>
7a956470 sago007 2016-02-14 17:09 281
          <value>MySecondValue</value>
7a956470 sago007 2016-02-14 17:09 282
        </item1>
7a956470 sago007 2016-02-14 17:09 283
      </mymap>
7a956470 sago007 2016-02-14 17:09 284
      @endcode
7a956470 sago007 2016-02-14 17:09 285
7a956470 sago007 2016-02-14 17:09 286
      \sa make_map_item
7a956470 sago007 2016-02-14 17:09 287
      @internal */
7a956470 sago007 2016-02-14 17:09 288
  template <class Key, class Value>
7a956470 sago007 2016-02-14 17:09 289
  struct MapItem
7a956470 sago007 2016-02-14 17:09 290
  {
7a956470 sago007 2016-02-14 17:09 291
    using KeyType = typename std::conditional<
7a956470 sago007 2016-02-14 17:09 292
      std::is_lvalue_reference<Key>::value,
7a956470 sago007 2016-02-14 17:09 293
      Key,
7a956470 sago007 2016-02-14 17:09 294
      typename std::decay<Key>::type>::type;
7a956470 sago007 2016-02-14 17:09 295
7a956470 sago007 2016-02-14 17:09 296
    using ValueType = typename std::conditional<
7a956470 sago007 2016-02-14 17:09 297
      std::is_lvalue_reference<Value>::value,
7a956470 sago007 2016-02-14 17:09 298
      Value,
7a956470 sago007 2016-02-14 17:09 299
      typename std::decay<Value>::type>::type;
7a956470 sago007 2016-02-14 17:09 300
7a956470 sago007 2016-02-14 17:09 301
    //! Construct a MapItem from a key and a value
7a956470 sago007 2016-02-14 17:09 302
    /*! @internal */
7a956470 sago007 2016-02-14 17:09 303
    MapItem( Key && key_, Value && value_ ) : key(std::forward<Key>(key_)), value(std::forward<Value>(value_)) {}
7a956470 sago007 2016-02-14 17:09 304
7a956470 sago007 2016-02-14 17:09 305
    MapItem & operator=( MapItem const & ) = delete;
7a956470 sago007 2016-02-14 17:09 306
7a956470 sago007 2016-02-14 17:09 307
    KeyType key;
7a956470 sago007 2016-02-14 17:09 308
    ValueType value;
7a956470 sago007 2016-02-14 17:09 309
7a956470 sago007 2016-02-14 17:09 310
    //! Serialize the MapItem with the NVPs "key" and "value"
7a956470 sago007 2016-02-14 17:09 311
    template <class Archive> inline
7a956470 sago007 2016-02-14 17:09 312
    void CEREAL_SERIALIZE_FUNCTION_NAME(Archive & archive)
7a956470 sago007 2016-02-14 17:09 313
    {
7a956470 sago007 2016-02-14 17:09 314
      archive( make_nvp<Archive>("key",   key),
7a956470 sago007 2016-02-14 17:09 315
               make_nvp<Archive>("value", value) );
7a956470 sago007 2016-02-14 17:09 316
    }
7a956470 sago007 2016-02-14 17:09 317
  };
7a956470 sago007 2016-02-14 17:09 318
7a956470 sago007 2016-02-14 17:09 319
  //! Create a MapItem so that human readable archives will group keys and values together
7a956470 sago007 2016-02-14 17:09 320
  /*! @internal
7a956470 sago007 2016-02-14 17:09 321
      @relates MapItem */
7a956470 sago007 2016-02-14 17:09 322
  template <class KeyType, class ValueType> inline
7a956470 sago007 2016-02-14 17:09 323
  MapItem<KeyType, ValueType> make_map_item(KeyType && key, ValueType && value)
7a956470 sago007 2016-02-14 17:09 324
  {
7a956470 sago007 2016-02-14 17:09 325
    return {std::forward<KeyType>(key), std::forward<ValueType>(value)};
7a956470 sago007 2016-02-14 17:09 326
  }
7a956470 sago007 2016-02-14 17:09 327
7a956470 sago007 2016-02-14 17:09 328
  namespace detail
7a956470 sago007 2016-02-14 17:09 329
  {
7a956470 sago007 2016-02-14 17:09 330
    //! Tag for Version, which due to its anonymous namespace, becomes a different
7a956470 sago007 2016-02-14 17:09 331
    //! type in each translation unit
7a956470 sago007 2016-02-14 17:09 332
    /*! This allows CEREAL_CLASS_VERSION to be safely called in a header file */
7a956470 sago007 2016-02-14 17:09 333
    namespace{ struct version_binding_tag {}; }
7a956470 sago007 2016-02-14 17:09 334
7a956470 sago007 2016-02-14 17:09 335
    // ######################################################################
7a956470 sago007 2016-02-14 17:09 336
    //! Version information class
7a956470 sago007 2016-02-14 17:09 337
    /*! This is the base case for classes that have not been explicitly
7a956470 sago007 2016-02-14 17:09 338
        registered */
7a956470 sago007 2016-02-14 17:09 339
    template <class T, class BindingTag = version_binding_tag> struct Version
7a956470 sago007 2016-02-14 17:09 340
    {
7a956470 sago007 2016-02-14 17:09 341
      static const std::uint32_t version = 0;
7a956470 sago007 2016-02-14 17:09 342
      // we don't need to explicitly register these types since they
7a956470 sago007 2016-02-14 17:09 343
      // always get a version number of 0
7a956470 sago007 2016-02-14 17:09 344
    };
7a956470 sago007 2016-02-14 17:09 345
7a956470 sago007 2016-02-14 17:09 346
    //! Holds all registered version information
7a956470 sago007 2016-02-14 17:09 347
    struct Versions
7a956470 sago007 2016-02-14 17:09 348
    {
7a956470 sago007 2016-02-14 17:09 349
      std::unordered_map<std::size_t, std::uint32_t> mapping;
7a956470 sago007 2016-02-14 17:09 350
7a956470 sago007 2016-02-14 17:09 351
      std::uint32_t find( std::size_t hash, std::uint32_t version )
7a956470 sago007 2016-02-14 17:09 352
      {
7a956470 sago007 2016-02-14 17:09 353
        const auto result = mapping.emplace( hash, version );
7a956470 sago007 2016-02-14 17:09 354
        return result.first->second;
7a956470 sago007 2016-02-14 17:09 355
      }
7a956470 sago007 2016-02-14 17:09 356
    }; // struct Versions
7a956470 sago007 2016-02-14 17:09 357
  } // namespace detail
7a956470 sago007 2016-02-14 17:09 358
} // namespace cereal
7a956470 sago007 2016-02-14 17:09 359
7a956470 sago007 2016-02-14 17:09 360
#endif // CEREAL_DETAILS_HELPERS_HPP_
1970-01-01 00:00 361