File indexing completed on 2026-05-03 08:13:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___CXX03___CHARCONV_TO_CHARS_INTEGRAL_H
0011 #define _LIBCPP___CXX03___CHARCONV_TO_CHARS_INTEGRAL_H
0012
0013 #include <__cxx03/__algorithm/copy_n.h>
0014 #include <__cxx03/__assert>
0015 #include <__cxx03/__bit/countl.h>
0016 #include <__cxx03/__charconv/tables.h>
0017 #include <__cxx03/__charconv/to_chars_base_10.h>
0018 #include <__cxx03/__charconv/to_chars_result.h>
0019 #include <__cxx03/__charconv/traits.h>
0020 #include <__cxx03/__config>
0021 #include <__cxx03/__system_error/errc.h>
0022 #include <__cxx03/__type_traits/enable_if.h>
0023 #include <__cxx03/__type_traits/integral_constant.h>
0024 #include <__cxx03/__type_traits/is_same.h>
0025 #include <__cxx03/__type_traits/make_32_64_or_128_bit.h>
0026 #include <__cxx03/__type_traits/make_unsigned.h>
0027 #include <__cxx03/__utility/unreachable.h>
0028 #include <__cxx03/cstddef>
0029 #include <__cxx03/cstdint>
0030 #include <__cxx03/limits>
0031
0032 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0033 # pragma GCC system_header
0034 #endif
0035
0036 _LIBCPP_PUSH_MACROS
0037 #include <__cxx03/__undef_macros>
0038
0039 _LIBCPP_BEGIN_NAMESPACE_STD
0040
0041 #if _LIBCPP_STD_VER >= 17
0042
0043 to_chars_result to_chars(char*, char*, bool, int = 10) = delete;
0044
0045 template <typename _Tp>
0046 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0047 __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type);
0048
0049 template <typename _Tp>
0050 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0051 __to_chars_itoa(char* __first, char* __last, _Tp __value, true_type) {
0052 auto __x = std::__to_unsigned_like(__value);
0053 if (__value < 0 && __first != __last) {
0054 *__first++ = '-';
0055 __x = std::__complement(__x);
0056 }
0057
0058 return std::__to_chars_itoa(__first, __last, __x, false_type());
0059 }
0060
0061 template <typename _Tp>
0062 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0063 __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type) {
0064 using __tx = __itoa::__traits<_Tp>;
0065 auto __diff = __last - __first;
0066
0067 if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
0068 return {__tx::__convert(__first, __value), errc(0)};
0069 else
0070 return {__last, errc::value_too_large};
0071 }
0072
0073 # ifndef _LIBCPP_HAS_NO_INT128
0074 template <>
0075 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0076 __to_chars_itoa(char* __first, char* __last, __uint128_t __value, false_type) {
0077
0078
0079
0080
0081 if (__value <= numeric_limits<uint64_t>::max())
0082 return __to_chars_itoa(__first, __last, static_cast<uint64_t>(__value), false_type());
0083
0084 using __tx = __itoa::__traits<__uint128_t>;
0085 auto __diff = __last - __first;
0086
0087 if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
0088 return {__tx::__convert(__first, __value), errc(0)};
0089 else
0090 return {__last, errc::value_too_large};
0091 }
0092 # endif
0093
0094 template <class _Tp>
0095 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0096 __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type);
0097
0098 template <typename _Tp>
0099 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0100 __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, true_type) {
0101 auto __x = std::__to_unsigned_like(__value);
0102 if (__value < 0 && __first != __last) {
0103 *__first++ = '-';
0104 __x = std::__complement(__x);
0105 }
0106
0107 return std::__to_chars_integral(__first, __last, __x, __base, false_type());
0108 }
0109
0110 namespace __itoa {
0111
0112 template <unsigned _Base>
0113 struct _LIBCPP_HIDDEN __integral;
0114
0115 template <>
0116 struct _LIBCPP_HIDDEN __integral<2> {
0117 template <typename _Tp>
0118 _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
0119
0120
0121
0122 return numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1);
0123 }
0124
0125 template <typename _Tp>
0126 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result
0127 __to_chars(char* __first, char* __last, _Tp __value) {
0128 ptrdiff_t __cap = __last - __first;
0129 int __n = __width(__value);
0130 if (__n > __cap)
0131 return {__last, errc::value_too_large};
0132
0133 __last = __first + __n;
0134 char* __p = __last;
0135 const unsigned __divisor = 16;
0136 while (__value > __divisor) {
0137 unsigned __c = __value % __divisor;
0138 __value /= __divisor;
0139 __p -= 4;
0140 std::copy_n(&__base_2_lut[4 * __c], 4, __p);
0141 }
0142 do {
0143 unsigned __c = __value % 2;
0144 __value /= 2;
0145 *--__p = "01"[__c];
0146 } while (__value != 0);
0147 return {__last, errc(0)};
0148 }
0149 };
0150
0151 template <>
0152 struct _LIBCPP_HIDDEN __integral<8> {
0153 template <typename _Tp>
0154 _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
0155
0156
0157
0158 return ((numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1)) + 2) / 3;
0159 }
0160
0161 template <typename _Tp>
0162 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result
0163 __to_chars(char* __first, char* __last, _Tp __value) {
0164 ptrdiff_t __cap = __last - __first;
0165 int __n = __width(__value);
0166 if (__n > __cap)
0167 return {__last, errc::value_too_large};
0168
0169 __last = __first + __n;
0170 char* __p = __last;
0171 unsigned __divisor = 64;
0172 while (__value > __divisor) {
0173 unsigned __c = __value % __divisor;
0174 __value /= __divisor;
0175 __p -= 2;
0176 std::copy_n(&__base_8_lut[2 * __c], 2, __p);
0177 }
0178 do {
0179 unsigned __c = __value % 8;
0180 __value /= 8;
0181 *--__p = "01234567"[__c];
0182 } while (__value != 0);
0183 return {__last, errc(0)};
0184 }
0185 };
0186
0187 template <>
0188 struct _LIBCPP_HIDDEN __integral<16> {
0189 template <typename _Tp>
0190 _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
0191
0192
0193
0194 return (numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1) + 3) / 4;
0195 }
0196
0197 template <typename _Tp>
0198 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result
0199 __to_chars(char* __first, char* __last, _Tp __value) {
0200 ptrdiff_t __cap = __last - __first;
0201 int __n = __width(__value);
0202 if (__n > __cap)
0203 return {__last, errc::value_too_large};
0204
0205 __last = __first + __n;
0206 char* __p = __last;
0207 unsigned __divisor = 256;
0208 while (__value > __divisor) {
0209 unsigned __c = __value % __divisor;
0210 __value /= __divisor;
0211 __p -= 2;
0212 std::copy_n(&__base_16_lut[2 * __c], 2, __p);
0213 }
0214 if (__first != __last)
0215 do {
0216 unsigned __c = __value % 16;
0217 __value /= 16;
0218 *--__p = "0123456789abcdef"[__c];
0219 } while (__value != 0);
0220 return {__last, errc(0)};
0221 }
0222 };
0223
0224 }
0225
0226 template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) >= sizeof(unsigned)), int> = 0>
0227 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value) {
0228 return __itoa::__integral<_Base>::__width(__value);
0229 }
0230
0231 template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) < sizeof(unsigned)), int> = 0>
0232 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value) {
0233 return std::__to_chars_integral_width<_Base>(static_cast<unsigned>(__value));
0234 }
0235
0236 template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) >= sizeof(unsigned)), int> = 0>
0237 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0238 __to_chars_integral(char* __first, char* __last, _Tp __value) {
0239 return __itoa::__integral<_Base>::__to_chars(__first, __last, __value);
0240 }
0241
0242 template <unsigned _Base, typename _Tp, __enable_if_t<(sizeof(_Tp) < sizeof(unsigned)), int> = 0>
0243 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0244 __to_chars_integral(char* __first, char* __last, _Tp __value) {
0245 return std::__to_chars_integral<_Base>(__first, __last, static_cast<unsigned>(__value));
0246 }
0247
0248 template <typename _Tp>
0249 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value, unsigned __base) {
0250 _LIBCPP_ASSERT_INTERNAL(__value >= 0, "The function requires a non-negative value.");
0251
0252 unsigned __base_2 = __base * __base;
0253 unsigned __base_3 = __base_2 * __base;
0254 unsigned __base_4 = __base_2 * __base_2;
0255
0256 int __r = 0;
0257 while (true) {
0258 if (__value < __base)
0259 return __r + 1;
0260 if (__value < __base_2)
0261 return __r + 2;
0262 if (__value < __base_3)
0263 return __r + 3;
0264 if (__value < __base_4)
0265 return __r + 4;
0266
0267 __value /= __base_4;
0268 __r += 4;
0269 }
0270
0271 __libcpp_unreachable();
0272 }
0273
0274 template <typename _Tp>
0275 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0276 __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type) {
0277 if (__base == 10) [[likely]]
0278 return std::__to_chars_itoa(__first, __last, __value, false_type());
0279
0280 switch (__base) {
0281 case 2:
0282 return std::__to_chars_integral<2>(__first, __last, __value);
0283 case 8:
0284 return std::__to_chars_integral<8>(__first, __last, __value);
0285 case 16:
0286 return std::__to_chars_integral<16>(__first, __last, __value);
0287 }
0288
0289 ptrdiff_t __cap = __last - __first;
0290 int __n = std::__to_chars_integral_width(__value, __base);
0291 if (__n > __cap)
0292 return {__last, errc::value_too_large};
0293
0294 __last = __first + __n;
0295 char* __p = __last;
0296 do {
0297 unsigned __c = __value % __base;
0298 __value /= __base;
0299 *--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c];
0300 } while (__value != 0);
0301 return {__last, errc(0)};
0302 }
0303
0304 template <typename _Tp, __enable_if_t<is_integral<_Tp>::value, int> = 0>
0305 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0306 to_chars(char* __first, char* __last, _Tp __value) {
0307 using _Type = __make_32_64_or_128_bit_t<_Tp>;
0308 static_assert(!is_same<_Type, void>::value, "unsupported integral type used in to_chars");
0309 return std::__to_chars_itoa(__first, __last, static_cast<_Type>(__value), is_signed<_Tp>());
0310 }
0311
0312 template <typename _Tp, __enable_if_t<is_integral<_Tp>::value, int> = 0>
0313 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
0314 to_chars(char* __first, char* __last, _Tp __value, int __base) {
0315 _LIBCPP_ASSERT_UNCATEGORIZED(2 <= __base && __base <= 36, "base not in [2, 36]");
0316
0317 using _Type = __make_32_64_or_128_bit_t<_Tp>;
0318 return std::__to_chars_integral(__first, __last, static_cast<_Type>(__value), __base, is_signed<_Tp>());
0319 }
0320
0321 #endif
0322
0323 _LIBCPP_END_NAMESPACE_STD
0324
0325 _LIBCPP_POP_MACROS
0326
0327 #endif