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_
cereal::InputArchive
The base input archive class.
Definition: cereal.hpp:710
cereal::epilogue
void epilogue(Archive &, T const &)
Definition: cereal.hpp:169
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::OutputArchive< JSONOutputArchive >::is_saving
std::true_type is_saving
Indicates this archive is intended for saving.
Definition: cereal.hpp:362
cereal::detail::OutputArchiveBase
Definition: helpers.hpp:269
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
common.hpp
Support common types - always included automatically.
cereal::OutputArchive< JSONOutputArchive >::is_loading
std::false_type is_loading
Indicates this archive is not intended for loading.
Definition: cereal.hpp:355
helpers.hpp
Internal helper functionality.
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::OutputArchive::serializeDeferments
void serializeDeferments()
Serializes any data marked for deferment using defer.
Definition: cereal.hpp:339
CEREAL_SERIALIZE_FUNCTION_NAME
#define CEREAL_SERIALIZE_FUNCTION_NAME
The serialization/deserialization function name to search for.
Definition: macros.hpp:78
cereal::prologue
void prologue(Archive &, T const &)
Definition: cereal.hpp:162
cereal::OutputArchive::operator&
ArchiveType & operator&(T &&arg)
Serializes passed in data.
Definition: cereal.hpp:369
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::NameValuePair::make_nvp
NameValuePair< T > make_nvp(const char *name, T &&value)
Creates a name value pair.
Definition: cereal.hpp:64
cereal::OutputArchive::registerPolymorphicType
std::uint32_t registerPolymorphicType(char const *name)
Registers a polymorphic type name with the archive.
Definition: cereal.hpp:425
macros.hpp
Preprocessor macros that can customise the cereal library.
CEREAL_LOAD_FUNCTION_NAME
#define CEREAL_LOAD_FUNCTION_NAME
The deserialization (load) function name to search for.
Definition: macros.hpp:85
cereal::detail::Construct
Definition: traits.hpp:1338
cereal::Flags
Flags
Special flags for archives.
Definition: cereal.hpp:185
cereal::detail::StaticObject::lock
static LockGuard lock()
Attempts to lock this static object for the current scope.
Definition: static_object.hpp:110
cereal::NameValuePair
For holding name value pairs.
Definition: helpers.hpp:139
cereal::DeferredData::defer
DeferredData< T > defer(T &&value)
Marks data for deferred serialization.
Definition: cereal.hpp:149
cereal::InputArchive< PortableBinaryInputArchive, AllowEmptyClassElision >::is_loading
std::true_type is_loading
Indicates this archive is intended for loading.
Definition: cereal.hpp:752
base_class.hpp
Support for base classes (virtual and non-virtual)
cereal::OutputArchive
The base output archive class.
Definition: cereal.hpp:318
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_SAVE_FUNCTION_NAME
#define CEREAL_SAVE_FUNCTION_NAME
The serialization (save) function name to search for.
Definition: macros.hpp:92
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
A wrapper around data that can be serialized in a binary fashion.
Definition: helpers.hpp:211
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
EnableIf
typename detail::EnableIfHelper< Conditions... >::type EnableIf
Provides a way to enable a function if conditions are met.
Definition: traits.hpp:116
cereal::OutputArchive::OutputArchive
OutputArchive(ArchiveType *const derived)
Construct the output archive.
Definition: cereal.hpp:323
cereal::SizeTag
A wrapper around size metadata.
Definition: helpers.hpp:312
cereal::Exception
An exception class thrown when things go wrong at runtime.
Definition: helpers.hpp:48
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::DeferredData
A wrapper around data that should be serialized after all non-deferred data.
Definition: helpers.hpp:232
cereal::InputArchive::operator&
ArchiveType & operator&(T &&arg)
Serializes passed in data.
Definition: cereal.hpp:766
cereal::detail::InputArchiveBase
Definition: helpers.hpp:281
cereal::NameValuePair::make_nvp
NameValuePair< T > make_nvp(std::string const &name, T &&value)
Creates a name value pair.
Definition: cereal.hpp:55
traits.hpp
Internal type trait support.
cereal::OutputArchive::operator()
ArchiveType & operator()(Types &&... args)
Serializes all passed in data.
Definition: cereal.hpp:331
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::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:777
cereal::InputArchive< PortableBinaryInputArchive, AllowEmptyClassElision >::is_saving
std::false_type is_saving
Indicates this archive is not intended for saving.
Definition: cereal.hpp:759