1 | // Primitive numeric conversions (to_chars and from_chars) -*- C++ -*- |
2 | |
3 | // Copyright (C) 2017-2023 Free Software Foundation, Inc. |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free |
6 | // software; you can redistribute it and/or modify it under the |
7 | // terms of the GNU General Public License as published by the |
8 | // Free Software Foundation; either version 3, or (at your option) |
9 | // any later version. |
10 | |
11 | // This library is distributed in the hope that it will be useful, |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | // GNU General Public License for more details. |
15 | |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version |
18 | // 3.1, as published by the Free Software Foundation. |
19 | |
20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
23 | // <http://www.gnu.org/licenses/>. |
24 | |
25 | /** @file include/charconv |
26 | * This is a Standard C++ Library header. |
27 | */ |
28 | |
29 | #ifndef _GLIBCXX_CHARCONV |
30 | #define _GLIBCXX_CHARCONV 1 |
31 | |
32 | #pragma GCC system_header |
33 | |
34 | #include <bits/requires_hosted.h> // for error codes |
35 | |
36 | // As an extension we support <charconv> in C++14, but this header should not |
37 | // be included by any other library headers in C++14 mode. This ensures that |
38 | // the names defined in this header are not added to namespace std unless a |
39 | // user explicitly includes <charconv> in C++14 code. |
40 | #if __cplusplus >= 201402L |
41 | |
42 | #include <type_traits> |
43 | #include <bit> // for __bit_width |
44 | #include <bits/charconv.h> // for __to_chars_len, __to_chars_10_impl |
45 | #include <bits/error_constants.h> // for std::errc |
46 | #include <ext/numeric_traits.h> |
47 | |
48 | #if _GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 \ |
49 | && __SIZE_WIDTH__ >= 32 && _GLIBCXX_HOSTED |
50 | # define __cpp_lib_to_chars 201611L |
51 | #endif |
52 | |
53 | #if __cplusplus > 202002L |
54 | # define __cpp_lib_constexpr_charconv 202207L |
55 | #endif |
56 | |
57 | namespace std _GLIBCXX_VISIBILITY(default) |
58 | { |
59 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
60 | |
61 | /// Result type of std::to_chars |
62 | struct to_chars_result |
63 | { |
64 | char* ptr; |
65 | errc ec; |
66 | |
67 | #if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L |
68 | friend bool |
69 | operator==(const to_chars_result&, const to_chars_result&) = default; |
70 | #endif |
71 | }; |
72 | |
73 | /// Result type of std::from_chars |
74 | struct from_chars_result |
75 | { |
76 | const char* ptr; |
77 | errc ec; |
78 | |
79 | #if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L |
80 | friend bool |
81 | operator==(const from_chars_result&, const from_chars_result&) = default; |
82 | #endif |
83 | }; |
84 | |
85 | namespace __detail |
86 | { |
87 | template<typename _Tp> |
88 | using __integer_to_chars_result_type |
89 | = enable_if_t<__or_<__is_signed_integer<_Tp>, |
90 | __is_unsigned_integer<_Tp>, |
91 | #if defined __SIZEOF_INT128__ && defined __STRICT_ANSI__ |
92 | is_same<_Tp, signed __int128>, |
93 | is_same<_Tp, unsigned __int128>, |
94 | #endif |
95 | is_same<char, remove_cv_t<_Tp>>>::value, |
96 | to_chars_result>; |
97 | |
98 | // Pick an unsigned type of suitable size. This is used to reduce the |
99 | // number of specializations of __to_chars_len, __to_chars etc. that |
100 | // get instantiated. For example, to_chars<char> and to_chars<short> |
101 | // and to_chars<unsigned> will all use the same code, and so will |
102 | // to_chars<long> when sizeof(int) == sizeof(long). |
103 | template<typename _Tp> |
104 | struct __to_chars_unsigned_type : __make_unsigned_selector_base |
105 | { |
106 | using _UInts = _List<unsigned int, unsigned long, unsigned long long |
107 | #if __SIZEOF_INT128__ > __SIZEOF_LONG_LONG__ |
108 | , unsigned __int128 |
109 | #endif |
110 | >; |
111 | using type = typename __select<sizeof(_Tp), _UInts>::__type; |
112 | }; |
113 | |
114 | template<typename _Tp> |
115 | using __unsigned_least_t = typename __to_chars_unsigned_type<_Tp>::type; |
116 | |
117 | // Generic implementation for arbitrary bases. |
118 | // Defined in <bits/charconv.h>. |
119 | template<typename _Tp> |
120 | constexpr unsigned |
121 | __to_chars_len(_Tp __value, int __base /* = 10 */) noexcept; |
122 | |
123 | template<typename _Tp> |
124 | constexpr unsigned |
125 | __to_chars_len_2(_Tp __value) noexcept |
126 | { return std::__bit_width(__value); } |
127 | |
128 | // Generic implementation for arbitrary bases. |
129 | template<typename _Tp> |
130 | constexpr to_chars_result |
131 | __to_chars(char* __first, char* __last, _Tp __val, int __base) noexcept |
132 | { |
133 | static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug" ); |
134 | |
135 | to_chars_result __res; |
136 | |
137 | const unsigned __len = __to_chars_len(__val, __base); |
138 | |
139 | if (__builtin_expect((__last - __first) < __len, 0)) |
140 | { |
141 | __res.ptr = __last; |
142 | __res.ec = errc::value_too_large; |
143 | return __res; |
144 | } |
145 | |
146 | unsigned __pos = __len - 1; |
147 | |
148 | constexpr char __digits[] = { |
149 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', |
150 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', |
151 | 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', |
152 | 'u', 'v', 'w', 'x', 'y', 'z' |
153 | }; |
154 | |
155 | while (__val >= (unsigned)__base) |
156 | { |
157 | auto const __quo = __val / __base; |
158 | auto const __rem = __val % __base; |
159 | __first[__pos--] = __digits[__rem]; |
160 | __val = __quo; |
161 | } |
162 | *__first = __digits[__val]; |
163 | |
164 | __res.ptr = __first + __len; |
165 | __res.ec = {}; |
166 | return __res; |
167 | } |
168 | |
169 | template<typename _Tp> |
170 | constexpr __integer_to_chars_result_type<_Tp> |
171 | __to_chars_16(char* __first, char* __last, _Tp __val) noexcept |
172 | { |
173 | static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug" ); |
174 | |
175 | to_chars_result __res; |
176 | |
177 | const unsigned __len = (__to_chars_len_2(__val) + 3) / 4; |
178 | |
179 | if (__builtin_expect((__last - __first) < __len, 0)) |
180 | { |
181 | __res.ptr = __last; |
182 | __res.ec = errc::value_too_large; |
183 | return __res; |
184 | } |
185 | |
186 | constexpr char __digits[] = { |
187 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', |
188 | 'a', 'b', 'c', 'd', 'e', 'f' |
189 | }; |
190 | unsigned __pos = __len - 1; |
191 | while (__val >= 0x100) |
192 | { |
193 | auto __num = __val & 0xF; |
194 | __val >>= 4; |
195 | __first[__pos] = __digits[__num]; |
196 | __num = __val & 0xF; |
197 | __val >>= 4; |
198 | __first[__pos - 1] = __digits[__num]; |
199 | __pos -= 2; |
200 | } |
201 | if (__val >= 0x10) |
202 | { |
203 | const auto __num = __val & 0xF; |
204 | __val >>= 4; |
205 | __first[1] = __digits[__num]; |
206 | __first[0] = __digits[__val]; |
207 | } |
208 | else |
209 | __first[0] = __digits[__val]; |
210 | __res.ptr = __first + __len; |
211 | __res.ec = {}; |
212 | return __res; |
213 | } |
214 | |
215 | template<typename _Tp> |
216 | constexpr __integer_to_chars_result_type<_Tp> |
217 | __to_chars_10(char* __first, char* __last, _Tp __val) noexcept |
218 | { |
219 | static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug" ); |
220 | |
221 | to_chars_result __res; |
222 | |
223 | const unsigned __len = __to_chars_len(__val, 10); |
224 | |
225 | if (__builtin_expect((__last - __first) < __len, 0)) |
226 | { |
227 | __res.ptr = __last; |
228 | __res.ec = errc::value_too_large; |
229 | return __res; |
230 | } |
231 | |
232 | __detail::__to_chars_10_impl(__first, __len, __val); |
233 | __res.ptr = __first + __len; |
234 | __res.ec = {}; |
235 | return __res; |
236 | } |
237 | |
238 | template<typename _Tp> |
239 | constexpr __integer_to_chars_result_type<_Tp> |
240 | __to_chars_8(char* __first, char* __last, _Tp __val) noexcept |
241 | { |
242 | static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug" ); |
243 | |
244 | to_chars_result __res; |
245 | unsigned __len = 0; |
246 | |
247 | if _GLIBCXX17_CONSTEXPR (__gnu_cxx::__int_traits<_Tp>::__digits <= 16) |
248 | { |
249 | __len = __val > 077777u ? 6u |
250 | : __val > 07777u ? 5u |
251 | : __val > 0777u ? 4u |
252 | : __val > 077u ? 3u |
253 | : __val > 07u ? 2u |
254 | : 1u; |
255 | } |
256 | else |
257 | __len = (__to_chars_len_2(__val) + 2) / 3; |
258 | |
259 | if (__builtin_expect((__last - __first) < __len, 0)) |
260 | { |
261 | __res.ptr = __last; |
262 | __res.ec = errc::value_too_large; |
263 | return __res; |
264 | } |
265 | |
266 | unsigned __pos = __len - 1; |
267 | while (__val >= 0100) |
268 | { |
269 | auto __num = __val & 7; |
270 | __val >>= 3; |
271 | __first[__pos] = '0' + __num; |
272 | __num = __val & 7; |
273 | __val >>= 3; |
274 | __first[__pos - 1] = '0' + __num; |
275 | __pos -= 2; |
276 | } |
277 | if (__val >= 010) |
278 | { |
279 | auto const __num = __val & 7; |
280 | __val >>= 3; |
281 | __first[1] = '0' + __num; |
282 | __first[0] = '0' + __val; |
283 | } |
284 | else |
285 | __first[0] = '0' + __val; |
286 | __res.ptr = __first + __len; |
287 | __res.ec = {}; |
288 | return __res; |
289 | } |
290 | |
291 | template<typename _Tp> |
292 | constexpr __integer_to_chars_result_type<_Tp> |
293 | __to_chars_2(char* __first, char* __last, _Tp __val) noexcept |
294 | { |
295 | static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug" ); |
296 | |
297 | to_chars_result __res; |
298 | |
299 | const unsigned __len = __to_chars_len_2(__val); |
300 | |
301 | if (__builtin_expect((__last - __first) < __len, 0)) |
302 | { |
303 | __res.ptr = __last; |
304 | __res.ec = errc::value_too_large; |
305 | return __res; |
306 | } |
307 | |
308 | unsigned __pos = __len - 1; |
309 | |
310 | while (__pos) |
311 | { |
312 | __first[__pos--] = '0' + (__val & 1); |
313 | __val >>= 1; |
314 | } |
315 | // First digit is always '1' because __to_chars_len_2 skips |
316 | // leading zero bits and std::to_chars handles zero values |
317 | // directly. |
318 | __first[0] = '1'; |
319 | |
320 | __res.ptr = __first + __len; |
321 | __res.ec = {}; |
322 | return __res; |
323 | } |
324 | |
325 | } // namespace __detail |
326 | |
327 | template<typename _Tp> |
328 | constexpr __detail::__integer_to_chars_result_type<_Tp> |
329 | __to_chars_i(char* __first, char* __last, _Tp __value, int __base = 10) |
330 | { |
331 | __glibcxx_assert(2 <= __base && __base <= 36); |
332 | |
333 | using _Up = __detail::__unsigned_least_t<_Tp>; |
334 | _Up __unsigned_val = __value; |
335 | |
336 | if (__first == __last) [[__unlikely__]] |
337 | return { __last, errc::value_too_large }; |
338 | |
339 | if (__value == 0) |
340 | { |
341 | *__first = '0'; |
342 | return { __first + 1, errc{} }; |
343 | } |
344 | else if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value) |
345 | if (__value < 0) |
346 | { |
347 | *__first++ = '-'; |
348 | __unsigned_val = _Up(~__value) + _Up(1); |
349 | } |
350 | |
351 | switch (__base) |
352 | { |
353 | case 16: |
354 | return __detail::__to_chars_16(__first, __last, __unsigned_val); |
355 | case 10: |
356 | return __detail::__to_chars_10(__first, __last, __unsigned_val); |
357 | case 8: |
358 | return __detail::__to_chars_8(__first, __last, __unsigned_val); |
359 | case 2: |
360 | return __detail::__to_chars_2(__first, __last, __unsigned_val); |
361 | default: |
362 | return __detail::__to_chars(__first, __last, __unsigned_val, __base); |
363 | } |
364 | } |
365 | |
366 | #define _GLIBCXX_TO_CHARS(T) \ |
367 | _GLIBCXX23_CONSTEXPR inline to_chars_result \ |
368 | to_chars(char* __first, char* __last, T __value, int __base = 10) \ |
369 | { return std::__to_chars_i<T>(__first, __last, __value, __base); } |
370 | _GLIBCXX_TO_CHARS(char) |
371 | _GLIBCXX_TO_CHARS(signed char) |
372 | _GLIBCXX_TO_CHARS(unsigned char) |
373 | _GLIBCXX_TO_CHARS(signed short) |
374 | _GLIBCXX_TO_CHARS(unsigned short) |
375 | _GLIBCXX_TO_CHARS(signed int) |
376 | _GLIBCXX_TO_CHARS(unsigned int) |
377 | _GLIBCXX_TO_CHARS(signed long) |
378 | _GLIBCXX_TO_CHARS(unsigned long) |
379 | _GLIBCXX_TO_CHARS(signed long long) |
380 | _GLIBCXX_TO_CHARS(unsigned long long) |
381 | #if defined(__GLIBCXX_TYPE_INT_N_0) |
382 | _GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_0) |
383 | _GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_0) |
384 | #endif |
385 | #if defined(__GLIBCXX_TYPE_INT_N_1) |
386 | _GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_1) |
387 | _GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_1) |
388 | #endif |
389 | #if defined(__GLIBCXX_TYPE_INT_N_2) |
390 | _GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_2) |
391 | _GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_2) |
392 | #endif |
393 | #if defined(__GLIBCXX_TYPE_INT_N_3) |
394 | _GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_3) |
395 | _GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_3) |
396 | #endif |
397 | #undef _GLIBCXX_TO_CHARS |
398 | |
399 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
400 | // 3266. to_chars(bool) should be deleted |
401 | to_chars_result to_chars(char*, char*, bool, int = 10) = delete; |
402 | |
403 | namespace __detail |
404 | { |
405 | template<typename _Tp> |
406 | constexpr bool |
407 | __raise_and_add(_Tp& __val, int __base, unsigned char __c) |
408 | { |
409 | if (__builtin_mul_overflow(__val, __base, &__val) |
410 | || __builtin_add_overflow(__val, __c, &__val)) |
411 | return false; |
412 | return true; |
413 | } |
414 | |
415 | template<bool _DecOnly> |
416 | struct __from_chars_alnum_to_val_table |
417 | { |
418 | struct type { unsigned char __data[1u << __CHAR_BIT__] = {}; }; |
419 | |
420 | // Construct and return a lookup table that maps 0-9, A-Z and a-z to their |
421 | // corresponding base-36 value and maps all other characters to 127. |
422 | static constexpr type |
423 | _S_make_table() |
424 | { |
425 | constexpr unsigned char __lower_letters[27] = "abcdefghijklmnopqrstuvwxyz" ; |
426 | constexpr unsigned char __upper_letters[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ; |
427 | type __table; |
428 | for (auto& __entry : __table.__data) |
429 | __entry = 127; |
430 | for (int __i = 0; __i < 10; ++__i) |
431 | __table.__data['0' + __i] = __i; |
432 | for (int __i = 0; __i < 26; ++__i) |
433 | { |
434 | __table.__data[__lower_letters[__i]] = 10 + __i; |
435 | __table.__data[__upper_letters[__i]] = 10 + __i; |
436 | } |
437 | return __table; |
438 | } |
439 | |
440 | // This initializer is made superficially dependent in order |
441 | // to prevent the compiler from wastefully constructing the |
442 | // table ahead of time when it's not needed. |
443 | static constexpr type value = (_DecOnly, _S_make_table()); |
444 | }; |
445 | |
446 | #if ! __cpp_inline_variables |
447 | template<bool _DecOnly> |
448 | const typename __from_chars_alnum_to_val_table<_DecOnly>::type |
449 | __from_chars_alnum_to_val_table<_DecOnly>::value; |
450 | #endif |
451 | |
452 | // If _DecOnly is true: if the character is a decimal digit, then |
453 | // return its corresponding base-10 value, otherwise return a value >= 127. |
454 | // If _DecOnly is false: if the character is an alphanumeric digit, then |
455 | // return its corresponding base-36 value, otherwise return a value >= 127. |
456 | template<bool _DecOnly = false> |
457 | _GLIBCXX20_CONSTEXPR unsigned char |
458 | __from_chars_alnum_to_val(unsigned char __c) |
459 | { |
460 | if _GLIBCXX17_CONSTEXPR (_DecOnly) |
461 | return static_cast<unsigned char>(__c - '0'); |
462 | else |
463 | return __from_chars_alnum_to_val_table<_DecOnly>::value.__data[__c]; |
464 | } |
465 | |
466 | /// std::from_chars implementation for integers in a power-of-two base. |
467 | /// If _DecOnly is true, then we may assume __base is at most 8. |
468 | template<bool _DecOnly, typename _Tp> |
469 | _GLIBCXX23_CONSTEXPR bool |
470 | __from_chars_pow2_base(const char*& __first, const char* __last, _Tp& __val, |
471 | int __base) |
472 | { |
473 | static_assert(is_integral<_Tp>::value, "implementation bug" ); |
474 | static_assert(is_unsigned<_Tp>::value, "implementation bug" ); |
475 | |
476 | // __glibcxx_assert((__base & (__base - 1)) == 0); |
477 | // __glibcxx_assert(_DecOnly ? __base <= 8 : __base <= 32); |
478 | const int __log2_base = __countr_zero(x: unsigned(__base & 0x3f)); |
479 | |
480 | const ptrdiff_t __len = __last - __first; |
481 | ptrdiff_t __i = 0; |
482 | while (__i < __len && __first[__i] == '0') |
483 | ++__i; |
484 | const ptrdiff_t __leading_zeroes = __i; |
485 | if (__i >= __len) [[__unlikely__]] |
486 | { |
487 | __first += __i; |
488 | return true; |
489 | } |
490 | |
491 | // Remember the leading significant digit value if necessary. |
492 | unsigned char __leading_c = 0; |
493 | if (__base != 2) |
494 | { |
495 | __leading_c = __from_chars_alnum_to_val<_DecOnly>(__first[__i]); |
496 | // __glibcxx_assert(__leading_c != 0); |
497 | if (__leading_c >= __base) [[__unlikely__]] |
498 | { |
499 | __first += __i; |
500 | return true; |
501 | } |
502 | __val = __leading_c; |
503 | ++__i; |
504 | } |
505 | |
506 | for (; __i < __len; ++__i) |
507 | { |
508 | const unsigned char __c = __from_chars_alnum_to_val<_DecOnly>(__first[__i]); |
509 | if (__c >= __base) |
510 | break; |
511 | __val = (__val << __log2_base) | __c; |
512 | } |
513 | __first += __i; |
514 | auto __significant_bits = (__i - __leading_zeroes) * __log2_base; |
515 | if (__base != 2) |
516 | // Compensate for a leading significant digit that didn't use all |
517 | // of its available bits. |
518 | __significant_bits -= __log2_base - __bit_width(x: __leading_c); |
519 | // __glibcxx_assert(__significant_bits >= 0); |
520 | return __significant_bits <= __gnu_cxx::__int_traits<_Tp>::__digits; |
521 | } |
522 | |
523 | /// std::from_chars implementation for integers in any base. |
524 | /// If _DecOnly is true, then we may assume __base is at most 10. |
525 | template<bool _DecOnly, typename _Tp> |
526 | constexpr bool |
527 | __from_chars_alnum(const char*& __first, const char* __last, _Tp& __val, |
528 | int __base) |
529 | { |
530 | // __glibcxx_assert(_DecOnly ? __base <= 10 : __base <= 36); |
531 | |
532 | const int __bits_per_digit = __bit_width(x: unsigned(__base & 0x3f)); |
533 | int __unused_bits_lower_bound = __gnu_cxx::__int_traits<_Tp>::__digits; |
534 | for (; __first != __last; ++__first) |
535 | { |
536 | const unsigned char __c = __from_chars_alnum_to_val<_DecOnly>(*__first); |
537 | if (__c >= __base) |
538 | return true; |
539 | |
540 | __unused_bits_lower_bound -= __bits_per_digit; |
541 | if (__unused_bits_lower_bound >= 0) [[__likely__]] |
542 | // We're definitely not going to overflow. |
543 | __val = __val * __base + __c; |
544 | else if (!__raise_and_add(__val, __base, __c)) [[__unlikely__]] |
545 | { |
546 | while (++__first != __last |
547 | && __from_chars_alnum_to_val<_DecOnly>(*__first) < __base) |
548 | ; |
549 | return false; |
550 | } |
551 | } |
552 | return true; |
553 | } |
554 | |
555 | template<typename _Tp> |
556 | using __integer_from_chars_result_type |
557 | = enable_if_t<__or_<__is_signed_integer<_Tp>, |
558 | __is_unsigned_integer<_Tp>, |
559 | is_same<char, remove_cv_t<_Tp>>>::value, |
560 | from_chars_result>; |
561 | |
562 | } // namespace __detail |
563 | |
564 | /// std::from_chars for integral types. |
565 | template<typename _Tp> |
566 | _GLIBCXX23_CONSTEXPR __detail::__integer_from_chars_result_type<_Tp> |
567 | from_chars(const char* __first, const char* __last, _Tp& __value, |
568 | int __base = 10) |
569 | { |
570 | __glibcxx_assert(2 <= __base && __base <= 36); |
571 | |
572 | from_chars_result __res{.ptr: __first, .ec: {}}; |
573 | |
574 | int __sign = 1; |
575 | if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value) |
576 | if (__first != __last && *__first == '-') |
577 | { |
578 | __sign = -1; |
579 | ++__first; |
580 | } |
581 | |
582 | using _Up = __detail::__unsigned_least_t<_Tp>; |
583 | _Up __val = 0; |
584 | |
585 | const auto __start = __first; |
586 | bool __valid; |
587 | if ((__base & (__base - 1)) == 0) |
588 | { |
589 | if (__base <= 8) |
590 | __valid = __detail::__from_chars_pow2_base<true>(__first, __last, __val, __base); |
591 | else |
592 | __valid = __detail::__from_chars_pow2_base<false>(__first, __last, __val, __base); |
593 | } |
594 | else if (__base <= 10) |
595 | __valid = __detail::__from_chars_alnum<true>(__first, __last, __val, __base); |
596 | else |
597 | __valid = __detail::__from_chars_alnum<false>(__first, __last, __val, __base); |
598 | |
599 | if (__builtin_expect(__first == __start, 0)) |
600 | __res.ec = errc::invalid_argument; |
601 | else |
602 | { |
603 | __res.ptr = __first; |
604 | if (!__valid) |
605 | __res.ec = errc::result_out_of_range; |
606 | else |
607 | { |
608 | if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value) |
609 | { |
610 | _Tp __tmp; |
611 | if (__builtin_mul_overflow(__val, __sign, &__tmp)) |
612 | __res.ec = errc::result_out_of_range; |
613 | else |
614 | __value = __tmp; |
615 | } |
616 | else |
617 | { |
618 | if _GLIBCXX17_CONSTEXPR (__gnu_cxx::__int_traits<_Up>::__max |
619 | > __gnu_cxx::__int_traits<_Tp>::__max) |
620 | { |
621 | if (__val > __gnu_cxx::__int_traits<_Tp>::__max) |
622 | __res.ec = errc::result_out_of_range; |
623 | else |
624 | __value = __val; |
625 | } |
626 | else |
627 | __value = __val; |
628 | } |
629 | } |
630 | } |
631 | return __res; |
632 | } |
633 | |
634 | /// floating-point format for primitive numerical conversion |
635 | enum class chars_format |
636 | { |
637 | scientific = 1, fixed = 2, hex = 4, general = fixed | scientific |
638 | }; |
639 | |
640 | constexpr chars_format |
641 | operator|(chars_format __lhs, chars_format __rhs) noexcept |
642 | { return (chars_format)((unsigned)__lhs | (unsigned)__rhs); } |
643 | |
644 | constexpr chars_format |
645 | operator&(chars_format __lhs, chars_format __rhs) noexcept |
646 | { return (chars_format)((unsigned)__lhs & (unsigned)__rhs); } |
647 | |
648 | constexpr chars_format |
649 | operator^(chars_format __lhs, chars_format __rhs) noexcept |
650 | { return (chars_format)((unsigned)__lhs ^ (unsigned)__rhs); } |
651 | |
652 | constexpr chars_format |
653 | operator~(chars_format __fmt) noexcept |
654 | { return (chars_format)~(unsigned)__fmt; } |
655 | |
656 | constexpr chars_format& |
657 | operator|=(chars_format& __lhs, chars_format __rhs) noexcept |
658 | { return __lhs = __lhs | __rhs; } |
659 | |
660 | constexpr chars_format& |
661 | operator&=(chars_format& __lhs, chars_format __rhs) noexcept |
662 | { return __lhs = __lhs & __rhs; } |
663 | |
664 | constexpr chars_format& |
665 | operator^=(chars_format& __lhs, chars_format __rhs) noexcept |
666 | { return __lhs = __lhs ^ __rhs; } |
667 | |
668 | #if defined __cpp_lib_to_chars || _GLIBCXX_HAVE_USELOCALE |
669 | from_chars_result |
670 | from_chars(const char* __first, const char* __last, float& __value, |
671 | chars_format __fmt = chars_format::general) noexcept; |
672 | |
673 | from_chars_result |
674 | from_chars(const char* __first, const char* __last, double& __value, |
675 | chars_format __fmt = chars_format::general) noexcept; |
676 | |
677 | from_chars_result |
678 | from_chars(const char* __first, const char* __last, long double& __value, |
679 | chars_format __fmt = chars_format::general) noexcept; |
680 | |
681 | // Library routines for 16-bit extended floating point formats |
682 | // using float as interchange format. |
683 | from_chars_result |
684 | __from_chars_float16_t(const char* __first, const char* __last, |
685 | float& __value, |
686 | chars_format __fmt = chars_format::general) noexcept; |
687 | from_chars_result |
688 | __from_chars_bfloat16_t(const char* __first, const char* __last, |
689 | float& __value, |
690 | chars_format __fmt = chars_format::general) noexcept; |
691 | |
692 | #if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32) \ |
693 | && defined(__cpp_lib_to_chars) |
694 | inline from_chars_result |
695 | from_chars(const char* __first, const char* __last, _Float16& __value, |
696 | chars_format __fmt = chars_format::general) noexcept |
697 | { |
698 | float __val; |
699 | from_chars_result __res |
700 | = __from_chars_float16_t(__first, __last, __val, __fmt); |
701 | if (__res.ec == errc{}) |
702 | __value = __val; |
703 | return __res; |
704 | } |
705 | #endif |
706 | |
707 | #if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32) |
708 | inline from_chars_result |
709 | from_chars(const char* __first, const char* __last, _Float32& __value, |
710 | chars_format __fmt = chars_format::general) noexcept |
711 | { |
712 | float __val; |
713 | from_chars_result __res = from_chars(__first, __last, __val, __fmt); |
714 | if (__res.ec == errc{}) |
715 | __value = __val; |
716 | return __res; |
717 | } |
718 | #endif |
719 | |
720 | #if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64) |
721 | inline from_chars_result |
722 | from_chars(const char* __first, const char* __last, _Float64& __value, |
723 | chars_format __fmt = chars_format::general) noexcept |
724 | { |
725 | double __val; |
726 | from_chars_result __res = from_chars(__first, __last, __val, __fmt); |
727 | if (__res.ec == errc{}) |
728 | __value = __val; |
729 | return __res; |
730 | } |
731 | #endif |
732 | |
733 | #if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128) |
734 | inline from_chars_result |
735 | from_chars(const char* __first, const char* __last, _Float128& __value, |
736 | chars_format __fmt = chars_format::general) noexcept |
737 | { |
738 | long double __val; |
739 | from_chars_result __res = from_chars(__first, __last, __val, __fmt); |
740 | if (__res.ec == errc{}) |
741 | __value = __val; |
742 | return __res; |
743 | } |
744 | #elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH) |
745 | #ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT |
746 | __extension__ from_chars_result |
747 | from_chars(const char* __first, const char* __last, __ieee128& __value, |
748 | chars_format __fmt = chars_format::general) noexcept; |
749 | |
750 | inline from_chars_result |
751 | from_chars(const char* __first, const char* __last, _Float128& __value, |
752 | chars_format __fmt = chars_format::general) noexcept |
753 | { |
754 | __extension__ __ieee128 __val; |
755 | from_chars_result __res = from_chars(__first, __last, __val, __fmt); |
756 | if (__res.ec == errc{}) |
757 | __value = __val; |
758 | return __res; |
759 | } |
760 | #else |
761 | from_chars_result |
762 | from_chars(const char* __first, const char* __last, _Float128& __value, |
763 | chars_format __fmt = chars_format::general) noexcept; |
764 | #endif |
765 | #endif |
766 | |
767 | #if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32) \ |
768 | && defined(__cpp_lib_to_chars) |
769 | inline from_chars_result |
770 | from_chars(const char* __first, const char* __last, |
771 | __gnu_cxx::__bfloat16_t & __value, |
772 | chars_format __fmt = chars_format::general) noexcept |
773 | { |
774 | float __val; |
775 | from_chars_result __res |
776 | = __from_chars_bfloat16_t(__first, __last, __val, __fmt); |
777 | if (__res.ec == errc{}) |
778 | __value = __val; |
779 | return __res; |
780 | } |
781 | #endif |
782 | #endif |
783 | |
784 | #if defined __cpp_lib_to_chars |
785 | // Floating-point std::to_chars |
786 | |
787 | // Overloads for float. |
788 | to_chars_result to_chars(char* __first, char* __last, float __value) noexcept; |
789 | to_chars_result to_chars(char* __first, char* __last, float __value, |
790 | chars_format __fmt) noexcept; |
791 | to_chars_result to_chars(char* __first, char* __last, float __value, |
792 | chars_format __fmt, int __precision) noexcept; |
793 | |
794 | // Overloads for double. |
795 | to_chars_result to_chars(char* __first, char* __last, double __value) noexcept; |
796 | to_chars_result to_chars(char* __first, char* __last, double __value, |
797 | chars_format __fmt) noexcept; |
798 | to_chars_result to_chars(char* __first, char* __last, double __value, |
799 | chars_format __fmt, int __precision) noexcept; |
800 | |
801 | // Overloads for long double. |
802 | to_chars_result to_chars(char* __first, char* __last, long double __value) |
803 | noexcept; |
804 | to_chars_result to_chars(char* __first, char* __last, long double __value, |
805 | chars_format __fmt) noexcept; |
806 | to_chars_result to_chars(char* __first, char* __last, long double __value, |
807 | chars_format __fmt, int __precision) noexcept; |
808 | |
809 | // Library routines for 16-bit extended floating point formats |
810 | // using float as interchange format. |
811 | to_chars_result __to_chars_float16_t(char* __first, char* __last, |
812 | float __value, |
813 | chars_format __fmt) noexcept; |
814 | to_chars_result __to_chars_bfloat16_t(char* __first, char* __last, |
815 | float __value, |
816 | chars_format __fmt) noexcept; |
817 | |
818 | #if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32) |
819 | inline to_chars_result |
820 | to_chars(char* __first, char* __last, _Float16 __value) noexcept |
821 | { |
822 | return __to_chars_float16_t(__first, __last, float(__value), |
823 | chars_format{}); |
824 | } |
825 | inline to_chars_result |
826 | to_chars(char* __first, char* __last, _Float16 __value, |
827 | chars_format __fmt) noexcept |
828 | { return __to_chars_float16_t(__first, __last, float(__value), __fmt); } |
829 | inline to_chars_result |
830 | to_chars(char* __first, char* __last, _Float16 __value, |
831 | chars_format __fmt, int __precision) noexcept |
832 | { return to_chars(__first, __last, float(__value), __fmt, __precision); } |
833 | #endif |
834 | |
835 | #if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32) |
836 | inline to_chars_result |
837 | to_chars(char* __first, char* __last, _Float32 __value) noexcept |
838 | { return to_chars(__first, __last, float(__value)); } |
839 | inline to_chars_result |
840 | to_chars(char* __first, char* __last, _Float32 __value, |
841 | chars_format __fmt) noexcept |
842 | { return to_chars(__first, __last, float(__value), __fmt); } |
843 | inline to_chars_result |
844 | to_chars(char* __first, char* __last, _Float32 __value, |
845 | chars_format __fmt, int __precision) noexcept |
846 | { return to_chars(__first, __last, float(__value), __fmt, __precision); } |
847 | #endif |
848 | |
849 | #if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64) |
850 | inline to_chars_result |
851 | to_chars(char* __first, char* __last, _Float64 __value) noexcept |
852 | { return to_chars(__first, __last, double(__value)); } |
853 | inline to_chars_result |
854 | to_chars(char* __first, char* __last, _Float64 __value, |
855 | chars_format __fmt) noexcept |
856 | { return to_chars(__first, __last, double(__value), __fmt); } |
857 | inline to_chars_result |
858 | to_chars(char* __first, char* __last, _Float64 __value, |
859 | chars_format __fmt, int __precision) noexcept |
860 | { return to_chars(__first, __last, double(__value), __fmt, __precision); } |
861 | #endif |
862 | |
863 | #if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128) |
864 | inline to_chars_result |
865 | to_chars(char* __first, char* __last, _Float128 __value) noexcept |
866 | { return to_chars(__first, __last, static_cast<long double>(__value)); } |
867 | inline to_chars_result |
868 | to_chars(char* __first, char* __last, _Float128 __value, |
869 | chars_format __fmt) noexcept |
870 | { |
871 | return to_chars(__first, __last, static_cast<long double>(__value), __fmt); |
872 | } |
873 | inline to_chars_result |
874 | to_chars(char* __first, char* __last, _Float128 __value, |
875 | chars_format __fmt, int __precision) noexcept |
876 | { |
877 | return to_chars(__first, __last, static_cast<long double>(__value), __fmt, |
878 | __precision); |
879 | } |
880 | #elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH) |
881 | #ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT |
882 | __extension__ to_chars_result |
883 | to_chars(char* __first, char* __last, __float128 __value) noexcept; |
884 | __extension__ to_chars_result |
885 | to_chars(char* __first, char* __last, __float128 __value, |
886 | chars_format __fmt) noexcept; |
887 | __extension__ to_chars_result |
888 | to_chars(char* __first, char* __last, __float128 __value, |
889 | chars_format __fmt, int __precision) noexcept; |
890 | |
891 | inline to_chars_result |
892 | to_chars(char* __first, char* __last, _Float128 __value) noexcept |
893 | { |
894 | return __extension__ to_chars(__first, __last, |
895 | static_cast<__float128>(__value)); |
896 | } |
897 | inline to_chars_result |
898 | to_chars(char* __first, char* __last, _Float128 __value, |
899 | chars_format __fmt) noexcept |
900 | { |
901 | |
902 | return __extension__ to_chars(__first, __last, |
903 | static_cast<__float128>(__value), __fmt); |
904 | } |
905 | inline to_chars_result |
906 | to_chars(char* __first, char* __last, _Float128 __value, |
907 | chars_format __fmt, int __precision) noexcept |
908 | { |
909 | |
910 | return __extension__ to_chars(__first, __last, |
911 | static_cast<__float128>(__value), __fmt, |
912 | __precision); |
913 | } |
914 | #else |
915 | to_chars_result to_chars(char* __first, char* __last, _Float128 __value) |
916 | noexcept; |
917 | to_chars_result to_chars(char* __first, char* __last, _Float128 __value, |
918 | chars_format __fmt) noexcept; |
919 | to_chars_result to_chars(char* __first, char* __last, _Float128 __value, |
920 | chars_format __fmt, int __precision) noexcept; |
921 | #endif |
922 | #endif |
923 | |
924 | #if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32) |
925 | inline to_chars_result |
926 | to_chars(char* __first, char* __last, |
927 | __gnu_cxx::__bfloat16_t __value) noexcept |
928 | { |
929 | return __to_chars_bfloat16_t(__first, __last, float(__value), |
930 | chars_format{}); |
931 | } |
932 | inline to_chars_result |
933 | to_chars(char* __first, char* __last, __gnu_cxx::__bfloat16_t __value, |
934 | chars_format __fmt) noexcept |
935 | { return __to_chars_bfloat16_t(__first, __last, float(__value), __fmt); } |
936 | inline to_chars_result |
937 | to_chars(char* __first, char* __last, __gnu_cxx::__bfloat16_t __value, |
938 | chars_format __fmt, int __precision) noexcept |
939 | { return to_chars(__first, __last, float(__value), __fmt, __precision); } |
940 | #endif |
941 | #endif |
942 | |
943 | _GLIBCXX_END_NAMESPACE_VERSION |
944 | } // namespace std |
945 | #endif // C++14 |
946 | #endif // _GLIBCXX_CHARCONV |
947 | |