summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/serialization/example/demo_auto_ptr.cpp
blob: ff86ac413b6eed68c7c0f9ed5aafc8fe35a04d2e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// demo_auto_ptr.cpp

// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#include <list>
#include <memory>
#include <fstream>
#include <string>

#include <cstdio> // remove, std::autoptr inteface wrong in dinkumware
#include <boost/config.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
    using ::remove;
}
#endif

#include <boost/archive/tmpdir.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

#include <boost/serialization/split_free.hpp>

namespace boost {
namespace serialization {

/////////////////////////////////////////////////////////////
// implement serialization for auto_ptr< T >
// note: this must be added to the boost namespace in order to
// be called by the library
template<class Archive, class T>
inline void save(
    Archive & ar,
    const std::auto_ptr< T > &t,
    const unsigned int file_version
){
    // only the raw pointer has to be saved
    // the ref count is rebuilt automatically on load
    const T * const tx = t.get();
    ar << tx;
}

template<class Archive, class T>
inline void load(
    Archive & ar,
    std::auto_ptr< T > &t,
    const unsigned int file_version
){
    T *pTarget;
    ar >> pTarget;
    // note that the reset automagically maintains the reference count
    #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
        t.release();
        t = std::auto_ptr< T >(pTarget);
    #else
        t.reset(pTarget);
    #endif
}

// split non-intrusive serialization function member into separate
// non intrusive save/load member functions
template<class Archive, class T>
inline void serialize(
    Archive & ar,
    std::auto_ptr< T > &t,
    const unsigned int file_version
){
    boost::serialization::split_free(ar, t, file_version);
}

} // namespace serialization
} // namespace boost

/////////////////////////////////////////////////////////////
// test auto_ptr serialization
class A
{
private:
    friend class boost::serialization::access;
    int x;
    template<class Archive>
    void serialize(Archive &ar, const unsigned int /* file_version */){
        ar & x;
    }
public:
    A(){}    // default constructor
    ~A(){}   // default destructor
};

void save(const std::auto_ptr<A> & spa, const char *filename)
{
    std::ofstream ofs(filename);
    boost::archive::text_oarchive oa(ofs);
    oa << spa;
}

void load(std::auto_ptr<A> & spa, const char *filename)
{
    // open the archive
    std::ifstream ifs(filename);
    boost::archive::text_iarchive ia(ifs);

    // restore the schedule from the archive
    ia >> spa;
}

int main(int argc, char *argv[])
{
    std::string filename = boost::archive::tmpdir();
    filename += "/testfile";

    // create  a new auto pointer to ta new object of type A
    std::auto_ptr<A> spa(new A);
    // serialize it
    save(spa, filename.c_str());
    // reset the auto pointer to NULL
    // thereby destroying the object of type A
    // note that the reset automagically maintains the reference count
    #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
        spa.release();
    #else
        spa.reset();
    #endif
    // restore state to one equivalent to the original
    // creating a new type A object
    load(spa, filename.c_str());
    // obj of type A gets destroyed
    // as auto_ptr goes out of scope
    std::remove(filename.c_str());
    return 0;
}