access.hpp
Go to the documentation of this file.
/*
Copyright (c) 2014, Randolph Voorhies, Shane Grant
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CEREAL_ACCESS_HPP_
#define CEREAL_ACCESS_HPP_
#include <type_traits>
#include <iostream>
#include <cstdint>
#include <functional>
#include "cereal/macros.hpp"
#include "cereal/specialize.hpp"
#include "cereal/details/helpers.hpp"
namespace cereal
{
// ######################################################################
template <class T>
struct LoadAndConstruct
{ };
// forward decl for construct
namespace memory_detail{ template <class Ar, class T> struct LoadAndConstructLoadWrapper; }
namespace boost_variant_detail{ template <class Ar, class T> struct LoadAndConstructLoadWrapper; }
template <class T>
class construct
{
public:
template <class ... Args>
void operator()( Args && ... args );
// implementation deferred due to reliance on cereal::access
T * operator->()
{
if( !itsValid )
throw Exception("Object must be initialized prior to accessing members");
return itsPtr;
}
T * ptr()
{
return operator->();
}
private:
template <class Ar, class TT> friend struct ::cereal::memory_detail::LoadAndConstructLoadWrapper;
template <class Ar, class TT> friend struct ::cereal::boost_variant_detail::LoadAndConstructLoadWrapper;
construct( T * p ) : itsPtr( p ), itsEnableSharedRestoreFunction( [](){} ), itsValid( false ) {}
construct( T * p, std::function<void()> enableSharedFunc ) : // g++4.7 ice with default lambda to std func
itsPtr( p ), itsEnableSharedRestoreFunction( enableSharedFunc ), itsValid( false ) {}
construct( construct const & ) = delete;
construct & operator=( construct const & ) = delete;
T * itsPtr;
std::function<void()> itsEnableSharedRestoreFunction;
bool itsValid;
};
// ######################################################################
class access
{
public:
// ####### Standard Serialization ########################################
template<class Archive, class T> inline
static auto member_serialize(Archive & ar, T & t) -> decltype(t.CEREAL_SERIALIZE_FUNCTION_NAME(ar))
{ return t.CEREAL_SERIALIZE_FUNCTION_NAME(ar); }
template<class Archive, class T> inline
static auto member_save(Archive & ar, T const & t) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar))
{ return t.CEREAL_SAVE_FUNCTION_NAME(ar); }
template<class Archive, class T> inline
static auto member_save_non_const(Archive & ar, T & t) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar))
{ return t.CEREAL_SAVE_FUNCTION_NAME(ar); }
template<class Archive, class T> inline
static auto member_load(Archive & ar, T & t) -> decltype(t.CEREAL_LOAD_FUNCTION_NAME(ar))
{ return t.CEREAL_LOAD_FUNCTION_NAME(ar); }
template<class Archive, class T> inline
static auto member_save_minimal(Archive const & ar, T const & t) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar))
{ return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar); }
template<class Archive, class T> inline
static auto member_save_minimal_non_const(Archive const & ar, T & t) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar))
{ return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar); }
template<class Archive, class T, class U> inline
static auto member_load_minimal(Archive const & ar, T & t, U && u) -> decltype(t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u)))
{ return t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u)); }
// ####### Versioned Serialization #######################################
template<class Archive, class T> inline
static auto member_serialize(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.CEREAL_SERIALIZE_FUNCTION_NAME(ar, version))
{ return t.CEREAL_SERIALIZE_FUNCTION_NAME(ar, version); }
template<class Archive, class T> inline
static auto member_save(Archive & ar, T const & t, const std::uint32_t version ) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar, version))
{ return t.CEREAL_SAVE_FUNCTION_NAME(ar, version); }
template<class Archive, class T> inline
static auto member_save_non_const(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar, version))
{ return t.CEREAL_SAVE_FUNCTION_NAME(ar, version); }
template<class Archive, class T> inline
static auto member_load(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.CEREAL_LOAD_FUNCTION_NAME(ar, version))
{ return t.CEREAL_LOAD_FUNCTION_NAME(ar, version); }
template<class Archive, class T> inline
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))
{ return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version); }
template<class Archive, class T> inline
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))
{ return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version); }
template<class Archive, class T, class U> inline
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))
{ return t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u), version); }
// ####### Other Functionality ##########################################
// for detecting inheritance from enable_shared_from_this
template <class T> inline
static auto shared_from_this(T & t) -> decltype(t.shared_from_this());
// for placement new
template <class T, class ... Args> inline
static void construct( T *& ptr, Args && ... args )
{
new (ptr) T( std::forward<Args>( args )... );
}
// for non-placement new with a default constructor
template <class T> inline
static T * construct()
{
return new T();
}
template <class T> inline
static std::false_type load_and_construct(...)
{ return std::false_type(); }
template<class T, class Archive> inline
static auto load_and_construct(Archive & ar, ::cereal::construct<T> & construct) -> decltype(T::load_and_construct(ar, construct))
{
T::load_and_construct( ar, construct );
}
template<class T, class Archive> inline
static auto load_and_construct(Archive & ar, ::cereal::construct<T> & construct, const std::uint32_t version) -> decltype(T::load_and_construct(ar, construct, version))
{
T::load_and_construct( ar, construct, version );
}
}; // end class access
// ######################################################################
// Deferred Implementation, see construct for more information
template <class T> template <class ... Args> inline
void construct<T>::operator()( Args && ... args )
{
if( itsValid )
throw Exception("Attempting to construct an already initialized object");
::cereal::access::construct( itsPtr, std::forward<Args>( args )... );
itsEnableSharedRestoreFunction();
itsValid = true;
}
} // namespace cereal
#endif // CEREAL_ACCESS_HPP_
cereal::construct
Used to construct types with no default constructor.
Definition: access.hpp:164
cereal::LoadAndConstruct
A class that allows cereal to load smart pointers to types that have no default constructor.
Definition: access.hpp:108
helpers.hpp
Internal helper functionality.
specialize.hpp
Serialization disambiguation.
macros.hpp
Preprocessor macros that can customise the cereal library.
cereal::construct::ptr
T * ptr()
Returns a raw pointer to the initialized underlying object.
Definition: access.hpp:201
cereal::construct::operator->
T * operator->()
Get a reference to the initialized underlying object.
Definition: access.hpp:185
cereal::Exception
An exception class thrown when things go wrong at runtime.
Definition: helpers.hpp:48
cereal::construct::operator()
void operator()(Args &&... args)
Construct and initialize the type T with the given arguments.
Definition: access.hpp:340
cereal::access
A class that can be made a friend to give cereal access to non public functions.
Definition: access.hpp:240