test_reset_object_address.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 413 行
CPP
413 行
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8// test_reset_object_address.cpp// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . // Use, modification and distribution is subject to the Boost Software// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)#include <sstream>#include <cassert>#include <cstdlib> // for rand()#include <cstddef> // size_t#include <boost/config.hpp>#if defined(BOOST_NO_STDC_NAMESPACE)namespace std{ using ::rand; using ::size_t;}#endif#include "test_tools.hpp"#include <boost/archive/text_oarchive.hpp>#include <boost/archive/text_iarchive.hpp>#include <boost/archive/polymorphic_text_oarchive.hpp>#include <boost/archive/polymorphic_text_iarchive.hpp>#include <boost/serialization/list.hpp>#include <boost/serialization/access.hpp>// Someday, maybe all tests will be converted to the unit test framework.// but for now use the text execution monitor to be consistent with all// the other tests.// simple test of untracked value#include "A.hpp"#include "A.ipp"void test1(){ std::stringstream ss; const A a; { boost::archive::text_oarchive oa(ss); oa << a; } A a1; { boost::archive::text_iarchive ia(ss); // load to temporary A a2; ia >> a2; BOOST_CHECK_EQUAL(a, a2); // move to final destination a1 = a2; ia.reset_object_address(& a1, & a2); } BOOST_CHECK_EQUAL(a, a1);}// simple test of tracked valueclass B { friend class boost::serialization::access; int m_i; template<class Archive> void serialize(Archive &ar, const unsigned int file_version){ ar & m_i; }public: bool operator==(const B & rhs) const { return m_i == rhs.m_i; } B() : m_i(std::rand()) {}};//BOOST_TEST_DONT_PRINT_LOG_VALUE( B )void test2(){ std::stringstream ss; B const b; B const * const b_ptr = & b; BOOST_CHECK_EQUAL(& b, b_ptr); { boost::archive::text_oarchive oa(ss); oa << b; oa << b_ptr; } B b1; B * b1_ptr; { boost::archive::text_iarchive ia(ss); // load to temporary B b2; ia >> b2; BOOST_CHECK_EQUAL(b, b2); // move to final destination b1 = b2; ia.reset_object_address(& b1, & b2); ia >> b1_ptr; } BOOST_CHECK_EQUAL(b, b1); BOOST_CHECK_EQUAL(& b1, b1_ptr);}// check that nested member values are properly movedclass D { friend class boost::serialization::access; template<class Archive> void serialize(Archive &ar, const unsigned int file_version){ ar & m_b; }public: B m_b; bool operator==(const D & rhs) const { return m_b == rhs.m_b; } D(){}};//BOOST_TEST_DONT_PRINT_LOG_VALUE( D )void test3(){ std::stringstream ss; D const d; B const * const b_ptr = & d.m_b; { boost::archive::text_oarchive oa(ss); oa << d; oa << b_ptr; } D d1; B * b1_ptr; { boost::archive::text_iarchive ia(ss); D d2; ia >> d2; d1 = d2; ia.reset_object_address(& d1, & d2); ia >> b1_ptr; } BOOST_CHECK_EQUAL(d, d1); BOOST_CHECK_EQUAL(* b_ptr, * b1_ptr);}// check that data pointed to by pointer members is NOT movedclass E { int m_i; friend class boost::serialization::access; template<class Archive> void serialize(Archive &ar, const unsigned int file_version){ ar & m_i; }public: bool operator==(const E &rhs) const { return m_i == rhs.m_i; } E() : m_i(std::rand()) {} E(const E & rhs) : m_i(rhs.m_i) {}};//BOOST_TEST_DONT_PRINT_LOG_VALUE( E )// check that moves don't move stuff pointed toclass F { friend class boost::serialization::access; E * m_eptr; template<class Archive> void serialize(Archive &ar, const unsigned int file_version){ ar & m_eptr; }public: bool operator==(const F &rhs) const { return *m_eptr == *rhs.m_eptr; } F & operator=(const F & rhs) { * m_eptr = * rhs.m_eptr; return *this; } F(){ m_eptr = new E; } F(const F & rhs){ *this = rhs; } ~F(){ delete m_eptr; }};//BOOST_TEST_DONT_PRINT_LOG_VALUE( F )void test4(){ std::stringstream ss; const F f; { boost::archive::text_oarchive oa(ss); oa << f; } F f1; { boost::archive::text_iarchive ia(ss); F f2; ia >> f2; f1 = f2; ia.reset_object_address(& f1, & f2); } BOOST_CHECK_EQUAL(f, f1);}// check that multiple moves keep track of the correct targetclass G { friend class boost::serialization::access; A m_a1; A m_a2; A *m_pa2; template<class Archive> void save(Archive &ar, const unsigned int file_version) const { ar << m_a1; ar << m_a2; ar << m_pa2; } template<class Archive> void load(Archive &ar, const unsigned int file_version){ A a; // temporary A ar >> a; m_a1 = a; ar.reset_object_address(& m_a1, & a); ar >> a; m_a2 = a; ar.reset_object_address(& m_a2, & a); ar & m_pa2; } BOOST_SERIALIZATION_SPLIT_MEMBER()public: bool operator==(const G &rhs) const { return m_a1 == rhs.m_a1 && m_a2 == rhs.m_a2 && *m_pa2 == *rhs.m_pa2; } G & operator=(const G & rhs) { m_a1 = rhs.m_a1; m_a2 = rhs.m_a2; m_pa2 = & m_a2; return *this; } G(){ m_pa2 = & m_a2; } G(const G & rhs){ *this = rhs; } ~G(){}};//BOOST_TEST_DONT_PRINT_LOG_VALUE( G )void test5(){ std::stringstream ss; const G g; { boost::archive::text_oarchive oa(ss); oa << g; } G g1; { boost::archive::text_iarchive ia(ss); ia >> g1; } BOOST_CHECK_EQUAL(g, g1);}// joaquin's test - this tests the case where rest_object_address// is applied to an item which in fact is not tracked so that // the call is in fact superfluous.struct foo{ int x;private: friend class boost::serialization::access; template<class Archive> void serialize(Archive &,const unsigned int) { }};struct bar{ foo f[2]; foo* pf[2];private: friend class boost::serialization::access; BOOST_SERIALIZATION_SPLIT_MEMBER() template<class Archive> void save(Archive& ar,const unsigned int)const { for(int i=0;i<2;++i){ ar<<f[i].x; ar<<f[i]; } for(int j=0;j<2;++j){ ar<<pf[j]; } } template<class Archive> void load(Archive& ar,const unsigned int) { for(int i=0;i<2;++i){ int x; ar>>x; f[i].x=x; ar.reset_object_address(&f[i].x,&x); ar>>f[i]; } for(int j=0;j<2;++j){ ar>>pf[j]; } }};int test6(){ bar b; b.f[0].x=0; b.f[1].x=1; b.pf[0]=&b.f[0]; b.pf[1]=&b.f[1]; std::ostringstream oss; { boost::archive::text_oarchive oa(oss); oa<<const_cast<const bar&>(b); } bar b1; b1.pf[0]=0; b1.pf[1]=0; std::istringstream iss(oss.str()); boost::archive::text_iarchive ia(iss); ia>>b1; BOOST_CHECK(b1.pf[0]==&b1.f[0]&&b1.pf[1]==&b1.f[1]); return 0;}// test one of the collectionsvoid test7(){ std::stringstream ss; B const b; B const * const b_ptr = & b; BOOST_CHECK_EQUAL(& b, b_ptr); { std::list<const B *> l; l.push_back(b_ptr); boost::archive::text_oarchive oa(ss); oa << const_cast<const std::list<const B *> &>(l); } B b1; { std::list<B *> l; boost::archive::text_iarchive ia(ss); ia >> l; delete l.front(); // prevent memory leak }}// test one of the collections with polymorphic archivevoid test8(){ std::stringstream ss; B const b; B const * const b_ptr = & b; BOOST_CHECK_EQUAL(& b, b_ptr); { std::list<const B *> l; l.push_back(b_ptr); boost::archive::polymorphic_text_oarchive oa(ss); boost::archive::polymorphic_oarchive & poa = oa; poa << const_cast<const std::list<const B *> &>(l); } B b1; { std::list<B *> l; boost::archive::polymorphic_text_iarchive ia(ss); boost::archive::polymorphic_iarchive & pia = ia; pia >> l; delete l.front(); // prevent memory leak }}int test_main(int /* argc */, char * /* argv */[]){ test1(); test2(); test3(); test4(); test5(); test6(); test7(); test8(); return EXIT_SUCCESS;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?