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