mirror of
https://github.com/USCiLab/cereal.git
synced 2025-10-18 01:45:52 +02:00
Working on type traits for Boost Transition Layer
This commit is contained in:
@@ -125,6 +125,25 @@ namespace cereal
|
||||
static auto member_load(Archive & ar, T & t) -> decltype(t.load(ar))
|
||||
{ t.load(ar); }
|
||||
|
||||
/*! @name Boost Transition Layer */
|
||||
//! @{
|
||||
template<class Archive, class T> inline
|
||||
static auto member_serialize(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.serialize(ar, version))
|
||||
{ t.serialize(ar, version); }
|
||||
|
||||
template<class Archive, class T> inline
|
||||
static auto member_save(Archive & ar, T const & t, const std::uint32_t version ) -> decltype(t.save(ar, version))
|
||||
{ t.save(ar, version); }
|
||||
|
||||
template<class Archive, class T> inline
|
||||
static auto member_save_non_const(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.save(ar, version))
|
||||
{ t.save(ar, version); }
|
||||
|
||||
template<class Archive, class T> inline
|
||||
static auto member_load(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.load(ar, version))
|
||||
{ t.load(ar, version); }
|
||||
//! @}
|
||||
|
||||
template <class T>
|
||||
static void load_and_allocate(...)
|
||||
{ }
|
||||
|
||||
@@ -309,7 +309,14 @@ namespace cereal
|
||||
/*! This is part of the Boost Transition Layer and is not the recommended way
|
||||
of using cereal. This works identically to how it does in Boost serialization,
|
||||
providing a version number associated with some type that is available by specifying
|
||||
a second parameter to serialize, save, or load. */
|
||||
a second parameter to serialize, save, or load.
|
||||
|
||||
If you are using the two parameter versions of serialization functions, a default
|
||||
value of 0 will be used for version unless you specify otherwise with this macro.
|
||||
|
||||
The recommended way of performing versioning in cereal is to implement it yourself
|
||||
on a class by class basis as required, creating a thin wrapper if you do not have
|
||||
access to the internals of a class. */
|
||||
#define CEREAL_CLASS_VERSION(TYPE, VERSION_NUMBER) \
|
||||
namespace cereal { namespace detail { \
|
||||
template <> struct Version<TYPE> { static const std::uint32_t version = VERSION_NUMBER; };\
|
||||
|
||||
@@ -81,6 +81,44 @@ namespace cereal
|
||||
template <class T, class A> \
|
||||
struct has_non_member_##name : std::integral_constant<bool, detail::has_non_member_##name##_impl<T, A>::value> {};
|
||||
|
||||
//! Creates a test for whether a non const member function exists with a version parameter
|
||||
/*! This creates a class derived from std::integral_constant that will be true if
|
||||
the type has the proper member function for the given archive. */
|
||||
#define CEREAL_MAKE_HAS_MEMBER_VERSIONED_TEST(name) \
|
||||
namespace detail \
|
||||
{ \
|
||||
template <class T, class A> \
|
||||
struct has_member_versioned_##name##_impl \
|
||||
{ \
|
||||
template <class TT, class AA> \
|
||||
static auto test(int) -> decltype( cereal::access::member_##name( std::declval<AA&>(), std::declval<TT&>(), 0 ), yes()); \
|
||||
template <class, class> \
|
||||
static no test(...); \
|
||||
static const bool value = std::is_same<decltype(test<T, A>(0)), yes>::value; \
|
||||
}; \
|
||||
} /* end namespace detail */ \
|
||||
template <class T, class A> \
|
||||
struct has_member_versioned_##name : std::integral_constant<bool, detail::has_member_versioned_##name##_impl<T, A>::value> {};
|
||||
|
||||
//! Creates a test for whether a non const non-member function exists with a version parameter
|
||||
/*! This creates a class derived from std::integral_constant that will be true if
|
||||
the type has the proper non-member function for the given archive. */
|
||||
#define CEREAL_MAKE_HAS_NON_MEMBER_VERSIONED_TEST(name) \
|
||||
namespace detail \
|
||||
{ \
|
||||
template <class T, class A> \
|
||||
struct has_non_member_versioned_##name##_impl \
|
||||
{ \
|
||||
template <class TT, class AA> \
|
||||
static auto test(int) -> decltype( name( std::declval<AA&>(), std::declval<TT&>(), 0 ), yes()); \
|
||||
template <class, class> \
|
||||
static no test( ... ); \
|
||||
static const bool value = std::is_same<decltype( test<T, A>( 0 ) ), yes>::value; \
|
||||
}; \
|
||||
} /* end namespace detail */ \
|
||||
template <class T, class A> \
|
||||
struct has_non_member_versioned_##name : std::integral_constant<bool, detail::has_non_member_versioned_##name##_impl<T, A>::value> {};
|
||||
|
||||
// ######################################################################
|
||||
// Member load_and_allocate
|
||||
template<typename T, typename A>
|
||||
@@ -104,18 +142,34 @@ namespace cereal
|
||||
// Member Serialize
|
||||
CEREAL_MAKE_HAS_MEMBER_TEST(serialize);
|
||||
|
||||
// ######################################################################
|
||||
// Member Serialize (versioned, Boost Transition Layer)
|
||||
CEREAL_MAKE_HAS_MEMBER_VERSIONED_TEST(serialize);
|
||||
|
||||
// ######################################################################
|
||||
// Non Member Serialize
|
||||
CEREAL_MAKE_HAS_NON_MEMBER_TEST(serialize);
|
||||
|
||||
// ######################################################################
|
||||
// Non Member Serialize (versioned, Boost Transition Layer)
|
||||
CEREAL_MAKE_HAS_NON_MEMBER_VERSIONED_TEST(serialize);
|
||||
|
||||
// ######################################################################
|
||||
// Member Load
|
||||
CEREAL_MAKE_HAS_MEMBER_TEST(load);
|
||||
|
||||
// ######################################################################
|
||||
// Member Load (versioned, Boost Transition Layer)
|
||||
CEREAL_MAKE_HAS_MEMBER_VERSIONED_TEST(load);
|
||||
|
||||
// ######################################################################
|
||||
// Non Member Load
|
||||
CEREAL_MAKE_HAS_NON_MEMBER_TEST(load);
|
||||
|
||||
// ######################################################################
|
||||
// Non Member Load (versioned, Boost Transition Layer)
|
||||
CEREAL_MAKE_HAS_NON_MEMBER_VERSIONED_TEST(load);
|
||||
|
||||
// ######################################################################
|
||||
// Member Save
|
||||
namespace detail
|
||||
@@ -146,6 +200,36 @@ namespace cereal
|
||||
"save member functions must always be const" );
|
||||
};
|
||||
|
||||
// ######################################################################
|
||||
// Member Save (versioned, Boost Transition Layer)
|
||||
namespace detail
|
||||
{
|
||||
template <class T, class A>
|
||||
struct has_member_versioned_save_impl
|
||||
{
|
||||
template <class TT, class AA>
|
||||
static auto test(int) -> decltype( cereal::access::member_save( std::declval<AA&>(), std::declval<TT const &>(), 0 ), yes());
|
||||
template <class, class>
|
||||
static no test(...);
|
||||
static const bool value = std::is_same<decltype(test<T, A>(0)), yes>::value;
|
||||
|
||||
template <class TT, class AA>
|
||||
static auto test2(int) -> decltype( cereal::access::member_save_non_const( std::declval<AA &>(), std::declval<typename std::remove_const<TT>::type&>(), 0 ), yes());
|
||||
template <class, class>
|
||||
static no test2(...);
|
||||
static const bool not_const_type = std::is_same<decltype(test2<T, A>(0)), yes>::value;
|
||||
};
|
||||
} // end namespace detail
|
||||
|
||||
template <class T, class A>
|
||||
struct has_member_versioned_save : std::integral_constant<bool, detail::has_member_versioned_save_impl<T, A>::value>
|
||||
{
|
||||
typedef typename detail::has_member_versioned_save_impl<T, A> check;
|
||||
static_assert( check::value || !check::not_const_type,
|
||||
"cereal detected a versioned non-const save.\n"
|
||||
"save member functions must always be const" );
|
||||
};
|
||||
|
||||
// ######################################################################
|
||||
// Non-const Member Save
|
||||
namespace detail
|
||||
@@ -176,6 +260,36 @@ namespace cereal
|
||||
"save non-member functions must always pass their types as const" );
|
||||
};
|
||||
|
||||
// ######################################################################
|
||||
// Non-const Member Save (versioned, Boost Transition Layer)
|
||||
namespace detail
|
||||
{
|
||||
template <class T, class A>
|
||||
struct has_non_member_versioned_save_impl
|
||||
{
|
||||
template <class TT, class AA>
|
||||
static auto test(int) -> decltype( save( std::declval<AA&>(), std::declval<TT const &>(), 0 ), yes());
|
||||
template <class, class>
|
||||
static no test(...);
|
||||
static const bool value = std::is_same<decltype(test<T, A>(0)), yes>::value;
|
||||
|
||||
template <class TT, class AA>
|
||||
static auto test2(int) -> decltype( save( std::declval<AA &>(), std::declval<typename std::remove_const<TT>::type&>(), 0 ), yes());
|
||||
template <class, class>
|
||||
static no test2(...);
|
||||
static const bool not_const_type = std::is_same<decltype(test2<T, A>(0)), yes>::value;
|
||||
};
|
||||
} // end namespace detail
|
||||
|
||||
template <class T, class A>
|
||||
struct has_non_member_versioned_save : std::integral_constant<bool, detail::has_non_member_versioned_save_impl<T, A>::value>
|
||||
{
|
||||
typedef typename detail::has_non_member_versioned_save_impl<T, A> check;
|
||||
static_assert( check::value || !check::not_const_type,
|
||||
"cereal detected a non-const type parameter in versioned non-member save.\n"
|
||||
"save non-member functions must always pass their types as const" );
|
||||
};
|
||||
|
||||
// ######################################################################
|
||||
template <class T, class InputArchive, class OutputArchive>
|
||||
struct has_member_split : std::integral_constant<bool,
|
||||
|
||||
23
sandbox.cpp
23
sandbox.cpp
@@ -380,6 +380,26 @@ void test_unordered_loads()
|
||||
}
|
||||
}
|
||||
|
||||
struct BoostTransitionMS
|
||||
{
|
||||
BoostTransitionMS( int xx ) : x(xx) {}
|
||||
|
||||
int x;
|
||||
|
||||
//template <class Archive>
|
||||
//void serialize( Archive & ar )
|
||||
//{
|
||||
// ar( x );
|
||||
//}
|
||||
|
||||
template <class Archive>
|
||||
void serialize( Archive & ar, const std::uint32_t version )
|
||||
{
|
||||
std::cout << "BoostTransitionMS " << version << std::endl;
|
||||
ar( x );
|
||||
}
|
||||
};
|
||||
|
||||
// ######################################################################
|
||||
int main()
|
||||
{
|
||||
@@ -652,7 +672,8 @@ int main()
|
||||
}
|
||||
|
||||
std::cerr << "-------------------------" << std::endl;
|
||||
test_unordered_loads<cereal::XMLInputArchive, cereal::XMLOutputArchive>();
|
||||
std::cout << cereal::traits::has_member_serialize<BoostTransitionMS, cereal::BinaryOutputArchive>() << std::endl;
|
||||
std::cout << cereal::traits::has_member_versioned_serialize<BoostTransitionMS, cereal::BinaryOutputArchive>() << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user