1/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
2// test_non_default_ctor.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 <cstddef> // NULL
16#include <cstdio> // remove()
17#include <fstream>
18#include <cstdlib> // for rand()
19#include <boost/config.hpp>
20#include <boost/detail/workaround.hpp>
21#include <boost/limits.hpp>
22#if BOOST_CXX_VERSION > 199711L // only include floating point if C++ version >= C++11
23#include <boost/math/special_functions/next.hpp>
24#endif
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{
43 friend class boost::serialization::access;
44
45 // note const values can only be initialized with a non
46 // non-default constructor
47 const int i;
48
49 signed char s;
50 unsigned char t;
51 signed int u;
52 unsigned int v;
53 float w;
54 double x;
55 bool operator==(const A & rhs) const;
56 bool operator<(const A & rhs) const;
57
58 template<class Archive>
59 void serialize(Archive & ar,const unsigned int /* file_version */){
60 ar & BOOST_SERIALIZATION_NVP(s);
61 ar & BOOST_SERIALIZATION_NVP(t);
62 ar & BOOST_SERIALIZATION_NVP(u);
63 ar & BOOST_SERIALIZATION_NVP(v);
64 ar & BOOST_SERIALIZATION_NVP(w);
65 ar & BOOST_SERIALIZATION_NVP(x);
66 }
67 A(const A & rhs);
68 A & operator=(const A & rhs);
69public:
70 static int count;
71 const int & get_i() const {
72 return i;
73 }
74 A(int i_);
75 ~A();
76};
77
78int A::count = 0;
79
80A::A(int i_) :
81 i(i_),
82 s(static_cast<signed char>(0xff & std::rand())),
83 t(static_cast<signed char>(0xff & std::rand())),
84 u(std::rand()),
85 v(std::rand()),
86 w((float)std::rand() / std::rand()),
87 x((double)std::rand() / std::rand())
88{
89 ++count;
90}
91
92A::~A(){
93 --count;
94}
95
96bool A::operator==(const A &rhs) const
97{
98 return
99 s == rhs.s
100 && t == rhs.t
101 && u == rhs.u
102 && v == rhs.v
103 #if BOOST_CXX_VERSION > 199711L // only include floating point if C++ version >= C++11
104 && std::abs( x: boost::math::float_distance(a: w, b: rhs.w)) < 2
105 && std::abs( x: boost::math::float_distance(a: x, b: rhs.x)) < 2
106 #endif
107 ;
108}
109
110 bool A::operator<(const A &rhs) const
111{
112 if(! (s == rhs.s) )
113 return s < rhs.s;
114 if(! (t == rhs.t) )
115 return t < rhs.t;
116 if(! (u == rhs.u) )
117 return t < rhs.u;
118 if(! (v == rhs.v) )
119 return t < rhs.v;
120 #if BOOST_CXX_VERSION > 199711L // only include floating point if C++ version >= C++11
121 if(std::abs( x: boost::math::float_distance(a: w, b: rhs.w)) > 1)
122 return false;
123 if(std::abs( x: boost::math::float_distance(a: x, b: rhs.x)) > 1)
124 return false;
125 #endif
126 return false;
127}
128
129namespace boost {
130namespace serialization {
131
132template<class Archive>
133inline void save_construct_data(
134 Archive & ar,
135 const A * a,
136 const unsigned int /* file_version */
137){
138 // variable used for construction
139 ar << boost::serialization::make_nvp(n: "i", v: a->get_i());
140}
141
142template<class Archive>
143inline void load_construct_data(
144 Archive & ar,
145 A * a,
146 const unsigned int /* file_version */
147){
148 int i;
149 ar >> boost::serialization::make_nvp(n: "i", v&: i);
150 ::new(a)A(i);
151}
152
153} // serialization
154} // namespace boost
155
156void save(const char * testfile){
157 test_ostream os(testfile, TEST_STREAM_FLAGS);
158 test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
159 A a(2);
160
161 oa << BOOST_SERIALIZATION_NVP(a);
162
163 // save a copy pointer to this item
164 A *pa1 = &a;
165 oa << BOOST_SERIALIZATION_NVP(pa1);
166
167 // save pointer to a new object
168 A *pa2 = new A(4);
169 oa << BOOST_SERIALIZATION_NVP(pa2);
170
171 delete pa2;
172}
173void load(const char * testfile){
174 test_istream is(testfile, TEST_STREAM_FLAGS);
175 test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
176
177 A a(4);
178 ia >> BOOST_SERIALIZATION_NVP(a);
179
180 A *pa1;
181 ia >> BOOST_SERIALIZATION_NVP(pa1);
182 BOOST_CHECK_MESSAGE(pa1 == &a, "Copy of pointer not correctly restored");
183
184 A *pa2;
185 ia >> BOOST_SERIALIZATION_NVP(pa2);
186 BOOST_CHECK_MESSAGE(pa2 != &a, "Pointer not correctly restored");
187
188 delete pa2;
189}
190
191int
192test_main( int /* argc */, char* /* argv */[] )
193{
194 const char * testfile = boost::archive::tmpnam(NULL);
195 BOOST_REQUIRE(NULL != testfile);
196 save(testfile);
197 load(testfile);
198 BOOST_CHECK(0 == A::count);
199 std::remove(filename: testfile);
200 return EXIT_SUCCESS;
201}
202
203// EOF
204

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