summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/serialization/test/test_shared_ptr_multi_base.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/serialization/test/test_shared_ptr_multi_base.cpp')
-rw-r--r--src/boost/libs/serialization/test/test_shared_ptr_multi_base.cpp302
1 files changed, 302 insertions, 0 deletions
diff --git a/src/boost/libs/serialization/test/test_shared_ptr_multi_base.cpp b/src/boost/libs/serialization/test/test_shared_ptr_multi_base.cpp
new file mode 100644
index 000000000..2ebab9816
--- /dev/null
+++ b/src/boost/libs/serialization/test/test_shared_ptr_multi_base.cpp
@@ -0,0 +1,302 @@
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// test_shared_ptr_multi_base.cpp
+
+// (C) Copyright 2002 Robert Ramey- http://www.rrsd.com and Takatoshi Kondo.
+// 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)
+//
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <cstddef> // NULL
+#include <cstdio> // remove
+#include <fstream>
+
+#include <boost/config.hpp>
+#if defined(BOOST_NO_STDC_NAMESPACE)
+namespace std{
+ using ::remove;
+}
+#endif
+
+#include <boost/serialization/nvp.hpp>
+#include <boost/serialization/export.hpp>
+
+#include <boost/serialization/shared_ptr.hpp>
+#include <boost/serialization/weak_ptr.hpp>
+
+#include "test_tools.hpp"
+
+struct Base1 {
+ Base1() {}
+ Base1(int x) : m_x(1 + x) {}
+ virtual ~Base1(){
+ }
+ int m_x;
+ // serialize
+ friend class boost::serialization::access;
+ template<class Archive>
+ void serialize(Archive &ar, const unsigned int /* file_version */)
+ {
+ ar & BOOST_SERIALIZATION_NVP(m_x);
+ }
+};
+
+struct Base2 {
+ Base2() {}
+ Base2(int x) : m_x(2 + x) {}
+ int m_x;
+ virtual ~Base2(){
+ }
+ // serialize
+ friend class boost::serialization::access;
+ template<class Archive>
+ void serialize(Archive &ar, const unsigned int /* file_version */)
+ {
+ ar & BOOST_SERIALIZATION_NVP(m_x);
+ }
+};
+
+struct Base3 {
+ Base3() {}
+ Base3(int x) : m_x(3 + x) {}
+ virtual ~Base3(){
+ }
+ int m_x;
+ // serialize
+ friend class boost::serialization::access;
+ template<class Archive>
+ void serialize(Archive &ar, const unsigned int /* file_version */)
+ {
+ ar & BOOST_SERIALIZATION_NVP(m_x);
+ }
+};
+
+// Sub is a subclass of Base1, Base1 and Base3.
+struct Sub:public Base1, public Base2, public Base3 {
+ static int count;
+ Sub() {
+ ++count;
+ }
+ Sub(int x) :
+ Base1(x),
+ Base2(x),
+ m_x(x)
+ {
+ ++count;
+ }
+ Sub(const Sub & rhs) :
+ m_x(rhs.m_x)
+ {
+ ++count;
+ }
+ virtual ~Sub() {
+ assert(0 < count);
+ --count;
+ }
+ int m_x;
+ // serialize
+ friend class boost::serialization::access;
+ template<class Archive>
+ void serialize(Archive &ar, const unsigned int /* file_version */)
+ {
+ ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base1);
+ ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base2);
+ ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base3);
+ ar & BOOST_SERIALIZATION_NVP(m_x);
+ }
+};
+
+// Sub needs to be exported because its serialized via a base class pointer
+BOOST_CLASS_EXPORT(Sub)
+BOOST_SERIALIZATION_SHARED_PTR(Sub)
+
+int Sub::count = 0;
+
+template <class FIRST, class SECOND>
+void save2(
+ const char * testfile,
+ const FIRST& first,
+ const SECOND& second
+){
+ test_ostream os(testfile, TEST_STREAM_FLAGS);
+ test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
+ oa << BOOST_SERIALIZATION_NVP(first);
+ oa << BOOST_SERIALIZATION_NVP(second);
+}
+
+template <class FIRST, class SECOND>
+void load2(
+ const char * testfile,
+ FIRST& first,
+ SECOND& second)
+{
+ test_istream is(testfile, TEST_STREAM_FLAGS);
+ test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
+ ia >> BOOST_SERIALIZATION_NVP(first);
+ ia >> BOOST_SERIALIZATION_NVP(second);
+}
+
+// Run tests by serializing two shared_ptrs into an archive,
+// clearing them (deleting the objects) and then reloading the
+// objects back from an archive.
+
+template<class T, class U>
+boost::shared_ptr<T> dynamic_pointer_cast(boost::shared_ptr<U> const & u)
+BOOST_NOEXCEPT
+{
+ return boost::dynamic_pointer_cast<T>(u);
+}
+
+#ifndef BOOST_NO_CXX11_SMART_PTR
+template<class T, class U>
+std::shared_ptr<T> dynamic_pointer_cast(std::shared_ptr<U> const & u)
+BOOST_NOEXCEPT
+{
+ return std::dynamic_pointer_cast<T>(u);
+}
+#endif
+
+// Serialization sequence
+// First, shared_ptr
+// Second, weak_ptr
+template <class SP, class WP>
+void shared_weak(
+ SP & first,
+ WP & second
+){
+ const char * testfile = boost::archive::tmpnam(NULL);
+ BOOST_REQUIRE(NULL != testfile);
+ int firstm = first->m_x;
+
+ BOOST_REQUIRE(! second.expired());
+ int secondm = second.lock()->m_x;
+ save2(testfile, first, second);
+
+ // Clear the pointers, thereby destroying the objects they contain
+ second.reset();
+ first.reset();
+
+ load2(testfile, first, second);
+ BOOST_CHECK(! second.expired());
+
+ // Check data member
+ BOOST_CHECK(firstm == first->m_x);
+ BOOST_CHECK(secondm == second.lock()->m_x);
+ // Check pointer to vtable
+ BOOST_CHECK(::dynamic_pointer_cast<Sub>(first));
+ BOOST_CHECK(::dynamic_pointer_cast<Sub>(second.lock()));
+
+ std::remove(testfile);
+}
+
+// Serialization sequence
+// First, weak_ptr
+// Second, shared_ptr
+template <class WP, class SP>
+void weak_shared(
+ WP & first,
+ SP & second
+){
+ const char * testfile = boost::archive::tmpnam(NULL);
+ BOOST_REQUIRE(NULL != testfile);
+ BOOST_CHECK(! first.expired());
+ int firstm = first.lock()->m_x;
+ int secondm = second->m_x;
+ save2(testfile, first, second);
+
+ // Clear the pointers, thereby destroying the objects they contain
+ first.reset();
+ second.reset();
+
+ load2(testfile, first, second);
+ BOOST_CHECK(! first.expired());
+
+ // Check data member
+ BOOST_CHECK(firstm == first.lock()->m_x);
+ BOOST_CHECK(secondm == second->m_x);
+ // Check pointer to vtable
+ BOOST_CHECK(::dynamic_pointer_cast<Sub>(first.lock()));
+ BOOST_CHECK(::dynamic_pointer_cast<Sub>(second));
+
+ std::remove(testfile);
+}
+
+// This does the tests
+template<template<class T> class SPT, template<class T> class WPT>
+bool test(){
+ // Both Sub
+ SPT<Sub> tc1_sp(new Sub(10));
+ WPT<Sub> tc1_wp(tc1_sp);
+ shared_weak(tc1_sp, tc1_wp);
+ weak_shared(tc1_wp, tc1_sp);
+ tc1_sp.reset();
+ BOOST_CHECK(0 == Sub::count);
+
+ // Sub and Base1
+ SPT<Sub> tc2_sp(new Sub(10));
+ WPT<Base1> tc2_wp(tc2_sp);
+ shared_weak(tc2_sp, tc2_wp);
+ weak_shared(tc2_wp, tc2_sp);
+ tc2_sp.reset();
+ BOOST_CHECK(0 == Sub::count);
+
+ // Sub and Base2
+ SPT<Sub> tc3_sp(new Sub(10));
+ WPT<Base2> tc3_wp(tc3_sp);
+ shared_weak(tc3_sp, tc3_wp);
+ weak_shared(tc3_wp, tc3_sp);
+ tc3_sp.reset();
+ BOOST_CHECK(0 == Sub::count);
+
+ // Sub and Base3
+ SPT<Sub> tc4_sp(new Sub(10));
+ WPT<Base3> tc4_wp(tc4_sp);
+ shared_weak(tc4_sp, tc4_wp);
+ weak_shared(tc4_wp, tc4_sp);
+ tc4_sp.reset();
+ BOOST_CHECK(0 == Sub::count);
+
+ // Base1 and Base2
+ SPT<Sub> tc5_sp_tmp(new Sub(10));
+ SPT<Base1> tc5_sp(tc5_sp_tmp);
+ WPT<Base2> tc5_wp(tc5_sp_tmp);
+ tc5_sp_tmp.reset();
+ shared_weak(tc5_sp, tc5_wp);
+ weak_shared(tc5_wp, tc5_sp);
+ tc5_sp.reset();
+ BOOST_CHECK(0 == Sub::count);
+
+ // Base2 and Base3
+ SPT<Sub> tc6_sp_tmp(new Sub(10));
+ SPT<Base2> tc6_sp(tc6_sp_tmp);
+ WPT<Base3> tc6_wp(tc6_sp_tmp);
+ tc6_sp_tmp.reset();
+ shared_weak(tc6_sp, tc6_wp);
+ weak_shared(tc6_wp, tc6_sp);
+ tc6_sp.reset();
+ BOOST_CHECK(0 == Sub::count);
+
+ // Base3 and Base1
+ SPT<Sub> tc7_sp_tmp(new Sub(10));
+ SPT<Base3> tc7_sp(tc7_sp_tmp);
+ WPT<Base1> tc7_wp(tc7_sp_tmp);
+ tc7_sp_tmp.reset();
+ shared_weak(tc7_sp, tc7_wp);
+ weak_shared(tc7_wp, tc7_sp);
+ tc7_sp.reset();
+ BOOST_CHECK(0 == Sub::count);
+
+ return true;
+}
+
+// This does the tests
+int test_main(int /* argc */, char * /* argv */[])
+{
+ bool result = true;
+ result &= test<boost::shared_ptr, boost::weak_ptr>();
+ #ifndef BOOST_NO_CXX11_SMART_PTR
+ result &= test<std::shared_ptr, std::weak_ptr>();
+ #endif
+ return result ? EXIT_SUCCESS : EXIT_FAILURE;
+}