Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/serialization/test/test_no_rtti.cpp @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 6.5 KB
Line 
1/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
2// test_no_rtti.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// note: this program tests the inter-operability of different
10// extended typeinfo systems.  In this example, one class is
11// identified using the default RTTI while the other uses a custom
12// system based on the export key.
13//
14// As this program uses RTTI for one of the types, the test will fail
15// on a system for which RTTI is not enabled or not existent.
16
17#include <fstream>
18
19#include <cstdio> // remove
20#include <boost/config.hpp>
21#if defined(BOOST_NO_STDC_NAMESPACE)
22namespace std{ 
23    using ::remove;
24}
25#endif
26
27#include <boost/static_assert.hpp>
28#include <boost/type_traits/is_same.hpp>
29
30#include <boost/archive/archive_exception.hpp>
31#include "test_tools.hpp"
32#include <boost/preprocessor/stringize.hpp>
33#include BOOST_PP_STRINGIZE(BOOST_ARCHIVE_TEST)
34
35#include <boost/serialization/nvp.hpp>
36#include <boost/serialization/base_object.hpp>
37#include <boost/serialization/export.hpp>
38#include <boost/serialization/type_info_implementation.hpp>
39#include <boost/serialization/extended_type_info_no_rtti.hpp>
40
41class polymorphic_base
42{
43    friend class boost::serialization::access;
44    template<class Archive>
45    void serialize(Archive & /* ar */, const unsigned int /* file_version */){
46    }
47public:
48    virtual const char * get_key() const = 0;
49    virtual ~polymorphic_base(){};
50};
51
52BOOST_IS_ABSTRACT(polymorphic_base)
53BOOST_CLASS_TYPE_INFO(
54    polymorphic_base,
55    extended_type_info_no_rtti<polymorphic_base>
56)
57// note: types which use ...no_rtti MUST be exported
58BOOST_CLASS_EXPORT(polymorphic_base)
59
60class polymorphic_derived1 : public polymorphic_base
61{
62    friend class boost::serialization::access;
63    template<class Archive>
64    void serialize(Archive &ar, const unsigned int  /* file_version */){
65        ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(polymorphic_base);
66    }
67public:
68    virtual const char * get_key() const ;
69};
70
71BOOST_CLASS_TYPE_INFO(
72    polymorphic_derived1,
73    extended_type_info_no_rtti<polymorphic_derived1>
74)
75BOOST_CLASS_EXPORT(polymorphic_derived1)
76
77const char * polymorphic_derived1::get_key() const {
78    const boost::serialization::extended_type_info *eti
79        = boost::serialization::type_info_implementation<polymorphic_derived1>
80            ::type::get_instance();
81    return eti->get_key();
82}
83
84class polymorphic_derived2 : public polymorphic_base
85{
86    friend class boost::serialization::access;
87    template<class Archive>
88    void serialize(Archive &ar, const unsigned int /* file_version */){
89        ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(polymorphic_base);
90    }
91public:
92    virtual const char * get_key() const ;
93};
94
95// note the mixing of type_info systems is supported.
96BOOST_CLASS_TYPE_INFO(
97    polymorphic_derived2,
98    boost::serialization::extended_type_info_typeid<polymorphic_derived2>
99)
100
101BOOST_CLASS_EXPORT(polymorphic_derived2)
102
103const char * polymorphic_derived2::get_key() const {
104    // use the exported key as the identifier
105    const boost::serialization::extended_type_info *eti
106        = boost::serialization::type_info_implementation<polymorphic_derived2>
107        ::type::get_instance();
108    return eti->get_key();
109}
110
111// save derived polymorphic class
112void save_derived(const char *testfile)
113{
114    test_ostream os(testfile, TEST_STREAM_FLAGS);
115    test_oarchive oa(os);
116
117    polymorphic_derived1 *rd1 = new polymorphic_derived1;
118    polymorphic_derived2 *rd2 = new polymorphic_derived2;
119
120    oa << BOOST_SERIALIZATION_NVP(rd1);
121    oa << BOOST_SERIALIZATION_NVP(rd2);
122
123    // the above opereration registers the derived classes as a side
124    // effect.  Hence, instances can now be correctly serialized through
125    // a base class pointer.
126    polymorphic_base *rb1 =  rd1;
127    polymorphic_base *rb2 =  rd2;
128    oa << BOOST_SERIALIZATION_NVP(rb1);
129    oa << BOOST_SERIALIZATION_NVP(rb2);
130
131    delete rd1;
132    delete rd2;
133}
134
135// save derived polymorphic class
136void load_derived(const char *testfile)
137{
138    test_istream is(testfile, TEST_STREAM_FLAGS);
139    test_iarchive ia(is);
140
141    polymorphic_derived1 *rd1 = NULL;
142    polymorphic_derived2 *rd2 = NULL;
143
144    ia >> BOOST_SERIALIZATION_NVP(rd1);
145
146    BOOST_CHECK_MESSAGE(
147        boost::serialization::type_info_implementation<polymorphic_derived1>
148            ::type::get_instance()
149        == boost::serialization::type_info_implementation<polymorphic_derived1>
150            ::type::get_derived_extended_type_info(*rd1),
151        "restored pointer d1 not of correct type"
152    );
153
154    ia >> BOOST_SERIALIZATION_NVP(rd2);
155
156    BOOST_CHECK_MESSAGE(
157        boost::serialization::type_info_implementation<polymorphic_derived2>
158            ::type::get_instance()
159        == boost::serialization::type_info_implementation<polymorphic_derived2>
160            ::type::get_derived_extended_type_info(*rd2),
161        "restored pointer d2 not of correct type"
162    );
163
164    polymorphic_base *rb1 = NULL;
165    polymorphic_base *rb2 = NULL;
166
167    // the above opereration registers the derived classes as a side
168    // effect.  Hence, instances can now be correctly serialized through
169    // a base class pointer.
170    ia >> BOOST_SERIALIZATION_NVP(rb1);
171
172    BOOST_CHECK_MESSAGE(
173        rb1 == dynamic_cast<polymorphic_base *>(rd1),
174        "serialized pointers not correctly restored"
175    );
176
177    BOOST_CHECK_MESSAGE(
178        boost::serialization::type_info_implementation<polymorphic_derived1>
179            ::type::get_instance()
180        == boost::serialization::type_info_implementation<polymorphic_base>
181            ::type::get_derived_extended_type_info(*rb1),
182        "restored pointer b1 not of correct type"
183    );
184
185    ia >> BOOST_SERIALIZATION_NVP(rb2);
186
187    BOOST_CHECK_MESSAGE(
188        rb2 ==  dynamic_cast<polymorphic_base *>(rd2),
189        "serialized pointers not correctly restored"
190    );
191
192    BOOST_CHECK_MESSAGE(
193        boost::serialization::type_info_implementation<polymorphic_derived2>
194            ::type::get_instance()
195        == boost::serialization::type_info_implementation<polymorphic_base>
196            ::type::get_derived_extended_type_info(*rb2),
197        "restored pointer b2 not of correct type"
198    );
199
200    delete rb1;
201    delete rb2;
202}
203
204int
205test_main( int /* argc */, char* /* argv */[] )
206{
207    const char * testfile = boost::archive::tmpnam(NULL);
208   
209    BOOST_REQUIRE(NULL != testfile);
210
211    save_derived(testfile);
212    load_derived(testfile);
213
214    std::remove(testfile);
215    return EXIT_SUCCESS;
216}
217
218// EOF
Note: See TracBrowser for help on using the repository browser.