COMBINATORIAL_BLAS 1.6
 
Loading...
Searching...
No Matches
Serialize.h
Go to the documentation of this file.
1#ifndef _SERIALIZE_H_
2#define _SERIALIZE_H_
3#include <iostream>
4#include <sstream>
5#include <vector>
6#include <set>
7#include <map>
8#include <tuple>
9
10// our "interface" for encoding
11// template<class T>
12// void encode(std::streambuf& os, T t);
13
14// our "interface" for decoding
15// template<class T>
16// void decode(std::streambuf& os, T& t);
17
18// helpers to encode pointers to arrays of data
19// also works for single elements
20template<class T>
21void encode(std::streambuf& os, T* t, size_t size = 1) {
22 os.sputn((char*)t, sizeof(T)*size);
23}
24
25template<class T>
26void decode(std::streambuf& os, T* t, size_t size = 1) {
27 os.sgetn((char*)t, sizeof(T)*size);
28}
29
30// This is a macro to allow easy construction of encode and decode for
31// trivial to serialize types.
32// Trivially serializable types are any type that can be copied by
33// copying its memory.
34// As a rule of thumb, anything with a pointer is not trivially serializable
35#define TRIVIALLY_SERIALIZABLE(T) \
36 void encode(std::streambuf& os, const T& t) { \
37 encode(os, &t); \
38 } \
39 void decode(std::streambuf& os, T& t) { \
40 decode(os, &t); \
41 }
42
43// integral types serialization methods
47TRIVIALLY_SERIALIZABLE(unsigned short int);
51TRIVIALLY_SERIALIZABLE(unsigned long int);
53TRIVIALLY_SERIALIZABLE(unsigned long long int);
54
55
56// STL container serializers
57// Some of these functions have template specializations to increase performance when
58// the entire structure exists as a contiguous piece of memory
59// we need some prototypes TODO: clean up order of functions
60template<class T>
61void decode(std::streambuf& os, std::set<T>& v);
62
63// std::pair
64// we pray that std::pair is contiguous memory
65// TODO: is it?
66template<class T, class S>
67inline
68typename std::enable_if<std::is_pod<T>::value && std::is_pod<S>::value, void>::type
69encode(std::streambuf& os, const std::pair<T, S>& p) {
70 encode(os, &p);
71}
72
73// specialization for non-contiguous mem
74template<class T, class S>
75inline
76typename std::enable_if<!(std::is_pod<T>::value && std::is_pod<S>::value), void>::type
77encode(std::streambuf& os, const std::pair<T, S>& p) {
78 encode(os, p.first);
79 encode(os, p.second);
80}
81
82template<class T, class S>
83inline
84typename std::enable_if<std::is_pod<T>::value && std::is_pod<S>::value, void>::type
85decode(std::streambuf& os, std::pair<T, S>& p) {
86 decode(os, &p);
87}
88
89template<class T, class S>
90inline
91typename std::enable_if<!(std::is_pod<T>::value && std::is_pod<S>::value), void>::type
92decode(std::streambuf& os, std::pair<T, S>& p) {
93 decode(os, p.first);
94 decode(os, p.second);
95}
96
97// helper to encode a size plus an interator
98template<class Iter>
99inline
100void encode_iter(std::streambuf& os, size_t size, Iter begin, Iter end);
101
102// std::vector
103
104// specialized for contiguous memory
105template<class T>
106inline
107typename std::enable_if<std::is_pod<T>::value, void>::type
108encode(std::streambuf& os, const std::vector<T>& v) {
109 encode(os, v.size());
110 encode(os, v.data(), v.size());
111}
112
113template<class T>
114inline
115typename std::enable_if<!std::is_pod<T>::value, void>::type
116encode(std::streambuf& os, const std::vector<T>& v) {
117 encode_iter(os, v.size(), v.begin(), v.end());
118}
119
120template<class T>
121inline
122typename std::enable_if<std::is_pod<T>::value, void>::type
123decode(std::streambuf& os, std::vector<T>& v) {
124 // read size of the vector
125 size_t size;
126 decode(os, size);
127 v.resize(size); // we know the size, so we reserve space
128 decode(os, v.data(), size);
129}
130
131template<class T>
132inline
133typename std::enable_if<!std::is_pod<T>::value, void>::type
134decode(std::streambuf& os, std::vector<T>& v) {
135 v.clear();
136 size_t size;
137 decode(os, size);
138 v.reserve(size);
139 for(size_t i = 0; i < size; i++) {
140 typename std::remove_reference<decltype(v)>::type::value_type t;
141 decode(os, t);
142 v.emplace_back(std::move(t));
143 }
144}
145
146// std::set
147template<class T>
148inline
149void encode(std::streambuf& os, const std::set<T>& v) {
150 encode_iter(os, v.size(), v.begin(), v.end());
151}
152
153template<class T>
154inline
155void decode_thing(std::streambuf& os, T& v) {
156 v.clear();
157 size_t size;
158 decode(os, size);
159 auto hint = v.end();
160 for(size_t i = 0; i < size; i++) {
161 typename std::remove_reference<decltype(v)>::type::value_type t;
162 decode(os, t);
163 hint = v.emplace_hint(hint, std::move(t));
164 }
165}
166
167template<class T>
168inline
169void decode(std::streambuf& os, std::set<T>& v) {
170 decode_thing(os, v);
171}
172
173// std::map
174template<class T, class S>
175inline
176void encode(std::streambuf& os, const std::map<T, S>& v) {
177 encode_iter(os, v.size(), v.begin(), v.end());
178}
179
180template<class T, class S>
181inline
182void decode(std::streambuf& os, std::map<T, S>& v) {
183 decode_thing(os, v);
184}
185
186// std::multimap
187template<class T, class S>
188inline
189void encode(std::streambuf& os, const std::multimap<T, S>& v) {
190 encode_iter(os, v.size(), v.begin(), v.end());
191}
192
193template<class T, class S>
194inline
195void decode(std::streambuf& os, std::multimap<T, S>& v) {
196 decode_thing(os, v);
197}
198
199template<class Iter>
200inline
201void encode_iter(std::streambuf& os, size_t size, Iter begin, Iter end) {
202 encode(os, size);
203 for (; begin != end; ++begin) {
204 encode(os, *begin);
205 }
206}
207
208#endif
void decode(std::streambuf &os, T *t, size_t size=1)
Definition Serialize.h:26
void encode(std::streambuf &os, T *t, size_t size=1)
Definition Serialize.h:21
void decode_thing(std::streambuf &os, T &v)
Definition Serialize.h:155
#define TRIVIALLY_SERIALIZABLE(T)
Definition Serialize.h:35
void encode_iter(std::streambuf &os, size_t size, Iter begin, Iter end)
Definition Serialize.h:201
int size
Definition common.h:20