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