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))
|
static auto member_load(Archive & ar, T & t) -> decltype(t.load(ar))
|
||||||
{ 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>
|
template <class T>
|
||||||
static void load_and_allocate(...)
|
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
|
/*! 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,
|
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
|
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) \
|
#define CEREAL_CLASS_VERSION(TYPE, VERSION_NUMBER) \
|
||||||
namespace cereal { namespace detail { \
|
namespace cereal { namespace detail { \
|
||||||
template <> struct Version<TYPE> { static const std::uint32_t version = VERSION_NUMBER; };\
|
template <> struct Version<TYPE> { static const std::uint32_t version = VERSION_NUMBER; };\
|
||||||
|
|||||||
@@ -81,6 +81,44 @@ namespace cereal
|
|||||||
template <class T, class A> \
|
template <class T, class A> \
|
||||||
struct has_non_member_##name : std::integral_constant<bool, detail::has_non_member_##name##_impl<T, A>::value> {};
|
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
|
// Member load_and_allocate
|
||||||
template<typename T, typename A>
|
template<typename T, typename A>
|
||||||
@@ -104,18 +142,34 @@ namespace cereal
|
|||||||
// Member Serialize
|
// Member Serialize
|
||||||
CEREAL_MAKE_HAS_MEMBER_TEST(serialize);
|
CEREAL_MAKE_HAS_MEMBER_TEST(serialize);
|
||||||
|
|
||||||
|
// ######################################################################
|
||||||
|
// Member Serialize (versioned, Boost Transition Layer)
|
||||||
|
CEREAL_MAKE_HAS_MEMBER_VERSIONED_TEST(serialize);
|
||||||
|
|
||||||
// ######################################################################
|
// ######################################################################
|
||||||
// Non Member Serialize
|
// Non Member Serialize
|
||||||
CEREAL_MAKE_HAS_NON_MEMBER_TEST(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
|
// Member Load
|
||||||
CEREAL_MAKE_HAS_MEMBER_TEST(load);
|
CEREAL_MAKE_HAS_MEMBER_TEST(load);
|
||||||
|
|
||||||
|
// ######################################################################
|
||||||
|
// Member Load (versioned, Boost Transition Layer)
|
||||||
|
CEREAL_MAKE_HAS_MEMBER_VERSIONED_TEST(load);
|
||||||
|
|
||||||
// ######################################################################
|
// ######################################################################
|
||||||
// Non Member Load
|
// Non Member Load
|
||||||
CEREAL_MAKE_HAS_NON_MEMBER_TEST(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
|
// Member Save
|
||||||
namespace detail
|
namespace detail
|
||||||
@@ -146,6 +200,36 @@ namespace cereal
|
|||||||
"save member functions must always be const" );
|
"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
|
// Non-const Member Save
|
||||||
namespace detail
|
namespace detail
|
||||||
@@ -176,6 +260,36 @@ namespace cereal
|
|||||||
"save non-member functions must always pass their types as const" );
|
"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>
|
template <class T, class InputArchive, class OutputArchive>
|
||||||
struct has_member_split : std::integral_constant<bool,
|
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()
|
int main()
|
||||||
{
|
{
|
||||||
@@ -652,7 +672,8 @@ int main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::cerr << "-------------------------" << std::endl;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user