Added a way to disambiguate serialization in cases where cereal can't figure it out on its own thanks to C++. In

access.hpp, there is now a struct called specialize which can be specialized to explicitly specify what type of
serialization a class will need.  This is mostly useful for derived classes that switch from one method of serialization
(that is member/non-member serialize vs load/split).
This commit is contained in:
Shane Grant
2013-06-25 14:51:43 -07:00
parent 514b08a2a0
commit e1fe25b66f
4 changed files with 164 additions and 111 deletions

View File

@@ -43,9 +43,7 @@
class Base
{
public:
//private:
private:
friend class cereal::access;
template <class Archive>
void serialize( Archive & ar )
@@ -53,31 +51,37 @@ class Base
std::cout << "Base serialize" << std::endl;
ar( x );
}
int x;
};
class Derived : private Base
class Derived : public Base
{
public:
//friend class cereal::access;
template <class Archive>
void save( Archive & ar ) const
{
ar( cereal::base_class<Base>(this) );
std::cout << "Derived save" << std::endl;
ar( y );
serialize( ar );
}
template <class Archive>
void load( Archive & ar )
{
ar( cereal::base_class<Base>(this) );
std::cout << "Derived load" << std::endl;
ar( y );
}
int y;
};
//ar( cereal::base_class<Test1>(this) );
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> {};
}
// ###################################
struct Test1
@@ -249,88 +253,16 @@ namespace cereal
};
}
template<typename T>
struct has_size_method
{
private:
typedef std::true_type yes;
typedef std::false_type no;
template<typename U> static auto test(int) -> decltype(std::declval<U>().size(), yes());
template<typename> static no test(...);
public:
static constexpr bool value = std::is_same<decltype(test<T>(0)),yes>::value;
};
#include <vector>
template<class T, class A>
struct has_serialize_method
{
private:
typedef std::true_type yes;
typedef std::false_type no;
template<class T2, class A2> static auto test(int) -> decltype(std::declval<T2>().serialize(std::declval<A2&>()), yes());
//template<class T2, class A2> static auto test(int) -> decltype( access::member_serialize(std::declval<A2&>()std::declval<T2>().serialize(std::declval<A2&>()), yes());
//decltype( access::member_serialize(std::declval<A&>(), std::declval<T&>() ) )
template<typename, typename> static no test(...);
public:
static constexpr bool value = std::is_same<decltype(test<T, A>(0)),yes>::value;
};
struct B
{
int size();
};
struct C : private B
{
};
// ######################################################################
int main()
{
std::cout << std::boolalpha << std::endl;
//std::cout << "Base" << std::endl;
//std::cout << "ms " << cereal::traits::has_member_save<Base, cereal::BinaryOutputArchive>() << std::endl;
//std::cout << "nms " << cereal::traits::has_non_member_save<Base, cereal::BinaryOutputArchive>() << std::endl;
//std::cout << "ml " << cereal::traits::has_member_load<Base, cereal::BinaryInputArchive>() << std::endl;
//std::cout << "nml " << cereal::traits::has_non_member_load<Base, cereal::BinaryInputArchive>() << std::endl;
//std::cout << "mse " << cereal::traits::has_member_serialize<Base, cereal::BinaryOutputArchive>() << std::endl;
//std::cout << "nse " << cereal::traits::has_non_member_serialize<Base, cereal::BinaryOutputArchive>() << std::endl;
//std::cout << "iser " << cereal::traits::is_input_serializable<Base, cereal::BinaryInputArchive>() << std::endl;
//std::cout << "oser " << cereal::traits::is_output_serializable<Base, cereal::BinaryOutputArchive>() << std::endl;
//std::cout << std::endl;
//std::cout << "Derived" << std::endl;
//std::cout << "ms " << cereal::traits::has_member_save<Derived, cereal::BinaryOutputArchive>() << std::endl;
//std::cout << "nms " << cereal::traits::has_non_member_save<Derived, cereal::BinaryOutputArchive>() << std::endl;
//std::cout << "ml " << cereal::traits::has_member_load<Derived, cereal::BinaryInputArchive>() << std::endl;
//std::cout << "nml " << cereal::traits::has_non_member_load<Derived, cereal::BinaryInputArchive>() << std::endl;
//std::cout << "mse " << cereal::traits::has_member_serialize<Derived, cereal::BinaryOutputArchive>() << std::endl;
//std::cout << "nse " << cereal::traits::has_non_member_serialize<Derived, cereal::BinaryOutputArchive>() << std::endl;
//std::cout << "iser " << cereal::traits::is_input_serializable<Derived, cereal::BinaryInputArchive>() << std::endl;
//std::cout << "oser " << cereal::traits::is_output_serializable<Derived, cereal::BinaryOutputArchive>() << std::endl;
//std::cout << std::endl;
std::stringstream os;
cereal::BinaryOutputArchive archive(os);
std::stringstream os;
cereal::BinaryOutputArchive archive(os);
std::cout << has_size_method<B>::value << std::endl;
std::cout << has_size_method<C>::value << std::endl;
//std::cout << has_serialize_method<int, cereal::BinaryInputArchive>::value << std::endl;
//std::cout << has_serialize_method<Base, cereal::BinaryInputArchive>::value << std::endl;
//std::cout << has_serialize_method<Derived, cereal::BinaryInputArchive>::value << std::endl;
//Derived d;
//d.serialize( archive );
Derived d;
archive( d );
//decltype(cereal::access::member_serialize(archive, d));
//decltype(std::declval<Derived&>().serialize( std::declval<cereal::BinaryOutputArchive&>() ));
//d.serialize<cereal::BinaryOutputArchive>( archive );