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