Loading...
Searching...
No Matches
cereal.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_CEREAL_HPP_
#define CEREAL_CEREAL_HPP_
#include <type_traits>
#include <string>
#include <memory>
#include <functional>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <cstddef>
#include <cstdint>
#include <functional>
#include "cereal/macros.hpp"
#include "cereal/details/traits.hpp"
#include "cereal/details/helpers.hpp"
#include "cereal/types/base_class.hpp"
namespace cereal
{
// ######################################################################
template <class T> inline
NameValuePair<T> make_nvp( std::string const & name, T && value )
{
return {name.c_str(), std::forward<T>(value)};
}
template <class T> inline
NameValuePair<T> make_nvp( const char * name, T && value )
{
return {name, std::forward<T>(value)};
}
#define CEREAL_NVP(T) ::cereal::make_nvp(#T, T)
// ######################################################################
template <class T> inline
BinaryData<T> binary_data( T && data, size_t size )
{
return {std::forward<T>(data), size};
}
// ######################################################################
template <class T> inline
SizeTag<T> make_size_tag( T && sz )
{
return {std::forward<T>(sz)};
}
// ######################################################################
template <class T> inline
DeferredData<T> defer( T && value )
{
return {std::forward<T>(value)};
}
// ######################################################################
template <class Archive, class T> inline
void prologue( Archive & /* archive */, T const & /* data */)
{ }
template <class Archive, class T> inline
void epilogue( Archive & /* archive */, T const & /* data */)
{ }
// ######################################################################
enum Flags { AllowEmptyClassElision = 1 };
// ######################################################################
#define CEREAL_REGISTER_ARCHIVE(Archive) \
namespace cereal { namespace detail { \
template <class T, class BindingTag> \
typename polymorphic_serialization_support<Archive, T>::type \
instantiate_polymorphic_binding( T*, Archive*, BindingTag, adl_tag ); \
} } /* end namespaces */
#if defined(__GNUC__)
// GCC / clang don't want the function
#define CEREAL_UNUSED_FUNCTION
#else
#define CEREAL_UNUSED_FUNCTION static void unused() { (void)version; }
#endif
// ######################################################################
#ifdef CEREAL_HAS_CPP17
#define CEREAL_CLASS_VERSION(TYPE, VERSION_NUMBER) \
namespace cereal { namespace detail { \
template <> struct Version<TYPE> \
{ \
static std::uint32_t registerVersion() \
{ \
::cereal::detail::StaticObject<Versions>::getInstance().mapping.emplace( \
std::type_index(typeid(TYPE)).hash_code(), VERSION_NUMBER ); \
return VERSION_NUMBER; \
} \
static inline const std::uint32_t version = registerVersion(); \
CEREAL_UNUSED_FUNCTION \
}; /* end Version */ \
} } // end namespaces
#else
#define CEREAL_CLASS_VERSION(TYPE, VERSION_NUMBER) \
namespace cereal { namespace detail { \
template <> struct Version<TYPE> \
{ \
static const std::uint32_t version; \
static std::uint32_t registerVersion() \
{ \
::cereal::detail::StaticObject<Versions>::getInstance().mapping.emplace( \
std::type_index(typeid(TYPE)).hash_code(), VERSION_NUMBER ); \
return VERSION_NUMBER; \
} \
CEREAL_UNUSED_FUNCTION \
}; /* end Version */ \
const std::uint32_t Version<TYPE>::version = \
Version<TYPE>::registerVersion(); \
} } // end namespaces
#endif
// ######################################################################
template<class ArchiveType, std::uint32_t Flags = 0>
class OutputArchive : public detail::OutputArchiveBase
{
public:
OutputArchive(ArchiveType * const derived) : self(derived), itsCurrentPointerId(1), itsCurrentPolymorphicTypeId(1)
{ }
OutputArchive & operator=( OutputArchive const & ) = delete;
template <class ... Types> inline
ArchiveType & operator()( Types && ... args )
{
self->process( std::forward<Types>( args )... );
return *self;
}
void serializeDeferments()
{
for( auto & deferment : itsDeferments )
deferment();
}
using is_loading = std::false_type;
using is_saving = std::true_type;
template <class T> inline
ArchiveType & operator&( T && arg )
{
self->process( std::forward<T>( arg ) );
return *self;
}
template <class T> inline
ArchiveType & operator<<( T && arg )
{
self->process( std::forward<T>( arg ) );
return *self;
}
inline std::uint32_t registerSharedPointer(const std::shared_ptr<const void>& sharedPointer)
{
void const * addr = sharedPointer.get();
// Handle null pointers by just returning 0
if(addr == 0) return 0;
itsSharedPointerStorage.push_back(sharedPointer);
auto id = itsSharedPointerMap.find( addr );
if( id == itsSharedPointerMap.end() )
{
auto ptrId = itsCurrentPointerId++;
itsSharedPointerMap.insert( {addr, ptrId} );
return ptrId | detail::msb_32bit; // mask MSB to be 1
}
else
return id->second;
}
inline std::uint32_t registerPolymorphicType( char const * name )
{
auto id = itsPolymorphicTypeMap.find( name );
if( id == itsPolymorphicTypeMap.end() )
{
auto polyId = itsCurrentPolymorphicTypeId++;
itsPolymorphicTypeMap.insert( {name, polyId} );
return polyId | detail::msb_32bit; // mask MSB to be 1
}
else
return id->second;
}
private:
template <class T> inline
void process( T && head )
{
prologue( *self, head );
self->processImpl( head );
epilogue( *self, head );
}
template <class T, class ... Other> inline
void process( T && head, Other && ... tail )
{
self->process( std::forward<T>( head ) );
self->process( std::forward<Other>( tail )... );
}
template <class T> inline
ArchiveType & processImpl(virtual_base_class<T> const & b)
{
traits::detail::base_class_id id(b.base_ptr);
if(itsBaseClassSet.count(id) == 0)
{
itsBaseClassSet.insert(id);
self->processImpl( *b.base_ptr );
}
return *self;
}
template <class T> inline
ArchiveType & processImpl(base_class<T> const & b)
{
self->processImpl( *b.base_ptr );
return *self;
}
std::vector<std::function<void(void)>> itsDeferments;
template <class T> inline
ArchiveType & processImpl(DeferredData<T> const & d)
{
std::function<void(void)> deferment( [this, d](){ self->process( d.value ); } );
itsDeferments.emplace_back( std::move(deferment) );
return *self;
}
#define PROCESS_IF(name) \
traits::EnableIf<traits::has_##name<T, ArchiveType>::value, \
!traits::has_invalid_output_versioning<T, ArchiveType>::value, \
(traits::is_output_serializable<T, ArchiveType>::value && \
(traits::is_specialized_##name<T, ArchiveType>::value || \
!traits::is_specialized<T, ArchiveType>::value))> = traits::sfinae
template <class T, PROCESS_IF(member_serialize)> inline
ArchiveType & processImpl(T const & t)
{
access::member_serialize(*self, const_cast<T &>(t));
return *self;
}
template <class T, PROCESS_IF(non_member_serialize)> inline
ArchiveType & processImpl(T const & t)
{
CEREAL_SERIALIZE_FUNCTION_NAME(*self, const_cast<T &>(t));
return *self;
}
template <class T, PROCESS_IF(member_save)> inline
ArchiveType & processImpl(T const & t)
{
access::member_save(*self, t);
return *self;
}
template <class T, PROCESS_IF(non_member_save)> inline
ArchiveType & processImpl(T const & t)
{
CEREAL_SAVE_FUNCTION_NAME(*self, t);
return *self;
}
template <class T, PROCESS_IF(member_save_minimal)> inline
ArchiveType & processImpl(T const & t)
{
self->process( access::member_save_minimal(*self, t) );
return *self;
}
template <class T, PROCESS_IF(non_member_save_minimal)> inline
ArchiveType & processImpl(T const & t)
{
self->process( CEREAL_SAVE_MINIMAL_FUNCTION_NAME(*self, t) );
return *self;
}
template <class T, traits::EnableIf<(Flags & AllowEmptyClassElision),
!traits::is_output_serializable<T, ArchiveType>::value,
std::is_empty<T>::value> = traits::sfinae> inline
ArchiveType & processImpl(T const &)
{
return *self;
}
template <class T, traits::EnableIf<traits::has_invalid_output_versioning<T, ArchiveType>::value ||
(!traits::is_output_serializable<T, ArchiveType>::value &&
(!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !std::is_empty<T>::value)))> = traits::sfinae> inline
ArchiveType & processImpl(T const &)
{
static_assert(traits::detail::count_output_serializers<T, ArchiveType>::value != 0,
"cereal could not find any output serialization functions for the provided type and archive combination. \n\n "
"Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
"Serialize functions generally have the following signature: \n\n "
"template<class Archive> \n "
" void serialize(Archive & ar) \n "
" { \n "
" ar( member1, member2, member3 ); \n "
" } \n\n " );
static_assert(traits::detail::count_output_serializers<T, ArchiveType>::value < 2,
"cereal found more than one compatible output serialization function for the provided type and archive combination. \n\n "
"Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
"Use specialization (see access.hpp) if you need to disambiguate between serialize vs load/save functions. \n "
"Note that serialization functions can be inherited which may lead to the aforementioned ambiguities. \n "
"In addition, you may not mix versioned with non-versioned serialization functions. \n\n ");
return *self;
}
template <class T> inline
std::uint32_t registerClassVersion()
{
static const auto hash = std::type_index(typeid(T)).hash_code();
const auto insertResult = itsVersionedTypes.insert( hash );
const auto lock = detail::StaticObject<detail::Versions>::lock();
const auto version =
detail::StaticObject<detail::Versions>::getInstance().find( hash, detail::Version<T>::version );
if( insertResult.second ) // insertion took place, serialize the version number
process( make_nvp<ArchiveType>("cereal_class_version", version) );
return version;
}
template <class T, PROCESS_IF(member_versioned_serialize)> inline
ArchiveType & processImpl(T const & t)
{
access::member_serialize(*self, const_cast<T &>(t), registerClassVersion<T>());
return *self;
}
template <class T, PROCESS_IF(non_member_versioned_serialize)> inline
ArchiveType & processImpl(T const & t)
{
CEREAL_SERIALIZE_FUNCTION_NAME(*self, const_cast<T &>(t), registerClassVersion<T>());
return *self;
}
template <class T, PROCESS_IF(member_versioned_save)> inline
ArchiveType & processImpl(T const & t)
{
access::member_save(*self, t, registerClassVersion<T>());
return *self;
}
template <class T, PROCESS_IF(non_member_versioned_save)> inline
ArchiveType & processImpl(T const & t)
{
CEREAL_SAVE_FUNCTION_NAME(*self, t, registerClassVersion<T>());
return *self;
}
template <class T, PROCESS_IF(member_versioned_save_minimal)> inline
ArchiveType & processImpl(T const & t)
{
self->process( access::member_save_minimal(*self, t, registerClassVersion<T>()) );
return *self;
}
template <class T, PROCESS_IF(non_member_versioned_save_minimal)> inline
ArchiveType & processImpl(T const & t)
{
self->process( CEREAL_SAVE_MINIMAL_FUNCTION_NAME(*self, t, registerClassVersion<T>()) );
return *self;
}
#undef PROCESS_IF
private:
ArchiveType * const self;
std::unordered_set<traits::detail::base_class_id, traits::detail::base_class_id_hash> itsBaseClassSet;
std::unordered_map<void const *, std::uint32_t> itsSharedPointerMap;
// during lifetime of itsSharedPointerMap to prevent CVE-2020-11105.
std::vector<std::shared_ptr<const void>> itsSharedPointerStorage;
std::uint32_t itsCurrentPointerId;
std::unordered_map<char const *, std::uint32_t> itsPolymorphicTypeMap;
std::uint32_t itsCurrentPolymorphicTypeId;
std::unordered_set<size_type> itsVersionedTypes;
}; // class OutputArchive
// ######################################################################
template<class ArchiveType, std::uint32_t Flags = 0>
class InputArchive : public detail::InputArchiveBase
{
public:
InputArchive(ArchiveType * const derived) :
self(derived),
itsBaseClassSet(),
itsSharedPointerMap(),
itsPolymorphicTypeMap(),
itsVersionedTypes()
{ }
InputArchive & operator=( InputArchive const & ) = delete;
template <class ... Types> inline
ArchiveType & operator()( Types && ... args )
{
process( std::forward<Types>( args )... );
return *self;
}
void serializeDeferments()
{
for( auto & deferment : itsDeferments )
deferment();
}
using is_loading = std::true_type;
using is_saving = std::false_type;
template <class T> inline
ArchiveType & operator&( T && arg )
{
self->process( std::forward<T>( arg ) );
return *self;
}
template <class T> inline
ArchiveType & operator>>( T && arg )
{
self->process( std::forward<T>( arg ) );
return *self;
}
inline std::shared_ptr<void> getSharedPointer(std::uint32_t const id)
{
if(id == 0) return std::shared_ptr<void>(nullptr);
auto iter = itsSharedPointerMap.find( id );
if(iter == itsSharedPointerMap.end())
throw Exception("Error while trying to deserialize a smart pointer. Could not find id " + std::to_string(id));
return iter->second;
}
inline void registerSharedPointer(std::uint32_t const id, std::shared_ptr<void> ptr)
{
std::uint32_t const stripped_id = id & ~detail::msb_32bit;
itsSharedPointerMap[stripped_id] = ptr;
}
inline std::string getPolymorphicName(std::uint32_t const id)
{
auto name = itsPolymorphicTypeMap.find( id );
if(name == itsPolymorphicTypeMap.end())
{
throw Exception("Error while trying to deserialize a polymorphic pointer. Could not find type id " + std::to_string(id));
}
return name->second;
}
inline void registerPolymorphicName(std::uint32_t const id, std::string const & name)
{
std::uint32_t const stripped_id = id & ~detail::msb_32bit;
itsPolymorphicTypeMap.insert( {stripped_id, name} );
}
private:
template <class T> inline
void process( T && head )
{
prologue( *self, head );
self->processImpl( head );
epilogue( *self, head );
}
template <class T, class ... Other> inline
void process( T && head, Other && ... tail )
{
process( std::forward<T>( head ) );
process( std::forward<Other>( tail )... );
}
template <class T> inline
ArchiveType & processImpl(virtual_base_class<T> & b)
{
traits::detail::base_class_id id(b.base_ptr);
if(itsBaseClassSet.count(id) == 0)
{
itsBaseClassSet.insert(id);
self->processImpl( *b.base_ptr );
}
return *self;
}
template <class T> inline
ArchiveType & processImpl(base_class<T> & b)
{
self->processImpl( *b.base_ptr );
return *self;
}
std::vector<std::function<void(void)>> itsDeferments;
template <class T> inline
ArchiveType & processImpl(DeferredData<T> const & d)
{
std::function<void(void)> deferment( [this, d](){ self->process( d.value ); } );
itsDeferments.emplace_back( std::move(deferment) );
return *self;
}
#define PROCESS_IF(name) \
traits::EnableIf<traits::has_##name<T, ArchiveType>::value, \
!traits::has_invalid_input_versioning<T, ArchiveType>::value, \
(traits::is_input_serializable<T, ArchiveType>::value && \
(traits::is_specialized_##name<T, ArchiveType>::value || \
!traits::is_specialized<T, ArchiveType>::value))> = traits::sfinae
template <class T, PROCESS_IF(member_serialize)> inline
ArchiveType & processImpl(T & t)
{
access::member_serialize(*self, t);
return *self;
}
template <class T, PROCESS_IF(non_member_serialize)> inline
ArchiveType & processImpl(T & t)
{
CEREAL_SERIALIZE_FUNCTION_NAME(*self, t);
return *self;
}
template <class T, PROCESS_IF(member_load)> inline
ArchiveType & processImpl(T & t)
{
access::member_load(*self, t);
return *self;
}
template <class T, PROCESS_IF(non_member_load)> inline
ArchiveType & processImpl(T & t)
{
CEREAL_LOAD_FUNCTION_NAME(*self, t);
return *self;
}
template <class T, PROCESS_IF(member_load_minimal)> inline
ArchiveType & processImpl(T & t)
{
using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
typename traits::has_member_save_minimal<T, OutArchiveType>::type value;
self->process( value );
access::member_load_minimal(*self, t, value);
return *self;
}
template <class T, PROCESS_IF(non_member_load_minimal)> inline
ArchiveType & processImpl(T & t)
{
using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
typename traits::has_non_member_save_minimal<T, OutArchiveType>::type value;
self->process( value );
CEREAL_LOAD_MINIMAL_FUNCTION_NAME(*self, t, value);
return *self;
}
template <class T, traits::EnableIf<(Flags & AllowEmptyClassElision),
!traits::is_input_serializable<T, ArchiveType>::value,
std::is_empty<T>::value> = traits::sfinae> inline
ArchiveType & processImpl(T const &)
{
return *self;
}
template <class T, traits::EnableIf<traits::has_invalid_input_versioning<T, ArchiveType>::value ||
(!traits::is_input_serializable<T, ArchiveType>::value &&
(!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !std::is_empty<T>::value)))> = traits::sfinae> inline
ArchiveType & processImpl(T const &)
{
static_assert(traits::detail::count_input_serializers<T, ArchiveType>::value != 0,
"cereal could not find any input serialization functions for the provided type and archive combination. \n\n "
"Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
"Serialize functions generally have the following signature: \n\n "
"template<class Archive> \n "
" void serialize(Archive & ar) \n "
" { \n "
" ar( member1, member2, member3 ); \n "
" } \n\n " );
static_assert(traits::detail::count_input_serializers<T, ArchiveType>::value < 2,
"cereal found more than one compatible input serialization function for the provided type and archive combination. \n\n "
"Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
"Use specialization (see access.hpp) if you need to disambiguate between serialize vs load/save functions. \n "
"Note that serialization functions can be inherited which may lead to the aforementioned ambiguities. \n "
"In addition, you may not mix versioned with non-versioned serialization functions. \n\n ");
return *self;
}
template <class A, class B, bool C, bool D, bool E, bool F> friend struct detail::Construct;
template <class T> inline
std::uint32_t loadClassVersion()
{
static const auto hash = std::type_index(typeid(T)).hash_code();
auto lookupResult = itsVersionedTypes.find( hash );
if( lookupResult != itsVersionedTypes.end() ) // already exists
return lookupResult->second;
else // need to load
{
std::uint32_t version;
process( make_nvp<ArchiveType>("cereal_class_version", version) );
itsVersionedTypes.emplace_hint( lookupResult, hash, version );
return version;
}
}
template <class T, PROCESS_IF(member_versioned_serialize)> inline
ArchiveType & processImpl(T & t)
{
const auto version = loadClassVersion<T>();
access::member_serialize(*self, t, version);
return *self;
}
template <class T, PROCESS_IF(non_member_versioned_serialize)> inline
ArchiveType & processImpl(T & t)
{
const auto version = loadClassVersion<T>();
CEREAL_SERIALIZE_FUNCTION_NAME(*self, t, version);
return *self;
}
template <class T, PROCESS_IF(member_versioned_load)> inline
ArchiveType & processImpl(T & t)
{
const auto version = loadClassVersion<T>();
access::member_load(*self, t, version);
return *self;
}
template <class T, PROCESS_IF(non_member_versioned_load)> inline
ArchiveType & processImpl(T & t)
{
const auto version = loadClassVersion<T>();
CEREAL_LOAD_FUNCTION_NAME(*self, t, version);
return *self;
}
template <class T, PROCESS_IF(member_versioned_load_minimal)> inline
ArchiveType & processImpl(T & t)
{
using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
const auto version = loadClassVersion<T>();
typename traits::has_member_versioned_save_minimal<T, OutArchiveType>::type value;
self->process(value);
access::member_load_minimal(*self, t, value, version);
return *self;
}
template <class T, PROCESS_IF(non_member_versioned_load_minimal)> inline
ArchiveType & processImpl(T & t)
{
using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
const auto version = loadClassVersion<T>();
typename traits::has_non_member_versioned_save_minimal<T, OutArchiveType>::type value;
self->process(value);
CEREAL_LOAD_MINIMAL_FUNCTION_NAME(*self, t, value, version);
return *self;
}
#undef PROCESS_IF
private:
ArchiveType * const self;
std::unordered_set<traits::detail::base_class_id, traits::detail::base_class_id_hash> itsBaseClassSet;
std::unordered_map<std::uint32_t, std::shared_ptr<void>> itsSharedPointerMap;
std::unordered_map<std::uint32_t, std::string> itsPolymorphicTypeMap;
std::unordered_map<std::size_t, std::uint32_t> itsVersionedTypes;
}; // class InputArchive
} // namespace cereal
// This include needs to come after things such as binary_data, make_nvp, etc
#include "cereal/types/common.hpp"
#endif // CEREAL_CEREAL_HPP_
base_class.hpp
Support for base classes (virtual and non-virtual)
cereal::DeferredData
A wrapper around data that should be serialized after all non-deferred data.
Definition helpers.hpp:233
cereal::InputArchive
The base input archive class.
Definition cereal.hpp:711
cereal::InputArchive::operator>>
ArchiveType & operator>>(T &&arg)
Serializes passed in data.
Definition cereal.hpp:777
cereal::InputArchive::getPolymorphicName
std::string getPolymorphicName(std::uint32_t const id)
Retrieves the string for a polymorphic type given a unique key for it.
Definition cereal.hpp:824
cereal::InputArchive::registerSharedPointer
void registerSharedPointer(std::uint32_t const id, std::shared_ptr< void > ptr)
Registers a shared pointer to its unique identifier.
Definition cereal.hpp:811
cereal::InputArchive::operator()
ArchiveType & operator()(Types &&... args)
Serializes all passed in data.
Definition cereal.hpp:728
cereal::InputArchive::InputArchive
InputArchive(ArchiveType *const derived)
Construct the output archive.
Definition cereal.hpp:715
cereal::InputArchive::serializeDeferments
void serializeDeferments()
Serializes any data marked for deferment using defer.
Definition cereal.hpp:736
cereal::InputArchive::getSharedPointer
std::shared_ptr< void > getSharedPointer(std::uint32_t const id)
Retrieves a shared pointer given a unique key for it.
Definition cereal.hpp:793
cereal::InputArchive::is_loading
std::true_type is_loading
Indicates this archive is intended for loading.
Definition cereal.hpp:752
cereal::InputArchive::registerPolymorphicName
void registerPolymorphicName(std::uint32_t const id, std::string const &name)
Registers a polymorphic name string to its unique identifier.
Definition cereal.hpp:841
cereal::InputArchive::operator&
ArchiveType & operator&(T &&arg)
Serializes passed in data.
Definition cereal.hpp:766
cereal::InputArchive::is_saving
std::false_type is_saving
Indicates this archive is not intended for saving.
Definition cereal.hpp:759
cereal::NameValuePair
For holding name value pairs.
Definition helpers.hpp:140
cereal::OutputArchive
The base output archive class.
Definition cereal.hpp:319
cereal::OutputArchive::registerSharedPointer
std::uint32_t registerSharedPointer(const std::shared_ptr< const void > &sharedPointer)
Registers a shared pointer with the archive.
Definition cereal.hpp:398
cereal::OutputArchive::operator<<
ArchiveType & operator<<(T &&arg)
Serializes passed in data.
Definition cereal.hpp:380
cereal::OutputArchive::operator&
ArchiveType & operator&(T &&arg)
Serializes passed in data.
Definition cereal.hpp:369
cereal::OutputArchive::is_loading
std::false_type is_loading
Indicates this archive is not intended for loading.
Definition cereal.hpp:355
cereal::OutputArchive::OutputArchive
OutputArchive(ArchiveType *const derived)
Construct the output archive.
Definition cereal.hpp:323
cereal::OutputArchive::operator()
ArchiveType & operator()(Types &&... args)
Serializes all passed in data.
Definition cereal.hpp:331
cereal::OutputArchive::registerPolymorphicType
std::uint32_t registerPolymorphicType(char const *name)
Registers a polymorphic type name with the archive.
Definition cereal.hpp:425
cereal::OutputArchive::serializeDeferments
void serializeDeferments()
Serializes any data marked for deferment using defer.
Definition cereal.hpp:339
cereal::OutputArchive::is_saving
std::true_type is_saving
Indicates this archive is intended for saving.
Definition cereal.hpp:362
cereal::SizeTag
A wrapper around size metadata.
Definition helpers.hpp:313
cereal::detail::InputArchiveBase
Definition helpers.hpp:282
cereal::detail::OutputArchiveBase
Definition helpers.hpp:270
cereal::detail::StaticObject::lock
static LockGuard lock()
Attempts to lock this static object for the current scope.
Definition static_object.hpp:110
common.hpp
Support common types - always included automatically.
cereal::Flags
Flags
Special flags for archives.
Definition cereal.hpp:185
cereal::NameValuePair::make_nvp
NameValuePair< T > make_nvp(const char *name, T &&value)
Creates a name value pair.
Definition cereal.hpp:64
cereal::SizeTag::make_size_tag
SizeTag< T > make_size_tag(T &&sz)
Creates a size tag from some variable.
Definition cereal.hpp:96
cereal::BinaryData::binary_data
BinaryData< T > binary_data(T &&data, size_t size)
Convenience function to create binary data for both const and non const pointers.
Definition cereal.hpp:81
cereal::NameValuePair::make_nvp
NameValuePair< T > make_nvp(std::string const &name, T &&value)
Creates a name value pair.
Definition cereal.hpp:55
cereal::DeferredData::defer
DeferredData< T > defer(T &&value)
Marks data for deferred serialization.
Definition cereal.hpp:149
helpers.hpp
Internal helper functionality.
cereal::epilogue
void epilogue(JSONOutputArchive &, NameValuePair< T > const &)
Epilogue for NVPs for JSON archives.
Definition json.hpp:763
cereal::prologue
void prologue(JSONOutputArchive &, NameValuePair< T > const &)
Prologue for NVPs for JSON archives.
Definition json.hpp:751
macros.hpp
Preprocessor macros that can customise the cereal library.
CEREAL_LOAD_MINIMAL_FUNCTION_NAME
#define CEREAL_LOAD_MINIMAL_FUNCTION_NAME
The deserialization (load_minimal) function name to search for.
Definition macros.hpp:99
CEREAL_LOAD_FUNCTION_NAME
#define CEREAL_LOAD_FUNCTION_NAME
The deserialization (load) function name to search for.
Definition macros.hpp:85
CEREAL_SAVE_FUNCTION_NAME
#define CEREAL_SAVE_FUNCTION_NAME
The serialization (save) function name to search for.
Definition macros.hpp:92
CEREAL_SAVE_MINIMAL_FUNCTION_NAME
#define CEREAL_SAVE_MINIMAL_FUNCTION_NAME
The serialization (save_minimal) function name to search for.
Definition macros.hpp:106
CEREAL_SERIALIZE_FUNCTION_NAME
#define CEREAL_SERIALIZE_FUNCTION_NAME
The serialization/deserialization function name to search for.
Definition macros.hpp:78
cereal::BinaryData
A wrapper around data that can be serialized in a binary fashion.
Definition helpers.hpp:212
cereal::Exception
An exception class thrown when things go wrong at runtime.
Definition helpers.hpp:49
cereal::detail::Construct
Definition traits.hpp:1339
traits.hpp
Internal type trait support.