git repos / blockattack-game

blame: source/code/Libs/include/cereal/access.hpp

normal view · raw

7a956470 sago007 2016-02-14 17:09 1
/*! \file access.hpp
7a956470 sago007 2016-02-14 17:09 2
    \brief Access control, default construction, and serialization disambiguation */
7a956470 sago007 2016-02-14 17:09 3
/*
7a956470 sago007 2016-02-14 17:09 4
  Copyright (c) 2014, Randolph Voorhies, Shane Grant
7a956470 sago007 2016-02-14 17:09 5
  All rights reserved.
7a956470 sago007 2016-02-14 17:09 6
7a956470 sago007 2016-02-14 17:09 7
  Redistribution and use in source and binary forms, with or without
7a956470 sago007 2016-02-14 17:09 8
  modification, are permitted provided that the following conditions are met:
7a956470 sago007 2016-02-14 17:09 9
      * Redistributions of source code must retain the above copyright
7a956470 sago007 2016-02-14 17:09 10
        notice, this list of conditions and the following disclaimer.
7a956470 sago007 2016-02-14 17:09 11
      * Redistributions in binary form must reproduce the above copyright
7a956470 sago007 2016-02-14 17:09 12
        notice, this list of conditions and the following disclaimer in the
7a956470 sago007 2016-02-14 17:09 13
        documentation and/or other materials provided with the distribution.
7a956470 sago007 2016-02-14 17:09 14
      * Neither the name of cereal nor the
7a956470 sago007 2016-02-14 17:09 15
        names of its contributors may be used to endorse or promote products
7a956470 sago007 2016-02-14 17:09 16
        derived from this software without specific prior written permission.
7a956470 sago007 2016-02-14 17:09 17
7a956470 sago007 2016-02-14 17:09 18
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
7a956470 sago007 2016-02-14 17:09 19
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7a956470 sago007 2016-02-14 17:09 20
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
7a956470 sago007 2016-02-14 17:09 21
  DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES OR SHANE GRANT BE LIABLE FOR ANY
7a956470 sago007 2016-02-14 17:09 22
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7a956470 sago007 2016-02-14 17:09 23
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
7a956470 sago007 2016-02-14 17:09 24
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
7a956470 sago007 2016-02-14 17:09 25
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7a956470 sago007 2016-02-14 17:09 26
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
7a956470 sago007 2016-02-14 17:09 27
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7a956470 sago007 2016-02-14 17:09 28
*/
7a956470 sago007 2016-02-14 17:09 29
#ifndef CEREAL_ACCESS_HPP_
7a956470 sago007 2016-02-14 17:09 30
#define CEREAL_ACCESS_HPP_
7a956470 sago007 2016-02-14 17:09 31
7a956470 sago007 2016-02-14 17:09 32
#include <type_traits>
7a956470 sago007 2016-02-14 17:09 33
#include <iostream>
7a956470 sago007 2016-02-14 17:09 34
#include <cstdint>
6c5f2c01 sago007 2017-03-15 17:56 35
#include <functional>
7a956470 sago007 2016-02-14 17:09 36
6c5f2c01 sago007 2017-03-15 17:56 37
#include "cereal/macros.hpp"
6c5f2c01 sago007 2017-03-15 17:56 38
#include "cereal/details/helpers.hpp"
7a956470 sago007 2016-02-14 17:09 39
7a956470 sago007 2016-02-14 17:09 40
namespace cereal
7a956470 sago007 2016-02-14 17:09 41
{
7a956470 sago007 2016-02-14 17:09 42
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 43
  //! A class that allows cereal to load smart pointers to types that have no default constructor
7a956470 sago007 2016-02-14 17:09 44
  /*! If your class does not have a default constructor, cereal will not be able
7a956470 sago007 2016-02-14 17:09 45
      to load any smart pointers to it unless you overload LoadAndConstruct
7a956470 sago007 2016-02-14 17:09 46
      for your class, and provide an appropriate load_and_construct method.  You can also
7a956470 sago007 2016-02-14 17:09 47
      choose to define a member static function instead of specializing this class.
7a956470 sago007 2016-02-14 17:09 48
7a956470 sago007 2016-02-14 17:09 49
      The specialization of LoadAndConstruct must be placed within the cereal namespace:
7a956470 sago007 2016-02-14 17:09 50
7a956470 sago007 2016-02-14 17:09 51
      @code{.cpp}
7a956470 sago007 2016-02-14 17:09 52
      struct MyType
7a956470 sago007 2016-02-14 17:09 53
      {
7a956470 sago007 2016-02-14 17:09 54
        MyType( int x ); // note: no default ctor
7a956470 sago007 2016-02-14 17:09 55
        int myX;
7a956470 sago007 2016-02-14 17:09 56
7a956470 sago007 2016-02-14 17:09 57
        // Define a serialize or load/save pair as you normally would
7a956470 sago007 2016-02-14 17:09 58
        template <class Archive>
7a956470 sago007 2016-02-14 17:09 59
        void serialize( Archive & ar )
7a956470 sago007 2016-02-14 17:09 60
        {
7a956470 sago007 2016-02-14 17:09 61
          ar( myX );
7a956470 sago007 2016-02-14 17:09 62
        }
7a956470 sago007 2016-02-14 17:09 63
      };
7a956470 sago007 2016-02-14 17:09 64
7a956470 sago007 2016-02-14 17:09 65
      // Provide a specialization for LoadAndConstruct for your type
7a956470 sago007 2016-02-14 17:09 66
      namespace cereal
7a956470 sago007 2016-02-14 17:09 67
      {
7a956470 sago007 2016-02-14 17:09 68
        template <> struct LoadAndConstruct<MyType>
7a956470 sago007 2016-02-14 17:09 69
        {
7a956470 sago007 2016-02-14 17:09 70
          // load_and_construct will be passed the archive that you will be loading
7a956470 sago007 2016-02-14 17:09 71
          // from as well as a construct object which you can use as if it were the
7a956470 sago007 2016-02-14 17:09 72
          // constructor for your type.  cereal will handle all memory management for you.
7a956470 sago007 2016-02-14 17:09 73
          template <class Archive>
7a956470 sago007 2016-02-14 17:09 74
          static void load_and_construct( Archive & ar, cereal::construct<MyType> & construct )
7a956470 sago007 2016-02-14 17:09 75
          {
7a956470 sago007 2016-02-14 17:09 76
            int x;
7a956470 sago007 2016-02-14 17:09 77
            ar( x );
7a956470 sago007 2016-02-14 17:09 78
            construct( x );
7a956470 sago007 2016-02-14 17:09 79
          }
6c5f2c01 sago007 2017-03-15 17:56 80
6c5f2c01 sago007 2017-03-15 17:56 81
          // if you require versioning, simply add a const std::uint32_t as the final parameter, e.g.:
6c5f2c01 sago007 2017-03-15 17:56 82
          // load_and_construct( Archive & ar, cereal::construct<MyType> & construct, std::uint32_t const version )
7a956470 sago007 2016-02-14 17:09 83
        };
7a956470 sago007 2016-02-14 17:09 84
      } // end namespace cereal
7a956470 sago007 2016-02-14 17:09 85
      @endcode
7a956470 sago007 2016-02-14 17:09 86
7a956470 sago007 2016-02-14 17:09 87
      Please note that just as in using external serialization functions, you cannot get
7a956470 sago007 2016-02-14 17:09 88
      access to non-public members of your class by befriending cereal::access.  If you
7a956470 sago007 2016-02-14 17:09 89
      have the ability to modify the class you wish to serialize, it is recommended that you
7a956470 sago007 2016-02-14 17:09 90
      use member serialize functions and a static member load_and_construct function.
7a956470 sago007 2016-02-14 17:09 91
6c5f2c01 sago007 2017-03-15 17:56 92
      load_and_construct functions, regardless of whether they are static members of your class or
6c5f2c01 sago007 2017-03-15 17:56 93
      whether you create one in the LoadAndConstruct specialization, have the following signature:
6c5f2c01 sago007 2017-03-15 17:56 94
6c5f2c01 sago007 2017-03-15 17:56 95
      @code{.cpp}
6c5f2c01 sago007 2017-03-15 17:56 96
      // generally Archive will be templated, but it can be specific if desired
6c5f2c01 sago007 2017-03-15 17:56 97
      template <class Archive>
6c5f2c01 sago007 2017-03-15 17:56 98
      static void load_and_construct( Archive & ar, cereal::construct<MyType> & construct );
6c5f2c01 sago007 2017-03-15 17:56 99
      // with an optional last parameter specifying the version: const std::uint32_t version
6c5f2c01 sago007 2017-03-15 17:56 100
      @endcode
6c5f2c01 sago007 2017-03-15 17:56 101
6c5f2c01 sago007 2017-03-15 17:56 102
      Versioning behaves the same way as it does for standard serialization functions.
6c5f2c01 sago007 2017-03-15 17:56 103
7a956470 sago007 2016-02-14 17:09 104
      @tparam T The type to specialize for
7a956470 sago007 2016-02-14 17:09 105
      @ingroup Access */
7a956470 sago007 2016-02-14 17:09 106
  template <class T>
7a956470 sago007 2016-02-14 17:09 107
  struct LoadAndConstruct
6c5f2c01 sago007 2017-03-15 17:56 108
  { };
7a956470 sago007 2016-02-14 17:09 109
7a956470 sago007 2016-02-14 17:09 110
  // forward decl for construct
7a956470 sago007 2016-02-14 17:09 111
  //! @cond PRIVATE_NEVERDEFINED
7a956470 sago007 2016-02-14 17:09 112
  namespace memory_detail{ template <class Ar, class T> struct LoadAndConstructLoadWrapper; }
7a956470 sago007 2016-02-14 17:09 113
  //! @endcond
7a956470 sago007 2016-02-14 17:09 114
7a956470 sago007 2016-02-14 17:09 115
  //! Used to construct types with no default constructor
7a956470 sago007 2016-02-14 17:09 116
  /*! When serializing a type that has no default constructor, cereal
7a956470 sago007 2016-02-14 17:09 117
      will attempt to call either the class static function load_and_construct
7a956470 sago007 2016-02-14 17:09 118
      or the appropriate template specialization of LoadAndConstruct.  cereal
7a956470 sago007 2016-02-14 17:09 119
      will pass that function a reference to the archive as well as a reference
7a956470 sago007 2016-02-14 17:09 120
      to a construct object which should be used to perform the allocation once
7a956470 sago007 2016-02-14 17:09 121
      data has been appropriately loaded.
7a956470 sago007 2016-02-14 17:09 122
7a956470 sago007 2016-02-14 17:09 123
      @code{.cpp}
7a956470 sago007 2016-02-14 17:09 124
      struct MyType
7a956470 sago007 2016-02-14 17:09 125
      {
7a956470 sago007 2016-02-14 17:09 126
        // note the lack of default constructor
7a956470 sago007 2016-02-14 17:09 127
        MyType( int xx, int yy );
7a956470 sago007 2016-02-14 17:09 128
7a956470 sago007 2016-02-14 17:09 129
        int x, y;
7a956470 sago007 2016-02-14 17:09 130
        double notInConstructor;
7a956470 sago007 2016-02-14 17:09 131
7a956470 sago007 2016-02-14 17:09 132
        template <class Archive>
7a956470 sago007 2016-02-14 17:09 133
        void serialize( Archive & ar )
7a956470 sago007 2016-02-14 17:09 134
        {
7a956470 sago007 2016-02-14 17:09 135
          ar( x, y );
7a956470 sago007 2016-02-14 17:09 136
          ar( notInConstructor );
7a956470 sago007 2016-02-14 17:09 137
        }
7a956470 sago007 2016-02-14 17:09 138
7a956470 sago007 2016-02-14 17:09 139
        template <class Archive>
7a956470 sago007 2016-02-14 17:09 140
        static void load_and_construct( Archive & ar, cereal::construct<MyType> & construct )
7a956470 sago007 2016-02-14 17:09 141
        {
7a956470 sago007 2016-02-14 17:09 142
          int x, y;
7a956470 sago007 2016-02-14 17:09 143
          ar( x, y );
7a956470 sago007 2016-02-14 17:09 144
7a956470 sago007 2016-02-14 17:09 145
          // use construct object to initialize with loaded data
7a956470 sago007 2016-02-14 17:09 146
          construct( x, y );
7a956470 sago007 2016-02-14 17:09 147
7a956470 sago007 2016-02-14 17:09 148
          // access to member variables and functions via -> operator
7a956470 sago007 2016-02-14 17:09 149
          ar( construct->notInConstructor );
7a956470 sago007 2016-02-14 17:09 150
7a956470 sago007 2016-02-14 17:09 151
          // could also do the above section by:
7a956470 sago007 2016-02-14 17:09 152
          double z;
7a956470 sago007 2016-02-14 17:09 153
          ar( z );
7a956470 sago007 2016-02-14 17:09 154
          construct->notInConstructor = z;
7a956470 sago007 2016-02-14 17:09 155
        }
7a956470 sago007 2016-02-14 17:09 156
      };
7a956470 sago007 2016-02-14 17:09 157
      @endcode
7a956470 sago007 2016-02-14 17:09 158
7a956470 sago007 2016-02-14 17:09 159
      @tparam T The class type being serialized
7a956470 sago007 2016-02-14 17:09 160
      */
7a956470 sago007 2016-02-14 17:09 161
  template <class T>
7a956470 sago007 2016-02-14 17:09 162
  class construct
7a956470 sago007 2016-02-14 17:09 163
  {
7a956470 sago007 2016-02-14 17:09 164
    public:
7a956470 sago007 2016-02-14 17:09 165
      //! Construct and initialize the type T with the given arguments
7a956470 sago007 2016-02-14 17:09 166
      /*! This will forward all arguments to the underlying type T,
7a956470 sago007 2016-02-14 17:09 167
          calling an appropriate constructor.
7a956470 sago007 2016-02-14 17:09 168
7a956470 sago007 2016-02-14 17:09 169
          Calling this function more than once will result in an exception
7a956470 sago007 2016-02-14 17:09 170
          being thrown.
7a956470 sago007 2016-02-14 17:09 171
7a956470 sago007 2016-02-14 17:09 172
          @param args The arguments to the constructor for T
7a956470 sago007 2016-02-14 17:09 173
          @throw Exception If called more than once */
7a956470 sago007 2016-02-14 17:09 174
      template <class ... Args>
7a956470 sago007 2016-02-14 17:09 175
      void operator()( Args && ... args );
7a956470 sago007 2016-02-14 17:09 176
      // implementation deferred due to reliance on cereal::access
7a956470 sago007 2016-02-14 17:09 177
7a956470 sago007 2016-02-14 17:09 178
      //! Get a reference to the initialized underlying object
7a956470 sago007 2016-02-14 17:09 179
      /*! This must be called after the object has been initialized.
7a956470 sago007 2016-02-14 17:09 180
7a956470 sago007 2016-02-14 17:09 181
          @return A reference to the initialized object
7a956470 sago007 2016-02-14 17:09 182
          @throw Exception If called before initialization */
7a956470 sago007 2016-02-14 17:09 183
      T * operator->()
7a956470 sago007 2016-02-14 17:09 184
      {
7a956470 sago007 2016-02-14 17:09 185
        if( !itsValid )
7a956470 sago007 2016-02-14 17:09 186
          throw Exception("Object must be initialized prior to accessing members");
7a956470 sago007 2016-02-14 17:09 187
7a956470 sago007 2016-02-14 17:09 188
        return itsPtr;
7a956470 sago007 2016-02-14 17:09 189
      }
7a956470 sago007 2016-02-14 17:09 190
7a956470 sago007 2016-02-14 17:09 191
      //! Returns a raw pointer to the initialized underlying object
7a956470 sago007 2016-02-14 17:09 192
      /*! This is mainly intended for use with passing an instance of
7a956470 sago007 2016-02-14 17:09 193
          a constructed object to cereal::base_class.
7a956470 sago007 2016-02-14 17:09 194
7a956470 sago007 2016-02-14 17:09 195
          It is strongly recommended to avoid using this function in
7a956470 sago007 2016-02-14 17:09 196
          any other circumstance.
7a956470 sago007 2016-02-14 17:09 197
7a956470 sago007 2016-02-14 17:09 198
          @return A raw pointer to the initialized type */
7a956470 sago007 2016-02-14 17:09 199
      T * ptr()
7a956470 sago007 2016-02-14 17:09 200
      {
7a956470 sago007 2016-02-14 17:09 201
        return operator->();
7a956470 sago007 2016-02-14 17:09 202
      }
7a956470 sago007 2016-02-14 17:09 203
7a956470 sago007 2016-02-14 17:09 204
    private:
7a956470 sago007 2016-02-14 17:09 205
      template <class A, class B> friend struct ::cereal::memory_detail::LoadAndConstructLoadWrapper;
7a956470 sago007 2016-02-14 17:09 206
6c5f2c01 sago007 2017-03-15 17:56 207
      construct( T * p ) : itsPtr( p ), itsEnableSharedRestoreFunction( [](){} ), itsValid( false ) {}
6c5f2c01 sago007 2017-03-15 17:56 208
      construct( T * p, std::function<void()> enableSharedFunc ) : // g++4.7 ice with default lambda to std func
6c5f2c01 sago007 2017-03-15 17:56 209
        itsPtr( p ), itsEnableSharedRestoreFunction( enableSharedFunc ), itsValid( false ) {}
7a956470 sago007 2016-02-14 17:09 210
      construct( construct const & ) = delete;
7a956470 sago007 2016-02-14 17:09 211
      construct & operator=( construct const & ) = delete;
7a956470 sago007 2016-02-14 17:09 212
7a956470 sago007 2016-02-14 17:09 213
      T * itsPtr;
6c5f2c01 sago007 2017-03-15 17:56 214
      std::function<void()> itsEnableSharedRestoreFunction;
7a956470 sago007 2016-02-14 17:09 215
      bool itsValid;
7a956470 sago007 2016-02-14 17:09 216
  };
7a956470 sago007 2016-02-14 17:09 217
7a956470 sago007 2016-02-14 17:09 218
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 219
  //! A class that can be made a friend to give cereal access to non public functions
7a956470 sago007 2016-02-14 17:09 220
  /*! If you desire non-public serialization functions within a class, cereal can only
7a956470 sago007 2016-02-14 17:09 221
      access these if you declare cereal::access a friend.
7a956470 sago007 2016-02-14 17:09 222
7a956470 sago007 2016-02-14 17:09 223
      @code{.cpp}
7a956470 sago007 2016-02-14 17:09 224
      class MyClass
7a956470 sago007 2016-02-14 17:09 225
      {
7a956470 sago007 2016-02-14 17:09 226
        private:
7a956470 sago007 2016-02-14 17:09 227
          friend class cereal::access; // gives access to the private serialize
7a956470 sago007 2016-02-14 17:09 228
7a956470 sago007 2016-02-14 17:09 229
          template <class Archive>
7a956470 sago007 2016-02-14 17:09 230
          void serialize( Archive & ar )
7a956470 sago007 2016-02-14 17:09 231
          {
7a956470 sago007 2016-02-14 17:09 232
            // some code
7a956470 sago007 2016-02-14 17:09 233
          }
7a956470 sago007 2016-02-14 17:09 234
      };
7a956470 sago007 2016-02-14 17:09 235
      @endcode
7a956470 sago007 2016-02-14 17:09 236
      @ingroup Access */
7a956470 sago007 2016-02-14 17:09 237
  class access
7a956470 sago007 2016-02-14 17:09 238
  {
7a956470 sago007 2016-02-14 17:09 239
    public:
7a956470 sago007 2016-02-14 17:09 240
      // ####### Standard Serialization ########################################
7a956470 sago007 2016-02-14 17:09 241
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 242
      static auto member_serialize(Archive & ar, T & t) -> decltype(t.CEREAL_SERIALIZE_FUNCTION_NAME(ar))
7a956470 sago007 2016-02-14 17:09 243
      { return t.CEREAL_SERIALIZE_FUNCTION_NAME(ar); }
7a956470 sago007 2016-02-14 17:09 244
7a956470 sago007 2016-02-14 17:09 245
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 246
      static auto member_save(Archive & ar, T const & t) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar))
7a956470 sago007 2016-02-14 17:09 247
      { return t.CEREAL_SAVE_FUNCTION_NAME(ar); }
7a956470 sago007 2016-02-14 17:09 248
7a956470 sago007 2016-02-14 17:09 249
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 250
      static auto member_save_non_const(Archive & ar, T & t) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar))
7a956470 sago007 2016-02-14 17:09 251
      { return t.CEREAL_SAVE_FUNCTION_NAME(ar); }
7a956470 sago007 2016-02-14 17:09 252
7a956470 sago007 2016-02-14 17:09 253
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 254
      static auto member_load(Archive & ar, T & t) -> decltype(t.CEREAL_LOAD_FUNCTION_NAME(ar))
7a956470 sago007 2016-02-14 17:09 255
      { return t.CEREAL_LOAD_FUNCTION_NAME(ar); }
7a956470 sago007 2016-02-14 17:09 256
7a956470 sago007 2016-02-14 17:09 257
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 258
      static auto member_save_minimal(Archive const & ar, T const & t) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar))
7a956470 sago007 2016-02-14 17:09 259
      { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar); }
7a956470 sago007 2016-02-14 17:09 260
7a956470 sago007 2016-02-14 17:09 261
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 262
      static auto member_save_minimal_non_const(Archive const & ar, T & t) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar))
7a956470 sago007 2016-02-14 17:09 263
      { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar); }
7a956470 sago007 2016-02-14 17:09 264
7a956470 sago007 2016-02-14 17:09 265
      template<class Archive, class T, class U> inline
7a956470 sago007 2016-02-14 17:09 266
      static auto member_load_minimal(Archive const & ar, T & t, U && u) -> decltype(t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u)))
7a956470 sago007 2016-02-14 17:09 267
      { return t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u)); }
7a956470 sago007 2016-02-14 17:09 268
7a956470 sago007 2016-02-14 17:09 269
      // ####### Versioned Serialization #######################################
7a956470 sago007 2016-02-14 17:09 270
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 271
      static auto member_serialize(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.CEREAL_SERIALIZE_FUNCTION_NAME(ar, version))
7a956470 sago007 2016-02-14 17:09 272
      { return t.CEREAL_SERIALIZE_FUNCTION_NAME(ar, version); }
7a956470 sago007 2016-02-14 17:09 273
7a956470 sago007 2016-02-14 17:09 274
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 275
      static auto member_save(Archive & ar, T const & t, const std::uint32_t version ) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar, version))
7a956470 sago007 2016-02-14 17:09 276
      { return t.CEREAL_SAVE_FUNCTION_NAME(ar, version); }
7a956470 sago007 2016-02-14 17:09 277
7a956470 sago007 2016-02-14 17:09 278
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 279
      static auto member_save_non_const(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar, version))
7a956470 sago007 2016-02-14 17:09 280
      { return t.CEREAL_SAVE_FUNCTION_NAME(ar, version); }
7a956470 sago007 2016-02-14 17:09 281
7a956470 sago007 2016-02-14 17:09 282
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 283
      static auto member_load(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.CEREAL_LOAD_FUNCTION_NAME(ar, version))
7a956470 sago007 2016-02-14 17:09 284
      { return t.CEREAL_LOAD_FUNCTION_NAME(ar, version); }
7a956470 sago007 2016-02-14 17:09 285
7a956470 sago007 2016-02-14 17:09 286
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 287
      static auto member_save_minimal(Archive const & ar, T const & t, const std::uint32_t version) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version))
7a956470 sago007 2016-02-14 17:09 288
      { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version); }
7a956470 sago007 2016-02-14 17:09 289
7a956470 sago007 2016-02-14 17:09 290
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 291
      static auto member_save_minimal_non_const(Archive const & ar, T & t, const std::uint32_t version) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version))
7a956470 sago007 2016-02-14 17:09 292
      { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version); }
7a956470 sago007 2016-02-14 17:09 293
7a956470 sago007 2016-02-14 17:09 294
      template<class Archive, class T, class U> inline
7a956470 sago007 2016-02-14 17:09 295
      static auto member_load_minimal(Archive const & ar, T & t, U && u, const std::uint32_t version) -> decltype(t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u), version))
7a956470 sago007 2016-02-14 17:09 296
      { return t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u), version); }
7a956470 sago007 2016-02-14 17:09 297
7a956470 sago007 2016-02-14 17:09 298
      // ####### Other Functionality ##########################################
7a956470 sago007 2016-02-14 17:09 299
      // for detecting inheritance from enable_shared_from_this
7a956470 sago007 2016-02-14 17:09 300
      template <class T> inline
7a956470 sago007 2016-02-14 17:09 301
      static auto shared_from_this(T & t) -> decltype(t.shared_from_this());
7a956470 sago007 2016-02-14 17:09 302
7a956470 sago007 2016-02-14 17:09 303
      // for placement new
7a956470 sago007 2016-02-14 17:09 304
      template <class T, class ... Args> inline
7a956470 sago007 2016-02-14 17:09 305
      static void construct( T *& ptr, Args && ... args )
7a956470 sago007 2016-02-14 17:09 306
      {
7a956470 sago007 2016-02-14 17:09 307
        new (ptr) T( std::forward<Args>( args )... );
7a956470 sago007 2016-02-14 17:09 308
      }
7a956470 sago007 2016-02-14 17:09 309
7a956470 sago007 2016-02-14 17:09 310
      // for non-placement new with a default constructor
7a956470 sago007 2016-02-14 17:09 311
      template <class T> inline
7a956470 sago007 2016-02-14 17:09 312
      static T * construct()
7a956470 sago007 2016-02-14 17:09 313
      {
7a956470 sago007 2016-02-14 17:09 314
        return new T();
7a956470 sago007 2016-02-14 17:09 315
      }
7a956470 sago007 2016-02-14 17:09 316
7a956470 sago007 2016-02-14 17:09 317
      template <class T> inline
7a956470 sago007 2016-02-14 17:09 318
      static std::false_type load_and_construct(...)
7a956470 sago007 2016-02-14 17:09 319
      { return std::false_type(); }
7a956470 sago007 2016-02-14 17:09 320
7a956470 sago007 2016-02-14 17:09 321
      template<class T, class Archive> inline
7a956470 sago007 2016-02-14 17:09 322
      static auto load_and_construct(Archive & ar, ::cereal::construct<T> & construct) -> decltype(T::load_and_construct(ar, construct))
7a956470 sago007 2016-02-14 17:09 323
      {
7a956470 sago007 2016-02-14 17:09 324
        T::load_and_construct( ar, construct );
7a956470 sago007 2016-02-14 17:09 325
      }
6c5f2c01 sago007 2017-03-15 17:56 326
6c5f2c01 sago007 2017-03-15 17:56 327
      template<class T, class Archive> inline
6c5f2c01 sago007 2017-03-15 17:56 328
      static auto load_and_construct(Archive & ar, ::cereal::construct<T> & construct, const std::uint32_t version) -> decltype(T::load_and_construct(ar, construct, version))
6c5f2c01 sago007 2017-03-15 17:56 329
      {
6c5f2c01 sago007 2017-03-15 17:56 330
        T::load_and_construct( ar, construct, version );
6c5f2c01 sago007 2017-03-15 17:56 331
      }
7a956470 sago007 2016-02-14 17:09 332
  }; // end class access
7a956470 sago007 2016-02-14 17:09 333
7a956470 sago007 2016-02-14 17:09 334
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 335
  //! A specifier used in conjunction with cereal::specialize to disambiguate
7a956470 sago007 2016-02-14 17:09 336
  //! serialization in special cases
7a956470 sago007 2016-02-14 17:09 337
  /*! @relates specialize
7a956470 sago007 2016-02-14 17:09 338
      @ingroup Access */
7a956470 sago007 2016-02-14 17:09 339
  enum class specialization
7a956470 sago007 2016-02-14 17:09 340
  {
7a956470 sago007 2016-02-14 17:09 341
    member_serialize,            //!< Force the use of a member serialize function
7a956470 sago007 2016-02-14 17:09 342
    member_load_save,            //!< Force the use of a member load/save pair
7a956470 sago007 2016-02-14 17:09 343
    member_load_save_minimal,    //!< Force the use of a member minimal load/save pair
7a956470 sago007 2016-02-14 17:09 344
    non_member_serialize,        //!< Force the use of a non-member serialize function
7a956470 sago007 2016-02-14 17:09 345
    non_member_load_save,        //!< Force the use of a non-member load/save pair
7a956470 sago007 2016-02-14 17:09 346
    non_member_load_save_minimal //!< Force the use of a non-member minimal load/save pair
7a956470 sago007 2016-02-14 17:09 347
  };
7a956470 sago007 2016-02-14 17:09 348
7a956470 sago007 2016-02-14 17:09 349
  //! A class used to disambiguate cases where cereal cannot detect a unique way of serializing a class
7a956470 sago007 2016-02-14 17:09 350
  /*! cereal attempts to figure out which method of serialization (member vs. non-member serialize
7a956470 sago007 2016-02-14 17:09 351
      or load/save pair) at compile time.  If for some reason cereal cannot find a non-ambiguous way
7a956470 sago007 2016-02-14 17:09 352
      of serializing a type, it will produce a static assertion complaining about this.
7a956470 sago007 2016-02-14 17:09 353
7a956470 sago007 2016-02-14 17:09 354
      This can happen because you have both a serialize and load/save pair, or even because a base
7a956470 sago007 2016-02-14 17:09 355
      class has a serialize (public or private with friend access) and a derived class does not
7a956470 sago007 2016-02-14 17:09 356
      overwrite this due to choosing some other serialization type.
7a956470 sago007 2016-02-14 17:09 357
7a956470 sago007 2016-02-14 17:09 358
      Specializing this class will tell cereal to explicitly use the serialization type you specify
7a956470 sago007 2016-02-14 17:09 359
      and it will not complain about ambiguity in its compile time selection.  However, if cereal detects
7a956470 sago007 2016-02-14 17:09 360
      an ambiguity in specializations, it will continue to issue a static assertion.
7a956470 sago007 2016-02-14 17:09 361
7a956470 sago007 2016-02-14 17:09 362
      @code{.cpp}
7a956470 sago007 2016-02-14 17:09 363
      class MyParent
7a956470 sago007 2016-02-14 17:09 364
      {
7a956470 sago007 2016-02-14 17:09 365
        friend class cereal::access;
7a956470 sago007 2016-02-14 17:09 366
        template <class Archive>
7a956470 sago007 2016-02-14 17:09 367
        void serialize( Archive & ar ) {}
7a956470 sago007 2016-02-14 17:09 368
      };
7a956470 sago007 2016-02-14 17:09 369
7a956470 sago007 2016-02-14 17:09 370
      // Although serialize is private in MyParent, to cereal::access it will look public,
7a956470 sago007 2016-02-14 17:09 371
      // even through MyDerived
7a956470 sago007 2016-02-14 17:09 372
      class MyDerived : public MyParent
7a956470 sago007 2016-02-14 17:09 373
      {
7a956470 sago007 2016-02-14 17:09 374
        public:
7a956470 sago007 2016-02-14 17:09 375
          template <class Archive>
7a956470 sago007 2016-02-14 17:09 376
          void load( Archive & ar ) {}
7a956470 sago007 2016-02-14 17:09 377
7a956470 sago007 2016-02-14 17:09 378
          template <class Archive>
7a956470 sago007 2016-02-14 17:09 379
          void save( Archive & ar ) {}
7a956470 sago007 2016-02-14 17:09 380
      };
7a956470 sago007 2016-02-14 17:09 381
7a956470 sago007 2016-02-14 17:09 382
      // The load/save pair in MyDerived is ambiguous because serialize in MyParent can
7a956470 sago007 2016-02-14 17:09 383
      // be accessed from cereal::access.  This looks the same as making serialize public
7a956470 sago007 2016-02-14 17:09 384
      // in MyParent, making it seem as though MyDerived has both a serialize and a load/save pair.
7a956470 sago007 2016-02-14 17:09 385
      // cereal will complain about this at compile time unless we disambiguate:
7a956470 sago007 2016-02-14 17:09 386
7a956470 sago007 2016-02-14 17:09 387
      namespace cereal
7a956470 sago007 2016-02-14 17:09 388
      {
7a956470 sago007 2016-02-14 17:09 389
        // This struct specialization will tell cereal which is the right way to serialize the ambiguity
7a956470 sago007 2016-02-14 17:09 390
        template <class Archive> struct specialize<Archive, MyDerived, cereal::specialization::member_load_save> {};
7a956470 sago007 2016-02-14 17:09 391
7a956470 sago007 2016-02-14 17:09 392
        // If we only had a disambiguation for a specific archive type, it would look something like this
7a956470 sago007 2016-02-14 17:09 393
        template <> struct specialize<cereal::BinaryOutputArchive, MyDerived, cereal::specialization::member_load_save> {};
7a956470 sago007 2016-02-14 17:09 394
      }
7a956470 sago007 2016-02-14 17:09 395
      @endcode
7a956470 sago007 2016-02-14 17:09 396
7a956470 sago007 2016-02-14 17:09 397
      You can also choose to use the macros CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES or
7a956470 sago007 2016-02-14 17:09 398
      CEREAL_SPECIALIZE_FOR_ARCHIVE if you want to type a little bit less.
7a956470 sago007 2016-02-14 17:09 399
7a956470 sago007 2016-02-14 17:09 400
      @tparam T The type to specialize the serialization for
7a956470 sago007 2016-02-14 17:09 401
      @tparam S The specialization type to use for T
7a956470 sago007 2016-02-14 17:09 402
      @ingroup Access */
7a956470 sago007 2016-02-14 17:09 403
  template <class Archive, class T, specialization S>
7a956470 sago007 2016-02-14 17:09 404
  struct specialize : public std::false_type {};
7a956470 sago007 2016-02-14 17:09 405
7a956470 sago007 2016-02-14 17:09 406
  //! Convenient macro for performing specialization for all archive types
7a956470 sago007 2016-02-14 17:09 407
  /*! This performs specialization for the specific type for all types of archives.
7a956470 sago007 2016-02-14 17:09 408
      This macro should be placed at the global namespace.
7a956470 sago007 2016-02-14 17:09 409
7a956470 sago007 2016-02-14 17:09 410
      @code{cpp}
7a956470 sago007 2016-02-14 17:09 411
      struct MyType {};
7a956470 sago007 2016-02-14 17:09 412
      CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES( MyType, cereal::specialization::member_load_save );
7a956470 sago007 2016-02-14 17:09 413
      @endcode
7a956470 sago007 2016-02-14 17:09 414
7a956470 sago007 2016-02-14 17:09 415
      @relates specialize
7a956470 sago007 2016-02-14 17:09 416
      @ingroup Access */
7a956470 sago007 2016-02-14 17:09 417
  #define CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES( Type, Specialization )                                \
7a956470 sago007 2016-02-14 17:09 418
  namespace cereal { template <class Archive> struct specialize<Archive, Type, Specialization> {}; }
7a956470 sago007 2016-02-14 17:09 419
7a956470 sago007 2016-02-14 17:09 420
  //! Convenient macro for performing specialization for a single archive type
7a956470 sago007 2016-02-14 17:09 421
  /*! This performs specialization for the specific type for a single type of archive.
7a956470 sago007 2016-02-14 17:09 422
      This macro should be placed at the global namespace.
7a956470 sago007 2016-02-14 17:09 423
7a956470 sago007 2016-02-14 17:09 424
      @code{cpp}
7a956470 sago007 2016-02-14 17:09 425
      struct MyType {};
7a956470 sago007 2016-02-14 17:09 426
      CEREAL_SPECIALIZE_FOR_ARCHIVE( cereal::XMLInputArchive, MyType, cereal::specialization::member_load_save );
7a956470 sago007 2016-02-14 17:09 427
      @endcode
7a956470 sago007 2016-02-14 17:09 428
7a956470 sago007 2016-02-14 17:09 429
      @relates specialize
7a956470 sago007 2016-02-14 17:09 430
      @ingroup Access */
7a956470 sago007 2016-02-14 17:09 431
  #define CEREAL_SPECIALIZE_FOR_ARCHIVE( Archive, Type, Specialization )               \
7a956470 sago007 2016-02-14 17:09 432
  namespace cereal { template <> struct specialize<Archive, Type, Specialization> {}; }
7a956470 sago007 2016-02-14 17:09 433
7a956470 sago007 2016-02-14 17:09 434
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 435
  // Deferred Implementation, see construct for more information
7a956470 sago007 2016-02-14 17:09 436
  template <class T> template <class ... Args> inline
7a956470 sago007 2016-02-14 17:09 437
  void construct<T>::operator()( Args && ... args )
7a956470 sago007 2016-02-14 17:09 438
  {
7a956470 sago007 2016-02-14 17:09 439
    if( itsValid )
7a956470 sago007 2016-02-14 17:09 440
      throw Exception("Attempting to construct an already initialized object");
7a956470 sago007 2016-02-14 17:09 441
7a956470 sago007 2016-02-14 17:09 442
    ::cereal::access::construct( itsPtr, std::forward<Args>( args )... );
6c5f2c01 sago007 2017-03-15 17:56 443
    itsEnableSharedRestoreFunction();
7a956470 sago007 2016-02-14 17:09 444
    itsValid = true;
7a956470 sago007 2016-02-14 17:09 445
  }
7a956470 sago007 2016-02-14 17:09 446
} // namespace cereal
7a956470 sago007 2016-02-14 17:09 447
7a956470 sago007 2016-02-14 17:09 448
#endif // CEREAL_ACCESS_HPP_
1970-01-01 00:00 449