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>
7a956470 sago007 2016-02-14 17:09 35
7a956470 sago007 2016-02-14 17:09 36
#include <cereal/macros.hpp>
7a956470 sago007 2016-02-14 17:09 37
#include <cereal/details/helpers.hpp>
7a956470 sago007 2016-02-14 17:09 38
7a956470 sago007 2016-02-14 17:09 39
namespace cereal
7a956470 sago007 2016-02-14 17:09 40
{
7a956470 sago007 2016-02-14 17:09 41
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 42
  //! A class that allows cereal to load smart pointers to types that have no default constructor
7a956470 sago007 2016-02-14 17:09 43
  /*! If your class does not have a default constructor, cereal will not be able
7a956470 sago007 2016-02-14 17:09 44
      to load any smart pointers to it unless you overload LoadAndConstruct
7a956470 sago007 2016-02-14 17:09 45
      for your class, and provide an appropriate load_and_construct method.  You can also
7a956470 sago007 2016-02-14 17:09 46
      choose to define a member static function instead of specializing this class.
7a956470 sago007 2016-02-14 17:09 47
7a956470 sago007 2016-02-14 17:09 48
      The specialization of LoadAndConstruct must be placed within the cereal namespace:
7a956470 sago007 2016-02-14 17:09 49
7a956470 sago007 2016-02-14 17:09 50
      @code{.cpp}
7a956470 sago007 2016-02-14 17:09 51
      struct MyType
7a956470 sago007 2016-02-14 17:09 52
      {
7a956470 sago007 2016-02-14 17:09 53
        MyType( int x ); // note: no default ctor
7a956470 sago007 2016-02-14 17:09 54
        int myX;
7a956470 sago007 2016-02-14 17:09 55
7a956470 sago007 2016-02-14 17:09 56
        // Define a serialize or load/save pair as you normally would
7a956470 sago007 2016-02-14 17:09 57
        template <class Archive>
7a956470 sago007 2016-02-14 17:09 58
        void serialize( Archive & ar )
7a956470 sago007 2016-02-14 17:09 59
        {
7a956470 sago007 2016-02-14 17:09 60
          ar( myX );
7a956470 sago007 2016-02-14 17:09 61
        }
7a956470 sago007 2016-02-14 17:09 62
      };
7a956470 sago007 2016-02-14 17:09 63
7a956470 sago007 2016-02-14 17:09 64
      // Provide a specialization for LoadAndConstruct for your type
7a956470 sago007 2016-02-14 17:09 65
      namespace cereal
7a956470 sago007 2016-02-14 17:09 66
      {
7a956470 sago007 2016-02-14 17:09 67
        template <> struct LoadAndConstruct<MyType>
7a956470 sago007 2016-02-14 17:09 68
        {
7a956470 sago007 2016-02-14 17:09 69
          // load_and_construct will be passed the archive that you will be loading
7a956470 sago007 2016-02-14 17:09 70
          // from as well as a construct object which you can use as if it were the
7a956470 sago007 2016-02-14 17:09 71
          // constructor for your type.  cereal will handle all memory management for you.
7a956470 sago007 2016-02-14 17:09 72
          template <class Archive>
7a956470 sago007 2016-02-14 17:09 73
          static void load_and_construct( Archive & ar, cereal::construct<MyType> & construct )
7a956470 sago007 2016-02-14 17:09 74
          {
7a956470 sago007 2016-02-14 17:09 75
            int x;
7a956470 sago007 2016-02-14 17:09 76
            ar( x );
7a956470 sago007 2016-02-14 17:09 77
            construct( x );
7a956470 sago007 2016-02-14 17:09 78
          }
7a956470 sago007 2016-02-14 17:09 79
        };
7a956470 sago007 2016-02-14 17:09 80
      } // end namespace cereal
7a956470 sago007 2016-02-14 17:09 81
      @endcode
7a956470 sago007 2016-02-14 17:09 82
7a956470 sago007 2016-02-14 17:09 83
      Please note that just as in using external serialization functions, you cannot get
7a956470 sago007 2016-02-14 17:09 84
      access to non-public members of your class by befriending cereal::access.  If you
7a956470 sago007 2016-02-14 17:09 85
      have the ability to modify the class you wish to serialize, it is recommended that you
7a956470 sago007 2016-02-14 17:09 86
      use member serialize functions and a static member load_and_construct function.
7a956470 sago007 2016-02-14 17:09 87
7a956470 sago007 2016-02-14 17:09 88
      @tparam T The type to specialize for
7a956470 sago007 2016-02-14 17:09 89
      @ingroup Access */
7a956470 sago007 2016-02-14 17:09 90
  template <class T>
7a956470 sago007 2016-02-14 17:09 91
  struct LoadAndConstruct
7a956470 sago007 2016-02-14 17:09 92
  {
7a956470 sago007 2016-02-14 17:09 93
    //! Called by cereal if no default constructor exists to load and construct data simultaneously
7a956470 sago007 2016-02-14 17:09 94
    /*! Overloads of this should return a pointer to T and expect an archive as a parameter */
7a956470 sago007 2016-02-14 17:09 95
    static std::false_type load_and_construct(...)
7a956470 sago007 2016-02-14 17:09 96
    { return std::false_type(); }
7a956470 sago007 2016-02-14 17:09 97
  };
7a956470 sago007 2016-02-14 17:09 98
7a956470 sago007 2016-02-14 17:09 99
  // forward decl for construct
7a956470 sago007 2016-02-14 17:09 100
  //! @cond PRIVATE_NEVERDEFINED
7a956470 sago007 2016-02-14 17:09 101
  namespace memory_detail{ template <class Ar, class T> struct LoadAndConstructLoadWrapper; }
7a956470 sago007 2016-02-14 17:09 102
  //! @endcond
7a956470 sago007 2016-02-14 17:09 103
7a956470 sago007 2016-02-14 17:09 104
  //! Used to construct types with no default constructor
7a956470 sago007 2016-02-14 17:09 105
  /*! When serializing a type that has no default constructor, cereal
7a956470 sago007 2016-02-14 17:09 106
      will attempt to call either the class static function load_and_construct
7a956470 sago007 2016-02-14 17:09 107
      or the appropriate template specialization of LoadAndConstruct.  cereal
7a956470 sago007 2016-02-14 17:09 108
      will pass that function a reference to the archive as well as a reference
7a956470 sago007 2016-02-14 17:09 109
      to a construct object which should be used to perform the allocation once
7a956470 sago007 2016-02-14 17:09 110
      data has been appropriately loaded.
7a956470 sago007 2016-02-14 17:09 111
7a956470 sago007 2016-02-14 17:09 112
      @code{.cpp}
7a956470 sago007 2016-02-14 17:09 113
      struct MyType
7a956470 sago007 2016-02-14 17:09 114
      {
7a956470 sago007 2016-02-14 17:09 115
        // note the lack of default constructor
7a956470 sago007 2016-02-14 17:09 116
        MyType( int xx, int yy );
7a956470 sago007 2016-02-14 17:09 117
7a956470 sago007 2016-02-14 17:09 118
        int x, y;
7a956470 sago007 2016-02-14 17:09 119
        double notInConstructor;
7a956470 sago007 2016-02-14 17:09 120
7a956470 sago007 2016-02-14 17:09 121
        template <class Archive>
7a956470 sago007 2016-02-14 17:09 122
        void serialize( Archive & ar )
7a956470 sago007 2016-02-14 17:09 123
        {
7a956470 sago007 2016-02-14 17:09 124
          ar( x, y );
7a956470 sago007 2016-02-14 17:09 125
          ar( notInConstructor );
7a956470 sago007 2016-02-14 17:09 126
        }
7a956470 sago007 2016-02-14 17:09 127
7a956470 sago007 2016-02-14 17:09 128
        template <class Archive>
7a956470 sago007 2016-02-14 17:09 129
        static void load_and_construct( Archive & ar, cereal::construct<MyType> & construct )
7a956470 sago007 2016-02-14 17:09 130
        {
7a956470 sago007 2016-02-14 17:09 131
          int x, y;
7a956470 sago007 2016-02-14 17:09 132
          ar( x, y );
7a956470 sago007 2016-02-14 17:09 133
7a956470 sago007 2016-02-14 17:09 134
          // use construct object to initialize with loaded data
7a956470 sago007 2016-02-14 17:09 135
          construct( x, y );
7a956470 sago007 2016-02-14 17:09 136
7a956470 sago007 2016-02-14 17:09 137
          // access to member variables and functions via -> operator
7a956470 sago007 2016-02-14 17:09 138
          ar( construct->notInConstructor );
7a956470 sago007 2016-02-14 17:09 139
7a956470 sago007 2016-02-14 17:09 140
          // could also do the above section by:
7a956470 sago007 2016-02-14 17:09 141
          double z;
7a956470 sago007 2016-02-14 17:09 142
          ar( z );
7a956470 sago007 2016-02-14 17:09 143
          construct->notInConstructor = z;
7a956470 sago007 2016-02-14 17:09 144
        }
7a956470 sago007 2016-02-14 17:09 145
      };
7a956470 sago007 2016-02-14 17:09 146
      @endcode
7a956470 sago007 2016-02-14 17:09 147
7a956470 sago007 2016-02-14 17:09 148
      @tparam T The class type being serialized
7a956470 sago007 2016-02-14 17:09 149
      */
7a956470 sago007 2016-02-14 17:09 150
  template <class T>
7a956470 sago007 2016-02-14 17:09 151
  class construct
7a956470 sago007 2016-02-14 17:09 152
  {
7a956470 sago007 2016-02-14 17:09 153
    public:
7a956470 sago007 2016-02-14 17:09 154
      //! Construct and initialize the type T with the given arguments
7a956470 sago007 2016-02-14 17:09 155
      /*! This will forward all arguments to the underlying type T,
7a956470 sago007 2016-02-14 17:09 156
          calling an appropriate constructor.
7a956470 sago007 2016-02-14 17:09 157
7a956470 sago007 2016-02-14 17:09 158
          Calling this function more than once will result in an exception
7a956470 sago007 2016-02-14 17:09 159
          being thrown.
7a956470 sago007 2016-02-14 17:09 160
7a956470 sago007 2016-02-14 17:09 161
          @param args The arguments to the constructor for T
7a956470 sago007 2016-02-14 17:09 162
          @throw Exception If called more than once */
7a956470 sago007 2016-02-14 17:09 163
      template <class ... Args>
7a956470 sago007 2016-02-14 17:09 164
      void operator()( Args && ... args );
7a956470 sago007 2016-02-14 17:09 165
      // implementation deferred due to reliance on cereal::access
7a956470 sago007 2016-02-14 17:09 166
7a956470 sago007 2016-02-14 17:09 167
      //! Get a reference to the initialized underlying object
7a956470 sago007 2016-02-14 17:09 168
      /*! This must be called after the object has been initialized.
7a956470 sago007 2016-02-14 17:09 169
7a956470 sago007 2016-02-14 17:09 170
          @return A reference to the initialized object
7a956470 sago007 2016-02-14 17:09 171
          @throw Exception If called before initialization */
7a956470 sago007 2016-02-14 17:09 172
      T * operator->()
7a956470 sago007 2016-02-14 17:09 173
      {
7a956470 sago007 2016-02-14 17:09 174
        if( !itsValid )
7a956470 sago007 2016-02-14 17:09 175
          throw Exception("Object must be initialized prior to accessing members");
7a956470 sago007 2016-02-14 17:09 176
7a956470 sago007 2016-02-14 17:09 177
        return itsPtr;
7a956470 sago007 2016-02-14 17:09 178
      }
7a956470 sago007 2016-02-14 17:09 179
7a956470 sago007 2016-02-14 17:09 180
      //! Returns a raw pointer to the initialized underlying object
7a956470 sago007 2016-02-14 17:09 181
      /*! This is mainly intended for use with passing an instance of
7a956470 sago007 2016-02-14 17:09 182
          a constructed object to cereal::base_class.
7a956470 sago007 2016-02-14 17:09 183
7a956470 sago007 2016-02-14 17:09 184
          It is strongly recommended to avoid using this function in
7a956470 sago007 2016-02-14 17:09 185
          any other circumstance.
7a956470 sago007 2016-02-14 17:09 186
7a956470 sago007 2016-02-14 17:09 187
          @return A raw pointer to the initialized type */
7a956470 sago007 2016-02-14 17:09 188
      T * ptr()
7a956470 sago007 2016-02-14 17:09 189
      {
7a956470 sago007 2016-02-14 17:09 190
        return operator->();
7a956470 sago007 2016-02-14 17:09 191
      }
7a956470 sago007 2016-02-14 17:09 192
7a956470 sago007 2016-02-14 17:09 193
    private:
7a956470 sago007 2016-02-14 17:09 194
      template <class A, class B> friend struct ::cereal::memory_detail::LoadAndConstructLoadWrapper;
7a956470 sago007 2016-02-14 17:09 195
7a956470 sago007 2016-02-14 17:09 196
      construct( T * p ) : itsPtr( p ), itsValid( false ) {}
7a956470 sago007 2016-02-14 17:09 197
      construct( construct const & ) = delete;
7a956470 sago007 2016-02-14 17:09 198
      construct & operator=( construct const & ) = delete;
7a956470 sago007 2016-02-14 17:09 199
7a956470 sago007 2016-02-14 17:09 200
      T * itsPtr;
7a956470 sago007 2016-02-14 17:09 201
      bool itsValid;
7a956470 sago007 2016-02-14 17:09 202
  };
7a956470 sago007 2016-02-14 17:09 203
7a956470 sago007 2016-02-14 17:09 204
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 205
  //! A class that can be made a friend to give cereal access to non public functions
7a956470 sago007 2016-02-14 17:09 206
  /*! If you desire non-public serialization functions within a class, cereal can only
7a956470 sago007 2016-02-14 17:09 207
      access these if you declare cereal::access a friend.
7a956470 sago007 2016-02-14 17:09 208
7a956470 sago007 2016-02-14 17:09 209
      @code{.cpp}
7a956470 sago007 2016-02-14 17:09 210
      class MyClass
7a956470 sago007 2016-02-14 17:09 211
      {
7a956470 sago007 2016-02-14 17:09 212
        private:
7a956470 sago007 2016-02-14 17:09 213
          friend class cereal::access; // gives access to the private serialize
7a956470 sago007 2016-02-14 17:09 214
7a956470 sago007 2016-02-14 17:09 215
          template <class Archive>
7a956470 sago007 2016-02-14 17:09 216
          void serialize( Archive & ar )
7a956470 sago007 2016-02-14 17:09 217
          {
7a956470 sago007 2016-02-14 17:09 218
            // some code
7a956470 sago007 2016-02-14 17:09 219
          }
7a956470 sago007 2016-02-14 17:09 220
      };
7a956470 sago007 2016-02-14 17:09 221
      @endcode
7a956470 sago007 2016-02-14 17:09 222
      @ingroup Access */
7a956470 sago007 2016-02-14 17:09 223
  class access
7a956470 sago007 2016-02-14 17:09 224
  {
7a956470 sago007 2016-02-14 17:09 225
    public:
7a956470 sago007 2016-02-14 17:09 226
      // ####### Standard Serialization ########################################
7a956470 sago007 2016-02-14 17:09 227
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 228
      static auto member_serialize(Archive & ar, T & t) -> decltype(t.CEREAL_SERIALIZE_FUNCTION_NAME(ar))
7a956470 sago007 2016-02-14 17:09 229
      { return t.CEREAL_SERIALIZE_FUNCTION_NAME(ar); }
7a956470 sago007 2016-02-14 17:09 230
7a956470 sago007 2016-02-14 17:09 231
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 232
      static auto member_save(Archive & ar, T const & t) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar))
7a956470 sago007 2016-02-14 17:09 233
      { return t.CEREAL_SAVE_FUNCTION_NAME(ar); }
7a956470 sago007 2016-02-14 17:09 234
7a956470 sago007 2016-02-14 17:09 235
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 236
      static auto member_save_non_const(Archive & ar, T & t) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar))
7a956470 sago007 2016-02-14 17:09 237
      { return t.CEREAL_SAVE_FUNCTION_NAME(ar); }
7a956470 sago007 2016-02-14 17:09 238
7a956470 sago007 2016-02-14 17:09 239
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 240
      static auto member_load(Archive & ar, T & t) -> decltype(t.CEREAL_LOAD_FUNCTION_NAME(ar))
7a956470 sago007 2016-02-14 17:09 241
      { return t.CEREAL_LOAD_FUNCTION_NAME(ar); }
7a956470 sago007 2016-02-14 17:09 242
7a956470 sago007 2016-02-14 17:09 243
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 244
      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 245
      { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar); }
7a956470 sago007 2016-02-14 17:09 246
7a956470 sago007 2016-02-14 17:09 247
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 248
      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 249
      { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar); }
7a956470 sago007 2016-02-14 17:09 250
7a956470 sago007 2016-02-14 17:09 251
      template<class Archive, class T, class U> inline
7a956470 sago007 2016-02-14 17:09 252
      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 253
      { return t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u)); }
7a956470 sago007 2016-02-14 17:09 254
7a956470 sago007 2016-02-14 17:09 255
      // ####### Versioned Serialization #######################################
7a956470 sago007 2016-02-14 17:09 256
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 257
      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 258
      { return t.CEREAL_SERIALIZE_FUNCTION_NAME(ar, version); }
7a956470 sago007 2016-02-14 17:09 259
7a956470 sago007 2016-02-14 17:09 260
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 261
      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 262
      { return t.CEREAL_SAVE_FUNCTION_NAME(ar, version); }
7a956470 sago007 2016-02-14 17:09 263
7a956470 sago007 2016-02-14 17:09 264
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 265
      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 266
      { return t.CEREAL_SAVE_FUNCTION_NAME(ar, version); }
7a956470 sago007 2016-02-14 17:09 267
7a956470 sago007 2016-02-14 17:09 268
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 269
      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 270
      { return t.CEREAL_LOAD_FUNCTION_NAME(ar, version); }
7a956470 sago007 2016-02-14 17:09 271
7a956470 sago007 2016-02-14 17:09 272
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 273
      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 274
      { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version); }
7a956470 sago007 2016-02-14 17:09 275
7a956470 sago007 2016-02-14 17:09 276
      template<class Archive, class T> inline
7a956470 sago007 2016-02-14 17:09 277
      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 278
      { return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version); }
7a956470 sago007 2016-02-14 17:09 279
7a956470 sago007 2016-02-14 17:09 280
      template<class Archive, class T, class U> inline
7a956470 sago007 2016-02-14 17:09 281
      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 282
      { return t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u), version); }
7a956470 sago007 2016-02-14 17:09 283
7a956470 sago007 2016-02-14 17:09 284
      // ####### Other Functionality ##########################################
7a956470 sago007 2016-02-14 17:09 285
      // for detecting inheritance from enable_shared_from_this
7a956470 sago007 2016-02-14 17:09 286
      template <class T> inline
7a956470 sago007 2016-02-14 17:09 287
      static auto shared_from_this(T & t) -> decltype(t.shared_from_this());
7a956470 sago007 2016-02-14 17:09 288
7a956470 sago007 2016-02-14 17:09 289
      // for placement new
7a956470 sago007 2016-02-14 17:09 290
      template <class T, class ... Args> inline
7a956470 sago007 2016-02-14 17:09 291
      static void construct( T *& ptr, Args && ... args )
7a956470 sago007 2016-02-14 17:09 292
      {
7a956470 sago007 2016-02-14 17:09 293
        new (ptr) T( std::forward<Args>( args )... );
7a956470 sago007 2016-02-14 17:09 294
      }
7a956470 sago007 2016-02-14 17:09 295
7a956470 sago007 2016-02-14 17:09 296
      // for non-placement new with a default constructor
7a956470 sago007 2016-02-14 17:09 297
      template <class T> inline
7a956470 sago007 2016-02-14 17:09 298
      static T * construct()
7a956470 sago007 2016-02-14 17:09 299
      {
7a956470 sago007 2016-02-14 17:09 300
        return new T();
7a956470 sago007 2016-02-14 17:09 301
      }
7a956470 sago007 2016-02-14 17:09 302
7a956470 sago007 2016-02-14 17:09 303
      template <class T> inline
7a956470 sago007 2016-02-14 17:09 304
      static std::false_type load_and_construct(...)
7a956470 sago007 2016-02-14 17:09 305
      { return std::false_type(); }
7a956470 sago007 2016-02-14 17:09 306
7a956470 sago007 2016-02-14 17:09 307
      template<class T, class Archive> inline
7a956470 sago007 2016-02-14 17:09 308
      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 309
      {
7a956470 sago007 2016-02-14 17:09 310
        T::load_and_construct( ar, construct );
7a956470 sago007 2016-02-14 17:09 311
      }
7a956470 sago007 2016-02-14 17:09 312
  }; // end class access
7a956470 sago007 2016-02-14 17:09 313
7a956470 sago007 2016-02-14 17:09 314
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 315
  //! A specifier used in conjunction with cereal::specialize to disambiguate
7a956470 sago007 2016-02-14 17:09 316
  //! serialization in special cases
7a956470 sago007 2016-02-14 17:09 317
  /*! @relates specialize
7a956470 sago007 2016-02-14 17:09 318
      @ingroup Access */
7a956470 sago007 2016-02-14 17:09 319
  enum class specialization
7a956470 sago007 2016-02-14 17:09 320
  {
7a956470 sago007 2016-02-14 17:09 321
    member_serialize,            //!< Force the use of a member serialize function
7a956470 sago007 2016-02-14 17:09 322
    member_load_save,            //!< Force the use of a member load/save pair
7a956470 sago007 2016-02-14 17:09 323
    member_load_save_minimal,    //!< Force the use of a member minimal load/save pair
7a956470 sago007 2016-02-14 17:09 324
    non_member_serialize,        //!< Force the use of a non-member serialize function
7a956470 sago007 2016-02-14 17:09 325
    non_member_load_save,        //!< Force the use of a non-member load/save pair
7a956470 sago007 2016-02-14 17:09 326
    non_member_load_save_minimal //!< Force the use of a non-member minimal load/save pair
7a956470 sago007 2016-02-14 17:09 327
  };
7a956470 sago007 2016-02-14 17:09 328
7a956470 sago007 2016-02-14 17:09 329
  //! A class used to disambiguate cases where cereal cannot detect a unique way of serializing a class
7a956470 sago007 2016-02-14 17:09 330
  /*! cereal attempts to figure out which method of serialization (member vs. non-member serialize
7a956470 sago007 2016-02-14 17:09 331
      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 332
      of serializing a type, it will produce a static assertion complaining about this.
7a956470 sago007 2016-02-14 17:09 333
7a956470 sago007 2016-02-14 17:09 334
      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 335
      class has a serialize (public or private with friend access) and a derived class does not
7a956470 sago007 2016-02-14 17:09 336
      overwrite this due to choosing some other serialization type.
7a956470 sago007 2016-02-14 17:09 337
7a956470 sago007 2016-02-14 17:09 338
      Specializing this class will tell cereal to explicitly use the serialization type you specify
7a956470 sago007 2016-02-14 17:09 339
      and it will not complain about ambiguity in its compile time selection.  However, if cereal detects
7a956470 sago007 2016-02-14 17:09 340
      an ambiguity in specializations, it will continue to issue a static assertion.
7a956470 sago007 2016-02-14 17:09 341
7a956470 sago007 2016-02-14 17:09 342
      @code{.cpp}
7a956470 sago007 2016-02-14 17:09 343
      class MyParent
7a956470 sago007 2016-02-14 17:09 344
      {
7a956470 sago007 2016-02-14 17:09 345
        friend class cereal::access;
7a956470 sago007 2016-02-14 17:09 346
        template <class Archive>
7a956470 sago007 2016-02-14 17:09 347
        void serialize( Archive & ar ) {}
7a956470 sago007 2016-02-14 17:09 348
      };
7a956470 sago007 2016-02-14 17:09 349
7a956470 sago007 2016-02-14 17:09 350
      // Although serialize is private in MyParent, to cereal::access it will look public,
7a956470 sago007 2016-02-14 17:09 351
      // even through MyDerived
7a956470 sago007 2016-02-14 17:09 352
      class MyDerived : public MyParent
7a956470 sago007 2016-02-14 17:09 353
      {
7a956470 sago007 2016-02-14 17:09 354
        public:
7a956470 sago007 2016-02-14 17:09 355
          template <class Archive>
7a956470 sago007 2016-02-14 17:09 356
          void load( Archive & ar ) {}
7a956470 sago007 2016-02-14 17:09 357
7a956470 sago007 2016-02-14 17:09 358
          template <class Archive>
7a956470 sago007 2016-02-14 17:09 359
          void save( Archive & ar ) {}
7a956470 sago007 2016-02-14 17:09 360
      };
7a956470 sago007 2016-02-14 17:09 361
7a956470 sago007 2016-02-14 17:09 362
      // The load/save pair in MyDerived is ambiguous because serialize in MyParent can
7a956470 sago007 2016-02-14 17:09 363
      // be accessed from cereal::access.  This looks the same as making serialize public
7a956470 sago007 2016-02-14 17:09 364
      // in MyParent, making it seem as though MyDerived has both a serialize and a load/save pair.
7a956470 sago007 2016-02-14 17:09 365
      // cereal will complain about this at compile time unless we disambiguate:
7a956470 sago007 2016-02-14 17:09 366
7a956470 sago007 2016-02-14 17:09 367
      namespace cereal
7a956470 sago007 2016-02-14 17:09 368
      {
7a956470 sago007 2016-02-14 17:09 369
        // This struct specialization will tell cereal which is the right way to serialize the ambiguity
7a956470 sago007 2016-02-14 17:09 370
        template <class Archive> struct specialize<Archive, MyDerived, cereal::specialization::member_load_save> {};
7a956470 sago007 2016-02-14 17:09 371
7a956470 sago007 2016-02-14 17:09 372
        // If we only had a disambiguation for a specific archive type, it would look something like this
7a956470 sago007 2016-02-14 17:09 373
        template <> struct specialize<cereal::BinaryOutputArchive, MyDerived, cereal::specialization::member_load_save> {};
7a956470 sago007 2016-02-14 17:09 374
      }
7a956470 sago007 2016-02-14 17:09 375
      @endcode
7a956470 sago007 2016-02-14 17:09 376
7a956470 sago007 2016-02-14 17:09 377
      You can also choose to use the macros CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES or
7a956470 sago007 2016-02-14 17:09 378
      CEREAL_SPECIALIZE_FOR_ARCHIVE if you want to type a little bit less.
7a956470 sago007 2016-02-14 17:09 379
7a956470 sago007 2016-02-14 17:09 380
      @tparam T The type to specialize the serialization for
7a956470 sago007 2016-02-14 17:09 381
      @tparam S The specialization type to use for T
7a956470 sago007 2016-02-14 17:09 382
      @ingroup Access */
7a956470 sago007 2016-02-14 17:09 383
  template <class Archive, class T, specialization S>
7a956470 sago007 2016-02-14 17:09 384
  struct specialize : public std::false_type {};
7a956470 sago007 2016-02-14 17:09 385
7a956470 sago007 2016-02-14 17:09 386
  //! Convenient macro for performing specialization for all archive types
7a956470 sago007 2016-02-14 17:09 387
  /*! This performs specialization for the specific type for all types of archives.
7a956470 sago007 2016-02-14 17:09 388
      This macro should be placed at the global namespace.
7a956470 sago007 2016-02-14 17:09 389
7a956470 sago007 2016-02-14 17:09 390
      @code{cpp}
7a956470 sago007 2016-02-14 17:09 391
      struct MyType {};
7a956470 sago007 2016-02-14 17:09 392
      CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES( MyType, cereal::specialization::member_load_save );
7a956470 sago007 2016-02-14 17:09 393
      @endcode
7a956470 sago007 2016-02-14 17:09 394
7a956470 sago007 2016-02-14 17:09 395
      @relates specialize
7a956470 sago007 2016-02-14 17:09 396
      @ingroup Access */
7a956470 sago007 2016-02-14 17:09 397
  #define CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES( Type, Specialization )                                \
7a956470 sago007 2016-02-14 17:09 398
  namespace cereal { template <class Archive> struct specialize<Archive, Type, Specialization> {}; }
7a956470 sago007 2016-02-14 17:09 399
7a956470 sago007 2016-02-14 17:09 400
  //! Convenient macro for performing specialization for a single archive type
7a956470 sago007 2016-02-14 17:09 401
  /*! This performs specialization for the specific type for a single type of archive.
7a956470 sago007 2016-02-14 17:09 402
      This macro should be placed at the global namespace.
7a956470 sago007 2016-02-14 17:09 403
7a956470 sago007 2016-02-14 17:09 404
      @code{cpp}
7a956470 sago007 2016-02-14 17:09 405
      struct MyType {};
7a956470 sago007 2016-02-14 17:09 406
      CEREAL_SPECIALIZE_FOR_ARCHIVE( cereal::XMLInputArchive, MyType, cereal::specialization::member_load_save );
7a956470 sago007 2016-02-14 17:09 407
      @endcode
7a956470 sago007 2016-02-14 17:09 408
7a956470 sago007 2016-02-14 17:09 409
      @relates specialize
7a956470 sago007 2016-02-14 17:09 410
      @ingroup Access */
7a956470 sago007 2016-02-14 17:09 411
  #define CEREAL_SPECIALIZE_FOR_ARCHIVE( Archive, Type, Specialization )               \
7a956470 sago007 2016-02-14 17:09 412
  namespace cereal { template <> struct specialize<Archive, Type, Specialization> {}; }
7a956470 sago007 2016-02-14 17:09 413
7a956470 sago007 2016-02-14 17:09 414
  // ######################################################################
7a956470 sago007 2016-02-14 17:09 415
  // Deferred Implementation, see construct for more information
7a956470 sago007 2016-02-14 17:09 416
  template <class T> template <class ... Args> inline
7a956470 sago007 2016-02-14 17:09 417
  void construct<T>::operator()( Args && ... args )
7a956470 sago007 2016-02-14 17:09 418
  {
7a956470 sago007 2016-02-14 17:09 419
    if( itsValid )
7a956470 sago007 2016-02-14 17:09 420
      throw Exception("Attempting to construct an already initialized object");
7a956470 sago007 2016-02-14 17:09 421
7a956470 sago007 2016-02-14 17:09 422
    ::cereal::access::construct( itsPtr, std::forward<Args>( args )... );
7a956470 sago007 2016-02-14 17:09 423
    itsValid = true;
7a956470 sago007 2016-02-14 17:09 424
  }
7a956470 sago007 2016-02-14 17:09 425
} // namespace cereal
7a956470 sago007 2016-02-14 17:09 426
7a956470 sago007 2016-02-14 17:09 427
#endif // CEREAL_ACCESS_HPP_
1970-01-01 00:00 428