github.com/platonnetwork/platon-go@v0.7.6/cases/tool/win/bls_win/include/cybozu/atoi.hpp (about) 1 #pragma once 2 /** 3 @file 4 @brief converter between integer and string 5 6 @author MITSUNARI Shigeo(@herumi) 7 */ 8 9 #include <memory.h> 10 #include <limits.h> 11 #include <limits> 12 #include <cybozu/exception.hpp> 13 14 namespace cybozu { 15 16 namespace atoi_local { 17 18 template<typename T, size_t n> 19 T convertToInt(bool *b, const char *p, size_t size, const char (&max)[n], T min, T overflow1, char overflow2) 20 { 21 if (size > 0 && *p) { 22 bool isMinus = false; 23 size_t i = 0; 24 if (*p == '-') { 25 isMinus = true; 26 i++; 27 } 28 if (i < size && p[i]) { 29 // skip leading zero 30 while (i < size && p[i] == '0') i++; 31 // check minimum 32 if (isMinus && size - i >= n - 1 && memcmp(max, &p[i], n - 1) == 0) { 33 if (b) *b = true; 34 return min; 35 } 36 T x = 0; 37 for (;;) { 38 unsigned char c; 39 if (i == size || (c = static_cast<unsigned char>(p[i])) == '\0') { 40 if (b) *b = true; 41 return isMinus ? -x : x; 42 } 43 unsigned int y = c - '0'; 44 if (y > 9 || x > overflow1 || (x == overflow1 && c >= overflow2)) { 45 break; 46 } 47 x = x * 10 + T(y); 48 i++; 49 } 50 } 51 } 52 if (b) { 53 *b = false; 54 return 0; 55 } else { 56 throw cybozu::Exception("atoi::convertToInt") << cybozu::exception::makeString(p, size); 57 } 58 } 59 60 template<typename T> 61 T convertToUint(bool *b, const char *p, size_t size, T overflow1, char overflow2) 62 { 63 if (size > 0 && *p) { 64 size_t i = 0; 65 // skip leading zero 66 while (i < size && p[i] == '0') i++; 67 T x = 0; 68 for (;;) { 69 unsigned char c; 70 if (i == size || (c = static_cast<unsigned char>(p[i])) == '\0') { 71 if (b) *b = true; 72 return x; 73 } 74 unsigned int y = c - '0'; 75 if (y > 9 || x > overflow1 || (x == overflow1 && c >= overflow2)) { 76 break; 77 } 78 x = x * 10 + T(y); 79 i++; 80 } 81 } 82 if (b) { 83 *b = false; 84 return 0; 85 } else { 86 throw cybozu::Exception("atoi::convertToUint") << cybozu::exception::makeString(p, size); 87 } 88 } 89 90 template<typename T> 91 T convertHexToInt(bool *b, const char *p, size_t size) 92 { 93 if (size > 0 && *p) { 94 size_t i = 0; 95 T x = 0; 96 for (;;) { 97 unsigned int c; 98 if (i == size || (c = static_cast<unsigned char>(p[i])) == '\0') { 99 if (b) *b = true; 100 return x; 101 } 102 if (c - 'A' <= 'F' - 'A') { 103 c = (c - 'A') + 10; 104 } else if (c - 'a' <= 'f' - 'a') { 105 c = (c - 'a') + 10; 106 } else if (c - '0' <= '9' - '0') { 107 c = c - '0'; 108 } else { 109 break; 110 } 111 // avoid overflow 112 if (x > (std::numeric_limits<T>::max)() / 16) break; 113 x = x * 16 + T(c); 114 i++; 115 } 116 } 117 if (b) { 118 *b = false; 119 return 0; 120 } else { 121 throw cybozu::Exception("atoi::convertHexToInt") << cybozu::exception::makeString(p, size); 122 } 123 } 124 125 } // atoi_local 126 127 /** 128 auto detect return value class 129 @note if you set bool pointer p then throw nothing and set *p = false if bad string 130 */ 131 class atoi { 132 const char *p_; 133 size_t size_; 134 bool *b_; 135 void set(bool *b, const char *p, size_t size) 136 { 137 b_ = b; 138 p_ = p; 139 size_ = size; 140 } 141 public: 142 atoi(const char *p, size_t size = -1) 143 { 144 set(0, p, size); 145 } 146 atoi(bool *b, const char *p, size_t size = -1) 147 { 148 set(b, p, size); 149 } 150 atoi(const std::string& str) 151 { 152 set(0, str.c_str(), str.size()); 153 } 154 atoi(bool *b, const std::string& str) 155 { 156 set(b, str.c_str(), str.size()); 157 } 158 inline operator signed char() const 159 { 160 return atoi_local::convertToInt<signed char>(b_, p_, size_, "128", -128, 12, '8'); 161 } 162 inline operator unsigned char() const 163 { 164 return atoi_local::convertToUint<unsigned char>(b_, p_, size_, 25, '6'); 165 } 166 inline operator short() const 167 { 168 return atoi_local::convertToInt<short>(b_, p_, size_, "32768", -32768, 3276, '8'); 169 } 170 inline operator unsigned short() const 171 { 172 return atoi_local::convertToUint<unsigned short>(b_, p_, size_, 6553, '6'); 173 } 174 inline operator int() const 175 { 176 return atoi_local::convertToInt<int>(b_, p_, size_, "2147483648", INT_MIN, 214748364, '8'); 177 } 178 inline operator unsigned int() const 179 { 180 return atoi_local::convertToUint<unsigned int>(b_, p_, size_, 429496729, '6'); 181 } 182 inline operator long long() const 183 { 184 return atoi_local::convertToInt<long long>(b_, p_, size_, "9223372036854775808", LLONG_MIN, 922337203685477580LL, '8'); 185 } 186 inline operator unsigned long long() const 187 { 188 return atoi_local::convertToUint<unsigned long long>(b_, p_, size_, 1844674407370955161ULL, '6'); 189 } 190 #if defined(__SIZEOF_LONG__) && (__SIZEOF_LONG__ == 8) 191 inline operator long() const { return static_cast<long>(static_cast<long long>(*this)); } 192 inline operator unsigned long() const { return static_cast<unsigned long>(static_cast<unsigned long long>(*this)); } 193 #else 194 inline operator long() const { return static_cast<long>(static_cast<int>(*this)); } 195 inline operator unsigned long() const { return static_cast<unsigned long>(static_cast<unsigned int>(*this)); } 196 #endif 197 }; 198 199 class hextoi { 200 const char *p_; 201 size_t size_; 202 bool *b_; 203 void set(bool *b, const char *p, size_t size) 204 { 205 b_ = b; 206 p_ = p; 207 size_ = size; 208 } 209 public: 210 hextoi(const char *p, size_t size = -1) 211 { 212 set(0, p, size); 213 } 214 hextoi(bool *b, const char *p, size_t size = -1) 215 { 216 set(b, p, size); 217 } 218 hextoi(const std::string& str) 219 { 220 set(0, str.c_str(), str.size()); 221 } 222 hextoi(bool *b, const std::string& str) 223 { 224 set(b, str.c_str(), str.size()); 225 } 226 operator unsigned char() const { return atoi_local::convertHexToInt<unsigned char>(b_, p_, size_); } 227 operator unsigned short() const { return atoi_local::convertHexToInt<unsigned short>(b_, p_, size_); } 228 operator unsigned int() const { return atoi_local::convertHexToInt<unsigned int>(b_, p_, size_); } 229 operator unsigned long() const { return atoi_local::convertHexToInt<unsigned long>(b_, p_, size_); } 230 operator unsigned long long() const { return atoi_local::convertHexToInt<unsigned long long>(b_, p_, size_); } 231 operator char() const { return atoi_local::convertHexToInt<char>(b_, p_, size_); } 232 operator signed char() const { return atoi_local::convertHexToInt<signed char>(b_, p_, size_); } 233 operator short() const { return atoi_local::convertHexToInt<short>(b_, p_, size_); } 234 operator int() const { return atoi_local::convertHexToInt<int>(b_, p_, size_); } 235 operator long() const { return atoi_local::convertHexToInt<long>(b_, p_, size_); } 236 operator long long() const { return atoi_local::convertHexToInt<long long>(b_, p_, size_); } 237 }; 238 239 } // cybozu