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