more progress, everything compiles except portable_binary and json. Archiving not working yet.

This commit is contained in:
Shane 2013-07-15 00:46:00 -07:00
parent e00a74ccfc
commit b562762291
18 changed files with 354 additions and 258 deletions

1
.gitignore vendored
View File

@ -16,6 +16,7 @@
*.opensdf
*.sdf
*.suo
*.user
vs2012/Debug
vs2012/Release

View File

@ -58,7 +58,7 @@ namespace cereal
//! Writes size bytes of data to the output stream
void saveBinary( const void * data, size_t size )
{
size_t const writtenSize = itsStream.rdbuf()->sputn( reinterpret_cast<const char*>( data ), size );
auto const writtenSize = itsStream.rdbuf()->sputn( reinterpret_cast<const char*>( data ), size );
if(writtenSize != size)
throw Exception("Failed to write " + std::to_string(size) + " bytes to output stream! Wrote " + std::to_string(writtenSize));
@ -87,7 +87,7 @@ namespace cereal
//! Reads size bytes of data from the input stream
void loadBinary( void * const data, size_t size )
{
size_t const readSize = itsStream.rdbuf()->sgetn( reinterpret_cast<char*>( data ), size );
auto const readSize = itsStream.rdbuf()->sgetn( reinterpret_cast<char*>( data ), size );
if(readSize != size)
throw Exception("Failed to read " + std::to_string(size) + " bytes from input stream! Read " + std::to_string(readSize));

View File

@ -87,7 +87,7 @@ namespace cereal
//! Writes size bytes of data to the output stream
void saveBinary( const void * data, size_t size )
{
size_t const writtenSize = itsStream.rdbuf()->sputn( reinterpret_cast<const char*>( data ), size );
auto const writtenSize = itsStream.rdbuf()->sputn( reinterpret_cast<const char*>( data ), size );
if(writtenSize != size)
throw Exception("Failed to write " + std::to_string(size) + " bytes to output stream! Wrote " + std::to_string(writtenSize));
@ -142,7 +142,7 @@ namespace cereal
void loadBinary( void * const data, size_t size )
{
// load data
size_t const readSize = itsStream.rdbuf()->sgetn( reinterpret_cast<char*>( data ), size );
auto const readSize = itsStream.rdbuf()->sgetn( reinterpret_cast<char*>( data ), size );
if(readSize != size)
throw Exception("Failed to read " + std::to_string(size) + " bytes from input stream! Read " + std::to_string(readSize));

View File

@ -286,7 +286,7 @@ namespace cereal
itsData.push_back('\0'); // rapidxml will do terrible things without the data being null terminated
itsXML.parse<rapidxml::parse_no_data_nodes | rapidxml::parse_declaration_node>( reinterpret_cast<char *>( itsData.data() ) );
}
catch( rapidxml::parse_error const & e )
catch( rapidxml::parse_error const & )
{
//std::cerr << "-----Original-----" << std::endl;
//stream.seekg(0);

View File

@ -269,8 +269,8 @@ namespace cereal
//! Member serialization
template <class T> inline
typename std::enable_if<traits::is_specialized_member_serialize<T, ArchiveType>() ||
(traits::is_output_serializable<T, ArchiveType>() && traits::has_member_serialize<T, ArchiveType>()),
typename std::enable_if<traits::is_specialized_member_serialize<T, ArchiveType>::value ||
(traits::is_output_serializable<T, ArchiveType>::value && traits::has_member_serialize<T, ArchiveType>::value),
ArchiveType &>::type
processImpl(T const & t)
{
@ -280,8 +280,8 @@ namespace cereal
//! Non member serialization
template <class T> inline
typename std::enable_if<traits::is_specialized_non_member_serialize<T, ArchiveType>() ||
(traits::is_output_serializable<T, ArchiveType>() && traits::has_non_member_serialize<T, ArchiveType>()),
typename std::enable_if<traits::is_specialized_non_member_serialize<T, ArchiveType>::value ||
(traits::is_output_serializable<T, ArchiveType>::value && traits::has_non_member_serialize<T, ArchiveType>::value),
ArchiveType &>::type
processImpl(T const & t)
{
@ -291,8 +291,8 @@ namespace cereal
//! Member split (save)
template <class T> inline
typename std::enable_if<traits::is_specialized_member_save<T, ArchiveType>() ||
(traits::is_output_serializable<T, ArchiveType>() && traits::has_member_save<T, ArchiveType>()),
typename std::enable_if<traits::is_specialized_member_save<T, ArchiveType>::value ||
(traits::is_output_serializable<T, ArchiveType>::value && traits::has_member_save<T, ArchiveType>::value),
ArchiveType &>::type
processImpl(T const & t)
{
@ -302,8 +302,8 @@ namespace cereal
//! Non member split (save)
template <class T> inline
typename std::enable_if<traits::is_specialized_non_member_save<T, ArchiveType>() ||
(traits::is_output_serializable<T, ArchiveType>() && traits::has_non_member_save<T, ArchiveType>()),
typename std::enable_if<traits::is_specialized_non_member_save<T, ArchiveType>::value ||
(traits::is_output_serializable<T, ArchiveType>::value && traits::has_non_member_save<T, ArchiveType>::value),
ArchiveType &>::type
processImpl(T const & t)
{
@ -314,7 +314,7 @@ namespace cereal
//! Empty class specialization
template <class T> inline
typename std::enable_if<(Flags & AllowEmptyClassElision) &&
!traits::is_output_serializable<T, ArchiveType>() && traits::is_empty_class<T>(), ArchiveType &>::type
!traits::is_output_serializable<T, ArchiveType>::value && std::is_empty<T>::value, ArchiveType &>::type
processImpl(T const &)
{
return *self;
@ -322,12 +322,12 @@ namespace cereal
//! No matching serialization
template <class T> inline
typename std::enable_if<!traits::is_specialized<T, ArchiveType>() && !traits::is_output_serializable<T, ArchiveType>() &&
(!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !traits::is_empty_class<T>())),
typename std::enable_if<!traits::is_specialized<T, ArchiveType>::value && !traits::is_output_serializable<T, ArchiveType>::value &&
(!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !std::is_empty<T>::value)),
ArchiveType &>::type
processImpl(T const &)
{
static_assert(traits::is_output_serializable<T, ArchiveType>(), "Trying to serialize an unserializable type with an output archive.\n\n"
static_assert(traits::is_output_serializable<T, ArchiveType>::value, "Trying to serialize an unserializable type with an output archive.\n\n"
"Types must either have a serialize function, or separate save/load functions (but not both).\n"
"Serialize functions generally have the following signature:\n\n"
"template<class Archive>\n"
@ -491,8 +491,8 @@ namespace cereal
//! Member serialization
template <class T> inline
typename std::enable_if<traits::is_specialized_member_serialize<T, ArchiveType>() ||
(traits::is_input_serializable<T, ArchiveType>() && traits::has_member_serialize<T, ArchiveType>()),
typename std::enable_if<traits::is_specialized_member_serialize<T, ArchiveType>::value ||
(traits::is_input_serializable<T, ArchiveType>::value && traits::has_member_serialize<T, ArchiveType>::value),
ArchiveType &>::type
processImpl(T & t)
{
@ -502,8 +502,8 @@ namespace cereal
//! Non member serialization
template <class T> inline
typename std::enable_if<traits::is_specialized_non_member_serialize<T, ArchiveType>() ||
(traits::is_input_serializable<T, ArchiveType>() && traits::has_non_member_serialize<T, ArchiveType>()),
typename std::enable_if<traits::is_specialized_non_member_serialize<T, ArchiveType>::value ||
(traits::is_input_serializable<T, ArchiveType>::value && traits::has_non_member_serialize<T, ArchiveType>::value),
ArchiveType &>::type
processImpl(T & t)
{
@ -513,8 +513,8 @@ namespace cereal
//! Member split (load)
template <class T> inline
typename std::enable_if<traits::is_specialized_member_load<T, ArchiveType>() ||
(traits::is_input_serializable<T, ArchiveType>() && traits::has_member_load<T, ArchiveType>()),
typename std::enable_if<traits::is_specialized_member_load<T, ArchiveType>::value ||
(traits::is_input_serializable<T, ArchiveType>::value && traits::has_member_load<T, ArchiveType>::value),
ArchiveType &>::type
processImpl(T & t)
{
@ -524,8 +524,8 @@ namespace cereal
//! Non member split (load)
template <class T> inline
typename std::enable_if<traits::is_specialized_non_member_load<T, ArchiveType>() ||
(traits::is_input_serializable<T, ArchiveType>() && traits::has_non_member_load<T, ArchiveType>()),
typename std::enable_if<traits::is_specialized_non_member_load<T, ArchiveType>::value ||
(traits::is_input_serializable<T, ArchiveType>::value && traits::has_non_member_load<T, ArchiveType>::value),
ArchiveType &>::type
processImpl(T & t)
{
@ -536,7 +536,7 @@ namespace cereal
//! Empty class specialization
template <class T> inline
typename std::enable_if<(Flags & AllowEmptyClassElision) &&
!traits::is_input_serializable<T, ArchiveType>() && traits::is_empty_class<T>(), ArchiveType &>::type
!traits::is_input_serializable<T, ArchiveType>::value && std::is_empty<T>::value, ArchiveType &>::type
processImpl(T const &)
{
return *self;
@ -544,12 +544,12 @@ namespace cereal
//! No matching serialization
template <class T> inline
typename std::enable_if<!traits::is_specialized<T, ArchiveType>() && !traits::is_input_serializable<T, ArchiveType>() &&
(!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !traits::is_empty_class<T>())),
typename std::enable_if<!traits::is_specialized<T, ArchiveType>::value && !traits::is_input_serializable<T, ArchiveType>::value &&
(!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !std::is_empty<T>::value)),
ArchiveType &>::type
processImpl(T const &)
{
static_assert(traits::is_output_serializable<T, ArchiveType>(), "Trying to serialize an unserializable type with an output archive.\n\n"
static_assert(traits::is_output_serializable<T, ArchiveType>::value, "Trying to serialize an unserializable type with an output archive.\n\n"
"Types must either have a serialize function, or separate save/load functions (but not both).\n"
"Serialize functions generally have the following signature:\n\n"
"template<class Archive>\n"

View File

@ -122,10 +122,10 @@ namespace cereal
private:
// If we get passed an RValue, we'll just make a local copy if it here
// otherwise, we store a reference
using DT = typename std::decay<T>::type;
using Type = typename std::conditional<std::is_rvalue_reference<T>::value,
DT,
typename std::add_lvalue_reference<DT>::type>::type;
typedef typename std::decay<T>::type DT;
typedef typename std::conditional<std::is_rvalue_reference<T>::value,
DT,
typename std::add_lvalue_reference<DT>::type>::type Type;
// prevent nested nvps
static_assert( !std::is_base_of<detail::NameValuePairCore, T>::value,
"Cannot pair a name to a NameValuePair" );
@ -189,9 +189,9 @@ namespace cereal
{
//! Internally store the pointer as a void *, keeping const if created with
//! a const pointer
using PT = typename std::conditional<std::is_const<typename std::remove_pointer<T>::type>::value,
const void *,
void *>::type;
typedef typename std::conditional<std::is_const<typename std::remove_pointer<T>::type>::value,
const void *,
void *>::type PT;
BinaryData( T && d, uint64_t s ) : data(d), size(s) {}
@ -230,10 +230,10 @@ namespace cereal
private:
// If we get passed an RValue, we'll just make a local copy if it here
// otherwise, we store a reference
using DT = typename std::decay<T>::type;
using Type = typename std::conditional<std::is_rvalue_reference<T>::value,
DT,
typename std::add_lvalue_reference<DT>::type>::type;
typedef typename std::decay<T>::type DT;
typedef typename std::conditional<std::is_rvalue_reference<T>::value,
DT,
typename std::add_lvalue_reference<DT>::type>::type Type;
public:
SizeTag( T && sz ) : size(const_cast<Type>(sz)) {}
@ -265,17 +265,17 @@ namespace cereal
template <class Key, class Value>
struct MapItem
{
using DecayKey = typename std::decay<Key>::type;
using KeyType = typename std::conditional<
typedef typename std::decay<Key>::type DecayKey;
typedef typename std::conditional<
std::is_rvalue_reference<Key>::value,
DecayKey,
typename std::add_lvalue_reference<DecayKey>::type>::type;
typename std::add_lvalue_reference<DecayKey>::type>::type KeyType;
using DecayValue = typename std::decay<Value>::type;
using ValueType = typename std::conditional<
typedef typename std::decay<Value>::type DecayValue;
typedef typename std::conditional<
std::is_rvalue_reference<Value>::value,
DecayValue,
typename std::add_lvalue_reference<DecayValue>::type>::type;
typename std::add_lvalue_reference<DecayValue>::type>::type ValueType;
//! Construct a MapItem from a key and a value
/*! @internal */

View File

@ -47,6 +47,7 @@
#include <cereal/details/static_object.hpp>
#include <cereal/types/memory.hpp>
#include <cereal/types/string.hpp>
#include <functional>
#include <typeindex>
#include <map>
@ -297,7 +298,7 @@ namespace cereal
//! Binding for non abstract types
void bind(std::false_type) const
{
instantiate_polymorphic_binding( (T*)0, 0, adl_tag{} );
instantiate_polymorphic_binding( (T*)0, 0, adl_tag() );
}
//! Binding for abstract types

View File

@ -56,7 +56,7 @@ namespace cereal
return t;
}
StaticObject( StaticObject const & other ) = delete;
StaticObject( StaticObject const & other ) {}
public:
static T & getInstance()

View File

@ -251,217 +251,212 @@ namespace cereal
has_member_serialize<T, InputArchive>::value ^
has_non_member_serialize<T, InputArchive>::value> {};
// // ######################################################################
// ######################################################################
namespace detail
{
template <class T, class A>
struct is_specialized_member_serialize : std::integral_constant<bool,
!std::is_base_of<std::false_type, specialize<A, T, specialization::member_serialize>>::value> {};
// namespace detail
// {
// template <class T, class A>
// constexpr auto is_specialized_member_serialize() -> bool
// { return !std::is_base_of<std::false_type, specialize<A, T, specialization::member_serialize>>(); }
template <class T, class A>
struct is_specialized_member_load_save : std::integral_constant<bool,
std::is_base_of<std::false_type, specialize<A, T, specialization::member_load_save>>::value> {};
// template <class T, class A>
// constexpr auto is_specialized_member_load_save() -> bool
// { return !std::is_base_of<std::false_type, specialize<A, T, specialization::member_load_save>>(); }
template <class T, class A>
struct is_specialized_non_member_serialize : std::integral_constant<bool,
!std::is_base_of<std::false_type, specialize<A, T, specialization::non_member_serialize>>::value> {};
// template <class T, class A>
// constexpr auto is_specialized_non_member_serialize() -> bool
// { return !std::is_base_of<std::false_type, specialize<A, T, specialization::non_member_serialize>>(); }
template <class T, class A>
struct is_specialized_non_member_load_save : std::integral_constant<bool,
!std::is_base_of<std::false_type, specialize<A, T, specialization::non_member_load_save>>::value> {};
// template <class T, class A>
// constexpr auto is_specialized_non_member_load_save() -> bool
// { return !std::is_base_of<std::false_type, specialize<A, T, specialization::non_member_load_save>>(); }
// Considered an error if specialization exists for more than one type
template <class T, class A>
struct is_specialized_error : std::integral_constant<bool,
(is_specialized_member_serialize<T, A>::value +
is_specialized_member_load_save<T, A>::value +
is_specialized_non_member_serialize<T, A>::value +
is_specialized_non_member_load_save<T, A>::value) <= 1> {};
} // namespace detail
// // Considered an error if specialization exists for more than one type
// template <class T, class A>
// constexpr auto is_specialized_error() -> bool
// {
// return (is_specialized_member_serialize<T, A>() +
// is_specialized_member_load_save<T, A>() +
// is_specialized_non_member_serialize<T, A>() +
// is_specialized_non_member_load_save<T, A>()) <= 1;
// }
// } // namespace detail
template <class T, class A>
struct is_specialized : std::integral_constant<bool,
detail::is_specialized_member_serialize<T, A>::value ||
detail::is_specialized_member_load_save<T, A>::value ||
detail::is_specialized_non_member_serialize<T, A>::value ||
detail::is_specialized_non_member_load_save<T, A>::value>
{
static_assert(detail::is_specialized_error<T, A>::value, "More than one explicit specialization detected for type.");
};
// template <class T, class A>
// constexpr auto is_specialized() -> bool
// {
// static_assert(detail::is_specialized_error<T, A>(), "More than one explicit specialization detected for type.");
// return detail::is_specialized_member_serialize<T, A>() ||
// detail::is_specialized_member_load_save<T, A>() ||
// detail::is_specialized_non_member_serialize<T, A>() ||
// detail::is_specialized_non_member_load_save<T, A>();
// }
template <class T, class A>
struct is_specialized_member_serialize : std::integral_constant<bool,
is_specialized<T, A>::value && detail::is_specialized_member_serialize<T, A>::value>
{
static_assert( (is_specialized<T, A>::value && detail::is_specialized_member_serialize<T, A>::value && has_member_serialize<T, A>::value)
|| !(is_specialized<T, A>::value && detail::is_specialized_member_serialize<T, A>::value),
"cereal detected member serialization specialization but no member serialize function" );
};
// template <class T, class A>
// constexpr auto is_specialized_member_serialize() -> bool
// {
// static_assert( (is_specialized<T, A>() && detail::is_specialized_member_serialize<T, A>() && has_member_serialize<T, A>())
// || !(is_specialized<T, A>() && detail::is_specialized_member_serialize<T, A>()),
// "cereal detected member serialization specialization but no member serialize function" );
// return is_specialized<T, A>() && detail::is_specialized_member_serialize<T, A>();
// }
template <class T, class A>
struct is_specialized_member_load : std::integral_constant<bool,
is_specialized<T, A>::value && detail::is_specialized_member_load_save<T, A>::value>
{
static_assert( (is_specialized<T, A>::value && detail::is_specialized_member_load_save<T, A>::value && has_member_load<T, A>::value)
|| !(is_specialized<T, A>::value && detail::is_specialized_member_load_save<T, A>::value),
"cereal detected member load specialization but no member load function" );
};
// template <class T, class A>
// constexpr auto is_specialized_member_load() -> bool
// {
// static_assert( (is_specialized<T, A>() && detail::is_specialized_member_load_save<T, A>() && has_member_load<T, A>())
// || !(is_specialized<T, A>() && detail::is_specialized_member_load_save<T, A>()),
// "cereal detected member load specialization but no member load function" );
// return is_specialized<T, A>() && detail::is_specialized_member_load_save<T, A>();
// }
template <class T, class A>
struct is_specialized_member_save : std::integral_constant<bool,
is_specialized<T, A>::value && detail::is_specialized_member_load_save<T, A>::value>
{
static_assert( (is_specialized<T, A>::value && detail::is_specialized_member_load_save<T, A>::value && has_member_save<T, A>::value)
|| !(is_specialized<T, A>::value && detail::is_specialized_member_load_save<T, A>::value),
"cereal detected member save specialization but no member save function" );
};
// template <class T, class A>
// constexpr auto is_specialized_member_save() -> bool
// {
// static_assert( (is_specialized<T, A>() && detail::is_specialized_member_load_save<T, A>() && has_member_save<T, A>())
// || !(is_specialized<T, A>() && detail::is_specialized_member_load_save<T, A>()),
// "cereal detected member save specialization but no member save function" );
// return is_specialized<T, A>() && detail::is_specialized_member_load_save<T, A>();
// }
template <class T, class A>
struct is_specialized_non_member_serialize : std::integral_constant<bool,
is_specialized<T, A>::value && detail::is_specialized_non_member_serialize<T, A>::value>
{
static_assert( (is_specialized<T, A>::value && detail::is_specialized_non_member_serialize<T, A>::value && has_non_member_serialize<T, A>::value)
|| !(is_specialized<T, A>::value && detail::is_specialized_non_member_serialize<T, A>::value),
"cereal detected non-member serialization specialization but no non-member serialize function" );
};
// template <class T, class A>
// constexpr auto is_specialized_non_member_serialize() -> bool
// {
// static_assert( (is_specialized<T, A>() && detail::is_specialized_non_member_serialize<T, A>() && has_non_member_serialize<T, A>())
// || !(is_specialized<T, A>() && detail::is_specialized_non_member_serialize<T, A>()),
// "cereal detected non-member serialization specialization but no non-member serialize function" );
// return is_specialized<T, A>() && detail::is_specialized_non_member_serialize<T, A>();
// }
template <class T, class A>
struct is_specialized_non_member_load : std::integral_constant<bool,
is_specialized<T, A>::value && detail::is_specialized_non_member_load_save<T, A>::value>
{
static_assert( (is_specialized<T, A>::value && detail::is_specialized_non_member_load_save<T, A>::value && has_non_member_load<T, A>::value)
|| !(is_specialized<T, A>::value && detail::is_specialized_non_member_load_save<T, A>::value),
"cereal detected non-member load specialization but no non-member load function" );
};
// template <class T, class A>
// constexpr auto is_specialized_non_member_load() -> bool
// {
// static_assert( (is_specialized<T, A>() && detail::is_specialized_non_member_load_save<T, A>() && has_non_member_load<T, A>())
// || !(is_specialized<T, A>() && detail::is_specialized_non_member_load_save<T, A>()),
// "cereal detected non-member load specialization but no non-member load function" );
// return is_specialized<T, A>() && detail::is_specialized_non_member_load_save<T, A>();
// }
template <class T, class A>
struct is_specialized_non_member_save : std::integral_constant<bool,
is_specialized<T, A>::value && detail::is_specialized_non_member_load_save<T, A>::value>
{
static_assert( (is_specialized<T, A>::value && detail::is_specialized_non_member_load_save<T, A>::value && has_non_member_save<T, A>::value)
|| !(is_specialized<T, A>::value && detail::is_specialized_non_member_load_save<T, A>::value),
"cereal detected non-member save specialization but no non-member save function" );
};
// template <class T, class A>
// constexpr auto is_specialized_non_member_save() -> bool
// {
// static_assert( (is_specialized<T, A>() && detail::is_specialized_non_member_load_save<T, A>() && has_non_member_save<T, A>())
// || !(is_specialized<T, A>() && detail::is_specialized_non_member_load_save<T, A>()),
// "cereal detected non-member save specialization but no non-member save function" );
// return is_specialized<T, A>() && detail::is_specialized_non_member_load_save<T, A>();
// }
// ######################################################################
namespace detail
{
template <class T, size_t rank = std::rank<T>::value>
struct sizeof_array_impl
{
static const auto value = std::extent<T>::value * sizeof_array_impl<typename std::remove_extent<T>::type, rank - 1>::value;
};
// // ######################################################################
// template <class T>
// constexpr size_t sizeof_array( size_t rank = std::rank<T>::value )
// {
// return rank == 0 ? 1 : std::extent<T>::value * sizeof_array<typename std::remove_extent<T>::type>( rank - 1 );
// }
template <class T>
struct sizeof_array_impl<T, 0>
{
static const auto value = 1;
};
};
// // ######################################################################
// namespace detail
// {
// template <class T, typename Enable = void>
// struct is_empty_class_impl
// { static constexpr bool value = false; };
template <class T>
struct sizeof_array : std::integral_constant<std::size_t, detail::sizeof_array_impl<T>::value> {};
// template <class T>
// struct is_empty_class_impl<T, typename std::enable_if<std::is_class<T>::value>::type>
// {
// struct S : T
// { uint8_t t; };
// ######################################################################
namespace detail
{
struct base_class_id
{
template<class T>
base_class_id(T const * const t) :
type(typeid(T)),
ptr(t),
hash(std::hash<std::type_index>()(typeid(T)) ^ (std::hash<void const *>()(t) << 1))
{ }
// static constexpr bool value = sizeof(S) == sizeof(uint8_t);
// };
bool operator==(base_class_id const & other) const
{ return (type == other.type) && (ptr == other.ptr); }
// struct base_class_id
// {
// template<class T>
// base_class_id(T const * const t) :
// type(typeid(T)),
// ptr(t),
// hash(std::hash<std::type_index>()(typeid(T)) ^ (std::hash<void const *>()(t) << 1))
// { }
std::type_index type;
void const * ptr;
size_t hash;
};
struct base_class_id_hash { size_t operator()(base_class_id const & id) const { return id.hash; } };
} // namespace detail
// bool operator==(base_class_id const & other) const
// { return (type == other.type) && (ptr == other.ptr); }
// std::type_index type;
// void const * ptr;
// size_t hash;
// };
// struct base_class_id_hash { size_t operator()(base_class_id const & id) const { return id.hash; } };
// }
// ######################################################################
//! A macro to use to restrict which types of archives your function will work for.
/*! This requires you to have a template class parameter named Archive and replaces the void return
type for your function.
// template<class T>
// using is_empty_class = std::integral_constant<bool, detail::is_empty_class_impl<T>::value>;
INTYPE refers to the input archive type you wish to restrict on.
OUTTYPE refers to the output archive type you wish to restrict on.
// // ######################################################################
// //! A macro to use to restrict which types of archives your function will work for.
// /*! This requires you to have a template class parameter named Archive and replaces the void return
// type for your function.
For example, if we want to limit a serialize to only work with binary serialization:
// INTYPE refers to the input archive type you wish to restrict on.
// OUTTYPE refers to the output archive type you wish to restrict on.
@code{.cpp}
template <class Archive>
CEREAL_ARCHIVE_RESTRICT(BinaryInputArchive, BinaryOutputArchive)
serialize( Archive & ar, MyCoolType & m )
{
ar & m;
}
@endcode
// For example, if we want to limit a serialize to only work with binary serialization:
// @code{.cpp}
// template <class Archive>
// CEREAL_ARCHIVE_RESTRICT(BinaryInputArchive, BinaryOutputArchive)
// serialize( Archive & ar, MyCoolType & m )
// {
// ar & m;
// }
// @endcode
// If you need to do more restrictions in your enable_if, you will need to do this by hand.
// */
// #define CEREAL_ARCHIVE_RESTRICT(INTYPE, OUTTYPE) \
// typename std::enable_if<std::is_same<Archive, INTYPE>::value || std::is_same<Archive, OUTTYPE>::value, void>::type
If you need to do more restrictions in your enable_if, you will need to do this by hand.
*/
#define CEREAL_ARCHIVE_RESTRICT(INTYPE, OUTTYPE) \
typename std::enable_if<std::is_same<Archive, INTYPE>::value || std::is_same<Archive, OUTTYPE>::value, void>::type
} // namespace traits
//namespace detail
//{
// template <class T, class A, bool Member = traits::has_member_load_and_allocate<T, A>(), bool NonMember = traits::has_non_member_load_and_allocate<T, A>()>
// struct Load
// {
// static_assert( !sizeof(T), "Cereal detected both member and non member load_and_allocate functions!" );
// static T * load_andor_allocate( A & ar )
// { return nullptr; }
// };
// ######################################################################
namespace detail
{
template <class T, class A, bool Member = traits::has_member_load_and_allocate<T, A>::value, bool NonMember = traits::has_non_member_load_and_allocate<T, A>::value>
struct Load
{
static_assert( !sizeof(T), "Cereal detected both member and non member load_and_allocate functions!" );
static T * load_andor_allocate( A & ar )
{ return nullptr; }
};
// template <class T, class A>
// struct Load<T, A, false, false>
// {
// static_assert( std::is_default_constructible<T>::value,
// "Trying to serialize a an object with no default constructor.\n\n"
// "Types must either be default constructible or define either a member or non member Construct function.\n"
// "Construct functions generally have the signature:\n\n"
// "template <class Archive>\n"
// "static T * load_and_allocate(Archive & ar)\n"
// "{\n"
// " var a;\n"
// " ar & a\n"
// " return new T(a);\n"
// "}\n\n" );
// static T * load_andor_allocate( A & ar )
// { return new T(); }
// };
template <class T, class A>
struct Load<T, A, false, false>
{
static_assert( std::is_default_constructible<T>::value,
"Trying to serialize a an object with no default constructor.\n\n"
"Types must either be default constructible or define either a member or non member Construct function.\n"
"Construct functions generally have the signature:\n\n"
"template <class Archive>\n"
"static T * load_and_allocate(Archive & ar)\n"
"{\n"
" var a;\n"
" ar & a\n"
" return new T(a);\n"
"}\n\n" );
static T * load_andor_allocate( A & ar )
{ return new T(); }
};
// template <class T, class A>
// struct Load<T, A, true, false>
// {
// static T * load_andor_allocate( A & ar )
// {
// return access::load_and_allocate<T>( ar );
// }
// };
template <class T, class A>
struct Load<T, A, true, false>
{
static T * load_andor_allocate( A & ar )
{
return access::load_and_allocate<T>( ar );
}
};
// template <class T, class A>
// struct Load<T, A, false, true>
// {
// static T * load_andor_allocate( A & ar )
// {
// return LoadAndAllocate<T>::load_and_allocate( ar );
// }
// };
//} // namespace detail
template <class T, class A>
struct Load<T, A, false, true>
{
static T * load_andor_allocate( A & ar )
{
return LoadAndAllocate<T>::load_and_allocate( ar );
}
};
} // namespace detail
} // namespace cereal
#endif // CEREAL_DETAILS_TRAITS_HPP_

View File

@ -31,9 +31,26 @@
#define CEREAL_DETAILS_UTIL_HPP_
#include <typeinfo>
#include <cxxabi.h>
#include <string>
#ifdef _WIN32
namespace cereal
{
//! Demangles the type encoded in a string
/*! @internal */
inline std::string demangle(std::string const & name)
{ return name; }
//! Gets the demangled name of a type
/*! @internal */
template <class T> inline
std::string demangledName()
{ return typeid(T).name(); }
} // namespace cereal
#else // clang or gcc
#include <cxxabi.h>
namespace cereal
{
namespace util
@ -60,6 +77,9 @@ namespace cereal
std::string demangledName()
{ return demangle(typeid(T).name()); }
}
}
} // namespace cereal
#endif
#endif // CEREAL_DETAILS_UTIL_HPP_

View File

@ -384,7 +384,7 @@ private:
template<class Ch>
typename std::enable_if<std::numeric_limits<Ch>::max() < 265, bool>::type
characterOk(Ch c)
characterOk(Ch )
{ return true; }
template<class Ch>

View File

@ -38,7 +38,7 @@ namespace cereal
//! Saving for std::array primitive types
//! using binary serialization, if supported
template <class Archive, class T, size_t N> inline
typename std::enable_if<traits::is_output_serializable<BinaryData<T>, Archive>()
typename std::enable_if<traits::is_output_serializable<BinaryData<T>, Archive>::value
&& std::is_arithmetic<T>::value, void>::type
save( Archive & ar, std::array<T, N> const & array )
{
@ -48,7 +48,7 @@ namespace cereal
//! Loading for std::array primitive types
//! using binary serialization, if supported
template <class Archive, class T, size_t N> inline
typename std::enable_if<traits::is_input_serializable<BinaryData<T>, Archive>()
typename std::enable_if<traits::is_input_serializable<BinaryData<T>, Archive>::value
&& std::is_arithmetic<T>::value, void>::type
load( Archive & ar, std::array<T, N> & array )
{
@ -57,7 +57,7 @@ namespace cereal
//! Saving for std::array all other types
template <class Archive, class T, size_t N> inline
typename std::enable_if<!traits::is_output_serializable<BinaryData<T>, Archive>()
typename std::enable_if<!traits::is_output_serializable<BinaryData<T>, Archive>::value
|| !std::is_arithmetic<T>::value, void>::type
save( Archive & ar, std::array<T, N> const & array )
{
@ -67,7 +67,7 @@ namespace cereal
//! Loading for std::array all other types
template <class Archive, class T, size_t N> inline
typename std::enable_if<!traits::is_input_serializable<BinaryData<T>, Archive>()
typename std::enable_if<!traits::is_input_serializable<BinaryData<T>, Archive>::value
|| !std::is_arithmetic<T>::value, void>::type
load( Archive & ar, std::array<T, N> & array )
{

View File

@ -129,7 +129,7 @@ namespace cereal
//! Loading std::shared_ptr, case when user load and allocate (wrapper implementation)
/*! @internal */
template <class Archive, class T> inline
typename std::enable_if<traits::has_load_and_allocate<T, Archive>(), void>::type
typename std::enable_if<traits::has_load_and_allocate<T, Archive>::value, void>::type
load( Archive & ar, memory_detail::PtrWrapper<std::shared_ptr<T> &> & wrapper )
{
auto & ptr = wrapper.ptr;
@ -152,7 +152,7 @@ namespace cereal
//! Loading std::shared_ptr, case when no user load and allocate (wrapper implementation)
/*! @internal */
template <class Archive, class T> inline
typename std::enable_if<!traits::has_load_and_allocate<T, Archive>(), void>::type
typename std::enable_if<!traits::has_load_and_allocate<T, Archive>::value, void>::type
load( Archive & ar, memory_detail::PtrWrapper<std::shared_ptr<T> &> & wrapper )
{
auto & ptr = wrapper.ptr;
@ -196,7 +196,7 @@ namespace cereal
//! Loading std::unique_ptr, case when user provides load_and_allocate (wrapper implementation)
/*! @internal */
template <class Archive, class T, class D> inline
typename std::enable_if<traits::has_load_and_allocate<T, Archive>(), void>::type
typename std::enable_if<traits::has_load_and_allocate<T, Archive>::value, void>::type
load( Archive & ar, memory_detail::PtrWrapper<std::unique_ptr<T, D> &> & wrapper )
{
uint8_t isValid;
@ -213,7 +213,7 @@ namespace cereal
//! Loading std::unique_ptr, case when no load_and_allocate (wrapper implementation)
/*! @internal */
template <class Archive, class T, class D> inline
typename std::enable_if<!traits::has_load_and_allocate<T, Archive>(), void>::type
typename std::enable_if<!traits::has_load_and_allocate<T, Archive>::value, void>::type
load( Archive & ar, memory_detail::PtrWrapper<std::unique_ptr<T, D> &> & wrapper )
{
uint8_t isValid;

View File

@ -38,6 +38,12 @@
#include <cereal/details/traits.hpp>
#include <cereal/details/polymorphic_impl.hpp>
#ifdef _WIN32
#define CONSTEXPR
#else
#define CONSTEXPR constexpr
#endif
//! Registers a polymorphic type with cereal
/*! Polymorphic types must be registered before pointers
to them can be serialized. This also assumes that
@ -59,7 +65,7 @@
template <> \
struct binding_name<T> \
{ \
static constexpr char const * name() { return #T; }; \
static CONSTEXPR char const * name() { return #T; }; \
}; \
} } /* end namespaces */ \
CEREAL_BIND_TO_ARCHIVES(T);
@ -75,7 +81,7 @@
namespace detail { \
template <> \
struct binding_name<T> \
{ static constexpr char const * name() { return Name; }; }; \
{ static CONSTEXPR char const * name() { return Name; }; }; \
} } /* end namespaces */ \
CEREAL_BIND_TO_ARCHIVES(T);
@ -119,7 +125,7 @@ namespace cereal
using the derived class serialize function
@internal */
template<class Archive, class T> inline
typename std::enable_if<std::is_default_constructible<T>::value || traits::has_load_and_allocate<T, Archive>(), bool>::type
typename std::enable_if<std::is_default_constructible<T>::value || traits::has_load_and_allocate<T, Archive>::value, bool>::type
serialize_wrapper(Archive & ar, std::shared_ptr<T> & ptr, std::uint32_t const nameid)
{
if(nameid & detail::msb2_32bit)
@ -135,7 +141,7 @@ namespace cereal
using the derived class serialize function
@internal */
template<class Archive, class T, class D> inline
typename std::enable_if<std::is_default_constructible<T>::value || traits::has_load_and_allocate<T, Archive>(), bool>::type
typename std::enable_if<std::is_default_constructible<T>::value || traits::has_load_and_allocate<T, Archive>::value, bool>::type
serialize_wrapper(Archive & ar, std::unique_ptr<T, D> & ptr, std::uint32_t const nameid)
{
if(nameid & detail::msb2_32bit)
@ -153,7 +159,7 @@ namespace cereal
this was a polymorphic type serialized by its proper pointer type
@internal */
template<class Archive, class T> inline
typename std::enable_if<!std::is_default_constructible<T>::value && !traits::has_load_and_allocate<T, Archive>(), bool>::type
typename std::enable_if<!std::is_default_constructible<T>::value && !traits::has_load_and_allocate<T, Archive>::value, bool>::type
serialize_wrapper(Archive &, std::shared_ptr<T> &, std::uint32_t const nameid)
{
if(nameid & detail::msb2_32bit)
@ -168,7 +174,7 @@ namespace cereal
this was a polymorphic type serialized by its proper pointer type
@internal */
template<class Archive, class T, class D> inline
typename std::enable_if<!std::is_default_constructible<T>::value && !traits::has_load_and_allocate<T, Archive>(), bool>::type
typename std::enable_if<!std::is_default_constructible<T>::value && !traits::has_load_and_allocate<T, Archive>::value, bool>::type
serialize_wrapper(Archive &, std::unique_ptr<T, D> &, std::uint32_t const nameid)
{
if(nameid & detail::msb2_32bit)

View File

@ -37,7 +37,7 @@ namespace cereal
{
//! Serialization for basic_string types, if binary data is supported
template<class Archive, class CharT, class Traits, class Alloc> inline
typename std::enable_if<traits::is_output_serializable<BinaryData<CharT>, Archive>(), void>::type
typename std::enable_if<traits::is_output_serializable<BinaryData<CharT>, Archive>::value, void>::type
save(Archive & ar, std::basic_string<CharT, Traits, Alloc> const & str)
{
// Save number of chars + the data
@ -47,7 +47,7 @@ namespace cereal
//! Serialization for basic_string types, if binary data is supported
template<class Archive, class CharT, class Traits, class Alloc> inline
typename std::enable_if<traits::is_input_serializable<BinaryData<CharT>, Archive>(), void>::type
typename std::enable_if<traits::is_input_serializable<BinaryData<CharT>, Archive>::value, void>::type
load(Archive & ar, std::basic_string<CharT, Traits, Alloc> & str)
{
size_type size;

View File

@ -37,7 +37,7 @@ namespace cereal
{
//! Serialization for std::vectors of arithmetic (but not bool) using binary serialization, if supported
template <class Archive, class T, class A> inline
typename std::enable_if<traits::is_output_serializable<BinaryData<T>, Archive>()
typename std::enable_if<traits::is_output_serializable<BinaryData<T>, Archive>::value
&& std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, void>::type
save( Archive & ar, std::vector<T, A> const & vector )
{
@ -47,7 +47,7 @@ namespace cereal
//! Serialization for std::vectors of arithmetic (but not bool) using binary serialization, if supported
template <class Archive, class T, class A> inline
typename std::enable_if<traits::is_input_serializable<BinaryData<T>, Archive>()
typename std::enable_if<traits::is_input_serializable<BinaryData<T>, Archive>::value
&& std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, void>::type
load( Archive & ar, std::vector<T, A> & vector )
{
@ -60,7 +60,7 @@ namespace cereal
//! Serialization for non-arithmetic (and bool) vector types
template <class Archive, class T, class A> inline
typename std::enable_if<!traits::is_output_serializable<BinaryData<T>, Archive>()
typename std::enable_if<!traits::is_output_serializable<BinaryData<T>, Archive>::value
|| !std::is_arithmetic<T>::value
|| std::is_same<T, bool>::value, void>::type
save( Archive & ar, std::vector<T, A> const & vector )
@ -72,7 +72,7 @@ namespace cereal
//! Serialization for non-arithmetic (and bool) vector types
template <class Archive, class T, class A> inline
typename std::enable_if<!traits::is_input_serializable<BinaryData<T>, Archive>()
typename std::enable_if<!traits::is_input_serializable<BinaryData<T>, Archive>::value
|| !std::is_arithmetic<T>::value
|| std::is_same<T, bool>::value, void>::type
load( Archive & ar, std::vector<T, A> & vector )

View File

@ -1,8 +1,44 @@
//#include <cereal/access.hpp>
#include <cereal/access.hpp>
#include <cereal/details/traits.hpp>
#include <cereal/details/helpers.hpp>
#include <cereal/types/base_class.hpp>
#include <cereal/cereal.hpp>
#include <cereal/types/array.hpp>
#include <cereal/types/bitset.hpp>
#include <cereal/types/boost_variant.hpp>
#include <cereal/types/chrono.hpp>
#include <cereal/types/common.hpp>
#include <cereal/types/complex.hpp>
#include <cereal/types/deque.hpp>
#include <cereal/types/forward_list.hpp>
#include <cereal/types/list.hpp>
#include <cereal/types/map.hpp>
#include <cereal/types/memory.hpp>
#include <cereal/details/util.hpp>
#include <cereal/details/polymorphic_impl.hpp>
#include <cereal/types/polymorphic.hpp>
#include <cereal/types/queue.hpp>
#include <cereal/types/set.hpp>
#include <cereal/types/stack.hpp>
#include <cereal/types/string.hpp>
#include <cereal/types/tuple.hpp>
#include <cereal/types/unordered_map.hpp>
#include <cereal/types/unordered_set.hpp>
#include <cereal/types/utility.hpp>
#include <cereal/types/vector.hpp>
#include <cereal/archives/binary.hpp>
//#include <cereal/archives/portable_binary.hpp>
#include <cereal/archives/xml.hpp>
//#include <cereal/archives/json.hpp>
#include <iostream>
#include <type_traits>
#include <functional>
struct Archive {};
@ -54,6 +90,23 @@ namespace cereal
};
}
struct A
{
virtual void foo() = 0;
};
struct B : A
{
void foo() {}
};
struct C
{
char a;
};
CEREAL_REGISTER_TYPE(B);
int main()
{
std::cout << std::boolalpha;
@ -86,6 +139,24 @@ int main()
// serialiable
std::cout << "\toutput serializable" << std::endl;
std::cout << cereal::traits::is_output_serializable<Test, Archive>::value << std::endl;
// array size
int x[5][3][2];
std::cout << cereal::traits::sizeof_array<decltype(x)>::value << std::endl;
std::cout << typeid(A).name() << std::endl;
std::cout << typeid(cereal::traits::has_load_and_allocate<int, bool>).name() << std::endl;
typedef std::function<void(void*, void const *)> Serializer;
std::numeric_limits<char>::max();
{
cereal::XMLOutputArchive ar( std::cout );
ar( 5 );
//ar( cereal::make_nvp("hello", 2.4f ) );
}
return 0;
}

View File

@ -39,10 +39,12 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>$(SolutionDir)\..\include;$(IncludePath)</IncludePath>
<IncludePath>$(SolutionDir)\..\include;C:\Boost\include\boost-1_54;$(IncludePath)</IncludePath>
<LibraryPath>C:\Boost\lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>$(SolutionDir)\..\include;$(IncludePath)</IncludePath>
<IncludePath>$(SolutionDir)\..\include;C:\Boost\include\boost-1_54;$(IncludePath)</IncludePath>
<LibraryPath>C:\Boost\lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>