• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <boost/math/special_functions/next.hpp>
22 
23 #if defined(BOOST_NO_STDC_NAMESPACE)
24 namespace std{
25     using ::rand;
26     using ::remove;
27     #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
28         using ::numeric_limits;
29     #endif
30 }
31 #endif
32 
33 #include <boost/archive/archive_exception.hpp>
34 #include "test_tools.hpp"
35 
36 ///////////////////////////////////////////////////////
37 // simple class test - using non-intrusive syntax
38 // illustrates the usage of the non-intrusve syntax
39 class A
40 {
41 public:
42     signed char s;
43     unsigned char t;
44     signed int u;
45     unsigned int v;
46     float w;
47     double x;
48     A();
49     bool operator==(const A & rhs) const;
50     bool operator<(const A & rhs) const;
51 };
52 
A()53 A::A() :
54     s(static_cast<signed char>(0xff & std::rand())),
55     t(static_cast<signed char>(0xff & std::rand())),
56     u(std::rand()),
57     v(std::rand()),
58     w((float)std::rand() / std::rand()),
59     x((double)std::rand() / std::rand())
60 {
61 }
62 
operator ==(const A & rhs) const63 bool A::operator==(const A &rhs) const
64 {
65     return
66         s == rhs.s
67         && t == rhs.t
68         && u == rhs.u
69         && v == rhs.v
70         && std::abs( boost::math::float_distance(w, rhs.w)) < 2
71         && std::abs( boost::math::float_distance(x, rhs.x)) < 2
72     ;
73 }
74 
operator <(const A & rhs) const75 bool A::operator<(const A &rhs) const
76 {
77     if(! (s == rhs.s) )
78         return s < rhs.s;
79     if(! (t == rhs.t) )
80         return t < rhs.t;
81     if(! (u == rhs.u) )
82         return t < rhs.u;
83     if(! (v == rhs.v) )
84         return t < rhs.v;
85     if(std::abs( boost::math::float_distance(w, rhs.w)) > 1)
86         return false;
87     if(std::abs( boost::math::float_distance(x, rhs.x)) > 1)
88         return false;
89     return false;
90 }
91 
92 // note the following:
93 
94 // function specializations must be defined in the appropriate
95 // namespace - boost::serialization
96 namespace boost {
97 namespace serialization {
98 
99 // This first set of overrides should work with all compilers.
100 
101 // The last argument is int while the default versions
102 // defined in serialization.hpp have long as the last argument.
103 // This is part of the work around for compilers that don't
104 // support correct function template ordering.  These functions
105 // are always called with 0 (i.e. an int) as the last argument.
106 // Our specialized versions also have int as the last argument
107 // while the default versions have a long as the last argument.
108 // This makes our specialized versions a better match than the
109 // default ones as no argument conversion is required to make a match
110 template<class Archive>
serialize(Archive & ar,A & a,const unsigned int)111 void serialize(
112     Archive & ar,
113     A & a,
114     const unsigned int /* file_version */
115 ){
116     ar & boost::serialization::make_nvp("s", a.s);
117     ar & boost::serialization::make_nvp("t", a.t);
118     ar & boost::serialization::make_nvp("u", a.u);
119     ar & boost::serialization::make_nvp("v", a.v);
120     ar & boost::serialization::make_nvp("w", a.w);
121     ar & boost::serialization::make_nvp("x", a.x);
122 }
123 
124 } // serialization
125 } // namespace boost
126 
save(const char * testfile)127 void save(const char * testfile){
128     test_ostream os(testfile, TEST_STREAM_FLAGS);
129     test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
130     A a;
131 
132     oa << BOOST_SERIALIZATION_NVP(a);
133 
134     // save a copy pointer to this item
135     A *pa1 = &a;
136     oa << BOOST_SERIALIZATION_NVP(pa1);
137 
138     // save pointer to a new object
139     A *pa2 = new A();
140     oa << BOOST_SERIALIZATION_NVP(pa2);
141 
142     delete pa2;
143 }
144 
load(const char * testfile)145 void load(const char * testfile){
146     test_istream is(testfile, TEST_STREAM_FLAGS);
147     test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
148 
149     A a;
150     ia >> BOOST_SERIALIZATION_NVP(a);
151 
152     A *pa1;
153     ia >> BOOST_SERIALIZATION_NVP(pa1);
154     BOOST_CHECK_MESSAGE(pa1 == &a, "Copy of pointer not correctly restored");
155 
156     A *pa2;
157     ia >> BOOST_SERIALIZATION_NVP(pa2);
158     BOOST_CHECK_MESSAGE(pa2 != &a, "Pointer not correctly restored");
159 
160     delete pa2;
161 }
162 
163 int
test_main(int,char * [])164 test_main( int /* argc */, char* /* argv */[] )
165 {
166     const char * testfile = boost::archive::tmpnam(NULL);
167     BOOST_REQUIRE(NULL != testfile);
168     save(testfile);
169     load(testfile);
170     std::remove(testfile);
171     return EXIT_SUCCESS;
172 }
173 
174 // EOF
175