to_chars_integral.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. // -*- C++ -*-
  2. //===----------------------------------------------------------------------===//
  3. //
  4. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5. // See https://llvm.org/LICENSE.txt for license information.
  6. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H
  10. #define _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H
  11. #include <__algorithm/copy_n.h>
  12. #include <__bit/countl.h>
  13. #include <__charconv/tables.h>
  14. #include <__charconv/to_chars_base_10.h>
  15. #include <__charconv/to_chars_result.h>
  16. #include <__charconv/traits.h>
  17. #include <__config>
  18. #include <__system_error/errc.h>
  19. #include <__type_traits/enable_if.h>
  20. #include <__type_traits/integral_constant.h>
  21. #include <__type_traits/is_same.h>
  22. #include <__type_traits/make_32_64_or_128_bit.h>
  23. #include <__type_traits/make_unsigned.h>
  24. #include <__utility/unreachable.h>
  25. #include <cstddef>
  26. #include <cstdint>
  27. #include <limits>
  28. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  29. # pragma GCC system_header
  30. #endif
  31. _LIBCPP_PUSH_MACROS
  32. #include <__undef_macros>
  33. _LIBCPP_BEGIN_NAMESPACE_STD
  34. #if _LIBCPP_STD_VER >= 17
  35. to_chars_result to_chars(char*, char*, bool, int = 10) = delete;
  36. template <typename _Tp>
  37. inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
  38. __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type);
  39. template <typename _Tp>
  40. inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
  41. __to_chars_itoa(char* __first, char* __last, _Tp __value, true_type) {
  42. auto __x = std::__to_unsigned_like(__value);
  43. if (__value < 0 && __first != __last) {
  44. *__first++ = '-';
  45. __x = std::__complement(__x);
  46. }
  47. return std::__to_chars_itoa(__first, __last, __x, false_type());
  48. }
  49. template <typename _Tp>
  50. inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
  51. __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type) {
  52. using __tx = __itoa::__traits<_Tp>;
  53. auto __diff = __last - __first;
  54. if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
  55. return {__tx::__convert(__first, __value), errc(0)};
  56. else
  57. return {__last, errc::value_too_large};
  58. }
  59. # ifndef _LIBCPP_HAS_NO_INT128
  60. template <>
  61. inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
  62. __to_chars_itoa(char* __first, char* __last, __uint128_t __value, false_type) {
  63. // When the value fits in 64-bits use the 64-bit code path. This reduces
  64. // the number of expensive calculations on 128-bit values.
  65. //
  66. // NOTE the 128-bit code path requires this optimization.
  67. if (__value <= numeric_limits<uint64_t>::max())
  68. return __to_chars_itoa(__first, __last, static_cast<uint64_t>(__value), false_type());
  69. using __tx = __itoa::__traits<__uint128_t>;
  70. auto __diff = __last - __first;
  71. if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
  72. return {__tx::__convert(__first, __value), errc(0)};
  73. else
  74. return {__last, errc::value_too_large};
  75. }
  76. # endif
  77. template <class _Tp>
  78. inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
  79. __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type);
  80. template <typename _Tp>
  81. inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
  82. __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, true_type) {
  83. auto __x = std::__to_unsigned_like(__value);
  84. if (__value < 0 && __first != __last) {
  85. *__first++ = '-';
  86. __x = std::__complement(__x);
  87. }
  88. return std::__to_chars_integral(__first, __last, __x, __base, false_type());
  89. }
  90. namespace __itoa {
  91. template <unsigned _Base>
  92. struct _LIBCPP_HIDDEN __integral;
  93. template <>
  94. struct _LIBCPP_HIDDEN __integral<2> {
  95. template <typename _Tp>
  96. _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
  97. // If value == 0 still need one digit. If the value != this has no
  98. // effect since the code scans for the most significant bit set. (Note
  99. // that __libcpp_clz doesn't work for 0.)
  100. return numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1);
  101. }
  102. template <typename _Tp>
  103. _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result
  104. __to_chars(char* __first, char* __last, _Tp __value) {
  105. ptrdiff_t __cap = __last - __first;
  106. int __n = __width(__value);
  107. if (__n > __cap)
  108. return {__last, errc::value_too_large};
  109. __last = __first + __n;
  110. char* __p = __last;
  111. const unsigned __divisor = 16;
  112. while (__value > __divisor) {
  113. unsigned __c = __value % __divisor;
  114. __value /= __divisor;
  115. __p -= 4;
  116. std::copy_n(&__base_2_lut[4 * __c], 4, __p);
  117. }
  118. do {
  119. unsigned __c = __value % 2;
  120. __value /= 2;
  121. *--__p = "01"[__c];
  122. } while (__value != 0);
  123. return {__last, errc(0)};
  124. }
  125. };
  126. template <>
  127. struct _LIBCPP_HIDDEN __integral<8> {
  128. template <typename _Tp>
  129. _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
  130. // If value == 0 still need one digit. If the value != this has no
  131. // effect since the code scans for the most significat bit set. (Note
  132. // that __libcpp_clz doesn't work for 0.)
  133. return ((numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1)) + 2) / 3;
  134. }
  135. template <typename _Tp>
  136. _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result
  137. __to_chars(char* __first, char* __last, _Tp __value) {
  138. ptrdiff_t __cap = __last - __first;
  139. int __n = __width(__value);
  140. if (__n > __cap)
  141. return {__last, errc::value_too_large};
  142. __last = __first + __n;
  143. char* __p = __last;
  144. unsigned __divisor = 64;
  145. while (__value > __divisor) {
  146. unsigned __c = __value % __divisor;
  147. __value /= __divisor;
  148. __p -= 2;
  149. std::copy_n(&__base_8_lut[2 * __c], 2, __p);
  150. }
  151. do {
  152. unsigned __c = __value % 8;
  153. __value /= 8;
  154. *--__p = "01234567"[__c];
  155. } while (__value != 0);
  156. return {__last, errc(0)};
  157. }
  158. };
  159. template <>
  160. struct _LIBCPP_HIDDEN __integral<16> {
  161. template <typename _Tp>
  162. _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
  163. // If value == 0 still need one digit. If the value != this has no
  164. // effect since the code scans for the most significat bit set. (Note
  165. // that __libcpp_clz doesn't work for 0.)
  166. return (numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1) + 3) / 4;
  167. }
  168. template <typename _Tp>
  169. _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result
  170. __to_chars(char* __first, char* __last, _Tp __value) {
  171. ptrdiff_t __cap = __last - __first;
  172. int __n = __width(__value);
  173. if (__n > __cap)
  174. return {__last, errc::value_too_large};
  175. __last = __first + __n;
  176. char* __p = __last;
  177. unsigned __divisor = 256;
  178. while (__value > __divisor) {
  179. unsigned __c = __value % __divisor;
  180. __value /= __divisor;
  181. __p -= 2;
  182. std::copy_n(&__base_16_lut[2 * __c], 2, __p);
  183. }
  184. if (__first != __last)
  185. do {
  186. unsigned __c = __value % 16;
  187. __value /= 16;
  188. *--__p = "0123456789abcdef"[__c];
  189. } while (__value != 0);
  190. return {__last, errc(0)};
  191. }
  192. };
  193. } // namespace __itoa
  194. template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) >= sizeof(unsigned)), int> = 0>
  195. _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value) {
  196. return __itoa::__integral<_Base>::__width(__value);
  197. }
  198. template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) < sizeof(unsigned)), int> = 0>
  199. _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value) {
  200. return std::__to_chars_integral_width<_Base>(static_cast<unsigned>(__value));
  201. }
  202. template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) >= sizeof(unsigned)), int> = 0>
  203. _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
  204. __to_chars_integral(char* __first, char* __last, _Tp __value) {
  205. return __itoa::__integral<_Base>::__to_chars(__first, __last, __value);
  206. }
  207. template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) < sizeof(unsigned)), int> = 0>
  208. _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
  209. __to_chars_integral(char* __first, char* __last, _Tp __value) {
  210. return std::__to_chars_integral<_Base>(__first, __last, static_cast<unsigned>(__value));
  211. }
  212. template <typename _Tp>
  213. _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value, unsigned __base) {
  214. _LIBCPP_ASSERT_UNCATEGORIZED(__value >= 0, "The function requires a non-negative value.");
  215. unsigned __base_2 = __base * __base;
  216. unsigned __base_3 = __base_2 * __base;
  217. unsigned __base_4 = __base_2 * __base_2;
  218. int __r = 0;
  219. while (true) {
  220. if (__value < __base)
  221. return __r + 1;
  222. if (__value < __base_2)
  223. return __r + 2;
  224. if (__value < __base_3)
  225. return __r + 3;
  226. if (__value < __base_4)
  227. return __r + 4;
  228. __value /= __base_4;
  229. __r += 4;
  230. }
  231. __libcpp_unreachable();
  232. }
  233. template <typename _Tp>
  234. inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
  235. __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type) {
  236. if (__base == 10) [[likely]]
  237. return std::__to_chars_itoa(__first, __last, __value, false_type());
  238. switch (__base) {
  239. case 2:
  240. return std::__to_chars_integral<2>(__first, __last, __value);
  241. case 8:
  242. return std::__to_chars_integral<8>(__first, __last, __value);
  243. case 16:
  244. return std::__to_chars_integral<16>(__first, __last, __value);
  245. }
  246. ptrdiff_t __cap = __last - __first;
  247. int __n = std::__to_chars_integral_width(__value, __base);
  248. if (__n > __cap)
  249. return {__last, errc::value_too_large};
  250. __last = __first + __n;
  251. char* __p = __last;
  252. do {
  253. unsigned __c = __value % __base;
  254. __value /= __base;
  255. *--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c];
  256. } while (__value != 0);
  257. return {__last, errc(0)};
  258. }
  259. template <typename _Tp, __enable_if_t<is_integral<_Tp>::value, int> = 0>
  260. inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
  261. to_chars(char* __first, char* __last, _Tp __value) {
  262. using _Type = __make_32_64_or_128_bit_t<_Tp>;
  263. static_assert(!is_same<_Type, void>::value, "unsupported integral type used in to_chars");
  264. return std::__to_chars_itoa(__first, __last, static_cast<_Type>(__value), is_signed<_Tp>());
  265. }
  266. template <typename _Tp, __enable_if_t<is_integral<_Tp>::value, int> = 0>
  267. inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
  268. to_chars(char* __first, char* __last, _Tp __value, int __base) {
  269. _LIBCPP_ASSERT_UNCATEGORIZED(2 <= __base && __base <= 36, "base not in [2, 36]");
  270. using _Type = __make_32_64_or_128_bit_t<_Tp>;
  271. return std::__to_chars_integral(__first, __last, static_cast<_Type>(__value), __base, is_signed<_Tp>());
  272. }
  273. #endif // _LIBCPP_STD_VER >= 17
  274. _LIBCPP_END_NAMESPACE_STD
  275. _LIBCPP_POP_MACROS
  276. #endif // _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H