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 #include "common.hpp"
28 #include <boost/test/unit_test.hpp>
29
30 class MemberMinimal
31 {
32 public:
33 MemberMinimal() = default;
MemberMinimal(std::string const & str)34 MemberMinimal( std::string const & str ) : x( str ) {}
35
36 protected:
37 friend class cereal::access;
38
39 template <class Archive>
save_minimal(Archive const &) const40 std::string save_minimal( Archive const & ) const
41 {
42 return x;
43 }
44
45 template <class Archive>
load_minimal(Archive const &,std::string const & str)46 void load_minimal( Archive const &, std::string const & str )
47 {
48 x = str;
49 }
50
51 public:
52 std::string x;
53 };
54
55 class MemberMinimalVersioned
56 {
57 public:
58 MemberMinimalVersioned() = default;
MemberMinimalVersioned(double d)59 MemberMinimalVersioned( double d ) : x( d ) {}
60
61 protected:
62 friend class cereal::access;
63
64 template <class Archive>
save_minimal(Archive const &,const std::uint32_t) const65 double save_minimal( Archive const &, const std::uint32_t ) const
66 {
67 return x;
68 }
69
70 template <class Archive>
load_minimal(Archive const &,double const & d,const std::uint32_t)71 void load_minimal( Archive const &, double const & d, const std::uint32_t )
72 {
73 x = d;
74 }
75
76 public:
77 double x;
78 };
79
80 struct NonMemberMinimal
81 {
82 NonMemberMinimal() = default;
NonMemberMinimalNonMemberMinimal83 NonMemberMinimal( std::uint32_t xx ) : x(xx) {}
84 std::uint32_t x;
85 };
86
87 template <class Archive>
save_minimal(Archive const &,NonMemberMinimal const & nmm)88 std::uint32_t save_minimal( Archive const &, NonMemberMinimal const & nmm )
89 {
90 return nmm.x;
91 }
92
93 template <class Archive>
load_minimal(Archive const &,NonMemberMinimal & nmm,std::uint32_t const & data)94 void load_minimal( Archive const &, NonMemberMinimal & nmm, std::uint32_t const & data )
95 {
96 nmm.x = data;
97 }
98
99 struct NonMemberMinimalVersioned
100 {
101 NonMemberMinimalVersioned() = default;
NonMemberMinimalVersionedNonMemberMinimalVersioned102 NonMemberMinimalVersioned( bool xx ) : x(xx) {}
103 bool x;
104 };
105
106 template <class Archive>
save_minimal(Archive const &,NonMemberMinimalVersioned const & nmm,std::uint32_t const)107 bool save_minimal( Archive const &, NonMemberMinimalVersioned const & nmm, std::uint32_t const )
108 {
109 return nmm.x;
110 }
111
112 template <class Archive>
load_minimal(Archive const &,NonMemberMinimalVersioned & nmm,bool const & data,std::uint32_t const)113 void load_minimal( Archive const &, NonMemberMinimalVersioned & nmm, bool const & data, std::uint32_t const )
114 {
115 nmm.x = data;
116 }
117
118 struct TestStruct
119 {
120 TestStruct() = default;
TestStructTestStruct121 TestStruct( std::string const & s, double d, std::uint32_t u, bool b ) :
122 mm(s), mmv(d), nmm(u), nmmv(b) {}
123
124 template <class Archive>
serializeTestStruct125 void serialize( Archive & ar )
126 {
127 ar( mm, mmv );
128 ar( nmm, nmmv );
129 }
130
131 MemberMinimal mm;
132 MemberMinimalVersioned mmv;
133 NonMemberMinimal nmm;
134 NonMemberMinimalVersioned nmmv;
135 };
136
137 struct Issue79Struct
138 {
139 Issue79Struct() = default;
Issue79StructIssue79Struct140 Issue79Struct( std::int32_t xx ) : x(xx) {}
141 std::int32_t x;
142 };
143
144 template <class Archive, cereal::traits::DisableIf<std::is_same<Archive, cereal::BinaryOutputArchive>::value ||
145 std::is_same<Archive, cereal::PortableBinaryOutputArchive>::value> = cereal::traits::sfinae>
save_minimal(Archive const &,Issue79Struct const & val)146 std::string save_minimal( Archive const &, Issue79Struct const & val )
147 {
148 return std::to_string( val.x );
149 }
150
151 template <class Archive, cereal::traits::DisableIf<std::is_same<Archive, cereal::BinaryInputArchive>::value ||
152 std::is_same<Archive, cereal::PortableBinaryInputArchive>::value> = cereal::traits::sfinae>
load_minimal(Archive const &,Issue79Struct & val,std::string const & str)153 void load_minimal( Archive const &, Issue79Struct & val, std::string const & str )
154 {
155 val.x = std::stoi( str );
156 }
157
158 template <class Archive, cereal::traits::EnableIf<std::is_same<Archive, cereal::BinaryOutputArchive>::value ||
159 std::is_same<Archive, cereal::PortableBinaryOutputArchive>::value> = cereal::traits::sfinae>
save_minimal(Archive const &,Issue79Struct const & val)160 std::int32_t save_minimal( Archive const &, Issue79Struct const & val )
161 {
162 return val.x;
163 }
164
165 template <class Archive, cereal::traits::EnableIf<std::is_same<Archive, cereal::BinaryInputArchive>::value ||
166 std::is_same<Archive, cereal::PortableBinaryInputArchive>::value> = cereal::traits::sfinae>
load_minimal(Archive const &,Issue79Struct & val,std::int32_t const & xx)167 void load_minimal( Archive const &, Issue79Struct & val, std::int32_t const & xx )
168 {
169 val.x = xx;
170 }
171
172 struct Issue79StructInternal
173 {
174 Issue79StructInternal() = default;
Issue79StructInternalIssue79StructInternal175 Issue79StructInternal( std::int32_t xx ) : x(xx) {}
176 std::int32_t x;
177
178 template <class Archive, cereal::traits::DisableIf<std::is_same<Archive, cereal::BinaryOutputArchive>::value ||
179 std::is_same<Archive, cereal::PortableBinaryOutputArchive>::value> = cereal::traits::sfinae>
save_minimalIssue79StructInternal180 std::string save_minimal( Archive const & ) const
181 {
182 return std::to_string( x );
183 }
184
185 template <class Archive, cereal::traits::DisableIf<std::is_same<Archive, cereal::BinaryInputArchive>::value ||
186 std::is_same<Archive, cereal::PortableBinaryInputArchive>::value> = cereal::traits::sfinae>
load_minimalIssue79StructInternal187 void load_minimal( Archive const &, std::string const & str )
188 {
189 x = std::stoi( str );
190 }
191
192 template <class Archive, cereal::traits::EnableIf<std::is_same<Archive, cereal::BinaryOutputArchive>::value ||
193 std::is_same<Archive, cereal::PortableBinaryOutputArchive>::value> = cereal::traits::sfinae>
save_minimalIssue79StructInternal194 std::int32_t save_minimal( Archive const & ) const
195 {
196 return x;
197 }
198
199 template <class Archive, cereal::traits::EnableIf<std::is_same<Archive, cereal::BinaryInputArchive>::value ||
200 std::is_same<Archive, cereal::PortableBinaryInputArchive>::value> = cereal::traits::sfinae>
load_minimalIssue79StructInternal201 void load_minimal( Archive const &, std::int32_t const & xx )
202 {
203 x = xx;
204 }
205 };
206
207 template <class IArchive, class OArchive>
test_structs_minimal()208 void test_structs_minimal()
209 {
210 std::random_device rd;
211 std::mt19937 gen(rd());
212
213 for(int ii=0; ii<100; ++ii)
214 {
215 TestStruct o_struct = { random_basic_string<char>(gen), random_value<double>(gen),
216 random_value<std::uint32_t>(gen), random_value<uint8_t>(gen) % 2 ? true : false };
217
218 Issue79Struct o_struct2 = { random_value<std::int32_t>(gen) };
219 Issue79StructInternal o_struct3 = { random_value<std::int32_t>(gen) };
220
221 std::ostringstream os;
222 {
223 OArchive oar(os);
224 oar( o_struct );
225 oar( o_struct2 );
226 oar( o_struct3 );
227 }
228
229 decltype(o_struct) i_struct;
230 decltype(o_struct2) i_struct2;
231 decltype(o_struct3) i_struct3;
232
233 std::istringstream is(os.str());
234 {
235 IArchive iar(is);
236 iar( i_struct );
237 iar( i_struct2 );
238 iar( i_struct3 );
239 }
240
241 BOOST_CHECK(o_struct.mm.x == i_struct.mm.x);
242 BOOST_CHECK_CLOSE(o_struct.mmv.x, i_struct.mmv.x, 1e-5);
243
244 BOOST_CHECK(o_struct.nmm.x == i_struct.nmm.x);
245 BOOST_CHECK(o_struct.nmmv.x == i_struct.nmmv.x);
246
247 BOOST_CHECK(o_struct2.x == i_struct2.x);
248
249 BOOST_CHECK(o_struct3.x == i_struct3.x);
250 }
251 }
252
BOOST_AUTO_TEST_CASE(binary_structs_minimal)253 BOOST_AUTO_TEST_CASE( binary_structs_minimal )
254 {
255 test_structs_minimal<cereal::BinaryInputArchive, cereal::BinaryOutputArchive>();
256 }
257
BOOST_AUTO_TEST_CASE(portable_binary_structs_minimal)258 BOOST_AUTO_TEST_CASE( portable_binary_structs_minimal )
259 {
260 test_structs_minimal<cereal::PortableBinaryInputArchive, cereal::PortableBinaryOutputArchive>();
261 }
262
BOOST_AUTO_TEST_CASE(xml_structs_minimal)263 BOOST_AUTO_TEST_CASE( xml_structs_minimal )
264 {
265 test_structs_minimal<cereal::XMLInputArchive, cereal::XMLOutputArchive>();
266 }
267
BOOST_AUTO_TEST_CASE(json_structs_minimal)268 BOOST_AUTO_TEST_CASE( json_structs_minimal )
269 {
270 test_structs_minimal<cereal::JSONInputArchive, cereal::JSONOutputArchive>();
271 }
272