1 /*
2 Copyright (c) 2014, Randolph Voorhies, Shane Grant
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of cereal nor the
13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES AND SHANE GRANT BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <type_traits>
29 #include <cereal/archives/binary.hpp>
30 #include <cereal/archives/xml.hpp>
31 #include <cereal/types/polymorphic.hpp>
32 #include <sstream>
33 #include <fstream>
34 #include <iostream>
35
36 struct Base
37 {
38 int y;
39 virtual void foo() = 0;
40
41 template<class Archive>
saveBase42 void save(Archive & ar) const
43 {
44 std::cout << "Saving Base" << std::endl;
45 ar( y );
46 }
47
48 template<class Archive>
loadBase49 void load(Archive & ar)
50 {
51 std::cout << "Loading Base" << std::endl;
52 ar( y );
53 }
54 };
55
56 struct MyType : public Base
57 {
58 int x;
59
fooMyType60 void foo() {}
61
62 template<class Archive>
saveMyType63 void save(Archive & ar) const
64 {
65 std::cout << "Saving MyType" << std::endl;
66 ar( cereal::virtual_base_class<Base>( this ) );
67 }
68
69 template<class Archive>
loadMyType70 void load(Archive & ar)
71 {
72 std::cout << "Loading MyType" << std::endl;
73 ar( cereal::base_class<Base>( this ) );
74 }
75 };
76 CEREAL_REGISTER_TYPE(MyType)
77
78 struct YourType : public Base
79 {
YourTypeYourType80 YourType(int xx) : x(xx) {}
YourTypeYourType81 YourType() : x(-1) {}
82 int x;
83
fooYourType84 void foo() {}
85
86 template<class Archive>
saveYourType87 void save(Archive & ar) const
88 {
89 std::cout << "Saving YourType" << std::endl;
90 ar( x );
91 }
92
93 template<class Archive>
loadYourType94 void load(Archive & ar)
95 {
96 std::cout << "Loading YourType" << std::endl;
97 ar( x );
98 }
99 };
100
101 CEREAL_REGISTER_TYPE(YourType)
102 CEREAL_REGISTER_POLYMORPHIC_RELATION(Base, YourType)
103
104 struct OurBase
105 {
fooOurBase106 virtual void foo() {}
107
108 template<class Archive>
serializeOurBase109 void serialize(Archive &)
110 { }
111 };
112
113 struct OurType : public OurBase
114 {
OurTypeOurType115 OurType() : OurBase(), x() {}
OurTypeOurType116 OurType(int x_) : x(x_) {}
fooOurType117 void foo() {}
118
119 int x;
120
121 template<class Archive>
serializeOurType122 void serialize(Archive & ar)
123 {
124 ar( x );
125 }
126 };
127
128 struct BaseVirtual
129 {
130 int x;
131 template <class Archive>
serializeBaseVirtual132 void serialize( Archive & ar )
133 { ar( x ); }
134 virtual void foo() = 0;
135 };
136
137 struct DerivedVirtual : public virtual BaseVirtual
138 {
139 int y;
fooDerivedVirtual140 virtual void foo() {}
141
142 template <class Archive>
saveDerivedVirtual143 void save( Archive & ar ) const
144 {
145 ar( cereal::virtual_base_class<BaseVirtual>( this ) );
146 ar( y );
147 }
148
149 template <class Archive>
loadDerivedVirtual150 void load( Archive & ar )
151 {
152 ar( cereal::virtual_base_class<BaseVirtual>( this ) );
153 ar( y );
154 }
155 };
156
157 struct TestType
158 {
159 int x;
160 template <class Archive>
serializeTestType161 void serialize( Archive & ar )
162 {
163 ar( x );
164 }
165 };
166
167 namespace cereal
168 {
169 template <class Archive> struct specialize<Archive, DerivedVirtual, cereal::specialization::member_load_save> {};
170 template <class Archive> struct specialize<Archive, TestType, cereal::specialization::member_serialize> {};
171 }
172
173 struct AAA
174 {
175 virtual void foo() = 0;
176 };
177
178 struct BBB : AAA
179 {
fooBBB180 void foo() {}
181 template <class Archive>
serializeBBB182 void serialize( Archive & ) {}
183 };
184
CEREAL_REGISTER_TYPE(BBB)185 CEREAL_REGISTER_TYPE(BBB)
186
187 template <class T> void nop(T&&) {}
188
main()189 int main()
190 {
191 {
192 std::ofstream ostream("rtti.txt");
193 //cereal::BinaryOutputArchive oarchive(ostream);
194 cereal::XMLOutputArchive oarchive(ostream);
195
196 std::shared_ptr<Base> ptr1 = std::make_shared<MyType>();
197 std::shared_ptr<Base> ptr2 = std::make_shared<YourType>(33);
198 std::unique_ptr<Base> ptr3(new MyType());
199 std::weak_ptr<Base> ptr4 = ptr2;
200
201 std::shared_ptr<OurType> ptr5 = std::make_shared<OurType>(99);
202
203 oarchive(ptr1);
204 oarchive(ptr2);
205 oarchive(ptr3);
206 oarchive(ptr4);
207 oarchive(ptr5);
208
209 //std::shared_ptr<AAA> a = std::make_shared<BBB>();
210 //oarchive(a);
211 }
212
213 {
214 std::ifstream istream("rtti.txt");
215 //cereal::BinaryInputArchive iarchive(istream);
216 cereal::XMLInputArchive iarchive(istream);
217
218 std::shared_ptr<Base> ptr1;
219 std::shared_ptr<Base> ptr2;
220 std::unique_ptr<Base> ptr3;
221 std::weak_ptr<Base> ptr4;
222
223 std::shared_ptr<OurType> ptr5;
224
225 iarchive(ptr1);
226 iarchive(ptr2);
227 iarchive(ptr3);
228 iarchive(ptr4);
229 iarchive(ptr5);
230 }
231 }
232