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 #ifndef CEREAL_TEST_STRUCTS_MINIMAL_H_
28 #define CEREAL_TEST_STRUCTS_MINIMAL_H_
29 #include "common.hpp"
30
31 struct BogusBase
32 {
33 template <class Archive>
serializeBogusBase34 void serialize( Archive & ) {}
35
36 template <class Archive>
saveBogusBase37 void save( Archive & ) const {}
38
39 template <class Archive>
loadBogusBase40 void load( Archive & ) {}
41
42 template <class Archive>
save_minimalBogusBase43 int save_minimal( Archive const & ) const { return 0; }
44
45 template <class Archive>
load_minimalBogusBase46 void load_minimal( Archive const &, int const & ) {}
47 };
48
49 struct BogusBaseVersioned
50 {
51 template <class Archive>
serializeBogusBaseVersioned52 void serialize( Archive &, const std::uint32_t ) {}
53
54 template <class Archive>
saveBogusBaseVersioned55 void save( Archive &, const std::uint32_t ) const {}
56
57 template <class Archive>
loadBogusBaseVersioned58 void load( Archive &, const std::uint32_t ) {}
59
60 template <class Archive>
save_minimalBogusBaseVersioned61 int save_minimal( Archive const &, const std::uint32_t ) const { return 0; }
62
63 template <class Archive>
load_minimalBogusBaseVersioned64 void load_minimal( Archive const &, int const &, const std::uint32_t ) {}
65 };
66
67 struct BogusBasePolymorphic
68 {
69 template <class Archive>
serializeBogusBasePolymorphic70 void serialize( Archive & ) {}
71
doesNothingBogusBasePolymorphic72 virtual void doesNothing() {}
73 };
74
75 class SpecializedMSerialize : public BogusBase
76 {
77 public:
78 SpecializedMSerialize() = default;
SpecializedMSerialize(int xx)79 SpecializedMSerialize( int xx ) : x(xx) {}
80
81 int x;
82
83 private:
84 friend class cereal::access;
85 template <class Archive>
serialize(Archive & ar)86 void serialize( Archive & ar )
87 {
88 ar( x );
89 }
90 };
91
92 class SpecializedMSerializeVersioned : public BogusBaseVersioned
93 {
94 public:
95 SpecializedMSerializeVersioned() = default;
SpecializedMSerializeVersioned(int xx)96 SpecializedMSerializeVersioned( int xx ) : x(xx) {}
97
98 int x;
99
100 private:
101 friend class cereal::access;
102 template <class Archive>
serialize(Archive & ar,const std::uint32_t)103 void serialize( Archive & ar, const std::uint32_t )
104 {
105 ar( x );
106 }
107 };
108
109 class SpecializedMSplit : public BogusBase
110 {
111 public:
112 SpecializedMSplit() = default;
SpecializedMSplit(int xx)113 SpecializedMSplit( int xx ) : x(xx) {}
114
115 int x;
116
117 private:
118 friend class cereal::access;
119 template <class Archive>
save(Archive & ar) const120 void save( Archive & ar ) const
121 {
122 ar( x );
123 }
124
125 template <class Archive>
load(Archive & ar)126 void load( Archive & ar )
127 {
128 ar( x );
129 }
130 };
131
132 class SpecializedMSplitVersioned : public BogusBaseVersioned
133 {
134 public:
135 SpecializedMSplitVersioned() = default;
SpecializedMSplitVersioned(int xx)136 SpecializedMSplitVersioned( int xx ) : x(xx) {}
137
138 int x;
139
140 private:
141 friend class cereal::access;
142 template <class Archive>
save(Archive & ar,const std::uint32_t) const143 void save( Archive & ar, const std::uint32_t ) const
144 {
145 ar( x );
146 }
147
148 template <class Archive>
load(Archive & ar,const std::uint32_t)149 void load( Archive & ar, const std::uint32_t )
150 {
151 ar( x );
152 }
153 };
154
155 class SpecializedMSplitPolymorphic : public BogusBasePolymorphic
156 {
157 public:
158 SpecializedMSplitPolymorphic() = default;
SpecializedMSplitPolymorphic(int xx)159 SpecializedMSplitPolymorphic( int xx ) : x(xx) {}
160
161 int x;
162
163 private:
164 friend class cereal::access;
165 template <class Archive>
save(Archive & ar) const166 void save( Archive & ar ) const
167 {
168 ar( x );
169 }
170
171 template <class Archive>
load(Archive & ar)172 void load( Archive & ar )
173 {
174 ar( x );
175 }
176 };
177
178 class SpecializedMSplitMinimal : public BogusBase
179 {
180 public:
181 SpecializedMSplitMinimal() = default;
SpecializedMSplitMinimal(int xx)182 SpecializedMSplitMinimal( int xx ) : x(xx) {}
183
184 int x;
185
186 private:
187 friend class cereal::access;
188 template <class Archive>
save_minimal(Archive const &) const189 int save_minimal( Archive const & ) const
190 {
191 return x;
192 }
193
194 template <class Archive>
load_minimal(Archive const &,int const & value)195 void load_minimal( Archive const &, int const & value )
196 {
197 x = value;
198 }
199 };
200
201 class SpecializedMSplitVersionedMinimal : public BogusBaseVersioned
202 {
203 public:
204 SpecializedMSplitVersionedMinimal() = default;
SpecializedMSplitVersionedMinimal(int xx)205 SpecializedMSplitVersionedMinimal( int xx ) : x(xx) {}
206
207 int x;
208
209 private:
210 friend class cereal::access;
211 template <class Archive>
save_minimal(Archive const &,const std::uint32_t) const212 int save_minimal( Archive const &, const std::uint32_t ) const
213 {
214 return x;
215 }
216
217 template <class Archive>
load_minimal(Archive const &,int const & value,const std::uint32_t)218 void load_minimal( Archive const &, int const & value, const std::uint32_t )
219 {
220 x = value;
221 }
222 };
223
224 class SpecializedNMSerialize : public BogusBase
225 {
226 public:
227 SpecializedNMSerialize() = default;
SpecializedNMSerialize(int xx)228 SpecializedNMSerialize( int xx ) : x(xx) {}
229
230 int x;
231 };
232
233 template <class Archive>
serialize(Archive & ar,SpecializedNMSerialize & s)234 void serialize( Archive & ar, SpecializedNMSerialize & s )
235 {
236 ar( s.x );
237 }
238
239 class SpecializedNMSerializeVersioned : public BogusBaseVersioned
240 {
241 public:
242 SpecializedNMSerializeVersioned() = default;
SpecializedNMSerializeVersioned(int xx)243 SpecializedNMSerializeVersioned( int xx ) : x(xx) {}
244
245 int x;
246 };
247
248 template <class Archive>
serialize(Archive & ar,SpecializedNMSerializeVersioned & s)249 void serialize( Archive & ar, SpecializedNMSerializeVersioned & s )
250 {
251 ar( s.x );
252 }
253
254 class SpecializedNMSplit : public BogusBase
255 {
256 public:
257 SpecializedNMSplit() = default;
SpecializedNMSplit(int xx)258 SpecializedNMSplit( int xx ) : x(xx) {}
259
260 int x;
261 };
262
263 template <class Archive>
load(Archive & ar,SpecializedNMSplit & s)264 void load( Archive & ar, SpecializedNMSplit & s )
265 {
266 ar( s.x );
267 }
268
269 template <class Archive>
save(Archive & ar,SpecializedNMSplit const & s)270 void save( Archive & ar, SpecializedNMSplit const & s )
271 {
272 ar( s.x );
273 }
274
275 class SpecializedNMSplitVersioned : public BogusBaseVersioned
276 {
277 public:
278 SpecializedNMSplitVersioned() = default;
SpecializedNMSplitVersioned(int xx)279 SpecializedNMSplitVersioned( int xx ) : x(xx) {}
280
281 int x;
282 };
283
284 template <class Archive>
load(Archive & ar,SpecializedNMSplitVersioned & s,const std::uint32_t)285 void load( Archive & ar, SpecializedNMSplitVersioned & s, const std::uint32_t )
286 {
287 ar( s.x );
288 }
289
290 template <class Archive>
save(Archive & ar,SpecializedNMSplitVersioned const & s,const std::uint32_t)291 void save( Archive & ar, SpecializedNMSplitVersioned const & s, const std::uint32_t )
292 {
293 ar( s.x );
294 }
295
296 class SpecializedNMSplitMinimal : public BogusBase
297 {
298 public:
299 SpecializedNMSplitMinimal() = default;
SpecializedNMSplitMinimal(int xx)300 SpecializedNMSplitMinimal( int xx ) : x(xx) {}
301
302 int x;
303 };
304
305 template <class Archive>
load_minimal(Archive const &,SpecializedNMSplitMinimal & s,int const & value)306 void load_minimal( Archive const &, SpecializedNMSplitMinimal & s, int const & value )
307 {
308 s.x = value;
309 }
310
311 template <class Archive>
save_minimal(Archive const &,SpecializedNMSplitMinimal const & s)312 int save_minimal( Archive const &, SpecializedNMSplitMinimal const & s )
313 {
314 return s.x;
315 }
316
317 class SpecializedNMSplitVersionedMinimal : public BogusBaseVersioned
318 {
319 public:
320 SpecializedNMSplitVersionedMinimal() = default;
SpecializedNMSplitVersionedMinimal(int xx)321 SpecializedNMSplitVersionedMinimal( int xx ) : x(xx) {}
322
323 int x;
324 };
325
326 template <class Archive>
load_minimal(Archive const &,SpecializedNMSplitVersionedMinimal & s,int const & value,const std::uint32_t)327 void load_minimal( Archive const &, SpecializedNMSplitVersionedMinimal & s, int const & value, const std::uint32_t )
328 {
329 s.x = value;
330 }
331
332 template <class Archive>
save_minimal(Archive const &,SpecializedNMSplitVersionedMinimal const & s,const std::uint32_t)333 int save_minimal( Archive const &, SpecializedNMSplitVersionedMinimal const & s, const std::uint32_t )
334 {
335 return s.x;
336 }
337
338 namespace cereal
339 {
340 template <class Archive> struct specialize<Archive, SpecializedMSerialize, cereal::specialization::member_serialize> {};
341 template <class Archive> struct specialize<Archive, SpecializedMSerializeVersioned, cereal::specialization::member_serialize> {};
342
343 template <class Archive> struct specialize<Archive, SpecializedMSplit, cereal::specialization::member_load_save> {};
344 template <class Archive> struct specialize<Archive, SpecializedMSplitVersioned, cereal::specialization::member_load_save> {};
345 template <class Archive> struct specialize<Archive, SpecializedMSplitPolymorphic, cereal::specialization::member_load_save> {};
346
347 template <class Archive> struct specialize<Archive, SpecializedMSplitMinimal, cereal::specialization::member_load_save_minimal> {};
348 template <class Archive> struct specialize<Archive, SpecializedMSplitVersionedMinimal, cereal::specialization::member_load_save_minimal> {};
349
350 template <class Archive> struct specialize<Archive, SpecializedNMSerialize, cereal::specialization::non_member_serialize> {};
351 template <class Archive> struct specialize<Archive, SpecializedNMSerializeVersioned, cereal::specialization::non_member_serialize> {};
352
353 template <class Archive> struct specialize<Archive, SpecializedNMSplit, cereal::specialization::non_member_load_save> {};
354 template <class Archive> struct specialize<Archive, SpecializedNMSplitVersioned, cereal::specialization::non_member_load_save> {};
355
356 template <class Archive> struct specialize<Archive, SpecializedNMSplitMinimal,
357 cereal::specialization::non_member_load_save_minimal> {};
358 template <class Archive> struct specialize<Archive, SpecializedNMSplitVersionedMinimal,
359 cereal::specialization::non_member_load_save_minimal> {};
360 }
361
362 CEREAL_REGISTER_TYPE(SpecializedMSplitPolymorphic)
CEREAL_REGISTER_POLYMORPHIC_RELATION(BogusBasePolymorphic,SpecializedMSplitPolymorphic)363 CEREAL_REGISTER_POLYMORPHIC_RELATION(BogusBasePolymorphic, SpecializedMSplitPolymorphic)
364
365 template <class IArchive, class OArchive> inline
366 void test_structs_specialized()
367 {
368 std::random_device rd;
369 std::mt19937 gen(rd());
370
371 for(int ii=0; ii<100; ++ii)
372 {
373 SpecializedMSerialize o_iser = { random_value<int>(gen) };
374 SpecializedMSerializeVersioned o_iserv = { random_value<int>(gen) };
375
376 SpecializedMSplit o_ispl = { random_value<int>(gen) };
377 SpecializedMSplitVersioned o_isplv = { random_value<int>(gen) };
378
379 // added re: issue #180
380 std::shared_ptr<BogusBasePolymorphic> o_shared_ispl = std::make_shared<SpecializedMSplitPolymorphic>( random_value<int>(gen) );
381
382 SpecializedMSplitMinimal o_isplm = { random_value<int>(gen) };
383 SpecializedMSplitVersionedMinimal o_isplvm = { random_value<int>(gen) };
384
385 SpecializedNMSerialize o_eser = { random_value<int>(gen) };
386 SpecializedNMSerializeVersioned o_eserv = { random_value<int>(gen) };
387
388 SpecializedNMSplit o_espl = { random_value<int>(gen) };
389 SpecializedNMSplitVersioned o_esplv = { random_value<int>(gen) };
390
391 SpecializedNMSplitMinimal o_esplm = { random_value<int>(gen) };
392 SpecializedNMSplitVersionedMinimal o_esplvm = { random_value<int>(gen) };
393
394
395 std::ostringstream os;
396 {
397 OArchive oar(os);
398
399 oar( o_iser, o_iserv,
400 o_ispl, o_isplv, o_shared_ispl,
401 o_isplm, o_isplvm,
402 o_eser, o_eserv,
403 o_espl, o_esplv,
404 o_esplm, o_esplvm );
405 }
406
407 decltype(o_iser) i_iser;
408 decltype(o_iserv) i_iserv;
409
410 decltype(o_ispl) i_ispl;
411 decltype(o_isplv) i_isplv;
412
413 decltype(o_shared_ispl) i_shared_ispl;
414
415 decltype(o_isplm) i_isplm;
416 decltype(o_isplvm) i_isplvm;
417
418 decltype(o_eser) i_eser;
419 decltype(o_eserv) i_eserv;
420
421 decltype(o_espl) i_espl;
422 decltype(o_esplv) i_esplv;
423
424 decltype(o_esplm) i_esplm;
425 decltype(o_esplvm) i_esplvm;
426
427 std::istringstream is(os.str());
428 {
429 IArchive iar(is);
430
431 iar( i_iser, i_iserv,
432 i_ispl, i_isplv, i_shared_ispl,
433 i_isplm, i_isplvm,
434 i_eser, i_eserv,
435 i_espl, i_esplv,
436 i_esplm, i_esplvm );
437 }
438
439 CHECK_EQ(i_iser.x, o_iser.x);
440 CHECK_EQ(i_iserv.x, o_iserv.x);
441
442 CHECK_EQ(i_ispl.x, o_ispl.x);
443 CHECK_EQ(i_isplv.x, o_isplv.x);
444
445 CHECK_EQ(dynamic_cast<SpecializedMSplitPolymorphic*>(i_shared_ispl.get())->x, dynamic_cast<SpecializedMSplitPolymorphic*>(o_shared_ispl.get())->x);
446
447 CHECK_EQ(i_isplm.x, o_isplm.x);
448 CHECK_EQ(i_isplvm.x, o_isplvm.x);
449
450 CHECK_EQ(i_eser.x, o_eser.x);
451 CHECK_EQ(i_eserv.x, o_eserv.x);
452
453 CHECK_EQ(i_espl.x, o_espl.x);
454 CHECK_EQ(i_esplv.x, o_esplv.x);
455
456 CHECK_EQ(i_esplm.x, o_esplm.x);
457 CHECK_EQ(i_esplvm.x, o_esplvm.x);
458 }
459 }
460
461 #endif // CEREAL_TEST_STRUCTS_SPECIALIZED_H_
462