/src/mcl/include/cybozu/itoa.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | /** |
3 | | @file |
4 | | @brief convert integer to string(ascii) |
5 | | |
6 | | @author MITSUNARI Shigeo(@herumi) |
7 | | */ |
8 | | #ifndef CYBOZU_DONT_USE_STRING |
9 | | #include <string> |
10 | | #endif |
11 | | #include <memory.h> |
12 | | #include <cybozu/inttype.hpp> |
13 | | #include <cybozu/bit_operation.hpp> |
14 | | |
15 | | namespace cybozu { |
16 | | |
17 | | template<class T> |
18 | | size_t getHexLength(T x) |
19 | 0 | { |
20 | 0 | return x == 0 ? 1 : cybozu::bsr(x) / 4 + 1; |
21 | 0 | } Unexecuted instantiation: unsigned long cybozu::getHexLength<unsigned long>(unsigned long) Unexecuted instantiation: unsigned long cybozu::getHexLength<unsigned char>(unsigned char) Unexecuted instantiation: unsigned long cybozu::getHexLength<unsigned short>(unsigned short) Unexecuted instantiation: unsigned long cybozu::getHexLength<unsigned int>(unsigned int) Unexecuted instantiation: unsigned long cybozu::getHexLength<unsigned long long>(unsigned long long) |
22 | | |
23 | | template<class T> |
24 | | size_t getBinLength(T x) |
25 | 0 | { |
26 | 0 | return x == 0 ? 1 : cybozu::bsr(x) + 1; |
27 | 0 | } Unexecuted instantiation: unsigned long cybozu::getBinLength<unsigned long>(unsigned long) Unexecuted instantiation: unsigned long cybozu::getBinLength<unsigned char>(unsigned char) Unexecuted instantiation: unsigned long cybozu::getBinLength<unsigned short>(unsigned short) Unexecuted instantiation: unsigned long cybozu::getBinLength<unsigned int>(unsigned int) Unexecuted instantiation: unsigned long cybozu::getBinLength<unsigned long long>(unsigned long long) |
28 | | /* |
29 | | convert x to hex string with len |
30 | | @note out should have getHexLength(x) size |
31 | | out is not NUL terminated |
32 | | */ |
33 | | template<class T> |
34 | | void itohex(char *out, size_t len, T x, bool upCase = true) |
35 | 0 | { |
36 | 0 | static const char *hexTbl[] = { |
37 | 0 | "0123456789abcdef", |
38 | 0 | "0123456789ABCDEF" |
39 | 0 | }; |
40 | 0 | const char *tbl = hexTbl[upCase]; |
41 | 0 | for (size_t i = 0; i < len; i++) { |
42 | 0 | out[len - i - 1] = tbl[x % 16]; |
43 | 0 | x /= 16; |
44 | 0 | } |
45 | 0 | } Unexecuted instantiation: void cybozu::itohex<unsigned char>(char*, unsigned long, unsigned char, bool) Unexecuted instantiation: void cybozu::itohex<unsigned long>(char*, unsigned long, unsigned long, bool) Unexecuted instantiation: void cybozu::itohex<unsigned short>(char*, unsigned long, unsigned short, bool) Unexecuted instantiation: void cybozu::itohex<unsigned int>(char*, unsigned long, unsigned int, bool) Unexecuted instantiation: void cybozu::itohex<unsigned long long>(char*, unsigned long, unsigned long long, bool) |
46 | | /* |
47 | | convert x to bin string with len |
48 | | @note out should have getBinLength(x) size |
49 | | out is not NUL terminated |
50 | | */ |
51 | | template<class T> |
52 | | void itobin(char *out, size_t len, T x) |
53 | 0 | { |
54 | 0 | for (size_t i = 0; i < len; i++) { |
55 | 0 | out[len - i - 1] = '0' + (x & 1); |
56 | 0 | x >>= 1; |
57 | 0 | } |
58 | 0 | } Unexecuted instantiation: void cybozu::itobin<unsigned long>(char*, unsigned long, unsigned long) Unexecuted instantiation: void cybozu::itobin<unsigned char>(char*, unsigned long, unsigned char) Unexecuted instantiation: void cybozu::itobin<unsigned short>(char*, unsigned long, unsigned short) Unexecuted instantiation: void cybozu::itobin<unsigned int>(char*, unsigned long, unsigned int) Unexecuted instantiation: void cybozu::itobin<unsigned long long>(char*, unsigned long, unsigned long long) |
59 | | |
60 | | namespace itoa_local { |
61 | | |
62 | | /* |
63 | | convert x to dec |
64 | | use buf[0, bufSize) |
65 | | return 0 if false |
66 | | return writtenSize which is not terminated |
67 | | @REMARK the top of string is buf + bufSize - writtenSize |
68 | | */ |
69 | | template<class UT> |
70 | | size_t uintToDec(char *buf, size_t bufSize, UT x) |
71 | 419k | { |
72 | 3.22M | for (size_t i = 0; i < bufSize; i++) { |
73 | 3.22M | buf[bufSize - 1 - i] = '0' + static_cast<int>(x % 10); |
74 | 3.22M | x /= 10; |
75 | 3.22M | if (x == 0) return i + 1; |
76 | 3.22M | } |
77 | 0 | return 0; |
78 | 419k | } unsigned long cybozu::itoa_local::uintToDec<unsigned int>(char*, unsigned long, unsigned int) Line | Count | Source | 71 | 419k | { | 72 | 3.22M | for (size_t i = 0; i < bufSize; i++) { | 73 | 3.22M | buf[bufSize - 1 - i] = '0' + static_cast<int>(x % 10); | 74 | 3.22M | x /= 10; | 75 | 3.22M | if (x == 0) return i + 1; | 76 | 3.22M | } | 77 | 0 | return 0; | 78 | 419k | } |
Unexecuted instantiation: unsigned long cybozu::itoa_local::uintToDec<unsigned long>(char*, unsigned long, unsigned long) Unexecuted instantiation: unsigned long cybozu::itoa_local::uintToDec<unsigned long long>(char*, unsigned long, unsigned long long) |
79 | | |
80 | | /* |
81 | | convert x to hex |
82 | | use buf[0, bufSize) |
83 | | return 0 if false |
84 | | return writtenSize which is not terminated |
85 | | @REMARK the top of string is buf + bufSize - writtenSize |
86 | | */ |
87 | | template<class UT> |
88 | | size_t uintToHex(char *buf, size_t bufSize, UT x, bool upCase = true) |
89 | | { |
90 | | static const char *hexTbl[] = { |
91 | | "0123456789abcdef", |
92 | | "0123456789ABCDEF" |
93 | | }; |
94 | | const char *tbl = hexTbl[upCase]; |
95 | | for (size_t i = 0; i < bufSize; i++) { |
96 | | buf[bufSize - 1 - i] = tbl[x % 16]; |
97 | | x /= 16; |
98 | | if (x == 0) return i + 1; |
99 | | } |
100 | | return 0; |
101 | | } |
102 | | |
103 | | /* |
104 | | convert x to bin |
105 | | use buf[0, bufSize) |
106 | | return 0 if false |
107 | | return writtenSize which is not terminated |
108 | | @REMARK the top of string is buf + bufSize - writtenSize |
109 | | */ |
110 | | template<class UT> |
111 | | size_t uintToBin(char *buf, size_t bufSize, UT x) |
112 | | { |
113 | | for (size_t i = 0; i < bufSize; i++) { |
114 | | buf[bufSize - 1 - i] = '0' + (x & 1); |
115 | | x >>= 1; |
116 | | if (x == 0) return i + 1; |
117 | | } |
118 | | return 0; |
119 | | } |
120 | | |
121 | | template<class T> |
122 | | size_t intToDec(char *buf, size_t bufSize, T x) |
123 | 0 | { |
124 | 0 | if (x == CYBOZU_LLONG_MIN) { |
125 | 0 | const char minStr[] = "-9223372036854775808"; |
126 | 0 | const size_t minStrLen = sizeof(minStr) - 1; |
127 | 0 | if (bufSize < minStrLen) { |
128 | 0 | return 0; |
129 | 0 | } else { |
130 | 0 | memcpy(buf + bufSize - minStrLen, minStr, minStrLen); |
131 | 0 | return minStrLen; |
132 | 0 | } |
133 | 0 | } |
134 | 0 | bool negative = x < 0; |
135 | 0 | uint64_t absX = negative ? -x : x; |
136 | 0 | size_t n = uintToDec(buf, bufSize, absX); |
137 | 0 | if (n == 0) return 0; |
138 | 0 | if (negative) { |
139 | 0 | if (bufSize == n) return 0; |
140 | 0 | n++; |
141 | 0 | buf[bufSize - n] = '-'; |
142 | 0 | } |
143 | 0 | return n; |
144 | 0 | } |
145 | | |
146 | | #ifndef CYBOZU_DONT_USE_STRING |
147 | | template<typename T> |
148 | | void convertFromUint(std::string& out, T x) |
149 | 0 | { |
150 | 0 | char buf[40]; |
151 | 0 | size_t n = uintToDec(buf, sizeof(buf), x); |
152 | 0 | assert(n > 0); |
153 | 0 | out.assign(buf + sizeof(buf) - n, n); |
154 | 0 | } Unexecuted instantiation: void cybozu::itoa_local::convertFromUint<unsigned int>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned int) Unexecuted instantiation: void cybozu::itoa_local::convertFromUint<unsigned long long>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned long long) |
155 | | |
156 | | inline void convertFromInt(std::string& out, long long x) |
157 | 0 | { |
158 | 0 | char buf[40]; |
159 | 0 | size_t n = intToDec(buf, sizeof(buf), x); |
160 | 0 | assert(n > 0); |
161 | 0 | out.assign(buf + sizeof(buf) - n, n); |
162 | 0 | } |
163 | | |
164 | | template<typename T> |
165 | | void itohexLocal(std::string& out, T x, bool upCase, bool withZero) |
166 | 0 | { |
167 | 0 | const size_t size = withZero ? sizeof(T) * 2 : getHexLength(x); |
168 | 0 | out.resize(size); |
169 | 0 | itohex(&out[0], size, x, upCase); |
170 | 0 | } Unexecuted instantiation: void cybozu::itoa_local::itohexLocal<unsigned char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned char, bool, bool) Unexecuted instantiation: void cybozu::itoa_local::itohexLocal<unsigned short>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned short, bool, bool) Unexecuted instantiation: void cybozu::itoa_local::itohexLocal<unsigned int>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned int, bool, bool) Unexecuted instantiation: void cybozu::itoa_local::itohexLocal<unsigned long>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned long, bool, bool) Unexecuted instantiation: void cybozu::itoa_local::itohexLocal<unsigned long long>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned long long, bool, bool) |
171 | | |
172 | | template<class T> |
173 | | void itobinLocal(std::string& out, T x, bool withZero) |
174 | 0 | { |
175 | 0 | const size_t size = withZero ? sizeof(T) * 8 : getBinLength(x); |
176 | 0 | out.resize(size); |
177 | 0 | itobin(&out[0], size, x); |
178 | 0 | } Unexecuted instantiation: void cybozu::itoa_local::itobinLocal<unsigned char>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned char, bool) Unexecuted instantiation: void cybozu::itoa_local::itobinLocal<unsigned short>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned short, bool) Unexecuted instantiation: void cybozu::itoa_local::itobinLocal<unsigned int>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned int, bool) Unexecuted instantiation: void cybozu::itoa_local::itobinLocal<unsigned long>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned long, bool) Unexecuted instantiation: void cybozu::itoa_local::itobinLocal<unsigned long long>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned long long, bool) |
179 | | #endif |
180 | | |
181 | | } // itoa_local |
182 | | |
183 | | #ifndef CYBOZU_DONT_USE_STRING |
184 | | /** |
185 | | convert int to string |
186 | | @param out [out] string |
187 | | @param x [in] int |
188 | | */ |
189 | | inline void itoa(std::string& out, int x) |
190 | 0 | { |
191 | 0 | itoa_local::convertFromInt(out, x); |
192 | 0 | } |
193 | | |
194 | | /** |
195 | | convert long long to string |
196 | | @param out [out] string |
197 | | @param x [in] long long |
198 | | */ |
199 | | inline void itoa(std::string& out, long long x) |
200 | 0 | { |
201 | 0 | itoa_local::convertFromInt(out, x); |
202 | 0 | } |
203 | | |
204 | | /** |
205 | | convert unsigned int to string |
206 | | @param out [out] string |
207 | | @param x [in] unsigned int |
208 | | */ |
209 | | inline void itoa(std::string& out, unsigned int x) |
210 | 0 | { |
211 | 0 | itoa_local::convertFromUint(out, x); |
212 | 0 | } |
213 | | |
214 | | /** |
215 | | convert unsigned long long to string |
216 | | @param out [out] string |
217 | | @param x [in] unsigned long long |
218 | | */ |
219 | | inline void itoa(std::string& out, unsigned long long x) |
220 | 0 | { |
221 | 0 | itoa_local::convertFromUint(out, x); |
222 | 0 | } |
223 | | |
224 | | #if defined(__SIZEOF_LONG__) && (__SIZEOF_LONG__ == 8) |
225 | 0 | inline void itoa(std::string& out, long x) { itoa(out, static_cast<long long>(x)); } |
226 | 0 | inline void itoa(std::string& out, unsigned long x) { itoa(out, static_cast<unsigned long long>(x)); } |
227 | | #else |
228 | | inline void itoa(std::string& out, long x) { itoa(out, static_cast<int>(x)); } |
229 | | inline void itoa(std::string& out, unsigned long x) { itoa(out, static_cast<int>(x)); } |
230 | | #endif |
231 | | /** |
232 | | convert integer to string |
233 | | @param x [in] int |
234 | | */ |
235 | | template<typename T> |
236 | | inline std::string itoa(T x) |
237 | | { |
238 | | std::string ret; |
239 | | itoa(ret, x); |
240 | | return ret; |
241 | | } |
242 | | |
243 | | inline void itohex(std::string& out, unsigned char x, bool upCase = true, bool withZero = true) |
244 | 0 | { |
245 | 0 | itoa_local::itohexLocal(out, x, upCase, withZero); |
246 | 0 | } |
247 | | |
248 | | inline void itohex(std::string& out, unsigned short x, bool upCase = true, bool withZero = true) |
249 | 0 | { |
250 | 0 | itoa_local::itohexLocal(out, x, upCase, withZero); |
251 | 0 | } |
252 | | |
253 | | inline void itohex(std::string& out, unsigned int x, bool upCase = true, bool withZero = true) |
254 | 0 | { |
255 | 0 | itoa_local::itohexLocal(out, x, upCase, withZero); |
256 | 0 | } |
257 | | |
258 | | inline void itohex(std::string& out, unsigned long x, bool upCase = true, bool withZero = true) |
259 | 0 | { |
260 | 0 | itoa_local::itohexLocal(out, x, upCase, withZero); |
261 | 0 | } |
262 | | |
263 | | inline void itohex(std::string& out, unsigned long long x, bool upCase = true, bool withZero = true) |
264 | 0 | { |
265 | 0 | itoa_local::itohexLocal(out, x, upCase, withZero); |
266 | 0 | } |
267 | | |
268 | | template<typename T> |
269 | | inline std::string itobin(T x, bool withZero = true) |
270 | | { |
271 | | std::string out; |
272 | | itoa_local::itobinLocal(out, x, withZero); |
273 | | return out; |
274 | | } |
275 | | |
276 | | inline void itobin(std::string& out, unsigned char x, bool withZero = true) |
277 | 0 | { |
278 | 0 | itoa_local::itobinLocal(out, x, withZero); |
279 | 0 | } |
280 | | |
281 | | inline void itobin(std::string& out, unsigned short x, bool withZero = true) |
282 | 0 | { |
283 | 0 | itoa_local::itobinLocal(out, x, withZero); |
284 | 0 | } |
285 | | |
286 | | inline void itobin(std::string& out, unsigned int x, bool withZero = true) |
287 | 0 | { |
288 | 0 | itoa_local::itobinLocal(out, x, withZero); |
289 | 0 | } |
290 | | |
291 | | inline void itobin(std::string& out, unsigned long x, bool withZero = true) |
292 | 0 | { |
293 | 0 | itoa_local::itobinLocal(out, x, withZero); |
294 | 0 | } |
295 | | |
296 | | inline void itobin(std::string& out, unsigned long long x, bool withZero = true) |
297 | 0 | { |
298 | 0 | itoa_local::itobinLocal(out, x, withZero); |
299 | 0 | } |
300 | | |
301 | | template<typename T> |
302 | | inline std::string itohex(T x, bool upCase = true, bool withZero = true) |
303 | | { |
304 | | std::string out; |
305 | | itohex(out, x, upCase, withZero); |
306 | | return out; |
307 | | } |
308 | | /** |
309 | | convert integer to string with zero padding |
310 | | @param x [in] int |
311 | | @param len [in] minimum lengh of string |
312 | | @param c [in] padding character |
313 | | @note |
314 | | itoa(12, 4) == "0012" |
315 | | itoa(1234, 4) == "1234" |
316 | | itoa(12345, 4) == "12345" |
317 | | itoa(-12, 4) == "-012" |
318 | | */ |
319 | | template<typename T> |
320 | | inline std::string itoaWithZero(T x, size_t len, char c = '0') |
321 | | { |
322 | | std::string ret; |
323 | | itoa(ret, x); |
324 | | if (ret.size() < len) { |
325 | | std::string zero(len - ret.size(), c); |
326 | | if (x >= 0) { |
327 | | ret = zero + ret; |
328 | | } else { |
329 | | ret = "-" + zero + ret.substr(1); |
330 | | } |
331 | | } |
332 | | return ret; |
333 | | } |
334 | | #endif |
335 | | |
336 | | } // cybozu |