libstdc++
charconv
Go to the documentation of this file.
1// Primitive numeric conversions (to_chars and from_chars) -*- C++ -*-
2
3// Copyright (C) 2017-2025 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#ifdef _GLIBCXX_SYSHDR
33#pragma GCC system_header
34#endif
35
36#pragma GCC diagnostic push
37#pragma GCC diagnostic ignored "-Wpedantic" // __int128
38#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
39
40#include <bits/requires_hosted.h> // for error codes
41
42// As an extension we support <charconv> in C++14, but this header should not
43// be included by any other library headers in C++14 mode. This ensures that
44// the names defined in this header are not added to namespace std unless a
45// user explicitly includes <charconv> in C++14 code.
46#if __cplusplus >= 201402L
47
48#include <type_traits>
49#include <bit> // for __bit_width
50#include <bits/charconv.h> // for __to_chars_len, __to_chars_10_impl
51#include <bits/error_constants.h> // for std::errc
52#include <ext/numeric_traits.h>
53
54#define __glibcxx_want_to_chars
55#define __glibcxx_want_constexpr_charconv
56#include <bits/version.h>
57
58namespace std _GLIBCXX_VISIBILITY(default)
59{
60_GLIBCXX_BEGIN_NAMESPACE_VERSION
61
62 /// Result type of std::to_chars
63 struct to_chars_result
64 {
65 char* ptr;
66 errc ec;
67
68#if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L
69 friend bool
70 operator==(const to_chars_result&, const to_chars_result&) = default;
71#endif
72#if __cplusplus > 202302L
73 constexpr explicit operator bool() const noexcept { return ec == errc{}; }
74#endif
75 };
76
77 /// Result type of std::from_chars
78 struct from_chars_result
79 {
80 const char* ptr;
81 errc ec;
82
83#if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L
84 friend bool
85 operator==(const from_chars_result&, const from_chars_result&) = default;
86#endif
87#if __cplusplus > 202302L
88 constexpr explicit operator bool() const noexcept { return ec == errc{}; }
89#endif
90 };
91
92namespace __detail
93{
94 // Pick an unsigned type of suitable size. This is used to reduce the
95 // number of specializations of __to_chars_len, __to_chars etc. that
96 // get instantiated. For example, to_chars<char> and to_chars<short>
97 // and to_chars<unsigned> will all use the same code, and so will
98 // to_chars<long> when sizeof(int) == sizeof(long).
99 template<typename _Tp>
100 struct __to_chars_unsigned_type : __make_unsigned_selector_base
101 {
102 using _UInts = _List<unsigned int, unsigned long, unsigned long long
103#if __SIZEOF_INT128__ > __SIZEOF_LONG_LONG__
104 , unsigned __int128
105#endif
106 >;
107 using type = typename __select<sizeof(_Tp), _UInts>::__type;
108 };
109
110 template<typename _Tp>
111 using __unsigned_least_t = typename __to_chars_unsigned_type<_Tp>::type;
112
113 // Generic implementation for arbitrary bases.
114 // Defined in <bits/charconv.h>.
115 template<typename _Tp>
116 constexpr unsigned
117 __to_chars_len(_Tp __value, int __base /* = 10 */) noexcept;
118
119 template<typename _Tp>
120 constexpr unsigned
121 __to_chars_len_2(_Tp __value) noexcept
122 { return std::__bit_width(__value); }
123
124 // Generic implementation for arbitrary bases.
125 template<typename _Tp>
126 constexpr to_chars_result
127 __to_chars(char* __first, char* __last, _Tp __val, int __base) noexcept
128 {
129 static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug");
130
131 to_chars_result __res;
132
133 const unsigned __len = __to_chars_len(__val, __base);
134
135 if (__builtin_expect(size_t(__last - __first) < __len, 0))
136 {
137 __res.ptr = __last;
138 __res.ec = errc::value_too_large;
139 return __res;
140 }
141
142 unsigned __pos = __len - 1;
143
144 constexpr char __digits[] = {
145 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
146 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
147 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
148 'u', 'v', 'w', 'x', 'y', 'z'
149 };
150
151 while (__val >= (unsigned)__base)
152 {
153 auto const __quo = __val / __base;
154 auto const __rem = __val % __base;
155 __first[__pos--] = __digits[__rem];
156 __val = __quo;
157 }
158 *__first = __digits[__val];
159
160 __res.ptr = __first + __len;
161 __res.ec = {};
162 return __res;
163 }
164
165 template<typename _Tp>
166 constexpr to_chars_result
167 __to_chars_16(char* __first, char* __last, _Tp __val) noexcept
168 {
169 static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug");
170
171 to_chars_result __res;
172
173 const unsigned __len = (__to_chars_len_2(__val) + 3) / 4;
174
175 if (__builtin_expect(size_t(__last - __first) < __len, 0))
176 {
177 __res.ptr = __last;
178 __res.ec = errc::value_too_large;
179 return __res;
180 }
181
182 constexpr char __digits[] = {
183 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
184 'a', 'b', 'c', 'd', 'e', 'f'
185 };
186 unsigned __pos = __len - 1;
187 while (__val >= 0x100)
188 {
189 auto __num = __val & 0xF;
190 __val >>= 4;
191 __first[__pos] = __digits[__num];
192 __num = __val & 0xF;
193 __val >>= 4;
194 __first[__pos - 1] = __digits[__num];
195 __pos -= 2;
196 }
197 if (__val >= 0x10)
198 {
199 const auto __num = __val & 0xF;
200 __val >>= 4;
201 __first[1] = __digits[__num];
202 __first[0] = __digits[__val];
203 }
204 else
205 __first[0] = __digits[__val];
206 __res.ptr = __first + __len;
207 __res.ec = {};
208 return __res;
209 }
210
211 template<typename _Tp>
212 constexpr to_chars_result
213 __to_chars_10(char* __first, char* __last, _Tp __val) noexcept
214 {
215 static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug");
216
217 to_chars_result __res;
218
219 const unsigned __len = __to_chars_len(__val, 10);
220
221 if (__builtin_expect(size_t(__last - __first) < __len, 0))
222 {
223 __res.ptr = __last;
224 __res.ec = errc::value_too_large;
225 return __res;
226 }
227
228 __detail::__to_chars_10_impl(__first, __len, __val);
229 __res.ptr = __first + __len;
230 __res.ec = {};
231 return __res;
232 }
233
234 template<typename _Tp>
235 constexpr to_chars_result
236 __to_chars_8(char* __first, char* __last, _Tp __val) noexcept
237 {
238 static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug");
239
240 to_chars_result __res;
241 unsigned __len = 0;
242
243 if constexpr (__gnu_cxx::__int_traits<_Tp>::__digits <= 16)
244 {
245 __len = __val > 077777u ? 6u
246 : __val > 07777u ? 5u
247 : __val > 0777u ? 4u
248 : __val > 077u ? 3u
249 : __val > 07u ? 2u
250 : 1u;
251 }
252 else
253 __len = (__to_chars_len_2(__val) + 2) / 3;
254
255 if (__builtin_expect(size_t(__last - __first) < __len, 0))
256 {
257 __res.ptr = __last;
258 __res.ec = errc::value_too_large;
259 return __res;
260 }
261
262 unsigned __pos = __len - 1;
263 while (__val >= 0100)
264 {
265 auto __num = __val & 7;
266 __val >>= 3;
267 __first[__pos] = '0' + __num;
268 __num = __val & 7;
269 __val >>= 3;
270 __first[__pos - 1] = '0' + __num;
271 __pos -= 2;
272 }
273 if (__val >= 010)
274 {
275 auto const __num = __val & 7;
276 __val >>= 3;
277 __first[1] = '0' + __num;
278 __first[0] = '0' + __val;
279 }
280 else
281 __first[0] = '0' + __val;
282 __res.ptr = __first + __len;
283 __res.ec = {};
284 return __res;
285 }
286
287 template<typename _Tp>
288 constexpr to_chars_result
289 __to_chars_2(char* __first, char* __last, _Tp __val) noexcept
290 {
291 static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug");
292
293 to_chars_result __res;
294
295 const unsigned __len = __to_chars_len_2(__val);
296
297 if (__builtin_expect(size_t(__last - __first) < __len, 0))
298 {
299 __res.ptr = __last;
300 __res.ec = errc::value_too_large;
301 return __res;
302 }
303
304 unsigned __pos = __len - 1;
305
306 while (__pos)
307 {
308 __first[__pos--] = '0' + (__val & 1);
309 __val >>= 1;
310 }
311 // First digit is always '1' because __to_chars_len_2 skips
312 // leading zero bits and std::to_chars handles zero values
313 // directly.
314 __first[0] = '1';
315
316 __res.ptr = __first + __len;
317 __res.ec = {};
318 return __res;
319 }
320
321} // namespace __detail
322
323 template<typename _Tp>
324 constexpr to_chars_result
325 __to_chars_i(char* __first, char* __last, _Tp __value, int __base = 10)
326 {
327 __glibcxx_assert(2 <= __base && __base <= 36);
328
329 using _Up = __detail::__unsigned_least_t<_Tp>;
330 _Up __unsigned_val = __value;
331
332 if (__first >= __last) [[__unlikely__]]
333 return { __last, errc::value_too_large };
334
335 if (__value == 0)
336 {
337 *__first = '0';
338 return { __first + 1, errc{} };
339 }
340 else if constexpr (std::is_signed<_Tp>::value)
341 if (__value < 0)
342 {
343 *__first++ = '-';
344 __unsigned_val = _Up(~__value) + _Up(1);
345 }
346
347 switch (__base)
348 {
349 case 16:
350 return __detail::__to_chars_16(__first, __last, __unsigned_val);
351 case 10:
352 return __detail::__to_chars_10(__first, __last, __unsigned_val);
353 case 8:
354 return __detail::__to_chars_8(__first, __last, __unsigned_val);
355 case 2:
356 return __detail::__to_chars_2(__first, __last, __unsigned_val);
357 default:
358 return __detail::__to_chars(__first, __last, __unsigned_val, __base);
359 }
360 }
361
362#define _GLIBCXX_TO_CHARS(T) \
363 _GLIBCXX23_CONSTEXPR inline to_chars_result \
364 to_chars(char* __first, char* __last, T __value, int __base = 10) \
365 { return std::__to_chars_i<T>(__first, __last, __value, __base); }
366_GLIBCXX_TO_CHARS(char)
367_GLIBCXX_TO_CHARS(signed char)
368_GLIBCXX_TO_CHARS(unsigned char)
369_GLIBCXX_TO_CHARS(signed short)
370_GLIBCXX_TO_CHARS(unsigned short)
371_GLIBCXX_TO_CHARS(signed int)
372_GLIBCXX_TO_CHARS(unsigned int)
373_GLIBCXX_TO_CHARS(signed long)
374_GLIBCXX_TO_CHARS(unsigned long)
375_GLIBCXX_TO_CHARS(signed long long)
376_GLIBCXX_TO_CHARS(unsigned long long)
377#if defined(__GLIBCXX_TYPE_INT_N_0)
378_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_0)
379_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_0)
380#endif
381#if defined(__GLIBCXX_TYPE_INT_N_1)
382_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_1)
383_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_1)
384#endif
385#if defined(__GLIBCXX_TYPE_INT_N_2)
386_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_2)
387_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_2)
388#endif
389#if defined(__GLIBCXX_TYPE_INT_N_3)
390_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_3)
391_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_3)
392#endif
393#if defined __SIZEOF_INT128__ && defined __STRICT_ANSI__
394_GLIBCXX_TO_CHARS(signed __int128)
395_GLIBCXX_TO_CHARS(unsigned __int128)
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
403namespace __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 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(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(__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(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} // namespace __detail
556
557 /// std::from_chars for integral types.
558 template<typename _Tp,
559 enable_if_t<__or_<__is_standard_integer<_Tp>,
560 is_same<char, remove_cv_t<_Tp>>>::value, int> = 0>
561 _GLIBCXX23_CONSTEXPR from_chars_result
562 from_chars(const char* __first, const char* __last, _Tp& __value,
563 int __base = 10)
564 {
565 __glibcxx_assert(2 <= __base && __base <= 36);
566
567 from_chars_result __res{__first, {}};
568
569 int __sign = 1;
570 if constexpr (std::is_signed<_Tp>::value)
571 if (__first != __last && *__first == '-')
572 {
573 __sign = -1;
574 ++__first;
575 }
576
577 using _Up = __detail::__unsigned_least_t<_Tp>;
578 _Up __val = 0;
579
580 const auto __start = __first;
581 bool __valid;
582 if ((__base & (__base - 1)) == 0)
583 {
584 if (__base <= 8)
585 __valid = __detail::__from_chars_pow2_base<true>(__first, __last, __val, __base);
586 else
587 __valid = __detail::__from_chars_pow2_base<false>(__first, __last, __val, __base);
588 }
589 else if (__base <= 10)
590 __valid = __detail::__from_chars_alnum<true>(__first, __last, __val, __base);
591 else
592 __valid = __detail::__from_chars_alnum<false>(__first, __last, __val, __base);
593
594 if (__builtin_expect(__first == __start, 0))
595 __res.ec = errc::invalid_argument;
596 else
597 {
598 __res.ptr = __first;
599 if (!__valid)
600 __res.ec = errc::result_out_of_range;
601 else
602 {
603 if constexpr (std::is_signed<_Tp>::value)
604 {
605 _Tp __tmp;
606 if (__builtin_mul_overflow(__val, __sign, &__tmp))
607 __res.ec = errc::result_out_of_range;
608 else
609 __value = __tmp;
610 }
611 else
612 {
613 if constexpr (__gnu_cxx::__int_traits<_Up>::__max
614 > __gnu_cxx::__int_traits<_Tp>::__max)
615 {
616 if (__val > __gnu_cxx::__int_traits<_Tp>::__max)
617 __res.ec = errc::result_out_of_range;
618 else
619 __value = __val;
620 }
621 else
622 __value = __val;
623 }
624 }
625 }
626 return __res;
627 }
628
629 /// floating-point format for primitive numerical conversion
630 enum class chars_format
631 {
632 scientific = 1, fixed = 2, hex = 4, general = fixed | scientific
633 };
634
635 [[nodiscard]]
636 constexpr chars_format
637 operator|(chars_format __lhs, chars_format __rhs) noexcept
638 { return (chars_format)((unsigned)__lhs | (unsigned)__rhs); }
639
640 [[nodiscard]]
641 constexpr chars_format
642 operator&(chars_format __lhs, chars_format __rhs) noexcept
643 { return (chars_format)((unsigned)__lhs & (unsigned)__rhs); }
644
645 [[nodiscard]]
646 constexpr chars_format
647 operator^(chars_format __lhs, chars_format __rhs) noexcept
648 { return (chars_format)((unsigned)__lhs ^ (unsigned)__rhs); }
649
650 [[nodiscard]]
651 constexpr chars_format
652 operator~(chars_format __fmt) noexcept
653 { return (chars_format)~(unsigned)__fmt; }
654
655 constexpr chars_format&
656 operator|=(chars_format& __lhs, chars_format __rhs) noexcept
657 { return __lhs = __lhs | __rhs; }
658
659 constexpr chars_format&
660 operator&=(chars_format& __lhs, chars_format __rhs) noexcept
661 { return __lhs = __lhs & __rhs; }
662
663 constexpr chars_format&
664 operator^=(chars_format& __lhs, chars_format __rhs) noexcept
665 { return __lhs = __lhs ^ __rhs; }
666
667#if defined __cpp_lib_to_chars || _GLIBCXX_HAVE_USELOCALE
668 from_chars_result
669 from_chars(const char* __first, const char* __last, float& __value,
670 chars_format __fmt = chars_format::general) noexcept;
671
672 from_chars_result
673 from_chars(const char* __first, const char* __last, double& __value,
674 chars_format __fmt = chars_format::general) noexcept;
675
676 from_chars_result
677 from_chars(const char* __first, const char* __last, long double& __value,
678 chars_format __fmt = chars_format::general) noexcept;
679
680 // Library routines for 16-bit extended floating point formats
681 // using float as interchange format.
682 from_chars_result
683 __from_chars_float16_t(const char* __first, const char* __last,
684 float& __value,
685 chars_format __fmt = chars_format::general) noexcept;
686 from_chars_result
687 __from_chars_bfloat16_t(const char* __first, const char* __last,
688 float& __value,
689 chars_format __fmt = chars_format::general) noexcept;
690
691#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32) \
692 && defined(__cpp_lib_to_chars)
693 inline from_chars_result
694 from_chars(const char* __first, const char* __last, _Float16& __value,
695 chars_format __fmt = chars_format::general) noexcept
696 {
697 float __val;
698 from_chars_result __res
699 = __from_chars_float16_t(__first, __last, __val, __fmt);
700 if (__res.ec == errc{})
701 __value = _Float16(__val);
702 return __res;
703 }
704#endif
705
706#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
707 inline from_chars_result
708 from_chars(const char* __first, const char* __last, _Float32& __value,
709 chars_format __fmt = chars_format::general) noexcept
710 {
711 float __val;
712 from_chars_result __res = from_chars(__first, __last, __val, __fmt);
713 if (__res.ec == errc{})
714 __value = _Float32(__val);
715 return __res;
716 }
717#endif
718
719#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
720 inline from_chars_result
721 from_chars(const char* __first, const char* __last, _Float64& __value,
722 chars_format __fmt = chars_format::general) noexcept
723 {
724 double __val;
725 from_chars_result __res = from_chars(__first, __last, __val, __fmt);
726 if (__res.ec == errc{})
727 __value = _Float64(__val);
728 return __res;
729 }
730#endif
731
732#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
733 inline from_chars_result
734 from_chars(const char* __first, const char* __last, _Float128& __value,
735 chars_format __fmt = chars_format::general) noexcept
736 {
737 long double __val;
738 from_chars_result __res = from_chars(__first, __last, __val, __fmt);
739 if (__res.ec == errc{})
740 __value = _Float128(__val);
741 return __res;
742 }
743#elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH)
744#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
745 __extension__ from_chars_result
746 from_chars(const char* __first, const char* __last, __ieee128& __value,
747 chars_format __fmt = chars_format::general) noexcept;
748
749 inline from_chars_result
750 from_chars(const char* __first, const char* __last, _Float128& __value,
751 chars_format __fmt = chars_format::general) noexcept
752 {
753 __extension__ __ieee128 __val;
754 from_chars_result __res = from_chars(__first, __last, __val, __fmt);
755 if (__res.ec == errc{})
756 __value = _Float128(__val);
757 return __res;
758 }
759#else
760 from_chars_result
761 from_chars(const char* __first, const char* __last, _Float128& __value,
762 chars_format __fmt = chars_format::general) noexcept;
763#endif
764#endif
765
766#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32) \
767 && defined(__cpp_lib_to_chars)
768 inline from_chars_result
769 from_chars(const char* __first, const char* __last,
770 __gnu_cxx::__bfloat16_t & __value,
771 chars_format __fmt = chars_format::general) noexcept
772 {
773 float __val;
774 from_chars_result __res
775 = __from_chars_bfloat16_t(__first, __last, __val, __fmt);
776 if (__res.ec == errc{})
777 __value = __gnu_cxx::__bfloat16_t(__val);
778 return __res;
779 }
780#endif
781#endif
782
783#if defined __cpp_lib_to_chars
784 // Floating-point std::to_chars
785
786 // Overloads for float.
787 to_chars_result to_chars(char* __first, char* __last, float __value) noexcept;
788 to_chars_result to_chars(char* __first, char* __last, float __value,
789 chars_format __fmt) noexcept;
790 to_chars_result to_chars(char* __first, char* __last, float __value,
791 chars_format __fmt, int __precision) noexcept;
792
793 // Overloads for double.
794 to_chars_result to_chars(char* __first, char* __last, double __value) noexcept;
795 to_chars_result to_chars(char* __first, char* __last, double __value,
796 chars_format __fmt) noexcept;
797 to_chars_result to_chars(char* __first, char* __last, double __value,
798 chars_format __fmt, int __precision) noexcept;
799
800 // Overloads for long double.
801 to_chars_result to_chars(char* __first, char* __last, long double __value)
802 noexcept;
803 to_chars_result to_chars(char* __first, char* __last, long double __value,
804 chars_format __fmt) noexcept;
805 to_chars_result to_chars(char* __first, char* __last, long double __value,
806 chars_format __fmt, int __precision) noexcept;
807
808 // Library routines for 16-bit extended floating point formats
809 // using float as interchange format.
810 to_chars_result __to_chars_float16_t(char* __first, char* __last,
811 float __value,
812 chars_format __fmt) noexcept;
813 to_chars_result __to_chars_bfloat16_t(char* __first, char* __last,
814 float __value,
815 chars_format __fmt) noexcept;
816
817#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
818 inline to_chars_result
819 to_chars(char* __first, char* __last, _Float16 __value) noexcept
820 {
821 return __to_chars_float16_t(__first, __last, float(__value),
822 chars_format{});
823 }
824 inline to_chars_result
825 to_chars(char* __first, char* __last, _Float16 __value,
826 chars_format __fmt) noexcept
827 { return __to_chars_float16_t(__first, __last, float(__value), __fmt); }
828 inline to_chars_result
829 to_chars(char* __first, char* __last, _Float16 __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_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
835 inline to_chars_result
836 to_chars(char* __first, char* __last, _Float32 __value) noexcept
837 { return to_chars(__first, __last, float(__value)); }
838 inline to_chars_result
839 to_chars(char* __first, char* __last, _Float32 __value,
840 chars_format __fmt) noexcept
841 { return to_chars(__first, __last, float(__value), __fmt); }
842 inline to_chars_result
843 to_chars(char* __first, char* __last, _Float32 __value,
844 chars_format __fmt, int __precision) noexcept
845 { return to_chars(__first, __last, float(__value), __fmt, __precision); }
846#endif
847
848#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
849 inline to_chars_result
850 to_chars(char* __first, char* __last, _Float64 __value) noexcept
851 { return to_chars(__first, __last, double(__value)); }
852 inline to_chars_result
853 to_chars(char* __first, char* __last, _Float64 __value,
854 chars_format __fmt) noexcept
855 { return to_chars(__first, __last, double(__value), __fmt); }
856 inline to_chars_result
857 to_chars(char* __first, char* __last, _Float64 __value,
858 chars_format __fmt, int __precision) noexcept
859 { return to_chars(__first, __last, double(__value), __fmt, __precision); }
860#endif
861
862#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
863 inline to_chars_result
864 to_chars(char* __first, char* __last, _Float128 __value) noexcept
865 { return to_chars(__first, __last, static_cast<long double>(__value)); }
866 inline to_chars_result
867 to_chars(char* __first, char* __last, _Float128 __value,
868 chars_format __fmt) noexcept
869 {
870 return to_chars(__first, __last, static_cast<long double>(__value), __fmt);
871 }
872 inline to_chars_result
873 to_chars(char* __first, char* __last, _Float128 __value,
874 chars_format __fmt, int __precision) noexcept
875 {
876 return to_chars(__first, __last, static_cast<long double>(__value), __fmt,
877 __precision);
878 }
879#elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH)
880#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
881 __extension__ to_chars_result
882 to_chars(char* __first, char* __last, __float128 __value) noexcept;
883 __extension__ to_chars_result
884 to_chars(char* __first, char* __last, __float128 __value,
885 chars_format __fmt) noexcept;
886 __extension__ to_chars_result
887 to_chars(char* __first, char* __last, __float128 __value,
888 chars_format __fmt, int __precision) noexcept;
889
890 inline to_chars_result
891 to_chars(char* __first, char* __last, _Float128 __value) noexcept
892 {
893 return __extension__ to_chars(__first, __last,
894 static_cast<__float128>(__value));
895 }
896 inline to_chars_result
897 to_chars(char* __first, char* __last, _Float128 __value,
898 chars_format __fmt) noexcept
899 {
900
901 return __extension__ to_chars(__first, __last,
902 static_cast<__float128>(__value), __fmt);
903 }
904 inline to_chars_result
905 to_chars(char* __first, char* __last, _Float128 __value,
906 chars_format __fmt, int __precision) noexcept
907 {
908
909 return __extension__ to_chars(__first, __last,
910 static_cast<__float128>(__value), __fmt,
911 __precision);
912 }
913#else
914 to_chars_result to_chars(char* __first, char* __last, _Float128 __value)
915 noexcept;
916 to_chars_result to_chars(char* __first, char* __last, _Float128 __value,
917 chars_format __fmt) noexcept;
918 to_chars_result to_chars(char* __first, char* __last, _Float128 __value,
919 chars_format __fmt, int __precision) noexcept;
920#endif
921#endif
922
923#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
924 inline to_chars_result
925 to_chars(char* __first, char* __last,
926 __gnu_cxx::__bfloat16_t __value) noexcept
927 {
928 return __to_chars_bfloat16_t(__first, __last, float(__value),
929 chars_format{});
930 }
931 inline to_chars_result
932 to_chars(char* __first, char* __last, __gnu_cxx::__bfloat16_t __value,
933 chars_format __fmt) noexcept
934 { return __to_chars_bfloat16_t(__first, __last, float(__value), __fmt); }
935 inline to_chars_result
936 to_chars(char* __first, char* __last, __gnu_cxx::__bfloat16_t __value,
937 chars_format __fmt, int __precision) noexcept
938 { return to_chars(__first, __last, float(__value), __fmt, __precision); }
939#endif
940#endif
941
942_GLIBCXX_END_NAMESPACE_VERSION
943} // namespace std
944#endif // C++14
945#pragma GCC diagnostic pop
946#endif // _GLIBCXX_CHARCONV