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