Add boost::core::split_member

This commit is contained in:
Peter Dimov 2023-02-20 21:00:26 +02:00
parent 7664d7ab7e
commit 38037b45f1
4 changed files with 109 additions and 5 deletions

View File

@ -27,6 +27,8 @@ namespace serialization
template<class T> struct version;
class access;
// Our own version_type replacement. This has to be in
// the `serialization` namespace, because its only purpose
// is to add `serialization` as an associated namespace.
@ -54,17 +56,17 @@ using serialization::make_nvp;
namespace detail
{
template<bool IsSaving> struct load_or_save;
template<bool IsSaving> struct load_or_save_f;
template<> struct load_or_save<true>
template<> struct load_or_save_f<true>
{
template<class A, class T> void operator()( A& a, T& t, unsigned int v ) const
{
save( a, t, serialization::core_version_type( v ) );
save( a, t, serialization::core_version_type( v ) );
}
};
template<> struct load_or_save<false>
template<> struct load_or_save_f<false>
{
template<class A, class T> void operator()( A& a, T& t, unsigned int v ) const
{
@ -76,7 +78,37 @@ template<> struct load_or_save<false>
template<class A, class T> inline void split_free( A& a, T& t, unsigned int v )
{
detail::load_or_save< A::is_saving::value >()( a, t, v );
detail::load_or_save_f< A::is_saving::value >()( a, t, v );
}
// split_member
namespace detail
{
template<bool IsSaving, class Access = serialization::access> struct load_or_save_m;
template<class Access> struct load_or_save_m<true, Access>
{
template<class A, class T> void operator()( A& a, T const& t, unsigned int v ) const
{
Access::member_save( a, t, v );
}
};
template<class Access> struct load_or_save_m<false, Access>
{
template<class A, class T> void operator()( A& a, T& t, unsigned int v ) const
{
Access::member_load( a, t, v );
}
};
} // namespace detail
template<class A, class T> inline void split_member( A& a, T& t, unsigned int v )
{
detail::load_or_save_m< A::is_saving::value >()( a, t, v );
}
} // namespace core

View File

@ -35,6 +35,7 @@ set(BOOST_TEST_LINK_LIBRARIES Boost::core Boost::serialization)
boost_test(TYPE run SOURCES serialization_nvp_test.cpp)
boost_test(TYPE run SOURCES serialization_split_free_test.cpp)
boost_test(TYPE run SOURCES serialization_split_member_test.cpp)
endif()

View File

@ -365,6 +365,7 @@ run size_test.cpp ;
run serialization_nvp_test.cpp : : : <library>/boost//serialization/<warnings>off ;
run serialization_split_free_test.cpp : : : <library>/boost//serialization/<warnings>off ;
run serialization_split_member_test.cpp : : : <library>/boost//serialization/<warnings>off ;
use-project /boost/core/swap : ./swap ;
build-project ./swap ;

View File

@ -0,0 +1,70 @@
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(__clang__) && defined(__has_warning)
# if __has_warning( "-Wdeprecated-copy" )
# pragma clang diagnostic ignored "-Wdeprecated-copy"
# endif
#endif
#include <boost/core/serialization.hpp>
struct X
{
int a, b;
private:
friend boost::serialization::access;
template<class Ar> void load( Ar& ar, unsigned /*v*/ )
{
ar >> a;
ar >> b;
}
template<class Ar> void save( Ar& ar, unsigned /*v*/ ) const
{
ar << a;
ar << b;
}
template<class Ar> void serialize( Ar& ar, unsigned v )
{
boost::core::split_member( ar, *this, v );
}
};
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/core/lightweight_test.hpp>
#include <sstream>
#include <string>
int main()
{
std::ostringstream os;
X x1 = { 7, 11 };
{
boost::archive::text_oarchive ar( os );
ar << x1;
}
std::string s = os.str();
X x2 = { 0, 0 };
{
std::istringstream is( s );
boost::archive::text_iarchive ar( is );
ar >> x2;
}
BOOST_TEST_EQ( x1.a, x2.a );
BOOST_TEST_EQ( x1.b, x2.b );
return boost::report_errors();
}