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