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_TRAITS |
11 | #define _LIBCPP___CHARCONV_TRAITS |
12 | |
13 | #include <__assert> |
14 | #include <__bit/countl.h> |
15 | #include <__charconv/tables.h> |
16 | #include <__charconv/to_chars_base_10.h> |
17 | #include <__config> |
18 | #include <__memory/addressof.h> |
19 | #include <__type_traits/enable_if.h> |
20 | #include <__type_traits/is_unsigned.h> |
21 | #include <cstdint> |
22 | #include <limits> |
23 | |
24 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
25 | # pragma GCC system_header |
26 | #endif |
27 | |
28 | _LIBCPP_PUSH_MACROS |
29 | #include <__undef_macros> |
30 | |
31 | _LIBCPP_BEGIN_NAMESPACE_STD |
32 | |
33 | namespace __itoa { |
34 | |
35 | template <typename _Tp, typename = void> |
36 | struct _LIBCPP_HIDDEN __traits_base; |
37 | |
38 | template <typename _Tp> |
39 | struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) <= sizeof(uint32_t)> > { |
40 | using type = uint32_t; |
41 | |
42 | /// The width estimation using a log10 algorithm. |
43 | /// |
44 | /// The algorithm is based on |
45 | /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 |
46 | /// Instead of using IntegerLogBase2 it uses __countl_zero. |
47 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) { |
48 | auto __t = (32 - std::__countl_zero(t: static_cast<type>(__v | 1))) * 1233 >> 12; |
49 | return __t - (__v < __itoa::__pow10_32[__t]) + 1; |
50 | } |
51 | |
52 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) { |
53 | return __itoa::__base_10_u32(first: __p, value: __v); |
54 | } |
55 | |
56 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_32)& __pow() { |
57 | return __itoa::__pow10_32; |
58 | } |
59 | }; |
60 | |
61 | template <typename _Tp> |
62 | struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(uint64_t)> > { |
63 | using type = uint64_t; |
64 | |
65 | /// The width estimation using a log10 algorithm. |
66 | /// |
67 | /// The algorithm is based on |
68 | /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 |
69 | /// Instead of using IntegerLogBase2 it uses __countl_zero. |
70 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) { |
71 | auto __t = (64 - std::__countl_zero(static_cast<type>(__v | 1))) * 1233 >> 12; |
72 | return __t - (__v < __itoa::__pow10_64[__t]) + 1; |
73 | } |
74 | |
75 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) { |
76 | return __itoa::__base_10_u64(buffer: __p, value: __v); |
77 | } |
78 | |
79 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_64)& __pow() { |
80 | return __itoa::__pow10_64; |
81 | } |
82 | }; |
83 | |
84 | # if _LIBCPP_HAS_INT128 |
85 | template <typename _Tp> |
86 | struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(__uint128_t)> > { |
87 | using type = __uint128_t; |
88 | |
89 | /// The width estimation using a log10 algorithm. |
90 | /// |
91 | /// The algorithm is based on |
92 | /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 |
93 | /// Instead of using IntegerLogBase2 it uses __countl_zero. |
94 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) { |
95 | _LIBCPP_ASSERT_INTERNAL( |
96 | __v > numeric_limits<uint64_t>::max(), "The optimizations for this algorithm fail when this isn't true." ); |
97 | // There's always a bit set in the upper 64-bits. |
98 | auto __t = (128 - std::__countl_zero(static_cast<uint64_t>(__v >> 64))) * 1233 >> 12; |
99 | _LIBCPP_ASSERT_INTERNAL(__t >= __itoa::__pow10_128_offset, "Index out of bounds" ); |
100 | // __t is adjusted since the lookup table misses the lower entries. |
101 | return __t - (__v < __itoa::__pow10_128[__t - __itoa::__pow10_128_offset]) + 1; |
102 | } |
103 | |
104 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) { |
105 | return __itoa::__base_10_u128(buffer: __p, value: __v); |
106 | } |
107 | |
108 | // TODO FMT This pow function should get an index. |
109 | // By moving this to its own header it can be reused by the pow function in to_chars_base_10. |
110 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_128)& __pow() { |
111 | return __itoa::__pow10_128; |
112 | } |
113 | }; |
114 | # endif |
115 | |
116 | template <typename _Tp> |
117 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool |
118 | __mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r) { |
119 | auto __c = __a * __b; |
120 | __r = __c; |
121 | return __c > numeric_limits<unsigned char>::max(); |
122 | } |
123 | |
124 | template <typename _Tp> |
125 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool |
126 | __mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r) { |
127 | auto __c = __a * __b; |
128 | __r = __c; |
129 | return __c > numeric_limits<unsigned short>::max(); |
130 | } |
131 | |
132 | template <typename _Tp> |
133 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool __mul_overflowed(_Tp __a, _Tp __b, _Tp& __r) { |
134 | static_assert(is_unsigned<_Tp>::value, "" ); |
135 | return __builtin_mul_overflow(__a, __b, std::addressof(__r)); |
136 | } |
137 | |
138 | template <typename _Tp, typename _Up> |
139 | inline _LIBCPP_HIDE_FROM_ABI bool _LIBCPP_CONSTEXPR_SINCE_CXX23 __mul_overflowed(_Tp __a, _Up __b, _Tp& __r) { |
140 | return __itoa::__mul_overflowed(__a, static_cast<_Tp>(__b), __r); |
141 | } |
142 | |
143 | template <typename _Tp> |
144 | struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp> { |
145 | static _LIBCPP_CONSTEXPR const int digits = numeric_limits<_Tp>::digits10 + 1; |
146 | using __traits_base<_Tp>::__pow; |
147 | using typename __traits_base<_Tp>::type; |
148 | |
149 | // precondition: at least one non-zero character available |
150 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char const* |
151 | __read(char const* __p, char const* __ep, type& __a, type& __b) { |
152 | type __cprod[digits]; |
153 | int __j = digits - 1; |
154 | int __i = digits; |
155 | do { |
156 | if (*__p < '0' || *__p > '9') |
157 | break; |
158 | __cprod[--__i] = *__p++ - '0'; |
159 | } while (__p != __ep && __i != 0); |
160 | |
161 | __a = __inner_product(__cprod + __i + 1, __cprod + __j, __pow() + 1, __cprod[__i]); |
162 | if (__itoa::__mul_overflowed(__cprod[__j], __pow()[__j - __i], __b)) |
163 | --__p; |
164 | return __p; |
165 | } |
166 | |
167 | template <typename _It1, typename _It2, class _Up> |
168 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _Up |
169 | __inner_product(_It1 __first1, _It1 __last1, _It2 __first2, _Up __init) { |
170 | for (; __first1 < __last1; ++__first1, ++__first2) |
171 | __init = __init + *__first1 * *__first2; |
172 | return __init; |
173 | } |
174 | }; |
175 | |
176 | } // namespace __itoa |
177 | |
178 | template <typename _Tp> |
179 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _Tp __complement(_Tp __x) { |
180 | static_assert(is_unsigned<_Tp>::value, "cast to unsigned first" ); |
181 | return _Tp(~__x + 1); |
182 | } |
183 | |
184 | _LIBCPP_END_NAMESPACE_STD |
185 | |
186 | _LIBCPP_POP_MACROS |
187 | |
188 | #endif // _LIBCPP___CHARCONV_TRAITS |
189 | |