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