1/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
2// test_non_intrursive.cpp
3
4// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
5// Use, modification and distribution is subject to the Boost Software
6// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8
9// should pass compilation and execution
10
11// this tests:
12// a) non-intrusive method of implementing serialization
13// b) usage of a non-default constructor
14
15#include <fstream>
16#include <cstdlib> // for rand()
17#include <cstdio> // remove
18#include <boost/config.hpp>
19#include <boost/detail/workaround.hpp>
20#include <boost/limits.hpp>
21#if BOOST_CXX_VERSION > 199711L // only include floating point if C++ version >= C++11
22#include <boost/math/special_functions/next.hpp>
23#endif
24
25#if defined(BOOST_NO_STDC_NAMESPACE)
26namespace std{
27 using ::rand;
28 using ::remove;
29 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
30 using ::numeric_limits;
31 #endif
32}
33#endif
34
35#include <boost/archive/archive_exception.hpp>
36#include "test_tools.hpp"
37
38///////////////////////////////////////////////////////
39// simple class test - using non-intrusive syntax
40// illustrates the usage of the non-intrusive syntax
41class A
42{
43public:
44 signed char s;
45 unsigned char t;
46 signed int u;
47 unsigned int v;
48 float w;
49 double x;
50 A();
51 bool operator==(const A & rhs) const;
52 bool operator<(const A & rhs) const;
53};
54
55A::A() :
56 s(static_cast<signed char>(0xff & std::rand())),
57 t(static_cast<signed char>(0xff & std::rand())),
58 u(std::rand()),
59 v(std::rand()),
60 w((float)std::rand() / std::rand()),
61 x((double)std::rand() / std::rand())
62{
63}
64
65bool A::operator==(const A &rhs) const
66{
67 return
68 s == rhs.s
69 && t == rhs.t
70 && u == rhs.u
71 && v == rhs.v
72 #if BOOST_CXX_VERSION > 199711L // only include floating point if C++ version >= C++11
73 && std::abs( x: boost::math::float_distance(a: w, b: rhs.w)) < 2
74 && std::abs( x: boost::math::float_distance(a: x, b: rhs.x)) < 2
75 #endif
76 ;
77}
78
79bool A::operator<(const A &rhs) const
80{
81 if(! (s == rhs.s) )
82 return s < rhs.s;
83 if(! (t == rhs.t) )
84 return t < rhs.t;
85 if(! (u == rhs.u) )
86 return t < rhs.u;
87 if(! (v == rhs.v) )
88 return t < rhs.v;
89 #if BOOST_CXX_VERSION > 199711L // only include floating point if C++ version >= C++11
90 if(std::abs( x: boost::math::float_distance(a: w, b: rhs.w)) > 1)
91 return false;
92 if(std::abs( x: boost::math::float_distance(a: x, b: rhs.x)) > 1)
93 return false;
94 #endif
95 return false;
96}
97
98// note the following:
99
100// function specializations must be defined in the appropriate
101// namespace - boost::serialization
102namespace boost {
103namespace serialization {
104
105// This first set of overrides should work with all compilers.
106
107// The last argument is int while the default versions
108// defined in serialization.hpp have long as the last argument.
109// This is part of the work around for compilers that don't
110// support correct function template ordering. These functions
111// are always called with 0 (i.e. an int) as the last argument.
112// Our specialized versions also have int as the last argument
113// while the default versions have a long as the last argument.
114// This makes our specialized versions a better match than the
115// default ones as no argument conversion is required to make a match
116template<class Archive>
117void serialize(
118 Archive & ar,
119 A & a,
120 const unsigned int /* file_version */
121){
122 ar & boost::serialization::make_nvp(n: "s", v&: a.s);
123 ar & boost::serialization::make_nvp(n: "t", v&: a.t);
124 ar & boost::serialization::make_nvp(n: "u", v&: a.u);
125 ar & boost::serialization::make_nvp(n: "v", v&: a.v);
126 ar & boost::serialization::make_nvp(n: "w", v&: a.w);
127 ar & boost::serialization::make_nvp(n: "x", v&: a.x);
128}
129
130} // serialization
131} // namespace boost
132
133void save(const char * testfile){
134 test_ostream os(testfile, TEST_STREAM_FLAGS);
135 test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
136 A a;
137
138 oa << BOOST_SERIALIZATION_NVP(a);
139
140 // save a copy pointer to this item
141 A *pa1 = &a;
142 oa << BOOST_SERIALIZATION_NVP(pa1);
143
144 // save pointer to a new object
145 A *pa2 = new A();
146 oa << BOOST_SERIALIZATION_NVP(pa2);
147
148 delete pa2;
149}
150
151void load(const char * testfile){
152 test_istream is(testfile, TEST_STREAM_FLAGS);
153 test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
154
155 A a;
156 ia >> BOOST_SERIALIZATION_NVP(a);
157
158 A *pa1;
159 ia >> BOOST_SERIALIZATION_NVP(pa1);
160 BOOST_CHECK_MESSAGE(pa1 == &a, "Copy of pointer not correctly restored");
161
162 A *pa2;
163 ia >> BOOST_SERIALIZATION_NVP(pa2);
164 BOOST_CHECK_MESSAGE(pa2 != &a, "Pointer not correctly restored");
165
166 delete pa2;
167}
168
169int
170test_main( int /* argc */, char* /* argv */[] )
171{
172 const char * testfile = boost::archive::tmpnam(NULL);
173 BOOST_REQUIRE(NULL != testfile);
174 save(testfile);
175 load(testfile);
176 std::remove(filename: testfile);
177 return EXIT_SUCCESS;
178}
179
180// EOF
181

source code of boost/libs/serialization/test/test_non_intrusive.cpp