TPIE

11a2c2d
serialization2.h
Go to the documentation of this file.
1 // -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
2 // vi:set ts=4 sts=4 sw=4 noet :
3 // Copyright 2010, The TPIE development team
4 //
5 // This file is part of TPIE.
6 //
7 // TPIE is free software: you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License as published by the
9 // Free Software Foundation, either version 3 of the License, or (at your
10 // option) any later version.
11 //
12 // TPIE is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public License
18 // along with TPIE. If not, see <http://www.gnu.org/licenses/>
19 
20 #ifndef TPIE_SERIALIZATION2_H
21 #define TPIE_SERIALIZATION2_H
22 
31 
32 #include <tpie/config.h>
33 #include <tpie/portability.h>
34 #include <typeinfo>
35 #include <type_traits>
36 #include <tpie/is_simple_iterator.h>
37 #include <tpie/tuple_utils.h>
38 #include <array>
39 #include <tpie/array.h>
40 
41 namespace tpie {
42 
43 #ifdef DOXYGEN
44 
46 // The following two declarations are for documentation purposes only.
48 
65 template <typename D>
66 void serialize(D & dst, const foo & v);
67 
81 template <typename S>
82 void unserialize(S & src, foo & v);
83 
84 #endif // DOXYGEN
85 // Library implementations of tpie::serialize and tpie::unserialize.
88 
89 template <typename T>
91  static bool const value
92  = std::is_trivially_copyable<T>::value && !std::is_pointer<T>::value;
93 };
94 
98 template <typename D, typename T>
99 void serialize(D & dst, const T & v,
100  typename std::enable_if<is_trivially_serializable<T>::value>::type * = 0) {
101  dst.write((const char *)&v, sizeof(T));
102 }
103 
107 template <typename S, typename T>
108 void unserialize(S & src, T & v,
109  typename std::enable_if<is_trivially_serializable<T>::value>::type * = 0) {
110  src.read((char *)&v, sizeof(T));
111 }
112 
113 namespace bits {
114 
119 template <typename D, typename T,
120  bool is_simple_itr=tpie::is_simple_iterator<T>::value,
121  bool is_ts=is_trivially_serializable<typename std::iterator_traits<T>::value_type>::value>
123  void operator()(D & dst, T start, T end) {
124  using tpie::serialize;
125  for (T i=start; i != end; ++i) serialize(dst, *i);
126  }
127 };
128 
129 template <typename D, typename T>
130 struct array_encode_magic<D, T, true, true> {
131  void operator()(D & d, T start, T end) {
132  if (start == end) {
133  // Do not dereference two iterators pointing to null
134  return;
135  }
136  // We can't derefence end
137  auto element_size = sizeof(typename std::iterator_traits<T>::value_type);
138  d.write(reinterpret_cast<const char *>(&*start), (end - start) * element_size);
139  }
140 };
141 
146 template <typename D, typename T,
147  bool is_simple_itr=tpie::is_simple_iterator<T>::value,
150  void operator()(D & dst, T start, T end) {
151  using tpie::unserialize;
152  for (T i=start; i != end; ++i) unserialize(dst, *i);
153  }
154 };
155 
156 template <typename D, typename T>
157 struct array_decode_magic<D, T, true, true> {
158  void operator()(D & d, T start, T end) {
159  if (start == end) {
160  // Do not dereference two iterators pointing to null
161  return;
162  }
163  // We can't derefence end
164  auto element_size = sizeof(typename std::iterator_traits<T>::value_type);
165  d.read(reinterpret_cast<char *>(&*start), (end - start) * element_size);
166  }
167 };
168 
172 struct counter {
173  size_t size;
174  counter(): size(0) {}
175  void write(const void *, size_t s) {size += s;}
176 };
177 
178 } // namespace bits
179 
186 template <typename D, typename T>
187 void serialize(D & dst, T start, T end) {
189  magic(dst, start, end);
190 }
191 
198 template <typename D, typename T>
199 void unserialize(D & dst, T start, T end) {
201  magic(dst, start, end);
202 }
203 
207 template <typename D, typename T, std::size_t size>
208 void serialize(D & dst, const T (&x)[size]) {
209  using tpie::serialize;
210  serialize(dst, x, &x[size]);
211 }
212 
216 template <typename S, typename T, std::size_t size>
217 void unserialize(S & src, T (&x)[size]) {
218  using tpie::unserialize;
219  unserialize(src, x, &x[size]);
220 }
221 
225 template <typename D, typename T, std::size_t size>
226 void serialize(D & dst, const std::array<T, size> & v) {
227  using tpie::serialize;
228  serialize(dst, v.begin(), v.end());
229 }
230 
234 template <typename S, typename T, std::size_t size>
235 void unserialize(S & src, std::array<T, size> & v) {
236  using tpie::unserialize;
237  unserialize(src, v.begin(), v.end());
238 }
239 
243 template <typename D, typename T, typename alloc_t>
244 void serialize(D & dst, const std::vector<T, alloc_t> & v) {
245  using tpie::serialize;
246  serialize(dst, v.size());
247  serialize(dst, v.begin(), v.end());
248 }
249 
253 template <typename S, typename T, typename alloc_t>
254 void unserialize(S & src, std::vector<T, alloc_t> & v) {
255  typename std::vector<T>::size_type s;
256  using tpie::unserialize;
257  unserialize(src, s);
258  v.resize(s);
259  unserialize(src, v.begin(), v.end());
260 }
261 
265 template <typename D, typename T>
266 void serialize(D & dst, const tpie::array<T> & v) {
267  using tpie::serialize;
268  serialize(dst, v.size());
269  serialize(dst, v.begin(), v.end());
270 }
271 
275 template <typename S, typename T>
276 void unserialize(S & src, tpie::array<T> & v) {
277  size_type s;
278  using tpie::unserialize;
279  unserialize(src, s);
280  v.resize(s);
281  unserialize(src, v.begin(), v.end());
282 }
283 
288 template <typename D, typename T>
289 void serialize(D & dst, const std::basic_string<T> & v) {
290  using tpie::serialize;
291  serialize(dst, v.size());
292  serialize(dst, v.c_str(), v.c_str() + v.size());
293 }
294 
299 template <typename S, typename T>
300 void unserialize(S & src, std::basic_string<T> & v) {
301  typename std::basic_string<T>::size_type s;
302  using tpie::unserialize;
303  unserialize(src, s);
304  v.resize(s);
305  unserialize(src, v.c_str(), v.c_str() + v.size());
306 }
307 
311 template <typename D, typename T, typename U>
312 void serialize(D & dst, const std::pair<T,U> & v) {
313  using tpie::serialize;
314  serialize(dst, v.first);
315  serialize(dst, v.second);
316 }
317 
321 template <typename S, typename T, typename U>
322 void unserialize(S & src, std::pair<T,U> & v) {
323  using tpie::unserialize;
324  unserialize(src, v.first);
325  unserialize(src, v.second);
326 }
327 
331 template <typename D, typename... Ts>
332 void serialize(D & dst, const std::tuple<Ts...> & t) {
333  tuple_for_each([&](const auto & el) {
334  using tpie::serialize;
335  serialize(dst, el);
336  }, t);
337 }
338 
342 template <typename S, typename... Ts>
343 void unserialize(S & src, std::tuple<Ts...> & t) {
344  tuple_for_each([&](auto & el) {
345  using tpie::unserialize;
346  unserialize(src, el);
347  }, t);
348 }
349 
353 template <typename T>
354 size_t serialized_size(const T & v) {
355  using tpie::serialize;
356  bits::counter c;
357  serialize(c, v);
358  return c.size;
359 }
360 
361 } // namespace tpie
362 
363 #endif // TPIE_SERIALIZATION2_H
tpie::bits::array_decode_magic
Helper to facilitate fast unserialization of trivially copyable arrays.
Definition: serialization2.h:149
tpie::bits::array_encode_magic
Helper to facilitate fast serialization of trivially copyable arrays.
Definition: serialization2.h:122
portability.h
tpie::array< T >
tpie::array::begin
iterator begin()
Return an iterator to the beginning of the array.
Definition: array.h:312
array.h
tpie::is_simple_iterator
Checks if an iterator is simple.
Definition: is_simple_iterator.h:36
tpie::unserialize
void unserialize(S &src, foo &v)
Sample tpie::unserialize prototype.
tpie::serialize
void serialize(D &dst, const foo &v)
Sample tpie::serialize prototype.
tpie::array::end
iterator end()
Return an iterator to the end of the array.
Definition: array.h:326
tpie::array::resize
void resize(size_t size, const T &elm)
Change the size of the array.
Definition: array.h:490
tpie::serialized_size
size_t serialized_size(const T &v)
Given a serializable, serialize it and measure its serialized size.
Definition: serialization2.h:354
tpie::bits::counter
Helper to count the serialized size of objects.
Definition: serialization2.h:172
tpie::is_trivially_serializable
Definition: serialization2.h:90
tpie
Definition: access_type.h:26
tpie::array::size
size_type size() const
Return the size of the array.
Definition: array.h:531