File indexing completed on 2026-05-03 08:13:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___CXX03___CHARCONV_TRAITS
0011 #define _LIBCPP___CXX03___CHARCONV_TRAITS
0012
0013 #include <__cxx03/__assert>
0014 #include <__cxx03/__bit/countl.h>
0015 #include <__cxx03/__charconv/tables.h>
0016 #include <__cxx03/__charconv/to_chars_base_10.h>
0017 #include <__cxx03/__config>
0018 #include <__cxx03/__type_traits/enable_if.h>
0019 #include <__cxx03/__type_traits/is_unsigned.h>
0020 #include <__cxx03/cstdint>
0021 #include <__cxx03/limits>
0022
0023 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0024 # pragma GCC system_header
0025 #endif
0026
0027 _LIBCPP_PUSH_MACROS
0028 #include <__cxx03/__undef_macros>
0029
0030 _LIBCPP_BEGIN_NAMESPACE_STD
0031
0032 #if _LIBCPP_STD_VER >= 17
0033
0034 namespace __itoa {
0035
0036 template <typename _Tp, typename = void>
0037 struct _LIBCPP_HIDDEN __traits_base;
0038
0039 template <typename _Tp>
0040 struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) <= sizeof(uint32_t)>> {
0041 using type = uint32_t;
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) {
0052 auto __t = (32 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
0053 return __t - (__v < __itoa::__pow10_32[__t]) + 1;
0054 }
0055
0056 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) {
0057 return __itoa::__base_10_u32(__p, __v);
0058 }
0059
0060 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_32)& __pow() {
0061 return __itoa::__pow10_32;
0062 }
0063 };
0064
0065 template <typename _Tp>
0066 struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(uint64_t)>> {
0067 using type = uint64_t;
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) {
0078 auto __t = (64 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
0079 return __t - (__v < __itoa::__pow10_64[__t]) + 1;
0080 }
0081
0082 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) {
0083 return __itoa::__base_10_u64(__p, __v);
0084 }
0085
0086 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_64)& __pow() {
0087 return __itoa::__pow10_64;
0088 }
0089 };
0090
0091 # ifndef _LIBCPP_HAS_NO_INT128
0092 template <typename _Tp>
0093 struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(__uint128_t)> > {
0094 using type = __uint128_t;
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) {
0105 _LIBCPP_ASSERT_INTERNAL(
0106 __v > numeric_limits<uint64_t>::max(), "The optimizations for this algorithm fail when this isn't true.");
0107
0108 auto __t = (128 - std::__libcpp_clz(static_cast<uint64_t>(__v >> 64))) * 1233 >> 12;
0109 _LIBCPP_ASSERT_INTERNAL(__t >= __itoa::__pow10_128_offset, "Index out of bounds");
0110
0111 return __t - (__v < __itoa::__pow10_128[__t - __itoa::__pow10_128_offset]) + 1;
0112 }
0113
0114 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) {
0115 return __itoa::__base_10_u128(__p, __v);
0116 }
0117
0118
0119
0120 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_128)& __pow() {
0121 return __itoa::__pow10_128;
0122 }
0123 };
0124 # endif
0125
0126 template <typename _Tp>
0127 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
0128 __mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r) {
0129 auto __c = __a * __b;
0130 __r = __c;
0131 return __c > numeric_limits<unsigned char>::max();
0132 }
0133
0134 template <typename _Tp>
0135 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
0136 __mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r) {
0137 auto __c = __a * __b;
0138 __r = __c;
0139 return __c > numeric_limits<unsigned short>::max();
0140 }
0141
0142 template <typename _Tp>
0143 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool __mul_overflowed(_Tp __a, _Tp __b, _Tp& __r) {
0144 static_assert(is_unsigned<_Tp>::value, "");
0145 return __builtin_mul_overflow(__a, __b, &__r);
0146 }
0147
0148 template <typename _Tp, typename _Up>
0149 inline _LIBCPP_HIDE_FROM_ABI bool _LIBCPP_CONSTEXPR_SINCE_CXX23 __mul_overflowed(_Tp __a, _Up __b, _Tp& __r) {
0150 return __itoa::__mul_overflowed(__a, static_cast<_Tp>(__b), __r);
0151 }
0152
0153 template <typename _Tp>
0154 struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp> {
0155 static constexpr int digits = numeric_limits<_Tp>::digits10 + 1;
0156 using __traits_base<_Tp>::__pow;
0157 using typename __traits_base<_Tp>::type;
0158
0159
0160 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char const*
0161 __read(char const* __p, char const* __ep, type& __a, type& __b) {
0162 type __cprod[digits];
0163 int __j = digits - 1;
0164 int __i = digits;
0165 do {
0166 if (*__p < '0' || *__p > '9')
0167 break;
0168 __cprod[--__i] = *__p++ - '0';
0169 } while (__p != __ep && __i != 0);
0170
0171 __a = __inner_product(__cprod + __i + 1, __cprod + __j, __pow() + 1, __cprod[__i]);
0172 if (__itoa::__mul_overflowed(__cprod[__j], __pow()[__j - __i], __b))
0173 --__p;
0174 return __p;
0175 }
0176
0177 template <typename _It1, typename _It2, class _Up>
0178 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _Up
0179 __inner_product(_It1 __first1, _It1 __last1, _It2 __first2, _Up __init) {
0180 for (; __first1 < __last1; ++__first1, ++__first2)
0181 __init = __init + *__first1 * *__first2;
0182 return __init;
0183 }
0184 };
0185
0186 }
0187
0188 template <typename _Tp>
0189 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _Tp __complement(_Tp __x) {
0190 static_assert(is_unsigned<_Tp>::value, "cast to unsigned first");
0191 return _Tp(~__x + 1);
0192 }
0193
0194 #endif
0195
0196 _LIBCPP_END_NAMESPACE_STD
0197
0198 _LIBCPP_POP_MACROS
0199
0200 #endif