1 | // -*- C++ -*- |
2 | //===------------------------------ charconv ------------------------------===// |
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 |
11 | #define _LIBCPP_CHARCONV |
12 | |
13 | /* |
14 | charconv synopsis |
15 | |
16 | namespace std { |
17 | |
18 | // floating-point format for primitive numerical conversion |
19 | enum class chars_format { |
20 | scientific = unspecified, |
21 | fixed = unspecified, |
22 | hex = unspecified, |
23 | general = fixed | scientific |
24 | }; |
25 | |
26 | // 23.20.2, primitive numerical output conversion |
27 | struct to_chars_result { |
28 | char* ptr; |
29 | errc ec; |
30 | }; |
31 | |
32 | to_chars_result to_chars(char* first, char* last, see below value, |
33 | int base = 10); |
34 | |
35 | to_chars_result to_chars(char* first, char* last, float value); |
36 | to_chars_result to_chars(char* first, char* last, double value); |
37 | to_chars_result to_chars(char* first, char* last, long double value); |
38 | |
39 | to_chars_result to_chars(char* first, char* last, float value, |
40 | chars_format fmt); |
41 | to_chars_result to_chars(char* first, char* last, double value, |
42 | chars_format fmt); |
43 | to_chars_result to_chars(char* first, char* last, long double value, |
44 | chars_format fmt); |
45 | |
46 | to_chars_result to_chars(char* first, char* last, float value, |
47 | chars_format fmt, int precision); |
48 | to_chars_result to_chars(char* first, char* last, double value, |
49 | chars_format fmt, int precision); |
50 | to_chars_result to_chars(char* first, char* last, long double value, |
51 | chars_format fmt, int precision); |
52 | |
53 | // 23.20.3, primitive numerical input conversion |
54 | struct from_chars_result { |
55 | const char* ptr; |
56 | errc ec; |
57 | }; |
58 | |
59 | from_chars_result from_chars(const char* first, const char* last, |
60 | see below& value, int base = 10); |
61 | |
62 | from_chars_result from_chars(const char* first, const char* last, |
63 | float& value, |
64 | chars_format fmt = chars_format::general); |
65 | from_chars_result from_chars(const char* first, const char* last, |
66 | double& value, |
67 | chars_format fmt = chars_format::general); |
68 | from_chars_result from_chars(const char* first, const char* last, |
69 | long double& value, |
70 | chars_format fmt = chars_format::general); |
71 | |
72 | } // namespace std |
73 | |
74 | */ |
75 | |
76 | #include <__errc> |
77 | #include <type_traits> |
78 | #include <limits> |
79 | #include <stdint.h> |
80 | #include <string.h> |
81 | #include <math.h> |
82 | |
83 | #include <__debug> |
84 | |
85 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
86 | #pragma GCC system_header |
87 | #endif |
88 | |
89 | _LIBCPP_PUSH_MACROS |
90 | #include <__undef_macros> |
91 | |
92 | _LIBCPP_BEGIN_NAMESPACE_STD |
93 | |
94 | namespace __itoa { |
95 | _LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer); |
96 | _LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer); |
97 | } |
98 | |
99 | #ifndef _LIBCPP_CXX03_LANG |
100 | |
101 | enum class _LIBCPP_ENUM_VIS chars_format |
102 | { |
103 | scientific = 0x1, |
104 | fixed = 0x2, |
105 | hex = 0x4, |
106 | general = fixed | scientific |
107 | }; |
108 | |
109 | struct _LIBCPP_TYPE_VIS to_chars_result |
110 | { |
111 | char* ptr; |
112 | errc ec; |
113 | }; |
114 | |
115 | struct _LIBCPP_TYPE_VIS from_chars_result |
116 | { |
117 | const char* ptr; |
118 | errc ec; |
119 | }; |
120 | |
121 | void to_chars(char*, char*, bool, int = 10) = delete; |
122 | void from_chars(const char*, const char*, bool, int = 10) = delete; |
123 | |
124 | namespace __itoa |
125 | { |
126 | |
127 | static _LIBCPP_CONSTEXPR uint64_t __pow10_64[] = { |
128 | UINT64_C(0), |
129 | UINT64_C(10), |
130 | UINT64_C(100), |
131 | UINT64_C(1000), |
132 | UINT64_C(10000), |
133 | UINT64_C(100000), |
134 | UINT64_C(1000000), |
135 | UINT64_C(10000000), |
136 | UINT64_C(100000000), |
137 | UINT64_C(1000000000), |
138 | UINT64_C(10000000000), |
139 | UINT64_C(100000000000), |
140 | UINT64_C(1000000000000), |
141 | UINT64_C(10000000000000), |
142 | UINT64_C(100000000000000), |
143 | UINT64_C(1000000000000000), |
144 | UINT64_C(10000000000000000), |
145 | UINT64_C(100000000000000000), |
146 | UINT64_C(1000000000000000000), |
147 | UINT64_C(10000000000000000000), |
148 | }; |
149 | |
150 | static _LIBCPP_CONSTEXPR uint32_t __pow10_32[] = { |
151 | UINT32_C(0), UINT32_C(10), UINT32_C(100), |
152 | UINT32_C(1000), UINT32_C(10000), UINT32_C(100000), |
153 | UINT32_C(1000000), UINT32_C(10000000), UINT32_C(100000000), |
154 | UINT32_C(1000000000), |
155 | }; |
156 | |
157 | template <typename _Tp, typename = void> |
158 | struct _LIBCPP_HIDDEN __traits_base |
159 | { |
160 | using type = uint64_t; |
161 | |
162 | #if !defined(_LIBCPP_COMPILER_MSVC) |
163 | static _LIBCPP_INLINE_VISIBILITY int __width(_Tp __v) |
164 | { |
165 | auto __t = (64 - __builtin_clzll(__v | 1)) * 1233 >> 12; |
166 | return __t - (__v < __pow10_64[__t]) + 1; |
167 | } |
168 | #endif |
169 | |
170 | static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p) |
171 | { |
172 | return __u64toa(__v, __p); |
173 | } |
174 | |
175 | static _LIBCPP_INLINE_VISIBILITY decltype(__pow10_64)& __pow() { return __pow10_64; } |
176 | }; |
177 | |
178 | template <typename _Tp> |
179 | struct _LIBCPP_HIDDEN |
180 | __traits_base<_Tp, decltype(void(uint32_t{declval<_Tp>()}))> |
181 | { |
182 | using type = uint32_t; |
183 | |
184 | #if !defined(_LIBCPP_COMPILER_MSVC) |
185 | static _LIBCPP_INLINE_VISIBILITY int __width(_Tp __v) |
186 | { |
187 | auto __t = (32 - __builtin_clz(__v | 1)) * 1233 >> 12; |
188 | return __t - (__v < __pow10_32[__t]) + 1; |
189 | } |
190 | #endif |
191 | |
192 | static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p) |
193 | { |
194 | return __u32toa(__v, __p); |
195 | } |
196 | |
197 | static _LIBCPP_INLINE_VISIBILITY decltype(__pow10_32)& __pow() { return __pow10_32; } |
198 | }; |
199 | |
200 | template <typename _Tp> |
201 | inline _LIBCPP_INLINE_VISIBILITY bool |
202 | __mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r) |
203 | { |
204 | auto __c = __a * __b; |
205 | __r = __c; |
206 | return __c > (numeric_limits<unsigned char>::max)(); |
207 | } |
208 | |
209 | template <typename _Tp> |
210 | inline _LIBCPP_INLINE_VISIBILITY bool |
211 | __mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r) |
212 | { |
213 | auto __c = __a * __b; |
214 | __r = __c; |
215 | return __c > (numeric_limits<unsigned short>::max)(); |
216 | } |
217 | |
218 | template <typename _Tp> |
219 | inline _LIBCPP_INLINE_VISIBILITY bool |
220 | __mul_overflowed(_Tp __a, _Tp __b, _Tp& __r) |
221 | { |
222 | static_assert(is_unsigned<_Tp>::value, "" ); |
223 | #if !defined(_LIBCPP_COMPILER_MSVC) |
224 | return __builtin_mul_overflow(__a, __b, &__r); |
225 | #else |
226 | bool __did = __b && ((numeric_limits<_Tp>::max)() / __b) < __a; |
227 | __r = __a * __b; |
228 | return __did; |
229 | #endif |
230 | } |
231 | |
232 | template <typename _Tp, typename _Up> |
233 | inline _LIBCPP_INLINE_VISIBILITY bool |
234 | __mul_overflowed(_Tp __a, _Up __b, _Tp& __r) |
235 | { |
236 | return __mul_overflowed(__a, static_cast<_Tp>(__b), __r); |
237 | } |
238 | |
239 | template <typename _Tp> |
240 | struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp> |
241 | { |
242 | static _LIBCPP_CONSTEXPR int digits = numeric_limits<_Tp>::digits10 + 1; |
243 | using __traits_base<_Tp>::__pow; |
244 | using typename __traits_base<_Tp>::type; |
245 | |
246 | // precondition: at least one non-zero character available |
247 | static _LIBCPP_INLINE_VISIBILITY char const* |
248 | __read(char const* __p, char const* __ep, type& __a, type& __b) |
249 | { |
250 | type __cprod[digits]; |
251 | int __j = digits - 1; |
252 | int __i = digits; |
253 | do |
254 | { |
255 | if (!('0' <= *__p && *__p <= '9')) |
256 | break; |
257 | __cprod[--__i] = *__p++ - '0'; |
258 | } while (__p != __ep && __i != 0); |
259 | |
260 | __a = __inner_product(__cprod + __i + 1, __cprod + __j, __pow() + 1, |
261 | __cprod[__i]); |
262 | if (__mul_overflowed(__cprod[__j], __pow()[__j - __i], __b)) |
263 | --__p; |
264 | return __p; |
265 | } |
266 | |
267 | template <typename _It1, typename _It2, class _Up> |
268 | static _LIBCPP_INLINE_VISIBILITY _Up |
269 | __inner_product(_It1 __first1, _It1 __last1, _It2 __first2, _Up __init) |
270 | { |
271 | for (; __first1 < __last1; ++__first1, ++__first2) |
272 | __init = __init + *__first1 * *__first2; |
273 | return __init; |
274 | } |
275 | }; |
276 | |
277 | } // namespace __itoa |
278 | |
279 | template <typename _Tp> |
280 | inline _LIBCPP_INLINE_VISIBILITY _Tp |
281 | __complement(_Tp __x) |
282 | { |
283 | static_assert(is_unsigned<_Tp>::value, "cast to unsigned first" ); |
284 | return _Tp(~__x + 1); |
285 | } |
286 | |
287 | template <typename _Tp> |
288 | inline _LIBCPP_INLINE_VISIBILITY typename make_unsigned<_Tp>::type |
289 | __to_unsigned(_Tp __x) |
290 | { |
291 | return static_cast<typename make_unsigned<_Tp>::type>(__x); |
292 | } |
293 | |
294 | template <typename _Tp> |
295 | inline _LIBCPP_INLINE_VISIBILITY to_chars_result |
296 | __to_chars_itoa(char* __first, char* __last, _Tp __value, true_type) |
297 | { |
298 | auto __x = __to_unsigned(__value); |
299 | if (__value < 0 && __first != __last) |
300 | { |
301 | *__first++ = '-'; |
302 | __x = __complement(__x); |
303 | } |
304 | |
305 | return __to_chars_itoa(__first, __last, __x, false_type()); |
306 | } |
307 | |
308 | template <typename _Tp> |
309 | inline _LIBCPP_INLINE_VISIBILITY to_chars_result |
310 | __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type) |
311 | { |
312 | using __tx = __itoa::__traits<_Tp>; |
313 | auto __diff = __last - __first; |
314 | |
315 | #if !defined(_LIBCPP_COMPILER_MSVC) |
316 | if (__tx::digits <= __diff || __tx::__width(__value) <= __diff) |
317 | return {__tx::__convert(__value, __first), errc(0)}; |
318 | else |
319 | return {__last, errc::value_too_large}; |
320 | #else |
321 | if (__tx::digits <= __diff) |
322 | return {__tx::__convert(__value, __first), {}}; |
323 | else |
324 | { |
325 | char __buf[__tx::digits]; |
326 | auto __p = __tx::__convert(__value, __buf); |
327 | auto __len = __p - __buf; |
328 | if (__len <= __diff) |
329 | { |
330 | memcpy(__first, __buf, __len); |
331 | return {__first + __len, {}}; |
332 | } |
333 | else |
334 | return {__last, errc::value_too_large}; |
335 | } |
336 | #endif |
337 | } |
338 | |
339 | template <typename _Tp> |
340 | inline _LIBCPP_INLINE_VISIBILITY to_chars_result |
341 | __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, |
342 | true_type) |
343 | { |
344 | auto __x = __to_unsigned(__value); |
345 | if (__value < 0 && __first != __last) |
346 | { |
347 | *__first++ = '-'; |
348 | __x = __complement(__x); |
349 | } |
350 | |
351 | return __to_chars_integral(__first, __last, __x, __base, false_type()); |
352 | } |
353 | |
354 | template <typename _Tp> |
355 | inline _LIBCPP_INLINE_VISIBILITY to_chars_result |
356 | __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, |
357 | false_type) |
358 | { |
359 | if (__base == 10) |
360 | return __to_chars_itoa(__first, __last, __value, false_type()); |
361 | |
362 | auto __p = __last; |
363 | while (__p != __first) |
364 | { |
365 | auto __c = __value % __base; |
366 | __value /= __base; |
367 | *--__p = "0123456789abcdefghijklmnopqrstuvwxyz" [__c]; |
368 | if (__value == 0) |
369 | break; |
370 | } |
371 | |
372 | auto __len = __last - __p; |
373 | if (__value != 0 || !__len) |
374 | return {__last, errc::value_too_large}; |
375 | else |
376 | { |
377 | memmove(__first, __p, __len); |
378 | return {__first + __len, {}}; |
379 | } |
380 | } |
381 | |
382 | template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> |
383 | inline _LIBCPP_INLINE_VISIBILITY to_chars_result |
384 | to_chars(char* __first, char* __last, _Tp __value) |
385 | { |
386 | return __to_chars_itoa(__first, __last, __value, is_signed<_Tp>()); |
387 | } |
388 | |
389 | template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> |
390 | inline _LIBCPP_INLINE_VISIBILITY to_chars_result |
391 | to_chars(char* __first, char* __last, _Tp __value, int __base) |
392 | { |
393 | _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]" ); |
394 | return __to_chars_integral(__first, __last, __value, __base, |
395 | is_signed<_Tp>()); |
396 | } |
397 | |
398 | template <typename _It, typename _Tp, typename _Fn, typename... _Ts> |
399 | inline _LIBCPP_INLINE_VISIBILITY from_chars_result |
400 | __sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args) |
401 | { |
402 | using __tl = numeric_limits<_Tp>; |
403 | decltype(__to_unsigned(__value)) __x; |
404 | |
405 | bool __neg = (__first != __last && *__first == '-'); |
406 | auto __r = __f(__neg ? __first + 1 : __first, __last, __x, __args...); |
407 | switch (__r.ec) |
408 | { |
409 | case errc::invalid_argument: |
410 | return {__first, __r.ec}; |
411 | case errc::result_out_of_range: |
412 | return __r; |
413 | default: |
414 | break; |
415 | } |
416 | |
417 | if (__neg) |
418 | { |
419 | if (__x <= __complement(__to_unsigned(__tl::min()))) |
420 | { |
421 | __x = __complement(__x); |
422 | memcpy(&__value, &__x, sizeof(__x)); |
423 | return __r; |
424 | } |
425 | } |
426 | else |
427 | { |
428 | if (__x <= (__tl::max)()) |
429 | { |
430 | __value = __x; |
431 | return __r; |
432 | } |
433 | } |
434 | |
435 | return {__r.ptr, errc::result_out_of_range}; |
436 | } |
437 | |
438 | template <typename _Tp> |
439 | inline _LIBCPP_INLINE_VISIBILITY bool |
440 | __in_pattern(_Tp __c) |
441 | { |
442 | return '0' <= __c && __c <= '9'; |
443 | } |
444 | |
445 | struct _LIBCPP_HIDDEN __in_pattern_result |
446 | { |
447 | bool __ok; |
448 | int __val; |
449 | |
450 | explicit _LIBCPP_INLINE_VISIBILITY operator bool() const { return __ok; } |
451 | }; |
452 | |
453 | template <typename _Tp> |
454 | inline _LIBCPP_INLINE_VISIBILITY __in_pattern_result |
455 | __in_pattern(_Tp __c, int __base) |
456 | { |
457 | if (__base <= 10) |
458 | return {'0' <= __c && __c < '0' + __base, __c - '0'}; |
459 | else if (__in_pattern(__c)) |
460 | return {true, __c - '0'}; |
461 | else if ('a' <= __c && __c < 'a' + __base - 10) |
462 | return {true, __c - 'a' + 10}; |
463 | else |
464 | return {'A' <= __c && __c < 'A' + __base - 10, __c - 'A' + 10}; |
465 | } |
466 | |
467 | template <typename _It, typename _Tp, typename _Fn, typename... _Ts> |
468 | inline _LIBCPP_INLINE_VISIBILITY from_chars_result |
469 | __subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, |
470 | _Ts... __args) |
471 | { |
472 | auto __find_non_zero = [](_It __first, _It __last) { |
473 | for (; __first != __last; ++__first) |
474 | if (*__first != '0') |
475 | break; |
476 | return __first; |
477 | }; |
478 | |
479 | auto __p = __find_non_zero(__first, __last); |
480 | if (__p == __last || !__in_pattern(*__p, __args...)) |
481 | { |
482 | if (__p == __first) |
483 | return {__first, errc::invalid_argument}; |
484 | else |
485 | { |
486 | __value = 0; |
487 | return {__p, {}}; |
488 | } |
489 | } |
490 | |
491 | auto __r = __f(__p, __last, __value, __args...); |
492 | if (__r.ec == errc::result_out_of_range) |
493 | { |
494 | for (; __r.ptr != __last; ++__r.ptr) |
495 | { |
496 | if (!__in_pattern(*__r.ptr, __args...)) |
497 | break; |
498 | } |
499 | } |
500 | |
501 | return __r; |
502 | } |
503 | |
504 | template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0> |
505 | inline _LIBCPP_INLINE_VISIBILITY from_chars_result |
506 | __from_chars_atoi(const char* __first, const char* __last, _Tp& __value) |
507 | { |
508 | using __tx = __itoa::__traits<_Tp>; |
509 | using __output_type = typename __tx::type; |
510 | |
511 | return __subject_seq_combinator( |
512 | __first, __last, __value, |
513 | [](const char* __first, const char* __last, |
514 | _Tp& __value) -> from_chars_result { |
515 | __output_type __a, __b; |
516 | auto __p = __tx::__read(__first, __last, __a, __b); |
517 | if (__p == __last || !__in_pattern(*__p)) |
518 | { |
519 | __output_type __m = (numeric_limits<_Tp>::max)(); |
520 | if (__m >= __a && __m - __a >= __b) |
521 | { |
522 | __value = __a + __b; |
523 | return {__p, {}}; |
524 | } |
525 | } |
526 | return {__p, errc::result_out_of_range}; |
527 | }); |
528 | } |
529 | |
530 | template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0> |
531 | inline _LIBCPP_INLINE_VISIBILITY from_chars_result |
532 | __from_chars_atoi(const char* __first, const char* __last, _Tp& __value) |
533 | { |
534 | using __t = decltype(__to_unsigned(__value)); |
535 | return __sign_combinator(__first, __last, __value, __from_chars_atoi<__t>); |
536 | } |
537 | |
538 | template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0> |
539 | inline _LIBCPP_INLINE_VISIBILITY from_chars_result |
540 | __from_chars_integral(const char* __first, const char* __last, _Tp& __value, |
541 | int __base) |
542 | { |
543 | if (__base == 10) |
544 | return __from_chars_atoi(__first, __last, __value); |
545 | |
546 | return __subject_seq_combinator( |
547 | __first, __last, __value, |
548 | [](const char* __p, const char* __last, _Tp& __value, |
549 | int __base) -> from_chars_result { |
550 | using __tl = numeric_limits<_Tp>; |
551 | auto __digits = __tl::digits / log2f(float(__base)); |
552 | _Tp __a = __in_pattern(*__p++, __base).__val, __b = 0; |
553 | |
554 | for (int __i = 1; __p != __last; ++__i, ++__p) |
555 | { |
556 | if (auto __c = __in_pattern(*__p, __base)) |
557 | { |
558 | if (__i < __digits - 1) |
559 | __a = __a * __base + __c.__val; |
560 | else |
561 | { |
562 | if (!__itoa::__mul_overflowed(__a, __base, __a)) |
563 | ++__p; |
564 | __b = __c.__val; |
565 | break; |
566 | } |
567 | } |
568 | else |
569 | break; |
570 | } |
571 | |
572 | if (__p == __last || !__in_pattern(*__p, __base)) |
573 | { |
574 | if ((__tl::max)() - __a >= __b) |
575 | { |
576 | __value = __a + __b; |
577 | return {__p, {}}; |
578 | } |
579 | } |
580 | return {__p, errc::result_out_of_range}; |
581 | }, |
582 | __base); |
583 | } |
584 | |
585 | template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0> |
586 | inline _LIBCPP_INLINE_VISIBILITY from_chars_result |
587 | __from_chars_integral(const char* __first, const char* __last, _Tp& __value, |
588 | int __base) |
589 | { |
590 | using __t = decltype(__to_unsigned(__value)); |
591 | return __sign_combinator(__first, __last, __value, |
592 | __from_chars_integral<__t>, __base); |
593 | } |
594 | |
595 | template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> |
596 | inline _LIBCPP_INLINE_VISIBILITY from_chars_result |
597 | from_chars(const char* __first, const char* __last, _Tp& __value) |
598 | { |
599 | return __from_chars_atoi(__first, __last, __value); |
600 | } |
601 | |
602 | template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> |
603 | inline _LIBCPP_INLINE_VISIBILITY from_chars_result |
604 | from_chars(const char* __first, const char* __last, _Tp& __value, int __base) |
605 | { |
606 | _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]" ); |
607 | return __from_chars_integral(__first, __last, __value, __base); |
608 | } |
609 | |
610 | #endif // _LIBCPP_CXX03_LANG |
611 | |
612 | _LIBCPP_END_NAMESPACE_STD |
613 | |
614 | _LIBCPP_POP_MACROS |
615 | |
616 | #endif // _LIBCPP_CHARCONV |
617 | |