Pothos  0.7.0-gf7fbae99
The Pothos dataflow programming software suite
Numbers.hpp
Go to the documentation of this file.
1 
21 #pragma once
22 #include <Pothos/Config.hpp>
25 #include <type_traits>
26 #include <limits> //is_iec559
27 
28 namespace Pothos {
29 namespace serialization {
30 
31 //------------ boolean support --------------//
32 template<typename Archive>
33 void save(Archive &ar, const bool &t, const unsigned int)
34 {
35  unsigned char value(t?1:0);
36  ar << value;
37 }
38 
39 template<typename Archive>
40 void load(Archive &ar, bool &t, const unsigned int)
41 {
42  unsigned char value;
43  ar >> value;
44  t = (value == 0)?false:true;
45 }
46 
47 //------------ 8 bit integer support (all char types) --------------//
48 template<typename Archive, typename T>
49 typename std::enable_if<
50  std::is_same<T, unsigned char>::value or
51  std::is_same<T, signed char>::value or
52  std::is_same<T, char>::value
53 >::type save(Archive &ar, const T &t, const unsigned int)
54 {
55  BinaryObject bo(&t, 1);
56  ar << bo;
57 }
58 
59 template<typename Archive, typename T>
60 typename std::enable_if<
61  std::is_same<T, unsigned char>::value or
62  std::is_same<T, signed char>::value or
63  std::is_same<T, char>::value
64 >::type load(Archive &ar, T &t, const unsigned int)
65 {
66  BinaryObject bo(&t, 1);
67  ar >> bo;
68 }
69 
70 //------------ 16 bit integer support (short types) --------------//
71 template<typename Archive, typename T>
72 typename std::enable_if<
73  std::is_same<T, unsigned short>::value or
74  std::is_same<T, signed short>::value
75 >::type save(Archive &ar, const T &t, const unsigned int)
76 {
77  unsigned char buff[2];
78  const auto v = static_cast<unsigned short>(t);
79  buff[0] = static_cast<unsigned char>(v >> 0);
80  buff[1] = static_cast<unsigned char>(v >> 8);
81  BinaryObject bo(buff, sizeof(buff));
82  ar << bo;
83 }
84 
85 template<typename Archive, typename T>
86 typename std::enable_if<
87  std::is_same<T, unsigned short>::value or
88  std::is_same<T, signed short>::value
89 >::type load(Archive &ar, T &t, const unsigned int)
90 {
91  unsigned char buff[2];
92  BinaryObject bo(buff, sizeof(buff));
93  ar >> bo;
94  t = static_cast<T>(
95  (static_cast<unsigned short>(buff[0]) << 0) |
96  (static_cast<unsigned short>(buff[1]) << 8));
97 }
98 
99 //------------ 32-64 bit signed integer types --------------//
100 // use signed LEB128 encoding for variable length encoding
101 // https://en.wikipedia.org/wiki/LEB128
102 template<typename Archive, typename T>
103 typename std::enable_if<
104  std::is_same<T, signed int>::value or
105  std::is_same<T, signed long>::value or
106  std::is_same<T, signed long long>::value
107 >::type save(Archive &ar, const T &t, const unsigned int)
108 {
109  T value(t);
110  unsigned char byte;
111  do
112  {
113  byte = static_cast<unsigned char>(value) & 0x7f;
114  value >>= 7; //must be arithmetic shift
115  const auto signbit = byte & 0x40;
116  if ((value != 0 or signbit != 0) and
117  (value != -1 or signbit == 0)) byte |= 0x80;
118  ar << byte;
119  } while ((byte & 0x80) != 0);
120 }
121 
122 template<typename Archive, typename T>
123 typename std::enable_if<
124  std::is_same<T, signed int>::value or
125  std::is_same<T, signed long>::value or
126  std::is_same<T, signed long long>::value
127 >::type load(Archive &ar, T &t, const unsigned int)
128 {
129  t = T(0);
130  unsigned shift(0);
131  unsigned char byte;
132  do
133  {
134  ar >> byte;
135  t |= T(byte & 0x7f) << shift;
136  shift += 7;
137  } while ((byte & 0x80) != 0);
138 
139  //sign extend the remaining bits when negative
140  const auto signbit = byte & 0x40;
141  if (signbit != 0 and shift < (sizeof(T)*8)) t |= -(1 << shift);
142 }
143 
144 //------------ 32-64 bit unsigned integer types --------------//
145 // use unsigned LEB128 encoding for variable length encoding
146 // https://en.wikipedia.org/wiki/LEB128
147 template<typename Archive, typename T>
148 typename std::enable_if<
149  std::is_same<T, unsigned int>::value or
150  std::is_same<T, unsigned long>::value or
151  std::is_same<T, unsigned long long>::value
152 >::type save(Archive &ar, const T &t, const unsigned int)
153 {
154  T value(t);
155  unsigned char byte;
156  do
157  {
158  byte = static_cast<unsigned char>(value) & 0x7f;
159  value >>= 7;
160  if (value != 0) byte |= 0x80;
161  ar << byte;
162  } while ((byte & 0x80) != 0);
163 }
164 
165 template<typename Archive, typename T>
166 typename std::enable_if<
167  std::is_same<T, unsigned int>::value or
168  std::is_same<T, unsigned long>::value or
169  std::is_same<T, unsigned long long>::value
170 >::type load(Archive &ar, T &t, const unsigned int)
171 {
172  t = T(0);
173  unsigned shift(0);
174  unsigned char byte;
175  do
176  {
177  ar >> byte;
178  t |= T(byte & 0x7f) << shift;
179  shift += 7;
180  } while ((byte & 0x80) != 0);
181 }
182 
183 //------------ 32-bit float support --------------//
184 static_assert(std::numeric_limits<float>::is_iec559, "System is IEEE-754");
185 
186 template<typename Archive>
187 typename std::enable_if<std::numeric_limits<float>::is_iec559>::type
188 save(Archive &ar, const float &t, const unsigned int)
189 {
190  const void *bin(&t);
191  ar << *static_cast<const unsigned int *>(bin);
192 }
193 
194 template<typename Archive>
195 typename std::enable_if<std::numeric_limits<float>::is_iec559>::type
196 load(Archive &ar, float &t, const unsigned int)
197 {
198  unsigned int num;
199  ar >> num;
200  const void *bin(&num);
201  t = *reinterpret_cast<const float *>(bin);
202 }
203 
204 //------------ 64-bit float support --------------//
205 static_assert(std::numeric_limits<double>::is_iec559, "System is IEEE-754");
206 
207 template<typename Archive>
208 typename std::enable_if<std::numeric_limits<double>::is_iec559>::type
209 save(Archive &ar, const double &t, const unsigned int)
210 {
211  const void *bin(&t);
212  ar << *static_cast<const unsigned long long *>(bin);
213 }
214 
215 template<typename Archive>
216 typename std::enable_if<std::numeric_limits<double>::is_iec559>::type
217 load(Archive &ar, double &t, const unsigned int)
218 {
219  unsigned long long num;
220  ar >> num;
221  const void *bin(&num);
222  t = *reinterpret_cast<const double *>(bin);
223 }
224 
225 //------------ serialize for integers and floats --------------//
226 template <typename Archive, typename T>
227 typename std::enable_if<std::is_arithmetic<T>::value>::type
228 serialize(Archive &ar, T &t, const unsigned int ver)
229 {
231 }
232 
233 }}
Definition: ArchiveEntry.hpp:20
std::enable_if< Archive::isSave::value >::type invokeSplit(Archive &ar, T &value, const unsigned int ver)
Definition: Invoke.hpp:69
void save(Archive &ar, const std::complex< T > &t, const unsigned int)
Definition: Complex.hpp:20
void serialize(Archive &ar, std::complex< T > &t, const unsigned int ver)
Definition: Complex.hpp:37
Definition: BinaryObject.hpp:23
void load(Archive &ar, std::complex< T > &t, const unsigned int)
Definition: Complex.hpp:27