mirror of
https://github.com/USCiLab/cereal.git
synced 2025-10-18 01:45:52 +02:00
NVP + traits changes
Added more NVP info to types that need it Adding ability to detect a save function (member or non-member) that is incorrectly declared as non-const. This is needed since some nasty compilation errors crop up if you explicitly specify a serialization type and register that type with an incorrectly constified save function. So not done yet, but soon in: using a non const save function will trigger a static assertion. Still need to investigate registering types with explicit disambiguation
This commit is contained in:
@@ -112,6 +112,11 @@ namespace cereal
|
||||
static auto member_save(Archive & ar, T const & t) -> decltype(t.save(ar))
|
||||
{ t.save(ar); }
|
||||
|
||||
// Used during detection of non const member save
|
||||
template<class Archive, class T> inline
|
||||
static auto non_const_member_save(Archive & ar, T & t) -> decltype(t.save(ar))
|
||||
{ t.save(ar); }
|
||||
|
||||
template<class Archive, class T> inline
|
||||
static auto member_load(Archive & ar, T & t) -> decltype(t.load(ar))
|
||||
{ t.load(ar); }
|
||||
|
||||
@@ -43,13 +43,13 @@ namespace cereal
|
||||
// Member load_and_allocate
|
||||
template<typename T, typename A>
|
||||
bool constexpr has_member_load_and_allocate()
|
||||
{ return std::is_same<decltype( access::load_and_allocate<T>( std::declval<A&>() ) ), T*>::value; };
|
||||
{ return std::is_same<decltype( access::load_and_allocate<T>( std::declval<A&>() ) ), T*>::value; }
|
||||
|
||||
// ######################################################################
|
||||
// Non Member load_and_allocate
|
||||
template<typename T, typename A>
|
||||
bool constexpr has_non_member_load_and_allocate()
|
||||
{ return std::is_same<decltype( LoadAndAllocate<T>::load_and_allocate( std::declval<A&>() ) ), T*>::value; };
|
||||
{ return std::is_same<decltype( LoadAndAllocate<T>::load_and_allocate( std::declval<A&>() ) ), T*>::value; }
|
||||
|
||||
// ######################################################################
|
||||
// Has either a member or non member allocate
|
||||
@@ -107,12 +107,51 @@ namespace cereal
|
||||
>::type
|
||||
>: std::true_type {};
|
||||
|
||||
// ######################################################################
|
||||
// Non-const Member Save
|
||||
namespace detail
|
||||
{
|
||||
// Detection of any (const or non const) member save
|
||||
template<typename T, class A, typename Sfinae = void>
|
||||
struct has_member_save_any: std::false_type {};
|
||||
|
||||
template<typename T, class A>
|
||||
struct has_member_save_any< T, A,
|
||||
typename Void<
|
||||
decltype( access::non_const_member_save(std::declval<A&>(), std::declval<typename std::remove_const<T>::type &>() ) )
|
||||
>::type
|
||||
>: std::true_type {};
|
||||
}
|
||||
|
||||
// Returns true if we detect a member save function that is not const
|
||||
template <class T, class A>
|
||||
constexpr bool is_non_const_member_save()
|
||||
{
|
||||
return !has_member_save<T, A>() && detail::has_member_save_any<T, A>();
|
||||
}
|
||||
|
||||
// ######################################################################
|
||||
// Non Member Save
|
||||
char & save(...);
|
||||
template<typename T, typename A>
|
||||
bool constexpr has_non_member_save()
|
||||
{ return std::is_void<decltype(save(std::declval<A&>(), std::declval<T&>()))>::value; };
|
||||
{ return std::is_void<decltype(save(std::declval<A&>(), std::declval<T const &>()))>::value; }
|
||||
|
||||
// ######################################################################
|
||||
// Non-const Non member Save
|
||||
namespace detail
|
||||
{
|
||||
template<typename T, typename A>
|
||||
bool constexpr has_non_member_save_any()
|
||||
{ return std::is_void<decltype(save(std::declval<A&>(), std::declval<typename std::remove_const<T>::type &>()))>::value; }
|
||||
}
|
||||
|
||||
// Returns true if we detect a non-member save function that is not const
|
||||
template<typename T, typename A>
|
||||
bool constexpr is_non_const_non_member_save()
|
||||
{ return !has_non_member_save<T, A>() && detail::has_non_member_save_any<T, A>(); }
|
||||
|
||||
|
||||
|
||||
// ######################################################################
|
||||
template <class T, class InputArchive, class OutputArchive>
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace cereal
|
||||
template <class Archive, class T, class C> inline
|
||||
void save( Archive & ar, std::queue<T, C> const & queue )
|
||||
{
|
||||
ar( queue_detail::container( queue ) );
|
||||
ar( _CEREAL_NVP("container", queue_detail::container( queue )) );
|
||||
}
|
||||
|
||||
//! Loading for std::queue
|
||||
@@ -100,8 +100,8 @@ namespace cereal
|
||||
template <class Archive, class T, class C, class Comp> inline
|
||||
void save( Archive & ar, std::priority_queue<T, C, Comp> const & priority_queue )
|
||||
{
|
||||
ar( queue_detail::comparator( priority_queue ) );
|
||||
ar( queue_detail::container( priority_queue ) );
|
||||
ar( _CEREAL_NVP("comparator", queue_detail::comparator( priority_queue )) );
|
||||
ar( _CEREAL_NVP("container", queue_detail::container( priority_queue )) );
|
||||
}
|
||||
|
||||
//! Loading for std::priority_queue
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace cereal
|
||||
template <class Archive, class T, class C> inline
|
||||
void save( Archive & ar, std::stack<T, C> const & stack )
|
||||
{
|
||||
ar( stack_detail::container( stack ) );
|
||||
ar( _CEREAL_NVP("container", stack_detail::container( stack )) );
|
||||
}
|
||||
|
||||
//! Loading for std::stack
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace cereal
|
||||
template <class Archive, class ... Types> inline
|
||||
static void apply( Archive & ar, std::tuple<Types...> & tuple )
|
||||
{
|
||||
ar( std::get<Height - 1>( tuple ) );
|
||||
ar( _CEREAL_NVP("tuple_element", std::get<Height - 1>( tuple )) );
|
||||
serialize<Height - 1>::template apply( ar, tuple );
|
||||
}
|
||||
};
|
||||
@@ -51,7 +51,7 @@ namespace cereal
|
||||
struct serialize<0>
|
||||
{
|
||||
template <class Archive, class ... Types> inline
|
||||
static void apply( Archive & ar, std::tuple<Types...> & tuple )
|
||||
static void apply( Archive &, std::tuple<Types...> & )
|
||||
{ }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ namespace cereal
|
||||
template <class Archive, class T1, class T2> inline
|
||||
void serialize( Archive & ar, std::pair<T1, T2> & pair )
|
||||
{
|
||||
ar( pair.first,
|
||||
pair.second );
|
||||
ar( _CEREAL_NVP("first", pair.first),
|
||||
_CEREAL_NVP("second", pair.second) );
|
||||
}
|
||||
} // namespace cereal
|
||||
|
||||
|
||||
16
sandbox.cpp
16
sandbox.cpp
@@ -37,6 +37,9 @@
|
||||
#include <cereal/types/array.hpp>
|
||||
#include <cereal/types/vector.hpp>
|
||||
#include <cereal/types/map.hpp>
|
||||
#include <cereal/types/utility.hpp>
|
||||
#include <cereal/types/bitset.hpp>
|
||||
#include <cereal/types/polymorphic.hpp>
|
||||
|
||||
#include <cxxabi.h>
|
||||
#include <sstream>
|
||||
@@ -56,6 +59,8 @@ class Base
|
||||
ar( x );
|
||||
}
|
||||
|
||||
virtual void foo() = 0;
|
||||
|
||||
int x;
|
||||
};
|
||||
|
||||
@@ -78,15 +83,18 @@ class Derived : public Base
|
||||
ar( y );
|
||||
}
|
||||
|
||||
void foo() {}
|
||||
|
||||
int y;
|
||||
};
|
||||
|
||||
namespace cereal
|
||||
{
|
||||
template <class Archive> struct specialize<Archive, Derived, cereal::specialization::member_load_save> {};
|
||||
//template <class Archive> struct specialize<Archive, Derived, cereal::specialization::non_member_load_save> {};
|
||||
}
|
||||
|
||||
CEREAL_REGISTER_TYPE(Derived);
|
||||
|
||||
// ###################################
|
||||
struct Test1
|
||||
{
|
||||
@@ -213,7 +221,7 @@ struct Everything
|
||||
struct EmptyStruct
|
||||
{
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar)
|
||||
void serialize(Archive &)
|
||||
{
|
||||
std::cout << "Side effects!" << std::endl;
|
||||
};
|
||||
@@ -233,7 +241,7 @@ struct NoDefaultCtor
|
||||
int y;
|
||||
|
||||
template <class Archive>
|
||||
void serialize( Archive & archive )
|
||||
void serialize( Archive & )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -250,7 +258,7 @@ namespace cereal
|
||||
struct LoadAndAllocate<NoDefaultCtor>
|
||||
{
|
||||
template <class Archive>
|
||||
static NoDefaultCtor * load_and_allocate( Archive & ar )
|
||||
static NoDefaultCtor * load_and_allocate( Archive & )
|
||||
{
|
||||
return new NoDefaultCtor(5);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <type_traits>
|
||||
#include <cereal/archives/binary.hpp>
|
||||
#include <cereal/archives/xml.hpp>
|
||||
#include <cereal/types/polymorphic.hpp>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
@@ -123,10 +124,63 @@ struct OurType : public OurBase
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> void nop(T&&t) {}
|
||||
struct BaseVirtual
|
||||
{
|
||||
int x;
|
||||
template <class Archive>
|
||||
void serialize( Archive & ar )
|
||||
{ ar( x ); }
|
||||
virtual void foo() = 0;
|
||||
};
|
||||
|
||||
struct DerivedVirtual : public virtual BaseVirtual
|
||||
{
|
||||
int y;
|
||||
virtual void foo() {}
|
||||
|
||||
template <class Archive>
|
||||
void save( Archive & ar ) const
|
||||
{
|
||||
ar( cereal::virtual_base_class<BaseVirtual>( this ) );
|
||||
ar( y );
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
void load( Archive & ar )
|
||||
{
|
||||
ar( cereal::virtual_base_class<BaseVirtual>( this ) );
|
||||
ar( y );
|
||||
}
|
||||
};
|
||||
|
||||
namespace cereal
|
||||
{
|
||||
template <class Archive> struct specialize<Archive, DerivedVirtual, cereal::specialization::member_load_save> {};
|
||||
}
|
||||
|
||||
//CEREAL_REGISTER_TYPE(DerivedVirtual);
|
||||
|
||||
template <class T> void nop(T&&) {}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << std::boolalpha;
|
||||
|
||||
std::cout << cereal::traits::is_specialized_member_load_save<DerivedVirtual, cereal::BinaryOutputArchive>() << std::endl;
|
||||
//std::cout << cereal::traits::is_specialized_non_member_serialize<DerivedVirtual, cereal::BinaryOutputArchive>() << std::endl;
|
||||
std::cout << cereal::traits::is_output_serializable<DerivedVirtual, cereal::BinaryOutputArchive>() << std::endl;
|
||||
//std::cout << cereal::traits::has_non_member_serialize<DerivedVirtual, cereal::BinaryOutputArchive>() << std::endl;
|
||||
//std::cout << cereal::traits::is_specialized_member_serialize<DerivedVirtual, cereal::BinaryOutputArchive>() << std::endl;
|
||||
std::cout << cereal::traits::has_member_serialize<DerivedVirtual, cereal::BinaryOutputArchive>() << std::endl;
|
||||
std::cout << "sssssssssssss" <<std::endl;
|
||||
std::cout << cereal::traits::has_member_save<DerivedVirtual, cereal::BinaryOutputArchive>() << std::endl;
|
||||
std::cout << cereal::traits::is_non_const_member_save<DerivedVirtual, cereal::BinaryOutputArchive>() << std::endl;
|
||||
std::cout << cereal::traits::detail::has_member_save_any<DerivedVirtual, cereal::BinaryOutputArchive>() << std::endl;
|
||||
std::cout << cereal::traits::has_non_member_save<DerivedVirtual, cereal::BinaryOutputArchive>() << std::endl;
|
||||
std::cout << cereal::traits::has_member_serialize<DerivedVirtual, cereal::BinaryOutputArchive>() << std::endl;
|
||||
std::cout << cereal::traits::has_non_member_serialize<DerivedVirtual, cereal::BinaryOutputArchive>() << std::endl;
|
||||
|
||||
|
||||
{
|
||||
std::ofstream ostream("rtti.txt");
|
||||
cereal::BinaryOutputArchive oarchive(ostream);
|
||||
|
||||
Reference in New Issue
Block a user