• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <boost/math/special_functions/next.hpp>
23 
24 #if defined(BOOST_NO_STDC_NAMESPACE)
25 namespace std{
26     using ::rand;
27     using ::remove;
28     #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
29         using ::numeric_limits;
30     #endif
31 }
32 #endif
33 
34 #include <boost/archive/archive_exception.hpp>
35 #include "test_tools.hpp"
36 
37 ///////////////////////////////////////////////////////
38 // simple class test - using non-intrusive syntax
39 // illustrates the usage of the non-intrusve syntax
40 class A
41 {
42     friend class boost::serialization::access;
43 
44     // note const values can only be initialized with a non
45     // non-default constructor
46     const int i;
47 
48     signed char s;
49     unsigned char t;
50     signed int u;
51     unsigned int v;
52     float w;
53     double x;
54     bool operator==(const A & rhs) const;
55     bool operator<(const A & rhs) const;
56 
57     template<class Archive>
serialize(Archive & ar,const unsigned int)58     void serialize(Archive & ar,const unsigned int /* file_version */){
59         ar & BOOST_SERIALIZATION_NVP(s);
60         ar & BOOST_SERIALIZATION_NVP(t);
61         ar & BOOST_SERIALIZATION_NVP(u);
62         ar & BOOST_SERIALIZATION_NVP(v);
63         ar & BOOST_SERIALIZATION_NVP(w);
64         ar & BOOST_SERIALIZATION_NVP(x);
65     }
66     A(const A & rhs);
67     A & operator=(const A & rhs);
68 public:
69     static int count;
get_i() const70     const int & get_i() const {
71         return i;
72     }
73     A(int i_);
74     ~A();
75 };
76 
77 int A::count = 0;
78 
A(int i_)79 A::A(int i_) :
80     i(i_),
81     s(static_cast<signed char>(0xff & std::rand())),
82     t(static_cast<signed char>(0xff & std::rand())),
83     u(std::rand()),
84     v(std::rand()),
85     w((float)std::rand() / std::rand()),
86     x((double)std::rand() / std::rand())
87 {
88     ++count;
89 }
90 
~A()91 A::~A(){
92     --count;
93 }
94 
operator ==(const A & rhs) const95 bool A::operator==(const A &rhs) const
96 {
97     return
98         s == rhs.s
99         && t == rhs.t
100         && u == rhs.u
101         && v == rhs.v
102         && std::abs( boost::math::float_distance(w, rhs.w)) < 2
103         && std::abs( boost::math::float_distance(x, rhs.x)) < 2
104     ;
105 }
106 
operator <(const A & rhs) const107 bool A::operator<(const A &rhs) const
108 {
109     if(! (s == rhs.s) )
110         return s < rhs.s;
111     if(! (t == rhs.t) )
112         return t < rhs.t;
113     if(! (u == rhs.u) )
114         return t < rhs.u;
115     if(! (v == rhs.v) )
116         return t < rhs.v;
117     if(std::abs( boost::math::float_distance(w, rhs.w)) > 1)
118         return false;
119     if(std::abs( boost::math::float_distance(x, rhs.x)) > 1)
120         return false;
121     return false;
122 }
123 
124 namespace boost {
125 namespace serialization {
126 
127 template<class Archive>
save_construct_data(Archive & ar,const A * a,const unsigned int)128 inline void save_construct_data(
129     Archive & ar,
130     const A * a,
131     const unsigned int /* file_version */
132 ){
133     // variable used for construction
134     ar << boost::serialization::make_nvp("i", a->get_i());
135 }
136 
137 template<class Archive>
load_construct_data(Archive & ar,A * a,const unsigned int)138 inline void load_construct_data(
139     Archive & ar,
140     A * a,
141     const unsigned int /* file_version */
142 ){
143     int i;
144     ar >> boost::serialization::make_nvp("i", i);
145     ::new(a)A(i);
146 }
147 
148 } // serialization
149 } // namespace boost
150 
save(const char * testfile)151 void save(const char * testfile){
152     test_ostream os(testfile, TEST_STREAM_FLAGS);
153     test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
154     A a(2);
155 
156     oa << BOOST_SERIALIZATION_NVP(a);
157 
158     // save a copy pointer to this item
159     A *pa1 = &a;
160     oa << BOOST_SERIALIZATION_NVP(pa1);
161 
162     // save pointer to a new object
163     A *pa2 = new A(4);
164     oa << BOOST_SERIALIZATION_NVP(pa2);
165 
166     delete pa2;
167 }
load(const char * testfile)168 void load(const char * testfile){
169     test_istream is(testfile, TEST_STREAM_FLAGS);
170     test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
171 
172     A a(4);
173     ia >> BOOST_SERIALIZATION_NVP(a);
174 
175     A *pa1;
176     ia >> BOOST_SERIALIZATION_NVP(pa1);
177     BOOST_CHECK_MESSAGE(pa1 == &a, "Copy of pointer not correctly restored");
178 
179     A *pa2;
180     ia >> BOOST_SERIALIZATION_NVP(pa2);
181     BOOST_CHECK_MESSAGE(pa2 != &a, "Pointer not correctly restored");
182 
183     delete pa2;
184 }
185 
186 int
test_main(int,char * [])187 test_main( int /* argc */, char* /* argv */[] )
188 {
189     const char * testfile = boost::archive::tmpnam(NULL);
190     BOOST_REQUIRE(NULL != testfile);
191     save(testfile);
192     load(testfile);
193     BOOST_CHECK(0 == A::count);
194     std::remove(testfile);
195     return EXIT_SUCCESS;
196 }
197 
198 // EOF
199