TPIE

2362a60
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 <array>
38 
39 namespace tpie {
40 
41 #ifdef DOXYGEN
42 
44 // The following two declarations are for documentation purposes only.
46 
63 template <typename D>
64 void serialize(D & dst, const foo & v);
65 
79 template <typename S>
80 void unserialize(S & src, foo & v);
81 
82 #endif // DOXYGEN
83 // Library implementations of tpie::serialize and tpie::unserialize.
86 
87 template <typename T>
89 private:
90  template <typename TT>
91  static char magic(TT *, typename std::enable_if<TT::is_trivially_serializable>::type *_=0);
92 
93  template <typename TT>
94  static long magic(...);
95 public:
96  static bool const value=
97  (std::is_pod<T>::value || sizeof(magic<T>((T*)nullptr))==sizeof(char)) && !std::is_pointer<T>::value;
98 };
99 
103 template <typename D, typename T>
104 void serialize(D & dst, const T & v,
105  typename std::enable_if<is_trivially_serializable<T>::value>::type * = 0) {
106  dst.write((const char *)&v, sizeof(T));
107 }
108 
112 template <typename S, typename T>
113 void unserialize(S & src, T & v,
114  typename std::enable_if<is_trivially_serializable<T>::value>::type * = 0) {
115  src.read((char *)&v, sizeof(T));
116 }
117 
118 namespace bits {
119 
124 template <typename D, typename T,
125  bool is_simple_itr=tpie::is_simple_iterator<T>::value,
126  bool is_ts=is_trivially_serializable<typename std::iterator_traits<T>::value_type>::value>
128  void operator()(D & dst, T start, T end) {
129  using tpie::serialize;
130  for (T i=start; i != end; ++i) serialize(dst, *i);
131  }
132 };
133 
134 template <typename D, typename T>
135 struct array_encode_magic<D, T, true, true> {
136  void operator()(D & d, T start, T end) {
137  if (start == end) {
138  // Do not dereference two iterators pointing to null
139  return;
140  }
141  const char * from = reinterpret_cast<const char *>(&*start);
142  const char * to = reinterpret_cast<const char *>(&*end);
143  d.write(from, to-from);
144  }
145 };
146 
151 template <typename D, typename T,
152  bool is_simple_itr=tpie::is_simple_iterator<T>::value,
155  void operator()(D & dst, T start, T end) {
156  using tpie::unserialize;
157  for (T i=start; i != end; ++i) unserialize(dst, *i);
158  }
159 };
160 
161 template <typename D, typename T>
162 struct array_decode_magic<D, T, true, true> {
163  void operator()(D & d, T start, T end) {
164  if (start == end) {
165  // Do not dereference two iterators pointing to null
166  return;
167  }
168  char * from = reinterpret_cast<char *>(&*start);
169  char * to = reinterpret_cast<char *>(&*end);
170  d.read(from, to-from);
171  }
172 };
173 
177 struct counter {
178  size_t size;
179  counter(): size(0) {}
180  void write(const void *, size_t s) {size += s;}
181 };
182 
183 } // namespace bits
184 
191 template <typename D, typename T>
192 void serialize(D & dst, T start, T end) {
194  magic(dst, start, end);
195 }
196 
203 template <typename D, typename T>
204 void unserialize(D & dst, T start, T end) {
206  magic(dst, start, end);
207 }
208 
212 template <typename D, typename T, std::size_t size>
213 void serialize(D & dst, const T (&x)[size]) {
214  using tpie::serialize;
215  serialize(dst, x, &x[size]);
216 }
217 
221 template <typename S, typename T, std::size_t size>
222 void unserialize(S & src, T (&x)[size]) {
223  using tpie::unserialize;
224  unserialize(src, x, &x[size]);
225 }
226 
230 template <typename D, typename T, std::size_t size>
231 void serialize(D & dst, const std::array<T, size> & v) {
232  using tpie::serialize;
233  serialize(dst, v.begin(), v.end());
234 }
235 
239 template <typename S, typename T, std::size_t size>
240 void unserialize(S & src, std::array<T, size> & v) {
241  using tpie::unserialize;
242  unserialize(src, v.begin(), v.end());
243 }
244 
248 template <typename D, typename T, typename alloc_t>
249 void serialize(D & dst, const std::vector<T, alloc_t> & v) {
250  using tpie::serialize;
251  serialize(dst, v.size());
252  serialize(dst, v.begin(), v.end());
253 }
254 
258 template <typename S, typename T, typename alloc_t>
259 void unserialize(S & src, std::vector<T, alloc_t> & v) {
260  typename std::vector<T>::size_type s;
261  using tpie::unserialize;
262  unserialize(src, s);
263  v.resize(s);
264  unserialize(src, v.begin(), v.end());
265 }
266 
271 template <typename D, typename T>
272 void serialize(D & dst, const std::basic_string<T> & v) {
273  using tpie::serialize;
274  serialize(dst, v.size());
275  serialize(dst, v.c_str(), v.c_str() + v.size());
276 }
277 
282 template <typename S, typename T>
283 void unserialize(S & src, std::basic_string<T> & v) {
284  typename std::basic_string<T>::size_type s;
285  using tpie::unserialize;
286  unserialize(src, s);
287  v.resize(s);
288  unserialize(src, v.c_str(), v.c_str() + v.size());
289 }
290 
294 template <typename T>
295 size_t serialized_size(const T & v) {
296  using tpie::serialize;
297  bits::counter c;
298  serialize(c, v);
299  return c.size;
300 }
301 
302 } // namespace tpie
303 
304 #endif // TPIE_SERIALIZATION2_H
Helper to facilitate fast serialization of trivially copyable arrays.
size_t serialized_size(const T &v)
Given a serializable, serialize it and measure its serialized size.
Checks if an iterator is simple.
This file contains a few deprecated definitions for legacy code.
void unserialize(S &src, foo &v)
Sample tpie::unserialize prototype.
Helper to facilitate fast unserialization of trivially copyable arrays.
Helper to count the serialized size of objects.
void serialize(D &dst, const foo &v)
Sample tpie::serialize prototype.