mirror of
https://github.com/USCiLab/cereal.git
synced 2025-10-18 01:45:52 +02:00
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:
@@ -124,6 +124,70 @@ namespace cereal
|
|||||||
return T::load_and_allocate( ar );
|
return T::load_and_allocate( ar );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! A specifier used in conjunction with cereal::specialize to disambiguate
|
||||||
|
//! serialization in special cases
|
||||||
|
/*! @relates specialize */
|
||||||
|
enum class specialization
|
||||||
|
{
|
||||||
|
member_serialize,
|
||||||
|
member_load_save,
|
||||||
|
non_member_serialize,
|
||||||
|
non_member_load_save
|
||||||
|
};
|
||||||
|
|
||||||
|
//! A class used to disambiguate cases where cereal cannot detect a unique way of serializing a class
|
||||||
|
/*! cereal attempts to figure out which method of serialization (member vs. non-member serialize
|
||||||
|
or load/save pair) at compile time. If for some reason cereal cannot find a non-ambiguous way
|
||||||
|
of serializing a type, it will produce a static assertion complaining about this.
|
||||||
|
|
||||||
|
This can happen because you have both a serialize and load/save pair, or even because a base
|
||||||
|
class has a serialize (public or private with friend access) and a derived class does not
|
||||||
|
overwrite this due to choosing some other serialization type.
|
||||||
|
|
||||||
|
Specializing this class will tell cereal to explicitly use the serialization type you specify
|
||||||
|
and it will not complain about ambiguity in its compile time selection. However, if cereal detects
|
||||||
|
an ambiguity in specializations, it will continue to issue a static assertion.
|
||||||
|
|
||||||
|
@code{.cpp}
|
||||||
|
class MyParent
|
||||||
|
{
|
||||||
|
friend class cereal::access;
|
||||||
|
template <class Archive>
|
||||||
|
void serialize( Archive & ar ) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Although serialize is private in MyParent, to cereal::access it will look public,
|
||||||
|
// even through MyDerived
|
||||||
|
class MyDerived : public MyParent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <class Archive>
|
||||||
|
void load( Archive & ar ) {}
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
void save( Archive & ar ) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// The save/load pair in MyDerived is ambiguous because serialize in MyParent can
|
||||||
|
// be accessed from cereal::access. This looks the same as making serialize public
|
||||||
|
// in MyParent, making it seem as though MyDerived has both a serialize and a load/save pair.
|
||||||
|
// cereal will complain about this at compile time unless we disambiguate:
|
||||||
|
|
||||||
|
namespace cereal
|
||||||
|
{
|
||||||
|
// This struct specialization will tell cereal which is the right way to serialize the ambiguity
|
||||||
|
template <class Archive> struct specialize<Archive, MyDerived, cereal::specialization::member_load_save> {};
|
||||||
|
|
||||||
|
// If we only had a disambiguation for a specific archive type, it would look something like this
|
||||||
|
template <> struct specialize<cereal::BinaryOutputArchive, MyDerived, cereal::specialization::member_load_save> {};
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@tparam T The type to specialize the serialization for
|
||||||
|
@tparam S The specialization type to use for T */
|
||||||
|
template <class Archive, class T, specialization S>
|
||||||
|
struct specialize : public std::false_type {};
|
||||||
} // namespace cereal
|
} // namespace cereal
|
||||||
|
|
||||||
#endif // CEREAL_ACCESS_HPP_
|
#endif // CEREAL_ACCESS_HPP_
|
||||||
|
|||||||
@@ -210,8 +210,9 @@ namespace cereal
|
|||||||
|
|
||||||
//! Member serialization
|
//! Member serialization
|
||||||
template <class T> inline
|
template <class T> inline
|
||||||
typename std::enable_if<traits::is_output_serializable<T, ArchiveType>() && traits::has_member_serialize<T, ArchiveType>(),
|
typename std::enable_if<traits::is_specialized_member_serialize<T, ArchiveType>() ||
|
||||||
ArchiveType &>::type
|
(traits::is_output_serializable<T, ArchiveType>() && traits::has_member_serialize<T, ArchiveType>()),
|
||||||
|
ArchiveType &>::type
|
||||||
operator & (T const & t)
|
operator & (T const & t)
|
||||||
{
|
{
|
||||||
access::member_serialize(*self, const_cast<T &>(t));
|
access::member_serialize(*self, const_cast<T &>(t));
|
||||||
@@ -220,8 +221,9 @@ namespace cereal
|
|||||||
|
|
||||||
//! Non member serialization
|
//! Non member serialization
|
||||||
template <class T> inline
|
template <class T> inline
|
||||||
typename std::enable_if<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>() ||
|
||||||
ArchiveType &>::type
|
(traits::is_output_serializable<T, ArchiveType>() && traits::has_non_member_serialize<T, ArchiveType>()),
|
||||||
|
ArchiveType &>::type
|
||||||
operator & (T const & t)
|
operator & (T const & t)
|
||||||
{
|
{
|
||||||
serialize(*self, const_cast<T &>(t));
|
serialize(*self, const_cast<T &>(t));
|
||||||
@@ -230,8 +232,9 @@ namespace cereal
|
|||||||
|
|
||||||
//! Member split (save)
|
//! Member split (save)
|
||||||
template <class T> inline
|
template <class T> inline
|
||||||
typename std::enable_if<traits::is_output_serializable<T, ArchiveType>() && traits::has_member_save<T, ArchiveType>(),
|
typename std::enable_if<traits::is_specialized_member_load_save<T, ArchiveType>() ||
|
||||||
ArchiveType &>::type
|
(traits::is_output_serializable<T, ArchiveType>() && traits::has_member_save<T, ArchiveType>()),
|
||||||
|
ArchiveType &>::type
|
||||||
operator & (T const & t)
|
operator & (T const & t)
|
||||||
{
|
{
|
||||||
access::member_save(*self, t);
|
access::member_save(*self, t);
|
||||||
@@ -240,24 +243,16 @@ namespace cereal
|
|||||||
|
|
||||||
//! Non member split (save)
|
//! Non member split (save)
|
||||||
template <class T> inline
|
template <class T> inline
|
||||||
typename std::enable_if<traits::is_output_serializable<T, ArchiveType>() && traits::has_non_member_save<T, ArchiveType>(),
|
typename std::enable_if<traits::is_specialized_non_member_load_save<T, ArchiveType>() ||
|
||||||
ArchiveType &>::type
|
(traits::is_output_serializable<T, ArchiveType>() && traits::has_non_member_save<T, ArchiveType>()),
|
||||||
|
ArchiveType &>::type
|
||||||
operator & (T const & t)
|
operator & (T const & t)
|
||||||
{
|
{
|
||||||
save(*self, t);
|
save(*self, t);
|
||||||
return *self;
|
return *self;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Non member split (save) non-const version
|
//! Empty class specialization
|
||||||
template <class T> inline
|
|
||||||
typename std::enable_if<traits::is_output_serializable<T, ArchiveType>() && traits::has_non_member_save<T, ArchiveType>(),
|
|
||||||
ArchiveType &>::type
|
|
||||||
operator & (T & t)
|
|
||||||
{
|
|
||||||
save(*self, t);
|
|
||||||
return *self;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> inline
|
template <class T> inline
|
||||||
typename std::enable_if<(Flags & AllowEmptyClassElision) &&
|
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>() && traits::is_empty_class<T>(), ArchiveType &>::type
|
||||||
@@ -268,7 +263,7 @@ namespace cereal
|
|||||||
|
|
||||||
//! No matching serialization
|
//! No matching serialization
|
||||||
template <class T> inline
|
template <class T> inline
|
||||||
typename std::enable_if<!traits::is_output_serializable<T, ArchiveType>() &&
|
typename std::enable_if<!traits::is_specialized<T, ArchiveType>() && !traits::is_output_serializable<T, ArchiveType>() &&
|
||||||
(!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !traits::is_empty_class<T>())),
|
(!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !traits::is_empty_class<T>())),
|
||||||
ArchiveType &>::type
|
ArchiveType &>::type
|
||||||
operator & (T const & t)
|
operator & (T const & t)
|
||||||
@@ -365,8 +360,9 @@ namespace cereal
|
|||||||
|
|
||||||
//! Member serialization
|
//! Member serialization
|
||||||
template <class T> inline
|
template <class T> inline
|
||||||
typename std::enable_if<traits::is_input_serializable<T, ArchiveType>() && traits::has_member_serialize<T, ArchiveType>(),
|
typename std::enable_if<traits::is_specialized_member_serialize<T, ArchiveType>() ||
|
||||||
ArchiveType &>::type
|
(traits::is_input_serializable<T, ArchiveType>() && traits::has_member_serialize<T, ArchiveType>()),
|
||||||
|
ArchiveType &>::type
|
||||||
operator & (T && t)
|
operator & (T && t)
|
||||||
{
|
{
|
||||||
access::member_serialize(*self, t);
|
access::member_serialize(*self, t);
|
||||||
@@ -375,8 +371,9 @@ namespace cereal
|
|||||||
|
|
||||||
//! Non member serialization
|
//! Non member serialization
|
||||||
template <class T> inline
|
template <class T> inline
|
||||||
typename std::enable_if<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>() ||
|
||||||
ArchiveType &>::type
|
(traits::is_input_serializable<T, ArchiveType>() && traits::has_non_member_serialize<T, ArchiveType>()),
|
||||||
|
ArchiveType &>::type
|
||||||
operator & (T && t)
|
operator & (T && t)
|
||||||
{
|
{
|
||||||
serialize(*self, std::forward<T>(t));
|
serialize(*self, std::forward<T>(t));
|
||||||
@@ -385,8 +382,9 @@ namespace cereal
|
|||||||
|
|
||||||
//! Member split (load)
|
//! Member split (load)
|
||||||
template <class T> inline
|
template <class T> inline
|
||||||
typename std::enable_if<traits::is_input_serializable<T, ArchiveType>() && traits::has_member_load<T, ArchiveType>(),
|
typename std::enable_if<traits::is_specialized_member_load_save<T, ArchiveType>() ||
|
||||||
ArchiveType &>::type
|
(traits::is_input_serializable<T, ArchiveType>() && traits::has_member_load<T, ArchiveType>()),
|
||||||
|
ArchiveType &>::type
|
||||||
operator & (T && t)
|
operator & (T && t)
|
||||||
{
|
{
|
||||||
access::member_load(*self, t);
|
access::member_load(*self, t);
|
||||||
@@ -395,14 +393,16 @@ namespace cereal
|
|||||||
|
|
||||||
//! Non member split (load)
|
//! Non member split (load)
|
||||||
template <class T> inline
|
template <class T> inline
|
||||||
typename std::enable_if<traits::is_input_serializable<T, ArchiveType>() && traits::has_non_member_load<T, ArchiveType>(),
|
typename std::enable_if<traits::is_specialized_non_member_load_save<T, ArchiveType>() ||
|
||||||
ArchiveType &>::type
|
(traits::is_input_serializable<T, ArchiveType>() && traits::has_non_member_load<T, ArchiveType>()),
|
||||||
|
ArchiveType &>::type
|
||||||
operator & (T && t)
|
operator & (T && t)
|
||||||
{
|
{
|
||||||
load(*self, std::forward<T>(t));
|
load(*self, std::forward<T>(t));
|
||||||
return *self;
|
return *self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Empty class specialization
|
||||||
template <class T> inline
|
template <class T> inline
|
||||||
typename std::enable_if<(Flags & AllowEmptyClassElision) &&
|
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>() && traits::is_empty_class<T>(), ArchiveType &>::type
|
||||||
@@ -413,7 +413,7 @@ namespace cereal
|
|||||||
|
|
||||||
//! No matching serialization
|
//! No matching serialization
|
||||||
template <class T> inline
|
template <class T> inline
|
||||||
typename std::enable_if<!traits::is_input_serializable<T, ArchiveType>() &&
|
typename std::enable_if<!traits::is_specialized<T, ArchiveType>() && !traits::is_input_serializable<T, ArchiveType>() &&
|
||||||
(!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !traits::is_empty_class<T>())),
|
(!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !traits::is_empty_class<T>())),
|
||||||
ArchiveType &>::type
|
ArchiveType &>::type
|
||||||
operator & (T const & t)
|
operator & (T const & t)
|
||||||
|
|||||||
@@ -146,6 +146,63 @@ namespace cereal
|
|||||||
has_non_member_serialize<T, InputArchive>();
|
has_non_member_serialize<T, InputArchive>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ######################################################################
|
||||||
|
|
||||||
|
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>
|
||||||
|
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>
|
||||||
|
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>
|
||||||
|
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>
|
||||||
|
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>
|
||||||
|
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>
|
||||||
|
constexpr auto is_specialized_member_serialize() -> bool
|
||||||
|
{ return is_specialized<T, A>() && detail::is_specialized_member_serialize<T, A>(); }
|
||||||
|
|
||||||
|
template <class T, class A>
|
||||||
|
constexpr auto is_specialized_member_load_save() -> bool
|
||||||
|
{ return is_specialized<T, A>() && detail::is_specialized_member_load_save<T, A>(); }
|
||||||
|
|
||||||
|
template <class T, class A>
|
||||||
|
constexpr auto is_specialized_non_member_serialize() -> bool
|
||||||
|
{ return is_specialized<T, A>() && detail::is_specialized_non_member_serialize<T, A>(); }
|
||||||
|
|
||||||
|
template <class T, class A>
|
||||||
|
constexpr auto is_specialized_non_member_load_save() -> bool
|
||||||
|
{ return is_specialized<T, A>() && detail::is_specialized_non_member_load_save<T, A>(); }
|
||||||
|
|
||||||
// ######################################################################
|
// ######################################################################
|
||||||
template <class T>
|
template <class T>
|
||||||
constexpr size_t sizeof_array( size_t rank = std::rank<T>::value )
|
constexpr size_t sizeof_array( size_t rank = std::rank<T>::value )
|
||||||
|
|||||||
98
sandbox.cpp
98
sandbox.cpp
@@ -43,9 +43,7 @@
|
|||||||
|
|
||||||
class Base
|
class Base
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
public:
|
|
||||||
//private:
|
|
||||||
friend class cereal::access;
|
friend class cereal::access;
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
void serialize( Archive & ar )
|
void serialize( Archive & ar )
|
||||||
@@ -53,31 +51,37 @@ class Base
|
|||||||
std::cout << "Base serialize" << std::endl;
|
std::cout << "Base serialize" << std::endl;
|
||||||
ar( x );
|
ar( x );
|
||||||
}
|
}
|
||||||
|
|
||||||
int x;
|
int x;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Derived : private Base
|
class Derived : public Base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//friend class cereal::access;
|
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
void save( Archive & ar ) const
|
void save( Archive & ar ) const
|
||||||
{
|
{
|
||||||
|
ar( cereal::base_class<Base>(this) );
|
||||||
std::cout << "Derived save" << std::endl;
|
std::cout << "Derived save" << std::endl;
|
||||||
ar( y );
|
ar( y );
|
||||||
serialize( ar );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
void load( Archive & ar )
|
void load( Archive & ar )
|
||||||
{
|
{
|
||||||
|
ar( cereal::base_class<Base>(this) );
|
||||||
std::cout << "Derived load" << std::endl;
|
std::cout << "Derived load" << std::endl;
|
||||||
ar( y );
|
ar( y );
|
||||||
}
|
}
|
||||||
|
|
||||||
int 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
|
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()
|
int main()
|
||||||
{
|
{
|
||||||
std::cout << std::boolalpha << std::endl;
|
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::stringstream os;
|
||||||
//std::cout << "ms " << cereal::traits::has_member_save<Derived, cereal::BinaryOutputArchive>() << std::endl;
|
cereal::BinaryOutputArchive archive(os);
|
||||||
//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;
|
Derived d;
|
||||||
cereal::BinaryOutputArchive archive(os);
|
archive( d );
|
||||||
|
|
||||||
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 );
|
|
||||||
//decltype(cereal::access::member_serialize(archive, d));
|
//decltype(cereal::access::member_serialize(archive, d));
|
||||||
//decltype(std::declval<Derived&>().serialize( std::declval<cereal::BinaryOutputArchive&>() ));
|
//decltype(std::declval<Derived&>().serialize( std::declval<cereal::BinaryOutputArchive&>() ));
|
||||||
//d.serialize<cereal::BinaryOutputArchive>( archive );
|
//d.serialize<cereal::BinaryOutputArchive>( archive );
|
||||||
|
|||||||
Reference in New Issue
Block a user