summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/serialization/test/test_cyclic_ptrs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/serialization/test/test_cyclic_ptrs.cpp')
-rw-r--r--src/boost/libs/serialization/test/test_cyclic_ptrs.cpp204
1 files changed, 204 insertions, 0 deletions
diff --git a/src/boost/libs/serialization/test/test_cyclic_ptrs.cpp b/src/boost/libs/serialization/test/test_cyclic_ptrs.cpp
new file mode 100644
index 000000000..cce8b6f9b
--- /dev/null
+++ b/src/boost/libs/serialization/test/test_cyclic_ptrs.cpp
@@ -0,0 +1,204 @@
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// test_cyclic_ptrs.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)
+
+// should pass compilation and execution
+
+#include <cstddef> // NULL
+#include <fstream>
+
+#include <cstdio> // remove
+#include <boost/config.hpp>
+#if defined(BOOST_NO_STDC_NAMESPACE)
+namespace std{
+ using ::remove;
+}
+#endif
+
+#include "test_tools.hpp"
+#include <boost/core/no_exceptions_support.hpp>
+
+#include <boost/serialization/nvp.hpp>
+#include <boost/serialization/version.hpp>
+#include <boost/serialization/base_object.hpp>
+
+#include "A.hpp"
+#include "A.ipp"
+
+///////////////////////////////////////////////////////
+// class with a member which refers to itself
+class J : public A
+{
+private:
+ friend class boost::serialization::access;
+ template<class Archive>
+ void serialize(Archive &ar, const unsigned int /* file_version */){
+ ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
+ ar & BOOST_SERIALIZATION_NVP(j);
+ }
+public:
+ bool operator==(const J &rhs) const;
+ J *j;
+ J(J *_j) : j(_j) {}
+ J() : j(NULL){}
+};
+
+BOOST_CLASS_VERSION(J, 6)
+
+bool J::operator==(const J &rhs) const
+{
+ return static_cast<const A &>(*this) == static_cast<const A &>(rhs);
+}
+
+///////////////////////////////////////////////////////
+// class with members that refer to each other
+// this is an example of a class that, as written, cannot
+// be serialized with this system. The problem is that the
+// serialization of the first member - j1 , provokes serialization
+// of those objects which it points to either directly or indirectly.
+// When those objects are subsequently serialized, it is discovered
+// that have already been serialized through pointers. This is
+// detected by the system and an exception - pointer_conflict -
+// is thrown. Permiting this to go undetected would result in the
+// creation of multiple equal objects rather than the original
+// structure.
+class K
+{
+ J j1;
+ J j2;
+ J j3;
+ friend class boost::serialization::access;
+ template<class Archive>
+ void serialize(
+ Archive &ar,
+ const unsigned int /* file_version */
+ ){
+ ar & BOOST_SERIALIZATION_NVP(j1);
+ ar & BOOST_SERIALIZATION_NVP(j2);
+ ar & BOOST_SERIALIZATION_NVP(j3);
+ }
+public:
+ bool operator==(const K &rhs) const;
+ K();
+};
+
+K::K()
+: j1(&j2), j2(&j3), j3(&j1)
+{
+}
+
+bool K::operator==(const K &rhs) const
+{
+ return
+ j1.j == & j2
+ && j2.j == & j3
+ && j3.j == & j1
+ && j1 == rhs.j1
+ && j2 == rhs.j2
+ && j3 == rhs.j3
+ ;
+}
+
+int test1(){
+ const char * testfile = boost::archive::tmpnam(NULL);
+ BOOST_REQUIRE(NULL != testfile);
+
+ J j1, j2;
+ {
+ test_ostream os(testfile, TEST_STREAM_FLAGS);
+ test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
+ oa << BOOST_SERIALIZATION_NVP(j1);
+ }
+ {
+ // try to read the archive
+ test_istream is(testfile, TEST_STREAM_FLAGS);
+ test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
+ ia >> BOOST_SERIALIZATION_NVP(j2);
+ }
+ BOOST_CHECK(j1 == j2);
+ std::remove(testfile);
+ return EXIT_SUCCESS;
+}
+
+int test2(){
+ const char * testfile = boost::archive::tmpnam(NULL);
+ BOOST_REQUIRE(NULL != testfile);
+
+ J *j1 = new J;
+ j1->j = j1;
+ J *j2 = reinterpret_cast<J *>(0xBAADF00D);
+ {
+ test_ostream os(testfile, TEST_STREAM_FLAGS);
+ test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
+ oa << BOOST_SERIALIZATION_NVP(j1);
+ }
+ {
+ // try to read the archive
+ test_istream is(testfile, TEST_STREAM_FLAGS);
+ test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
+ ia >> BOOST_SERIALIZATION_NVP(j2);
+ }
+ BOOST_CHECK(*j1 == *j2);
+ delete j1;
+ BOOST_CHECK(j2 == j2->j);
+ std::remove(testfile);
+ return EXIT_SUCCESS;
+}
+
+int test3(){
+ const char * testfile = boost::archive::tmpnam(NULL);
+ BOOST_REQUIRE(NULL != testfile);
+
+ K k;
+ boost::archive::archive_exception exception(
+ boost::archive::archive_exception::no_exception
+ );
+ {
+ test_ostream os(testfile, TEST_STREAM_FLAGS);
+ test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
+ BOOST_TRY {
+ oa << BOOST_SERIALIZATION_NVP(k);
+ }
+ BOOST_CATCH (boost::archive::archive_exception const& ae){
+ exception = ae;
+ }
+ BOOST_CATCH_END
+ BOOST_CHECK(
+ exception.code == boost::archive::archive_exception::pointer_conflict
+ );
+ }
+ // if exception wasn't invoked
+ if(exception.code == boost::archive::archive_exception::no_exception){
+ // try to read the archive
+ test_istream is(testfile, TEST_STREAM_FLAGS);
+ test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
+ exception = boost::archive::archive_exception(
+ boost::archive::archive_exception::no_exception
+ );
+ BOOST_TRY {
+ ia >> BOOST_SERIALIZATION_NVP(k);
+ }
+ BOOST_CATCH (boost::archive::archive_exception const& ae){
+ exception = ae;
+ }
+ BOOST_CATCH_END
+ BOOST_CHECK(
+ exception.code == boost::archive::archive_exception::pointer_conflict
+ );
+ }
+ std::remove(testfile);
+ return EXIT_SUCCESS;
+}
+
+int test_main( int /* argc */, char* /* argv */[] ){
+ test1();
+ test2();
+ test3();
+ return EXIT_SUCCESS;
+}
+
+// EOF