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