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
6c5f2c01 sago007 2017-03-15 17:56 40
#include "cereal/macros.hpp"
6c5f2c01 sago007 2017-03-15 17:56 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
6c5f2c01 sago007 2017-03-15 17:56 58
      machine.
6c5f2c01 sago007 2017-03-15 17:56 59
6c5f2c01 sago007 2017-03-15 17:56 60
      The default value for CEREAL_SIZE_TYPE is specified in cereal/macros.hpp */
6c5f2c01 sago007 2017-03-15 17:56 61
  using size_type = CEREAL_SIZE_TYPE;
7a956470 sago007 2016-02-14 17:09 62
7a956470 sago007 2016-02-14 17:09 63
  // forward decls
7a956470 sago007 2016-02-14 17:09 64
  class BinaryOutputArchive;
7a956470 sago007 2016-02-14 17:09 65
  class BinaryInputArchive;
7a956470 sago007 2016-02-14 17:09 66
7a956470 sago007 2016-02-14 17:09 67
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 68
  namespace detail
7a956470 sago007 2016-02-14 17:09 69
  {
7a956470 sago007 2016-02-14 17:09 70
    struct NameValuePairCore {}; //!< Traits struct for NVPs
7a956470 sago007 2016-02-14 17:09 71
  }
7a956470 sago007 2016-02-14 17:09 72
7a956470 sago007 2016-02-14 17:09 73
  //! For holding name value pairs
7a956470 sago007 2016-02-14 17:09 74
  /*! This pairs a name (some string) with some value such that an archive
7a956470 sago007 2016-02-14 17:09 75
      can potentially take advantage of the pairing.
7a956470 sago007 2016-02-14 17:09 76
7a956470 sago007 2016-02-14 17:09 77
      In serialization functions, NameValuePairs are usually created like so:
7a956470 sago007 2016-02-14 17:09 78
      @code{.cpp}
7a956470 sago007 2016-02-14 17:09 79
      struct MyStruct
7a956470 sago007 2016-02-14 17:09 80
      {
7a956470 sago007 2016-02-14 17:09 81
        int a, b, c, d, e;
7a956470 sago007 2016-02-14 17:09 82
7a956470 sago007 2016-02-14 17:09 83
        template<class Archive>
7a956470 sago007 2016-02-14 17:09 84
        void serialize(Archive & archive)
7a956470 sago007 2016-02-14 17:09 85
        {
7a956470 sago007 2016-02-14 17:09 86
          archive( CEREAL_NVP(a),
7a956470 sago007 2016-02-14 17:09 87
                   CEREAL_NVP(b),
7a956470 sago007 2016-02-14 17:09 88
                   CEREAL_NVP(c),
7a956470 sago007 2016-02-14 17:09 89
                   CEREAL_NVP(d),
7a956470 sago007 2016-02-14 17:09 90
                   CEREAL_NVP(e) );
7a956470 sago007 2016-02-14 17:09 91
        }
7a956470 sago007 2016-02-14 17:09 92
      };
7a956470 sago007 2016-02-14 17:09 93
      @endcode
7a956470 sago007 2016-02-14 17:09 94
7a956470 sago007 2016-02-14 17:09 95
      Alternatively, you can give you data members custom names like so:
7a956470 sago007 2016-02-14 17:09 96
      @code{.cpp}
7a956470 sago007 2016-02-14 17:09 97
      struct MyStruct
7a956470 sago007 2016-02-14 17:09 98
      {
7a956470 sago007 2016-02-14 17:09 99
        int a, b, my_embarrassing_variable_name, d, e;
7a956470 sago007 2016-02-14 17:09 100
7a956470 sago007 2016-02-14 17:09 101
        template<class Archive>
7a956470 sago007 2016-02-14 17:09 102
        void serialize(Archive & archive)
7a956470 sago007 2016-02-14 17:09 103
        {
7a956470 sago007 2016-02-14 17:09 104
          archive( CEREAL_NVP(a),
7a956470 sago007 2016-02-14 17:09 105
                   CEREAL_NVP(b),
7a956470 sago007 2016-02-14 17:09 106
                   cereal::make_nvp("var", my_embarrassing_variable_name) );
7a956470 sago007 2016-02-14 17:09 107
                   CEREAL_NVP(d),
7a956470 sago007 2016-02-14 17:09 108
                   CEREAL_NVP(e) );
7a956470 sago007 2016-02-14 17:09 109
        }
7a956470 sago007 2016-02-14 17:09 110
      };
7a956470 sago007 2016-02-14 17:09 111
      @endcode
7a956470 sago007 2016-02-14 17:09 112
7a956470 sago007 2016-02-14 17:09 113
      There is a slight amount of overhead to creating NameValuePairs, so there
7a956470 sago007 2016-02-14 17:09 114
      is a third method which will elide the names when they are not used by
7a956470 sago007 2016-02-14 17:09 115
      the Archive:
7a956470 sago007 2016-02-14 17:09 116
7a956470 sago007 2016-02-14 17:09 117
      @code{.cpp}
7a956470 sago007 2016-02-14 17:09 118
      struct MyStruct
7a956470 sago007 2016-02-14 17:09 119
      {
7a956470 sago007 2016-02-14 17:09 120
        int a, b;
7a956470 sago007 2016-02-14 17:09 121
7a956470 sago007 2016-02-14 17:09 122
        template<class Archive>
7a956470 sago007 2016-02-14 17:09 123
        void serialize(Archive & archive)
7a956470 sago007 2016-02-14 17:09 124
        {
7a956470 sago007 2016-02-14 17:09 125
          archive( cereal::make_nvp<Archive>(a),
7a956470 sago007 2016-02-14 17:09 126
                   cereal::make_nvp<Archive>(b) );
7a956470 sago007 2016-02-14 17:09 127
        }
7a956470 sago007 2016-02-14 17:09 128
      };
7a956470 sago007 2016-02-14 17:09 129
      @endcode
7a956470 sago007 2016-02-14 17:09 130
7a956470 sago007 2016-02-14 17:09 131
      This third method is generally only used when providing generic type
7a956470 sago007 2016-02-14 17:09 132
      support.  Users writing their own serialize functions will normally
7a956470 sago007 2016-02-14 17:09 133
      explicitly control whether they want to use NVPs or not.
7a956470 sago007 2016-02-14 17:09 134
7a956470 sago007 2016-02-14 17:09 135
      @internal */
7a956470 sago007 2016-02-14 17:09 136
  template <class T>
7a956470 sago007 2016-02-14 17:09 137
  class NameValuePair : detail::NameValuePairCore
7a956470 sago007 2016-02-14 17:09 138
  {
7a956470 sago007 2016-02-14 17:09 139
    private:
7a956470 sago007 2016-02-14 17:09 140
      // If we get passed an array, keep the type as is, otherwise store
7a956470 sago007 2016-02-14 17:09 141
      // a reference if we were passed an l value reference, else copy the value
7a956470 sago007 2016-02-14 17:09 142
      using Type = typename std::conditional<std::is_array<typename std::remove_reference<T>::type>::value,
7a956470 sago007 2016-02-14 17:09 143
                                             typename std::remove_cv<T>::type,
7a956470 sago007 2016-02-14 17:09 144
                                             typename std::conditional<std::is_lvalue_reference<T>::value,
7a956470 sago007 2016-02-14 17:09 145
                                                                       T,
7a956470 sago007 2016-02-14 17:09 146
                                                                       typename std::decay<T>::type>::type>::type;
7a956470 sago007 2016-02-14 17:09 147
7a956470 sago007 2016-02-14 17:09 148
      // prevent nested nvps
7a956470 sago007 2016-02-14 17:09 149
      static_assert( !std::is_base_of<detail::NameValuePairCore, T>::value,
7a956470 sago007 2016-02-14 17:09 150
                     "Cannot pair a name to a NameValuePair" );
7a956470 sago007 2016-02-14 17:09 151
7a956470 sago007 2016-02-14 17:09 152
      NameValuePair & operator=( NameValuePair const & ) = delete;
7a956470 sago007 2016-02-14 17:09 153
7a956470 sago007 2016-02-14 17:09 154
    public:
7a956470 sago007 2016-02-14 17:09 155
      //! Constructs a new NameValuePair
7a956470 sago007 2016-02-14 17:09 156
      /*! @param n The name of the pair
7a956470 sago007 2016-02-14 17:09 157
          @param v The value to pair.  Ideally this should be an l-value reference so that
7a956470 sago007 2016-02-14 17:09 158
                   the value can be both loaded and saved to.  If you pass an r-value reference,
7a956470 sago007 2016-02-14 17:09 159
                   the NameValuePair will store a copy of it instead of a reference.  Thus you should
7a956470 sago007 2016-02-14 17:09 160
                   only pass r-values in cases where this makes sense, such as the result of some
7a956470 sago007 2016-02-14 17:09 161
                   size() call.
7a956470 sago007 2016-02-14 17:09 162
          @internal */
7a956470 sago007 2016-02-14 17:09 163
      NameValuePair( char const * n, T && v ) : name(n), value(std::forward<T>(v)) {}
7a956470 sago007 2016-02-14 17:09 164
7a956470 sago007 2016-02-14 17:09 165
      char const * name;
7a956470 sago007 2016-02-14 17:09 166
      Type value;
7a956470 sago007 2016-02-14 17:09 167
  };
7a956470 sago007 2016-02-14 17:09 168
7a956470 sago007 2016-02-14 17:09 169
  //! A specialization of make_nvp<> that simply forwards the value for binary archives
7a956470 sago007 2016-02-14 17:09 170
  /*! @relates NameValuePair
7a956470 sago007 2016-02-14 17:09 171
      @internal */
7a956470 sago007 2016-02-14 17:09 172
  template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 173
  typename
7a956470 sago007 2016-02-14 17:09 174
  std::enable_if<std::is_same<Archive, ::cereal::BinaryInputArchive>::value ||
7a956470 sago007 2016-02-14 17:09 175
                 std::is_same<Archive, ::cereal::BinaryOutputArchive>::value,
7a956470 sago007 2016-02-14 17:09 176
  T && >::type
7a956470 sago007 2016-02-14 17:09 177
  make_nvp( const char *, T && value )
7a956470 sago007 2016-02-14 17:09 178
  {
7a956470 sago007 2016-02-14 17:09 179
    return std::forward<T>(value);
7a956470 sago007 2016-02-14 17:09 180
  }
7a956470 sago007 2016-02-14 17:09 181
7a956470 sago007 2016-02-14 17:09 182
  //! A specialization of make_nvp<> that actually creates an nvp for non-binary archives
7a956470 sago007 2016-02-14 17:09 183
  /*! @relates NameValuePair
7a956470 sago007 2016-02-14 17:09 184
      @internal */
7a956470 sago007 2016-02-14 17:09 185
  template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 186
  typename
7a956470 sago007 2016-02-14 17:09 187
  std::enable_if<!std::is_same<Archive, ::cereal::BinaryInputArchive>::value &&
7a956470 sago007 2016-02-14 17:09 188
                 !std::is_same<Archive, ::cereal::BinaryOutputArchive>::value,
7a956470 sago007 2016-02-14 17:09 189
  NameValuePair<T> >::type
7a956470 sago007 2016-02-14 17:09 190
  make_nvp( const char * name, T && value)
7a956470 sago007 2016-02-14 17:09 191
  {
7a956470 sago007 2016-02-14 17:09 192
    return {name, std::forward<T>(value)};
7a956470 sago007 2016-02-14 17:09 193
  }
7a956470 sago007 2016-02-14 17:09 194
7a956470 sago007 2016-02-14 17:09 195
  //! Convenience for creating a templated NVP
6c5f2c01 sago007 2017-03-15 17:56 196
  /*! For use in internal generic typing functions which have an
7a956470 sago007 2016-02-14 17:09 197
      Archive type declared
7a956470 sago007 2016-02-14 17:09 198
      @internal */
7a956470 sago007 2016-02-14 17:09 199
  #define CEREAL_NVP_(name, value) ::cereal::make_nvp<Archive>(name, value)
7a956470 sago007 2016-02-14 17:09 200
7a956470 sago007 2016-02-14 17:09 201
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 202
  //! A wrapper around data that can be serialized in a binary fashion
7a956470 sago007 2016-02-14 17:09 203
  /*! This class is used to demarcate data that can safely be serialized
7a956470 sago007 2016-02-14 17:09 204
      as a binary chunk of data.  Individual archives can then choose how
7a956470 sago007 2016-02-14 17:09 205
      best represent this during serialization.
7a956470 sago007 2016-02-14 17:09 206
7a956470 sago007 2016-02-14 17:09 207
      @internal */
7a956470 sago007 2016-02-14 17:09 208
  template <class T>
7a956470 sago007 2016-02-14 17:09 209
  struct BinaryData
7a956470 sago007 2016-02-14 17:09 210
  {
7a956470 sago007 2016-02-14 17:09 211
    //! Internally store the pointer as a void *, keeping const if created with
7a956470 sago007 2016-02-14 17:09 212
    //! a const pointer
7a956470 sago007 2016-02-14 17:09 213
    using PT = typename std::conditional<std::is_const<typename std::remove_pointer<T>::type>::value,
7a956470 sago007 2016-02-14 17:09 214
                                         const void *,
7a956470 sago007 2016-02-14 17:09 215
                                         void *>::type;
7a956470 sago007 2016-02-14 17:09 216
7a956470 sago007 2016-02-14 17:09 217
    BinaryData( T && d, uint64_t s ) : data(std::forward<T>(d)), size(s) {}
7a956470 sago007 2016-02-14 17:09 218
7a956470 sago007 2016-02-14 17:09 219
    PT data;       //!< pointer to beginning of data
7a956470 sago007 2016-02-14 17:09 220
    uint64_t size; //!< size in bytes
7a956470 sago007 2016-02-14 17:09 221
  };
7a956470 sago007 2016-02-14 17:09 222
7a956470 sago007 2016-02-14 17:09 223
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 224
  namespace detail
7a956470 sago007 2016-02-14 17:09 225
  {
7a956470 sago007 2016-02-14 17:09 226
    // base classes for type checking
7a956470 sago007 2016-02-14 17:09 227
    /* The rtti virtual function only exists to enable an archive to
7a956470 sago007 2016-02-14 17:09 228
       be used in a polymorphic fashion, if necessary.  See the
7a956470 sago007 2016-02-14 17:09 229
       archive adapters for an example of this */
6c5f2c01 sago007 2017-03-15 17:56 230
    class OutputArchiveBase
6c5f2c01 sago007 2017-03-15 17:56 231
    {
6c5f2c01 sago007 2017-03-15 17:56 232
      public:
6c5f2c01 sago007 2017-03-15 17:56 233
        OutputArchiveBase() = default;
6c5f2c01 sago007 2017-03-15 17:56 234
        OutputArchiveBase( OutputArchiveBase && ) CEREAL_NOEXCEPT {}
6c5f2c01 sago007 2017-03-15 17:56 235
        OutputArchiveBase & operator=( OutputArchiveBase && ) CEREAL_NOEXCEPT { return *this; }
6c5f2c01 sago007 2017-03-15 17:56 236
        virtual ~OutputArchiveBase() CEREAL_NOEXCEPT = default;
6c5f2c01 sago007 2017-03-15 17:56 237
6c5f2c01 sago007 2017-03-15 17:56 238
      private:
6c5f2c01 sago007 2017-03-15 17:56 239
        virtual void rtti() {}
6c5f2c01 sago007 2017-03-15 17:56 240
    };
6c5f2c01 sago007 2017-03-15 17:56 241
6c5f2c01 sago007 2017-03-15 17:56 242
    class InputArchiveBase
6c5f2c01 sago007 2017-03-15 17:56 243
    {
6c5f2c01 sago007 2017-03-15 17:56 244
      public:
6c5f2c01 sago007 2017-03-15 17:56 245
        InputArchiveBase() = default;
6c5f2c01 sago007 2017-03-15 17:56 246
        InputArchiveBase( InputArchiveBase && ) CEREAL_NOEXCEPT {}
6c5f2c01 sago007 2017-03-15 17:56 247
        InputArchiveBase & operator=( InputArchiveBase && ) CEREAL_NOEXCEPT { return *this; }
6c5f2c01 sago007 2017-03-15 17:56 248
        virtual ~InputArchiveBase() CEREAL_NOEXCEPT = default;
6c5f2c01 sago007 2017-03-15 17:56 249
6c5f2c01 sago007 2017-03-15 17:56 250
      private:
6c5f2c01 sago007 2017-03-15 17:56 251
        virtual void rtti() {}
6c5f2c01 sago007 2017-03-15 17:56 252
    };
7a956470 sago007 2016-02-14 17:09 253
7a956470 sago007 2016-02-14 17:09 254
    // forward decls for polymorphic support
7a956470 sago007 2016-02-14 17:09 255
    template <class Archive, class T> struct polymorphic_serialization_support;
7a956470 sago007 2016-02-14 17:09 256
    struct adl_tag;
7a956470 sago007 2016-02-14 17:09 257
7a956470 sago007 2016-02-14 17:09 258
    // used during saving pointers
7a956470 sago007 2016-02-14 17:09 259
    static const int32_t msb_32bit  = 0x80000000;
7a956470 sago007 2016-02-14 17:09 260
    static const int32_t msb2_32bit = 0x40000000;
7a956470 sago007 2016-02-14 17:09 261
  }
7a956470 sago007 2016-02-14 17:09 262
7a956470 sago007 2016-02-14 17:09 263
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 264
  //! A wrapper around size metadata
7a956470 sago007 2016-02-14 17:09 265
  /*! This class provides a way for archives to have more flexibility over how
7a956470 sago007 2016-02-14 17:09 266
      they choose to serialize size metadata for containers.  For some archive
7a956470 sago007 2016-02-14 17:09 267
      types, the size may be implicitly encoded in the output (e.g. JSON) and
7a956470 sago007 2016-02-14 17:09 268
      not need an explicit entry.  Specializing serialize or load/save for
7a956470 sago007 2016-02-14 17:09 269
      your archive and SizeTags allows you to choose what happens.
7a956470 sago007 2016-02-14 17:09 270
7a956470 sago007 2016-02-14 17:09 271
      @internal */
7a956470 sago007 2016-02-14 17:09 272
  template <class T>
7a956470 sago007 2016-02-14 17:09 273
  class SizeTag
7a956470 sago007 2016-02-14 17:09 274
  {
7a956470 sago007 2016-02-14 17:09 275
    private:
7a956470 sago007 2016-02-14 17:09 276
      // Store a reference if passed an lvalue reference, otherwise
7a956470 sago007 2016-02-14 17:09 277
      // make a copy of the data
7a956470 sago007 2016-02-14 17:09 278
      using Type = typename std::conditional<std::is_lvalue_reference<T>::value,
7a956470 sago007 2016-02-14 17:09 279
                                             T,
7a956470 sago007 2016-02-14 17:09 280
                                             typename std::decay<T>::type>::type;
7a956470 sago007 2016-02-14 17:09 281
7a956470 sago007 2016-02-14 17:09 282
      SizeTag & operator=( SizeTag const & ) = delete;
7a956470 sago007 2016-02-14 17:09 283
7a956470 sago007 2016-02-14 17:09 284
    public:
7a956470 sago007 2016-02-14 17:09 285
      SizeTag( T && sz ) : size(std::forward<T>(sz)) {}
7a956470 sago007 2016-02-14 17:09 286
7a956470 sago007 2016-02-14 17:09 287
      Type size;
7a956470 sago007 2016-02-14 17:09 288
  };
7a956470 sago007 2016-02-14 17:09 289
7a956470 sago007 2016-02-14 17:09 290
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 291
  //! A wrapper around a key and value for serializing data into maps.
7a956470 sago007 2016-02-14 17:09 292
  /*! This class just provides a grouping of keys and values into a struct for
7a956470 sago007 2016-02-14 17:09 293
      human readable archives. For example, XML archives will use this wrapper
7a956470 sago007 2016-02-14 17:09 294
      to write maps like so:
7a956470 sago007 2016-02-14 17:09 295
7a956470 sago007 2016-02-14 17:09 296
      @code{.xml}
7a956470 sago007 2016-02-14 17:09 297
      <mymap>
7a956470 sago007 2016-02-14 17:09 298
        <item0>
7a956470 sago007 2016-02-14 17:09 299
          <key>MyFirstKey</key>
7a956470 sago007 2016-02-14 17:09 300
          <value>MyFirstValue</value>
7a956470 sago007 2016-02-14 17:09 301
        </item0>
7a956470 sago007 2016-02-14 17:09 302
        <item1>
7a956470 sago007 2016-02-14 17:09 303
          <key>MySecondKey</key>
7a956470 sago007 2016-02-14 17:09 304
          <value>MySecondValue</value>
7a956470 sago007 2016-02-14 17:09 305
        </item1>
7a956470 sago007 2016-02-14 17:09 306
      </mymap>
7a956470 sago007 2016-02-14 17:09 307
      @endcode
7a956470 sago007 2016-02-14 17:09 308
7a956470 sago007 2016-02-14 17:09 309
      \sa make_map_item
7a956470 sago007 2016-02-14 17:09 310
      @internal */
7a956470 sago007 2016-02-14 17:09 311
  template <class Key, class Value>
7a956470 sago007 2016-02-14 17:09 312
  struct MapItem
7a956470 sago007 2016-02-14 17:09 313
  {
7a956470 sago007 2016-02-14 17:09 314
    using KeyType = typename std::conditional<
7a956470 sago007 2016-02-14 17:09 315
      std::is_lvalue_reference<Key>::value,
7a956470 sago007 2016-02-14 17:09 316
      Key,
7a956470 sago007 2016-02-14 17:09 317
      typename std::decay<Key>::type>::type;
7a956470 sago007 2016-02-14 17:09 318
7a956470 sago007 2016-02-14 17:09 319
    using ValueType = typename std::conditional<
7a956470 sago007 2016-02-14 17:09 320
      std::is_lvalue_reference<Value>::value,
7a956470 sago007 2016-02-14 17:09 321
      Value,
7a956470 sago007 2016-02-14 17:09 322
      typename std::decay<Value>::type>::type;
7a956470 sago007 2016-02-14 17:09 323
7a956470 sago007 2016-02-14 17:09 324
    //! Construct a MapItem from a key and a value
7a956470 sago007 2016-02-14 17:09 325
    /*! @internal */
7a956470 sago007 2016-02-14 17:09 326
    MapItem( Key && key_, Value && value_ ) : key(std::forward<Key>(key_)), value(std::forward<Value>(value_)) {}
7a956470 sago007 2016-02-14 17:09 327
7a956470 sago007 2016-02-14 17:09 328
    MapItem & operator=( MapItem const & ) = delete;
7a956470 sago007 2016-02-14 17:09 329
7a956470 sago007 2016-02-14 17:09 330
    KeyType key;
7a956470 sago007 2016-02-14 17:09 331
    ValueType value;
7a956470 sago007 2016-02-14 17:09 332
7a956470 sago007 2016-02-14 17:09 333
    //! Serialize the MapItem with the NVPs "key" and "value"
7a956470 sago007 2016-02-14 17:09 334
    template <class Archive> inline
7a956470 sago007 2016-02-14 17:09 335
    void CEREAL_SERIALIZE_FUNCTION_NAME(Archive & archive)
7a956470 sago007 2016-02-14 17:09 336
    {
7a956470 sago007 2016-02-14 17:09 337
      archive( make_nvp<Archive>("key",   key),
7a956470 sago007 2016-02-14 17:09 338
               make_nvp<Archive>("value", value) );
7a956470 sago007 2016-02-14 17:09 339
    }
7a956470 sago007 2016-02-14 17:09 340
  };
7a956470 sago007 2016-02-14 17:09 341
7a956470 sago007 2016-02-14 17:09 342
  //! Create a MapItem so that human readable archives will group keys and values together
7a956470 sago007 2016-02-14 17:09 343
  /*! @internal
7a956470 sago007 2016-02-14 17:09 344
      @relates MapItem */
7a956470 sago007 2016-02-14 17:09 345
  template <class KeyType, class ValueType> inline
7a956470 sago007 2016-02-14 17:09 346
  MapItem<KeyType, ValueType> make_map_item(KeyType && key, ValueType && value)
7a956470 sago007 2016-02-14 17:09 347
  {
7a956470 sago007 2016-02-14 17:09 348
    return {std::forward<KeyType>(key), std::forward<ValueType>(value)};
7a956470 sago007 2016-02-14 17:09 349
  }
7a956470 sago007 2016-02-14 17:09 350
7a956470 sago007 2016-02-14 17:09 351
  namespace detail
7a956470 sago007 2016-02-14 17:09 352
  {
7a956470 sago007 2016-02-14 17:09 353
    //! Tag for Version, which due to its anonymous namespace, becomes a different
7a956470 sago007 2016-02-14 17:09 354
    //! type in each translation unit
7a956470 sago007 2016-02-14 17:09 355
    /*! This allows CEREAL_CLASS_VERSION to be safely called in a header file */
7a956470 sago007 2016-02-14 17:09 356
    namespace{ struct version_binding_tag {}; }
7a956470 sago007 2016-02-14 17:09 357
7a956470 sago007 2016-02-14 17:09 358
    // ######################################################################
7a956470 sago007 2016-02-14 17:09 359
    //! Version information class
7a956470 sago007 2016-02-14 17:09 360
    /*! This is the base case for classes that have not been explicitly
7a956470 sago007 2016-02-14 17:09 361
        registered */
7a956470 sago007 2016-02-14 17:09 362
    template <class T, class BindingTag = version_binding_tag> struct Version
7a956470 sago007 2016-02-14 17:09 363
    {
7a956470 sago007 2016-02-14 17:09 364
      static const std::uint32_t version = 0;
7a956470 sago007 2016-02-14 17:09 365
      // we don't need to explicitly register these types since they
7a956470 sago007 2016-02-14 17:09 366
      // always get a version number of 0
7a956470 sago007 2016-02-14 17:09 367
    };
7a956470 sago007 2016-02-14 17:09 368
7a956470 sago007 2016-02-14 17:09 369
    //! Holds all registered version information
7a956470 sago007 2016-02-14 17:09 370
    struct Versions
7a956470 sago007 2016-02-14 17:09 371
    {
7a956470 sago007 2016-02-14 17:09 372
      std::unordered_map<std::size_t, std::uint32_t> mapping;
7a956470 sago007 2016-02-14 17:09 373
7a956470 sago007 2016-02-14 17:09 374
      std::uint32_t find( std::size_t hash, std::uint32_t version )
7a956470 sago007 2016-02-14 17:09 375
      {
7a956470 sago007 2016-02-14 17:09 376
        const auto result = mapping.emplace( hash, version );
7a956470 sago007 2016-02-14 17:09 377
        return result.first->second;
7a956470 sago007 2016-02-14 17:09 378
      }
7a956470 sago007 2016-02-14 17:09 379
    }; // struct Versions
7a956470 sago007 2016-02-14 17:09 380
  } // namespace detail
7a956470 sago007 2016-02-14 17:09 381
} // namespace cereal
7a956470 sago007 2016-02-14 17:09 382
7a956470 sago007 2016-02-14 17:09 383
#endif // CEREAL_DETAILS_HELPERS_HPP_
1970-01-01 00:00 384