| /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 |
| // test_non_intrursive.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 |
| |
| // this tests: |
| // a) non-intrusive method of implementing serialization |
| // b) usage of a non-default constructor |
| |
| #include <fstream> |
| #include <cstdlib> // for rand() |
| #include <cstdio> // remove |
| #include <cmath> // for fabs() |
| #include <limits> |
| |
| #include <boost/config.hpp> |
| #if defined(BOOST_NO_STDC_NAMESPACE) |
| namespace std{ |
| using ::rand; |
| using ::fabs; |
| using ::remove; |
| #ifndef UNDER_CE |
| using ::numeric_limits; |
| #endif |
| } |
| #endif |
| |
| #include <boost/archive/archive_exception.hpp> |
| #include "test_tools.hpp" |
| |
| /////////////////////////////////////////////////////// |
| // simple class test - using non-intrusive syntax |
| // illustrates the usage of the non-intrusve syntax |
| class A |
| { |
| public: |
| signed char s; |
| unsigned char t; |
| signed int u; |
| unsigned int v; |
| float w; |
| double x; |
| A(); |
| bool operator==(const A & rhs) const; |
| bool operator<(const A & rhs) const; |
| }; |
| |
| A::A() : |
| s(static_cast<signed char>(0xff & std::rand())), |
| t(static_cast<signed char>(0xff & std::rand())), |
| u(std::rand()), |
| v(std::rand()), |
| w((float)std::rand() / std::rand()), |
| x((double)std::rand() / std::rand()) |
| { |
| } |
| |
| bool A::operator==(const A &rhs) const |
| { |
| return |
| s == rhs.s |
| && t == rhs.t |
| && u == rhs.u |
| && v == rhs.v |
| && std::fabs(w - rhs.w) <= std::numeric_limits<float>::round_error() |
| && std::fabs(x - rhs.x) <= std::numeric_limits<float>::round_error() |
| ; |
| } |
| |
| bool A::operator<(const A &rhs) const |
| { |
| if(! (s == rhs.s) ) |
| return s < rhs.s; |
| if(! (t == rhs.t) ) |
| return t < rhs.t; |
| if(! (u == rhs.u) ) |
| return t < rhs.u; |
| if(! (v == rhs.v) ) |
| return t < rhs.v; |
| if(! (std::fabs(w - rhs.w) < std::numeric_limits<float>::round_error() ) ) |
| return t < rhs.w; |
| if(! (std::fabs(x - rhs.x) < std::numeric_limits<float>::round_error() ) ) |
| return t < rhs.x; |
| return false; |
| } |
| |
| // note the following: |
| |
| // function specializations must be defined in the appropriate |
| // namespace - boost::serialization |
| namespace boost { |
| namespace serialization { |
| |
| // This first set of overrides should work with all compilers. |
| |
| // The last argument is int while the default versions |
| // defined in serialization.hpp have long as the last argument. |
| // This is part of the work around for compilers that don't |
| // support correct function template ordering. These functions |
| // are always called with 0 (i.e. an int) as the last argument. |
| // Our specialized versions also have int as the last argument |
| // while the default versions have a long as the last argument. |
| // This makes our specialized versions a better match than the |
| // default ones as no argument conversion is required to make a match |
| template<class Archive> |
| void serialize( |
| Archive & ar, |
| A & a, |
| const unsigned int /* file_version */ |
| ){ |
| ar & boost::serialization::make_nvp("s", a.s); |
| ar & boost::serialization::make_nvp("t", a.t); |
| ar & boost::serialization::make_nvp("u", a.u); |
| ar & boost::serialization::make_nvp("v", a.v); |
| ar & boost::serialization::make_nvp("w", a.w); |
| ar & boost::serialization::make_nvp("x", a.x); |
| } |
| |
| } // serialization |
| } // namespace boost |
| |
| void save(const char * testfile){ |
| test_ostream os(testfile, TEST_STREAM_FLAGS); |
| test_oarchive oa(os, TEST_ARCHIVE_FLAGS); |
| A a; |
| |
| oa << BOOST_SERIALIZATION_NVP(a); |
| |
| // save a copy pointer to this item |
| A *pa1 = &a; |
| oa << BOOST_SERIALIZATION_NVP(pa1); |
| |
| // save pointer to a new object |
| A *pa2 = new A(); |
| oa << BOOST_SERIALIZATION_NVP(pa2); |
| |
| delete pa2; |
| } |
| |
| void load(const char * testfile){ |
| test_istream is(testfile, TEST_STREAM_FLAGS); |
| test_iarchive ia(is, TEST_ARCHIVE_FLAGS); |
| |
| A a; |
| ia >> BOOST_SERIALIZATION_NVP(a); |
| |
| A *pa1; |
| ia >> BOOST_SERIALIZATION_NVP(pa1); |
| BOOST_CHECK_MESSAGE(pa1 == &a, "Copy of pointer not correctly restored"); |
| |
| A *pa2; |
| ia >> BOOST_SERIALIZATION_NVP(pa2); |
| BOOST_CHECK_MESSAGE(pa2 != &a, "Pointer not correctly restored"); |
| |
| delete pa2; |
| } |
| |
| int |
| test_main( int /* argc */, char* /* argv */[] ) |
| { |
| const char * testfile = boost::archive::tmpnam(NULL); |
| BOOST_REQUIRE(NULL != testfile); |
| save(testfile); |
| load(testfile); |
| std::remove(testfile); |
| return EXIT_SUCCESS; |
| } |
| |
| // EOF |