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 
13 #ifndef PACK_STL_H
14 #define PACK_STL_H
15 
16 #include "pack_base.h"
17 #include <iterator>
18 
19 #include <vector>
20 #include <iterator>
21 #include <string>
22 
23 namespace classdesc
24 {
25  // utility types for marking sequences and associative containers
26  template <class T> struct sequence {};
27  template <class T> struct associative_container {};
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;
54  friend struct classdesc_access::access_pack<Iterator>;
55  friend struct classdesc_access::access_unpack<Iterator>;
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;
70  friend struct classdesc_access::access_pack<Iterator>;
71  friend struct classdesc_access::access_unpack<Iterator>;
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) << x.size();
84  if (!x.empty())
85  packer.packraw(reinterpret_cast<const char*>(&x[0]),
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  size_t sz;
93  (*this) >> sz;
94  x.resize(sz);
95  if (sz)
96  packer.unpackraw(reinterpret_cast<char*>(&x[0]),
97  x.size()*sizeof(x[0]));
98  return *this;
99  }
100 
101 }
102 
103 namespace classdesc_access
104 {
105  template <class T> struct access_pack<classdesc::sequence<T> >
106  {
107  template <class U>
108  void operator()(classdesc::pack_t& b, const classdesc::string& d, U& a)
109  {
110  b << a.size();
111  for (typename T::const_iterator i=a.begin(); i!=a.end(); ++i)
112  b << *i;
113  }
114  };
115 #if defined(__GNUC__) && !defined(__ICC)
116 #pragma GCC diagnostic push
117 #pragma GCC diagnostic ignored "-Wunused-value"
118 #endif
119  template <class T> struct access_unpack<classdesc::sequence<T> >
120  {
121  template <class U>
122  void operator()(classdesc::pack_t& b, const classdesc::string& d, U& a)
123  {
124  typename T::size_type sz;
125  b >> sz; a.resize(sz);
126  for (typename T::iterator i=a.begin(); i!=a.end(); ++i)
127  b >> *i;
128  }
129  template <class U>
130  void operator()(classdesc::pack_t& b, const classdesc::string& d, const U& a)
131  {
132  typename T::size_type sz;
133  b >> sz;
134  typename T::value_type x;
135  for (unsigned i=0; i<sz; ++i) b>>x;
136  }
137  };
138 #if defined(__GNUC__) && !defined(__ICC)
139 #pragma GCC diagnostic pop
140 #endif
141 
142  template <class T>
143  struct access_pack<classdesc::associative_container<T> >:
144  access_pack<classdesc::sequence<T> > {};
145 
146  template <class T> struct access_unpack<classdesc::associative_container<T> >
147  {
148  template <class U>
149  void operator()(classdesc::pack_t& b, const classdesc::string& d, U& a)
150  {
151  typename T::size_type sz;
152  b >> sz;
153  a.clear();
154  for (typename T::size_type i=0; i<sz; ++i)
155  {
156  typename classdesc::Value_Type<T>::value_type e;
157  b >> e;
158  a.insert(e);
159  }
160  }
161  };
162 
163 
164  template <class T>
165  struct access_pack<classdesc::Iterator<T> >
166  {
167  template <class U>
168  void operator()(classdesc::pack_t& b, const classdesc::string& d, U& a)
169  {
170  typename T::size_type i=a.container?
171  std::distance(a.container->begin(),a.iter()): 0;
172  b << i;
173  }
174  };
175 
176  template <class T>
177  struct access_unpack<classdesc::Iterator<T> >
178  {
179  template <class U>
180  void operator()(classdesc::pack_t& b, const classdesc::string& d, U& a)
181  {
182  typename T::size_type i;
183  b >> i;
184  if (a.container)
185  {
186  a=a.container->begin();
187  std::advance(a.iter(),i);
188  }
189  }
190  };
191 
192 /*
193  strings
194 */
195 
196 #ifdef _CLASSDESC
197 #pragma omit pack std::char_traits
198 #pragma omit unpack std::char_traits
199 #pragma omit pack std::basic_string
200 #pragma omit unpack std::basic_string
201 #pragma omit pack std::string
202 #pragma omit unpack std::string
203 #endif
204 
205  template <class cT, class t, class A>
206  struct access_pack<std::basic_string<cT,t,A> >
207  {
208  template <class U>
209  void operator()(classdesc::pack_t& targ, const classdesc::string& desc, U& arg)
210  {targ<<arg.size(); targ.packraw(arg.data(),arg.size());}
211  };
212 
213  template <class cT, class t, class A>
214  struct access_unpack<std::basic_string<cT,t,A> >
215  {
216  typedef std::basic_string<cT,t,A> string;
217  void asg(const string& x, const std::vector<cT>& b) {}
218  void asg(string& x, const std::vector<cT>& b)
219  {
220  if (!b.empty())
221  x=string(&b[0], b.size()-1);
222  }
223 
224  template <class U>
225  void operator()(classdesc::pack_t& targ, const classdesc::string& desc, U& arg)
226  {
227  typename string::size_type size; targ>>size;
228  std::vector<cT> buf(size+1); //ensure buf[0] exists
229  targ.unpackraw(&buf[0],size);
230  asg(arg, buf);
231  }
232  };
233 }
234 
235 /*
236  auxilliary types
237 */
238 
239 #if defined(__GNUC__) && __GNUC__ < 3
240 #include <pair.h> // pair is part of <utility> now
241 #else
242 #include <utility>
243 #endif
244 #ifdef _CLASSDESC
245 #pragma omit pack std::pair
246 #pragma omit unpack std::pair
247 #endif
248 
249 namespace classdesc_access
250 {
251  template <class A, class B> struct access_pack<std::pair<A,B> >
252  {
253  template <class U>
254  void operator()(classdesc::pack_t& targ, const classdesc::string& desc, U& arg)
255  {
256  ::pack(targ,desc,arg.first);
257  ::pack(targ,desc,arg.second);
258  }
259  };
260 
261  template <class A, class B> struct access_unpack<std::pair<A,B> >
262  {
263  template <class U>
264  void operator()(classdesc::pack_t& targ, const classdesc::string& desc, U& arg)
265  {
266  ::unpack(targ,desc,arg.first);
267  ::unpack(targ,desc,arg.second);
268  }
269  };
270 }
271 #ifdef _CLASSDESC
272 #pragma omit pack std::plus
273 #pragma omit unpack std::plus
274 #pragma omit pack std::minus
275 #pragma omit unpack std::minus
276 #pragma omit pack std::multiplies
277 #pragma omit unpack std::multiplies
278 #pragma omit pack std::divides
279 #pragma omit unpack std::divides
280 #pragma omit pack std::modulus
281 #pragma omit unpack std::modulus
282 #pragma omit pack negate
283 #pragma omit unpack negate
284 
285 #pragma omit pack equal_to
286 #pragma omit unpack equal_to
287 #pragma omit pack not_equal_to
288 #pragma omit unpack not_equal_to
289 #pragma omit pack less
290 #pragma omit unpack less
291 #pragma omit pack greater
292 #pragma omit unpack greater
293 #pragma omit pack less_equal
294 #pragma omit unpack less_equal
295 #pragma omit pack greater_equal
296 #pragma omit unpack greater_equal
297 
298 #pragma omit pack logical_and
299 #pragma omit unpack logical_and
300 #pragma omit pack logical_or
301 #pragma omit unpack logical_or
302 #pragma omit pack logical_not
303 #pragma omit unpack logical_not
304 
305 #pragma omit pack identity
306 #pragma omit unpack identity
307 #pragma omit pack project1st
308 #pragma omit unpack project1st
309 #pragma omit pack project2nd
310 #pragma omit unpack project2nd
311 #pragma omit pack select1st
312 #pragma omit unpack select1st
313 #pragma omit pack select2nd
314 #pragma omit unpack select2nd
315 
316 
317 #pragma omit pack binary_function
318 #pragma omit unpack binary_function
319 #endif
320 
321 template <class A1, class A2, class R>
322 void pack(classdesc::pack_t& targ, const classdesc::string& desc, std::binary_function<A1,A2,R>& arg) {}
323 
324 template <class A1, class A2, class R>
325 void unpack(classdesc::pack_t& targ, const classdesc::string& desc, std::binary_function<A1,A2,R>& arg) {}
326 
327 #ifdef _CLASSDESC
328 #pragma omit pack unary_function
329 #pragma omit unpack unary_function
330 #endif
331 
332 template <class A, class R>
333 void pack(classdesc::pack_t& targ, const classdesc::string& desc, std::unary_function<A,R>& arg) {}
334 
335 template <class A, class R>
336 void unpack(classdesc::pack_t& targ, const classdesc::string& desc, std::unary_function<A,R>& arg) {}
337 
338 template <class C> typename
340 pack(classdesc::pack_t& b, const classdesc::string& d, typename C::iterator& a)
341 {}
342 template <class C> typename
344 unpack(classdesc::pack_t& b, const classdesc::string& d, typename C::iterator& a)
345 {}
346 
347 using classdesc::pack;
348 using classdesc::unpack;
349 
350 #endif /* PACK_STL_H */
size_t size() const
size of buffer
Definition: pack_base.h:154
Definition: graph.h:537
serialisation descriptor
Definition: pack_base.h:330
Definition: pack_stl.h:27
class to allow access to private members
Definition: classdesc_access.h:21
class to allow access to private members
Definition: classdesc_access.h:22
Iterator()
serialisation is a nop if no container provided
Definition: pack_stl.h:73
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
Contains definitions related to classdesc functionality.
Definition: arrays.h:2514
Definition: pack_base.h:124
controlled template specialisation: stolen from boost::enable_if.
Definition: classdesc.h:249
Definition: pack_stl.h:26
Iterator()
serialisation is a nop if no container provided
Definition: pack_stl.h:57
Definition: pack_stl.h:30
Contains access_* structs, and nothing else. These structs are used to gain access to private members...
Definition: accessor.h:55
Definition: pack_stl.h:50
void unpack(unpack_t &targ, const string &desc, is_treenode dum, T *&arg)
unserialise a tree.
Definition: pack_graph.h:44