summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/serialization/test/test_reset_object_address.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/serialization/test/test_reset_object_address.cpp')
-rw-r--r--src/boost/libs/serialization/test/test_reset_object_address.cpp412
1 files changed, 412 insertions, 0 deletions
diff --git a/src/boost/libs/serialization/test/test_reset_object_address.cpp b/src/boost/libs/serialization/test/test_reset_object_address.cpp
new file mode 100644
index 000000000..a3d0195f6
--- /dev/null
+++ b/src/boost/libs/serialization/test/test_reset_object_address.cpp
@@ -0,0 +1,412 @@
+/////////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 value
+class 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 moved
+class 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 moved
+class 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 to
+class 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 target
+class 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 collections
+void 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 archive
+void 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;
+}