Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/serialization/test/test_reset_object_address.cpp @ 33

Last change on this file since 33 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 8.6 KB
Line 
1/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
2// test_reset_object_address.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#include <sstream>
10#include <cassert>
11#include <cstdlib> // for rand()
12#include <cstddef> // size_t
13
14#include <boost/config.hpp>
15#if defined(BOOST_NO_STDC_NAMESPACE)
16namespace std{
17    using ::rand; 
18    using ::size_t;
19}
20#endif
21
22#include <boost/test/test_tools.hpp>
23
24#include <boost/archive/text_oarchive.hpp>
25#include <boost/archive/text_iarchive.hpp>
26#include <boost/archive/polymorphic_text_oarchive.hpp>
27#include <boost/archive/polymorphic_text_iarchive.hpp>
28
29#include <boost/serialization/list.hpp>
30#include <boost/serialization/access.hpp>
31
32// Someday, maybe all tests will be converted to the unit test framework.
33// but for now use the text execution monitor to be consistent with all
34// the other tests.
35
36// simple test of untracked value
37#include "A.hpp"
38
39void test1(){
40    std::stringstream ss;
41    const A a;
42    {
43        boost::archive::text_oarchive oa(ss);
44        oa << a;
45    }
46    A a1;
47    {
48        boost::archive::text_iarchive ia(ss);
49        // load to temporary
50        A a2;
51        ia >> a2;
52        BOOST_CHECK_EQUAL(a, a2);
53        // move to final destination
54        a1 = a2;
55        ia.reset_object_address(& a1, & a2);
56    }
57    BOOST_CHECK_EQUAL(a, a1);
58}
59
60// simple test of tracked value
61class B {
62    friend class boost::serialization::access;
63    int m_i;
64    template<class Archive>
65    void serialize(Archive &ar, const unsigned int file_version){
66        ar & m_i;
67    }
68public:
69    bool operator==(const B & rhs) const {
70        return m_i == rhs.m_i;
71    }
72    B() :
73        m_i(std::rand())
74    {}
75};
76
77BOOST_TEST_DONT_PRINT_LOG_VALUE( B )
78
79void test2(){
80    std::stringstream ss;
81    B const b;
82    B const * const b_ptr = & b;
83    BOOST_CHECK_EQUAL(& b, b_ptr);
84    {
85        boost::archive::text_oarchive oa(ss);
86        oa << b;
87        oa << b_ptr;
88    }
89    B b1;
90    B * b1_ptr;
91    {
92        boost::archive::text_iarchive ia(ss);
93        // load to temporary
94        B b2;
95        ia >> b2;
96        BOOST_CHECK_EQUAL(b, b2);
97        // move to final destination
98        b1 = b2;
99        ia.reset_object_address(& b1, & b2);
100        ia >> b1_ptr;
101    }
102    BOOST_CHECK_EQUAL(b, b1);
103    BOOST_CHECK_EQUAL(& b1, b1_ptr);
104}
105
106// check that nested member values are properly moved
107class D {
108    friend class boost::serialization::access;
109    template<class Archive>
110    void serialize(Archive &ar, const unsigned int file_version){
111        ar & m_b;
112    }
113public:
114    B m_b;
115    bool operator==(const D & rhs) const {
116        return m_b == rhs.m_b;
117    }
118    D(){}
119};
120
121BOOST_TEST_DONT_PRINT_LOG_VALUE( D )
122
123void test3(){
124    std::stringstream ss;
125    D const d;
126    B const * const b_ptr = & d.m_b;
127    {
128        boost::archive::text_oarchive oa(ss);
129        oa << d;
130        oa << b_ptr;
131    }
132    D d1;
133    B * b1_ptr;
134    {
135        boost::archive::text_iarchive ia(ss);
136        D d2;
137        ia >> d2;
138        d1 = d2;
139        ia.reset_object_address(& d1, & d2);
140        ia >> b1_ptr;
141    }
142    BOOST_CHECK_EQUAL(d, d1);
143    BOOST_CHECK_EQUAL(* b_ptr, * b1_ptr);
144}
145
146// check that data pointed to by pointer members is NOT moved
147class E {
148    int m_i;
149    friend class boost::serialization::access;
150    template<class Archive>
151    void serialize(Archive &ar, const unsigned int file_version){
152        ar & m_i;
153    }
154public:
155    bool operator==(const E &rhs) const {
156        return m_i == rhs.m_i;
157    }
158    E() :
159        m_i(std::rand())
160    {}
161    E(const E & rhs) :
162        m_i(rhs.m_i)
163    {}
164};
165BOOST_TEST_DONT_PRINT_LOG_VALUE( E )
166
167// check that moves don't move stuff pointed to
168class F {
169    friend class boost::serialization::access;
170    E * m_eptr;
171    template<class Archive>
172    void serialize(Archive &ar, const unsigned int file_version){
173        ar & m_eptr;
174    }
175public:
176    bool operator==(const F &rhs) const {
177        return *m_eptr == *rhs.m_eptr;
178    }
179    F & operator=(const F & rhs) {
180        * m_eptr = * rhs.m_eptr;
181        return *this;
182    }
183    F(){
184        m_eptr = new E;
185    }
186    F(const F & rhs){
187        *this = rhs;
188    }
189    ~F(){
190        delete m_eptr;
191    }
192};
193
194BOOST_TEST_DONT_PRINT_LOG_VALUE( F )
195
196void test4(){
197    std::stringstream ss;
198    const F f;
199    {
200        boost::archive::text_oarchive oa(ss);
201        oa << f;
202    }
203    F f1;
204    {
205        boost::archive::text_iarchive ia(ss);
206        F f2;
207        ia >> f2;
208        f1 = f2;
209        ia.reset_object_address(& f1, & f2);
210    }
211    BOOST_CHECK_EQUAL(f, f1);
212}
213
214// check that multiple moves keep track of the correct target
215class G {
216    friend class boost::serialization::access;
217    A m_a1;
218    A m_a2;
219    A *m_pa2;
220    template<class Archive>
221    void save(Archive &ar, const unsigned int file_version) const {
222        ar << m_a1;
223        ar << m_a2;
224        ar << m_pa2;
225    }
226    template<class Archive>
227    void load(Archive &ar, const unsigned int file_version){
228        A a; // temporary A
229        ar >> a;
230        m_a1 = a;
231        ar.reset_object_address(& m_a1, & a);
232        ar >> a;
233        m_a2 = a;
234        ar.reset_object_address(& m_a2, & a);
235        ar & m_pa2;
236    }
237    BOOST_SERIALIZATION_SPLIT_MEMBER()
238public:
239    bool operator==(const G &rhs) const {
240        return 
241            m_a1 == rhs.m_a1
242            && m_a2 == rhs.m_a2
243            && *m_pa2 == *rhs.m_pa2;
244    }
245    G & operator=(const G & rhs) {
246        m_a1 = rhs.m_a1;
247        m_a2 = rhs.m_a2;
248        m_pa2 = & m_a2;
249        return *this;
250    }
251    G(){
252        m_pa2 = & m_a2;
253    }
254    G(const G & rhs){
255        *this = rhs;
256    }
257    ~G(){}
258};
259
260BOOST_TEST_DONT_PRINT_LOG_VALUE( G )
261
262void test5(){
263    std::stringstream ss;
264    const G g;
265    {
266        boost::archive::text_oarchive oa(ss);
267        oa << g;
268    }
269    G g1;
270    {
271        boost::archive::text_iarchive ia(ss);
272        ia >> g1;
273    }
274    BOOST_CHECK_EQUAL(g, g1);
275}
276
277// joaquin's test - this tests the case where rest_object_address
278// is applied to an item which in fact is not tracked so that
279// the call is in fact superfluous.
280struct foo
281{
282  int x;
283
284private:
285  friend class boost::serialization::access;
286
287  template<class Archive>
288  void serialize(Archive &,const unsigned int)
289  {
290  }
291};
292
293struct bar
294{
295  foo  f[2];
296  foo* pf[2];
297
298private:
299  friend class boost::serialization::access;
300  BOOST_SERIALIZATION_SPLIT_MEMBER()
301
302  template<class Archive>
303  void save(Archive& ar,const unsigned int)const
304  {
305    for(int i=0;i<2;++i){
306      ar<<f[i].x;
307      ar<<f[i];
308    }
309    for(int j=0;j<2;++j){
310      ar<<pf[j];
311    }
312  }
313
314  template<class Archive>
315  void load(Archive& ar,const unsigned int)
316  {
317    for(int i=0;i<2;++i){
318      int x;
319      ar>>x;
320      f[i].x=x;
321      ar.reset_object_address(&f[i].x,&x);
322      ar>>f[i];
323    }
324    for(int j=0;j<2;++j){
325      ar>>pf[j];
326    }
327  }
328};
329
330int test6()
331{
332  bar b;
333  b.f[0].x=0;
334  b.f[1].x=1;
335  b.pf[0]=&b.f[0];
336  b.pf[1]=&b.f[1];
337
338  std::ostringstream oss;
339  {
340    boost::archive::text_oarchive oa(oss);
341    oa<<const_cast<const bar&>(b);
342  }
343
344  bar b1;
345  b1.pf[0]=0;
346  b1.pf[1]=0;
347
348  std::istringstream iss(oss.str());
349  boost::archive::text_iarchive ia(iss);
350  ia>>b1;
351  BOOST_CHECK(b1.pf[0]==&b1.f[0]&&b1.pf[1]==&b1.f[1]);
352
353  return 0;
354}
355
356// test one of the collections
357void test7(){
358    std::stringstream ss;
359    B const b;
360    B const * const b_ptr = & b;
361    BOOST_CHECK_EQUAL(& b, b_ptr);
362    {
363        std::list<const B *> l;
364        l.push_back(b_ptr);
365        boost::archive::text_oarchive oa(ss);
366        oa << const_cast<const std::list<const B *> &>(l);
367    }
368    B b1;
369    {
370        std::list<B *> l;
371        boost::archive::text_iarchive ia(ss);
372        ia >> l;
373        delete l.front(); // prevent memory leak
374    }
375}
376
377// test one of the collections with polymorphic archive
378void test8(){
379    std::stringstream ss;
380    B const b;
381    B const * const b_ptr = & b;
382    BOOST_CHECK_EQUAL(& b, b_ptr);
383    {
384        std::list<const B *> l;
385        l.push_back(b_ptr);
386        boost::archive::polymorphic_text_oarchive oa(ss);
387        boost::archive::polymorphic_oarchive & poa(oa);
388        poa << const_cast<const std::list<const B *> &>(l);
389    }
390    B b1;
391    {
392        std::list<B *> l;
393        boost::archive::polymorphic_text_iarchive ia(ss);
394        boost::archive::polymorphic_iarchive & pia(ia);
395        pia >> l;
396        delete l.front(); // prevent memory leak
397    }
398}
399
400int test_main(int /* argc */, char * /* argv */[])
401{
402    test1();
403    test2();
404    test3();
405    test4();
406    test5();
407    test6();
408    test7();
409    test8();
410    return EXIT_SUCCESS;
411}
Note: See TracBrowser for help on using the repository browser.