Classdesc 3.44
pack_stl.h
Go to the documentation of this file.
1/*
2 @copyright Russell Standish 2000-2013
3 @author Russell Standish
4 This file is part of Classdesc
5
6 Open source licensed under the MIT license. See LICENSE for details.
7*/
8
12
13#ifndef CLASSDESC_PACK_STL_H
14#define CLASSDESC_PACK_STL_H
15
16#include "pack_base.h"
17
18#if defined(__cplusplus) && __cplusplus>=201103L
19#include <array>
20#endif
21#include <iterator>
22#include <string>
23#include <vector>
24
25namespace classdesc
26{
27 typedef unsigned long long uint64;
28
29 // map<K,V>::value_type is pair<const K,V>, which causes problems
30 template <class C> struct Value_Type
31 {typedef typename C::value_type value_type;};
32
33 template <class K, class V, class C, class A>
34 struct Value_Type<std::map<K,V,C,A> > {typedef std::pair<K,V> value_type;};
35
36 template <class K, class V, class C, class A>
37 struct Value_Type<std::multimap<K,V,C,A> >
38 {typedef std::pair<K,V> value_type;};
39
40
49 template <class T>
50 class Iterator: public T::iterator
51 {
52 // maintain a reference to the container for serialisation purposes
53 T *container;
56 public:
57 Iterator(): container(NULL) {}
58 Iterator(T& container): container(&container) {}
59 void operator=(const typename T::iterator& i) {T::iterator::operator=(i);}
60 typename T::iterator& iter() {return *this;}
61 const typename T::iterator& iter() const {return *this;}
62 };
63
64 // partial specialisation for const_iterators
65 template <class T>
66 class Iterator<const T>: public T::const_iterator
67 {
68 // maintain a reference to the container for serialisation purposes
69 const T *container;
72 public:
73 Iterator(): container(NULL) {}
74 Iterator(const T& container): container(&container) {}
75 void operator=(const typename T::const_iterator& i) {T::const_iterator::operator=(i);}
76 typename T::const_iterator& iter() {return *this;}
77 const typename T::const_iterator& iter() const {return *this;}
78 };
79
80 template <class T, class A>
81 BinStream& BinStream::operator<<(const std::vector<T,A>& x)
82 {
83 (*this) << uint64(x.size());
84 if (!x.empty())
85 packer.packraw(reinterpret_cast<const char*>(x.data()),
86 x.size()*sizeof(x[0]));
87 return *this;
88 }
89 template <class T, class A>
90 BinStream& BinStream::operator>>(std::vector<T,A>& x)
91 {
92 uint64 sz;
93 (*this) >> sz;
94 if (uint64(packer.size()-packer.pos())<sz*sizeof(T))
95 throw pack_error("invalid size for data available");
96 x.resize(sz);
97 if (sz)
98 packer.unpackraw(reinterpret_cast<char*>(x.data()),
99 x.size()*sizeof(x[0]));
100 return *this;
101 }
102
103
104 template <class T>
105 typename enable_if<is_container<T>, void>::T
106 pack(classdesc::pack_t& b, const classdesc::string&, const T& a)
107 {
108 b << uint64(a.size());
109 for (typename T::const_iterator i=a.begin(); i!=a.end(); ++i)
110 b << *i;
111 }
112#if defined(__GNUC__) && !defined(__ICC)
113#pragma GCC diagnostic push
114#pragma GCC diagnostic ignored "-Wunused-value"
115#endif
116
117 template <class T>
118 void unpackSequence(classdesc::pack_t& b, const classdesc::string& d, T& a)
119 {
120 uint64 sz=0, i=0;
121 b >> sz;
122 resize(a,0);
123 for (typename T::iterator j=a.begin(); i<sz; ++i, ++j)
124 {
125 typename T::value_type x;
126 b >> x;
127 classdesc::push_back(a, x);
128 }
129 }
130
131#if defined(__cplusplus) && __cplusplus>=201103L
132 template <class T, size_t N>
133 void unpackSequence(classdesc::pack_t& b, const classdesc::string& d, std::array<T,N>& a)
134 {
135 uint64 sz=0, i=0;
136 b >> sz;
137 for (size_t i=0; i<sz && i<N; ++i)
138 b >> a[i];
139 }
140#endif
141
142 template <class T>
143 typename enable_if<is_sequence<T>,void>::T
144 unpack(classdesc::pack_t& b, const classdesc::string& d, T& a)
145 {unpackSequence(b,d,a);}
146
147 template <class T>
148 typename enable_if<is_sequence<T>, void>::T
149 unpack(classdesc::pack_t& b, const classdesc::string&, const T& a)
150 {
151 uint64 sz;
152 b >> sz;
153 typename T::value_type x;
154 for (typename T::size_type i=0; i<sz; ++i) b>>x;
155 }
156
157#if defined(__GNUC__) && !defined(__ICC)
158#pragma GCC diagnostic pop
159#endif
160
161 template <class T>
163 unpack(classdesc::pack_t& b, const classdesc::string&, T& a)
164 {
165 uint64 sz;
166 b >> sz;
167 a.clear();
168 for (typename T::size_type i=0; i<sz; ++i)
169 {
170 typename classdesc::Value_Type<T>::value_type e;
171 b >> e;
172 a.insert(e);
173 }
174 }
175
176 template <class T>
178 unpack(classdesc::pack_t& b, const classdesc::string&, const T& a)
179 {
180 uint64 sz;
181 b >> sz;
182 for (typename T::size_type i=0; i<sz; ++i)
183 {
184 typename classdesc::Value_Type<T>::value_type e;
185 b >> e;
186 }
187 }
188
189}
190using classdesc::pack;
192
193namespace classdesc_access
194{
195
196 template <class T>
197 struct access_pack<classdesc::Iterator<T> >
198 {
199 template <class U>
200 void operator()(classdesc::pack_t& b, const classdesc::string& d, U& a)
201 {
202 typename T::size_type i=a.container?
203 std::distance(a.container->begin(),a.iter()): 0;
204 b << i;
205 }
206 };
207
208 template <class T>
209 struct access_unpack<classdesc::Iterator<T> >
210 {
211 template <class U>
212 void operator()(classdesc::pack_t& b, const classdesc::string& d, U& a)
213 {
214 typename T::size_type i;
215 b >> i;
216 if (a.container)
217 {
218 a=a.container->begin();
219 std::advance(a.iter(),i);
220 }
221 }
222 };
223
224/*
225 strings
226*/
227
228#ifdef _CLASSDESC
229#pragma omit pack std::char_traits
230#pragma omit unpack std::char_traits
231#pragma omit pack std::basic_string
232#pragma omit unpack std::basic_string
233#pragma omit pack std::string
234#pragma omit unpack std::string
235#endif
236
237 template <class cT, class t, class A>
238 struct access_pack<std::basic_string<cT,t,A> >
239 {
240 template <class U>
241 void operator()(classdesc::pack_t& targ, const classdesc::string& desc, U& arg)
242 {
243 targ<<classdesc::uint64(arg.size());
244 targ.packraw((const char*)arg.data(), sizeof(cT)*arg.size());
245 }
246 };
247
248 template <class cT, class t, class A>
249 struct access_unpack<std::basic_string<cT,t,A> >
250 {
251 typedef std::basic_string<cT,t,A> string;
252 void asg(const string& x, const std::vector<cT>& b) {}
253 void asg(string& x, const std::vector<cT>& b)
254 {
255 if (!b.empty())
256 x=string(b.data(), b.size()-1);
257 }
258
259 template <class U>
260 void operator()(classdesc::pack_t& targ, const classdesc::string& desc, U& arg)
261 {
262 classdesc::uint64 size=0; targ>>size;
263 std::vector<cT> buf(size+1); //ensure buf[0] exists
264 targ.unpackraw(buf.data(),sizeof(cT)*size);
265 asg(arg, buf);
266 }
267 };
268}
269
270/*
271 auxilliary types
272*/
273
274#if defined(__GNUC__) && __GNUC__ < 3
275#include <pair.h> // pair is part of <utility> now
276#else
277#include <utility>
278#endif
279#ifdef _CLASSDESC
280#pragma omit pack std::pair
281#pragma omit unpack std::pair
282#endif
283
284namespace classdesc_access
285{
286 template <class A, class B> struct access_pack<std::pair<A,B> >
287 {
288 template <class U>
289 void operator()(classdesc::pack_t& targ, const classdesc::string& desc, U& arg)
290 {
291 ::pack(targ,desc,arg.first);
292 ::pack(targ,desc,arg.second);
293 }
294 };
295
296 template <class A, class B> struct access_unpack<std::pair<A,B> >
297 {
298 template <class U>
299 void operator()(classdesc::pack_t& targ, const classdesc::string& desc, U& arg)
300 {
301 ::unpack(targ,desc,arg.first);
302 ::unpack(targ,desc,arg.second);
303 }
304 };
305}
306#ifdef _CLASSDESC
307#pragma omit pack std::plus
308#pragma omit unpack std::plus
309#pragma omit pack std::minus
310#pragma omit unpack std::minus
311#pragma omit pack std::multiplies
312#pragma omit unpack std::multiplies
313#pragma omit pack std::divides
314#pragma omit unpack std::divides
315#pragma omit pack std::modulus
316#pragma omit unpack std::modulus
317#pragma omit pack negate
318#pragma omit unpack negate
319
320#pragma omit pack equal_to
321#pragma omit unpack equal_to
322#pragma omit pack not_equal_to
323#pragma omit unpack not_equal_to
324#pragma omit pack less
325#pragma omit unpack less
326#pragma omit pack greater
327#pragma omit unpack greater
328#pragma omit pack less_equal
329#pragma omit unpack less_equal
330#pragma omit pack greater_equal
331#pragma omit unpack greater_equal
332
333#pragma omit pack logical_and
334#pragma omit unpack logical_and
335#pragma omit pack logical_or
336#pragma omit unpack logical_or
337#pragma omit pack logical_not
338#pragma omit unpack logical_not
339
340#pragma omit pack identity
341#pragma omit unpack identity
342#pragma omit pack project1st
343#pragma omit unpack project1st
344#pragma omit pack project2nd
345#pragma omit unpack project2nd
346#pragma omit pack select1st
347#pragma omit unpack select1st
348#pragma omit pack select2nd
349#pragma omit unpack select2nd
350
351
352#pragma omit pack binary_function
353#pragma omit unpack binary_function
354#pragma omit pack unary_function
355#pragma omit unpack unary_function
356
357#endif
358
359#if defined(__cplusplus) && __cplusplus<201103L
360// note - these types were deprecated in C++11 and removed in C++17.
361template <class A1, class A2, class R>
362void pack(classdesc::pack_t& targ, const classdesc::string& desc, std::binary_function<A1,A2,R>& arg) {}
363
364template <class A1, class A2, class R>
365void unpack(classdesc::pack_t& targ, const classdesc::string& desc, std::binary_function<A1,A2,R>& arg) {}
366
367
368template <class A, class R>
369void pack(classdesc::pack_t& targ, const classdesc::string& desc, std::unary_function<A,R>& arg) {}
370
371template <class A, class R>
372void unpack(classdesc::pack_t& targ, const classdesc::string& desc, std::unary_function<A,R>& arg) {}
373#endif
374
375template <class C> typename
377pack(classdesc::pack_t& b, const classdesc::string& d, typename C::iterator& a)
378{}
379template <class C> typename
381unpack(classdesc::pack_t& b, const classdesc::string& d, typename C::iterator& a)
382{}
383
384#endif /* PACK_STL_H */
Definition pack_base.h:372
Iterator()
serialisation is a nop if no container provided
Definition pack_stl.h:73
Iterator()
serialisation is a nop if no container provided
Definition pack_stl.h:57
Definition pack_base.h:41
Definition pack_base.h:138
size_t size() const
size of buffer
Definition pack_base.h:170
size_t pos() const
position of read pointer
Definition pack_base.h:171
Contains access_* structs, and nothing else. These structs are used to gain access to private members...
Definition classdesc_access.h:20
Contains definitions related to classdesc functionality.
void pack(pack_t &targ, const string &desc, is_treenode dum, const T *const &arg)
serialise a tree (or DAG)
Definition pack_graph.h:28
void unpack(unpack_t &targ, const string &desc, is_treenode dum, T *&arg)
unserialise a tree.
Definition pack_graph.h:44
STL namespace.
serialisation descriptor
Definition pack_stl.h:31
controlled template specialisation: stolen from boost::enable_if.
Definition classdesc.h:282
class to allow access to private members
Definition classdesc_access.h:21
class to allow access to private members
Definition classdesc_access.h:22