1 // Copyright (c) 2014 Thomas Heller
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #include <hpx/runtime/serialization/serialize.hpp>
7 #include <hpx/runtime/serialization/list.hpp>
8
9 #include <hpx/runtime/serialization/input_archive.hpp>
10 #include <hpx/runtime/serialization/output_archive.hpp>
11
12 #include <hpx/util/lightweight_test.hpp>
13
14 #include <cstddef>
15 #include <list>
16 #include <vector>
17
18 template <typename T>
19 struct A
20 {
AA21 A() {}
22
AA23 A(T t) : t_(t) {}
24 T t_;
25
operator =A26 A & operator=(T t) { t_ = t; return *this; }
27
28 template <typename Archive>
serializeA29 void serialize(Archive & ar, unsigned)
30 {
31 ar & t_;
32 }
33 };
34
35 // non-default constructible
36 struct B
37 {
38 const int a;
39 double b;
40
41 public:
42 B() = delete;
BB43 B(int a): a(a) {}
44
45 template <class Archive>
serializeB46 void serialize(Archive& ar, unsigned)
47 {
48 ar & b;
49 }
50
get_aB51 int get_a() const
52 {
53 return a;
54 }
55
set_bB56 void set_b(short b)
57 {
58 this->b = b;
59 }
60
get_bB61 short get_b() const
62 {
63 return b;
64 }
65 };
66
67 template <class Archive>
save_construct_data(Archive & ar,const B * b,unsigned)68 void save_construct_data(Archive& ar, const B* b, unsigned)
69 {
70 ar << b->get_a();
71 }
72
73 template <class Archive>
load_construct_data(Archive & ar,B * b,unsigned)74 void load_construct_data(Archive& ar, B* b, unsigned)
75 {
76 int a = 0;
77 ar >> a;
78 ::new (b) B(a);
79 }
80
test_bool()81 void test_bool()
82 {
83 {
84 std::vector<char> buffer;
85 hpx::serialization::output_archive oarchive(buffer);
86
87 std::list<bool> os;
88 os.push_back(true);
89 os.push_back(false);
90 os.push_back(false);
91 os.push_back(true);
92 oarchive << os;
93
94 hpx::serialization::input_archive iarchive(buffer);
95 std::list<bool> is;
96 iarchive >> is;
97 HPX_TEST_EQ(os.size(), is.size());
98 for (auto ot = os.begin(), it = is.begin();
99 ot != os.end(); ++ot, ++it)
100 {
101 HPX_TEST_EQ(*ot, *it);
102 }
103 }
104 {
105 std::vector<char> buffer;
106 hpx::serialization::output_archive oarchive(buffer);
107
108 std::list<A<bool> > os;
109 os.push_back(true);
110 os.push_back(false);
111 os.push_back(false);
112 os.push_back(true);
113 oarchive << os;
114
115 hpx::serialization::input_archive iarchive(buffer);
116 std::list<A<bool> > is;
117 iarchive >> is;
118 HPX_TEST_EQ(os.size(), is.size());
119 for (auto ot = os.begin(), it = is.begin();
120 ot != os.end(); ++ot, ++it)
121 {
122 HPX_TEST_EQ(ot->t_, it->t_);
123 }
124 }
125 }
126
127 template <typename T>
test(T min,T max)128 void test(T min, T max)
129 {
130 {
131 std::vector<char> buffer;
132 hpx::serialization::output_archive oarchive(buffer);
133 std::list<T> os;
134 for (T c = min; c < max; ++c)
135 {
136 os.push_back(c);
137 }
138 oarchive << os;
139 hpx::serialization::input_archive iarchive(buffer);
140 std::list<T> is;
141 iarchive >> is;
142 HPX_TEST_EQ(os.size(), is.size());
143 for (auto ot = os.begin(), it = is.begin();
144 ot != os.end(); ++ot, ++it)
145 {
146 HPX_TEST_EQ(*ot, *it);
147 }
148 }
149 {
150 std::vector<char> buffer;
151 hpx::serialization::output_archive oarchive(buffer);
152 std::list<A<T> > os;
153 for (T c = min; c < max; ++c)
154 {
155 os.push_back(c);
156 }
157 oarchive << os;
158 hpx::serialization::input_archive iarchive(buffer);
159 std::list<A<T> > is;
160 iarchive >> is;
161 HPX_TEST_EQ(os.size(), is.size());
162 for (auto ot = os.begin(), it = is.begin();
163 ot != os.end(); ++ot, ++it)
164 {
165 HPX_TEST_EQ(ot->t_, it->t_);
166 }
167 }
168 }
169
170 template <typename T>
test_fp(T min,T max)171 void test_fp(T min, T max)
172 {
173 {
174 std::vector<char> buffer;
175 hpx::serialization::output_archive oarchive(buffer);
176 std::list<T> os;
177 for (T c = min; c < max; c += static_cast<T>(0.5))
178 {
179 os.push_back(c);
180 }
181 oarchive << os;
182 hpx::serialization::input_archive iarchive(buffer);
183 std::list<T> is;
184 iarchive >> is;
185 HPX_TEST_EQ(os.size(), is.size());
186 for (auto ot = os.begin(), it = is.begin();
187 ot != os.end(); ++ot, ++it)
188 {
189 HPX_TEST_EQ(*ot++, *it++);
190 }
191 }
192 {
193 std::vector<char> buffer;
194 hpx::serialization::output_archive oarchive(buffer);
195 std::list<A<T> > os;
196 for (T c = min; c < max; c += static_cast<T>(0.5))
197 {
198 os.push_back(c);
199 }
200 oarchive << os;
201 hpx::serialization::input_archive iarchive(buffer);
202 std::list<A<T> > is;
203 iarchive >> is;
204 HPX_TEST_EQ(os.size(), is.size());
205 for (auto ot = os.begin(), it = is.begin();
206 ot != os.end(); ++ot, ++it)
207 {
208 HPX_TEST_EQ(ot->t_, it->t_);
209 }
210 }
211 }
212
test_non_default_constructible()213 void test_non_default_constructible()
214 {
215 std::vector<char> buffer;
216 hpx::serialization::output_archive oarchive(buffer);
217
218 std::list<B> os;
219 os.push_back(1);
220 os.push_back(2);
221 os.push_back(3);
222 os.push_back(4);
223
224 short b = 1;
225 for (auto& i: os) {
226 i.set_b(b);
227 ++b;
228 }
229
230 oarchive << os;
231
232 hpx::serialization::input_archive iarchive(buffer);
233 std::list<B> is;
234 iarchive >> is;
235 HPX_TEST_EQ(os.size(), is.size());
236 for (auto ot = os.begin(), it = is.begin();
237 ot != os.end(); ++ot, ++it)
238 {
239 HPX_TEST_EQ(ot->get_a(), it->get_a());
240 HPX_TEST_EQ(ot->get_b(), it->get_b());
241 }
242 }
243
main()244 int main()
245 {
246 test_bool();
247 test<char>((std::numeric_limits<char>::min)(),
248 (std::numeric_limits<char>::max)());
249 test<int>((std::numeric_limits<int>::min)(),
250 (std::numeric_limits<int>::min)() + 100);
251 test<int>((std::numeric_limits<int>::max)() - 100,
252 (std::numeric_limits<int>::max)());
253 test<int>(-100, 100);
254 test<unsigned>((std::numeric_limits<unsigned>::min)(),
255 (std::numeric_limits<unsigned>::min)() + 100);
256 test<unsigned>((std::numeric_limits<unsigned>::max)() - 100,
257 (std::numeric_limits<unsigned>::max)());
258 test<long>((std::numeric_limits<long>::min)(),
259 (std::numeric_limits<long>::min)() + 100);
260 test<long>((std::numeric_limits<long>::max)() - 100,
261 (std::numeric_limits<long>::max)());
262 test<long>(-100, 100);
263 test<unsigned long>((std::numeric_limits<unsigned long>::min)(),
264 (std::numeric_limits<unsigned long>::min)() + 100);
265 test<unsigned long>((std::numeric_limits<unsigned long>::max)() - 100,
266 (std::numeric_limits<unsigned long>::max)());
267 test_fp<float>((std::numeric_limits<float>::min)(),
268 (std::numeric_limits<float>::min)() + 100);
269 test_fp<float>((std::numeric_limits<float>::max)() - 100,
270 (std::numeric_limits<float>::max)()); //it's incorrect
271 // because floatmax() - 100 causes cancellations error,
272 // digits are not affected
273 test_fp<float>(-100, 100);
274 test<double>((std::numeric_limits<double>::min)(),
275 (std::numeric_limits<double>::min)() + 100);
276 test<double>((std::numeric_limits<double>::max)() - 100,
277 (std::numeric_limits<double>::max)()); //it's the same
278 test<double>(-100, 100);
279
280 test_non_default_constructible();
281
282 return hpx::util::report_errors();
283 }
284