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 
52 namespace std _GLIBCXX_VISIBILITY(default)
53 {
54 _GLIBCXX_BEGIN_NAMESPACE_VERSION
55 
56  /// Result type of std::to_chars
57  struct to_chars_result
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
72  struct from_chars_result
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 
86 namespace __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 
393 namespace __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
604  > __gnu_cxx::__int_traits<_Tp>::__max)
605  {
606  if (__val > __gnu_cxx::__int_traits<_Tp>::__max)
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  [[nodiscard]]
626  constexpr chars_format
627  operator|(chars_format __lhs, chars_format __rhs) noexcept
628  { return (chars_format)((unsigned)__lhs | (unsigned)__rhs); }
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 __fmt) noexcept
643  { return (chars_format)~(unsigned)__fmt; }
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  constexpr chars_format&
654  operator^=(chars_format& __lhs, chars_format __rhs) noexcept
655  { return __lhs = __lhs ^ __rhs; }
656 
657 #if defined __cpp_lib_to_chars || _GLIBCXX_HAVE_USELOCALE
658  from_chars_result
659  from_chars(const char* __first, const char* __last, float& __value,
660  chars_format __fmt = chars_format::general) noexcept;
661 
662  from_chars_result
663  from_chars(const char* __first, const char* __last, double& __value,
664  chars_format __fmt = chars_format::general) noexcept;
665 
666  from_chars_result
667  from_chars(const char* __first, const char* __last, long double& __value,
668  chars_format __fmt = chars_format::general) noexcept;
669 
670  // Library routines for 16-bit extended floating point formats
671  // using float as interchange format.
672  from_chars_result
673  __from_chars_float16_t(const char* __first, const char* __last,
674  float& __value,
675  chars_format __fmt = chars_format::general) noexcept;
676  from_chars_result
677  __from_chars_bfloat16_t(const char* __first, const char* __last,
678  float& __value,
679  chars_format __fmt = chars_format::general) noexcept;
680 
681 #if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32) \
682  && defined(__cpp_lib_to_chars)
683  inline from_chars_result
684  from_chars(const char* __first, const char* __last, _Float16& __value,
685  chars_format __fmt = chars_format::general) noexcept
686  {
687  float __val;
688  from_chars_result __res
689  = __from_chars_float16_t(__first, __last, __val, __fmt);
690  if (__res.ec == errc{})
691  __value = _Float16(__val);
692  return __res;
693  }
694 #endif
695 
696 #if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
697  inline from_chars_result
698  from_chars(const char* __first, const char* __last, _Float32& __value,
699  chars_format __fmt = chars_format::general) noexcept
700  {
701  float __val;
702  from_chars_result __res = from_chars(__first, __last, __val, __fmt);
703  if (__res.ec == errc{})
704  __value = _Float32(__val);
705  return __res;
706  }
707 #endif
708 
709 #if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
710  inline from_chars_result
711  from_chars(const char* __first, const char* __last, _Float64& __value,
712  chars_format __fmt = chars_format::general) noexcept
713  {
714  double __val;
715  from_chars_result __res = from_chars(__first, __last, __val, __fmt);
716  if (__res.ec == errc{})
717  __value = _Float64(__val);
718  return __res;
719  }
720 #endif
721 
722 #if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
723  inline from_chars_result
724  from_chars(const char* __first, const char* __last, _Float128& __value,
725  chars_format __fmt = chars_format::general) noexcept
726  {
727  long double __val;
728  from_chars_result __res = from_chars(__first, __last, __val, __fmt);
729  if (__res.ec == errc{})
730  __value = _Float128(__val);
731  return __res;
732  }
733 #elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH)
734 #ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
735  __extension__ from_chars_result
736  from_chars(const char* __first, const char* __last, __ieee128& __value,
737  chars_format __fmt = chars_format::general) noexcept;
738 
739  inline from_chars_result
740  from_chars(const char* __first, const char* __last, _Float128& __value,
741  chars_format __fmt = chars_format::general) noexcept
742  {
743  __extension__ __ieee128 __val;
744  from_chars_result __res = from_chars(__first, __last, __val, __fmt);
745  if (__res.ec == errc{})
746  __value = _Float128(__val);
747  return __res;
748  }
749 #else
750  from_chars_result
751  from_chars(const char* __first, const char* __last, _Float128& __value,
752  chars_format __fmt = chars_format::general) noexcept;
753 #endif
754 #endif
755 
756 #if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32) \
757  && defined(__cpp_lib_to_chars)
758  inline from_chars_result
759  from_chars(const char* __first, const char* __last,
760  __gnu_cxx::__bfloat16_t & __value,
761  chars_format __fmt = chars_format::general) noexcept
762  {
763  float __val;
764  from_chars_result __res
765  = __from_chars_bfloat16_t(__first, __last, __val, __fmt);
766  if (__res.ec == errc{})
767  __value = __gnu_cxx::__bfloat16_t(__val);
768  return __res;
769  }
770 #endif
771 #endif
772 
773 #if defined __cpp_lib_to_chars
774  // Floating-point std::to_chars
775 
776  // Overloads for float.
777  to_chars_result to_chars(char* __first, char* __last, float __value) noexcept;
778  to_chars_result to_chars(char* __first, char* __last, float __value,
779  chars_format __fmt) noexcept;
780  to_chars_result to_chars(char* __first, char* __last, float __value,
781  chars_format __fmt, int __precision) noexcept;
782 
783  // Overloads for double.
784  to_chars_result to_chars(char* __first, char* __last, double __value) noexcept;
785  to_chars_result to_chars(char* __first, char* __last, double __value,
786  chars_format __fmt) noexcept;
787  to_chars_result to_chars(char* __first, char* __last, double __value,
788  chars_format __fmt, int __precision) noexcept;
789 
790  // Overloads for long double.
791  to_chars_result to_chars(char* __first, char* __last, long double __value)
792  noexcept;
793  to_chars_result to_chars(char* __first, char* __last, long double __value,
794  chars_format __fmt) noexcept;
795  to_chars_result to_chars(char* __first, char* __last, long double __value,
796  chars_format __fmt, int __precision) noexcept;
797 
798  // Library routines for 16-bit extended floating point formats
799  // using float as interchange format.
800  to_chars_result __to_chars_float16_t(char* __first, char* __last,
801  float __value,
802  chars_format __fmt) noexcept;
803  to_chars_result __to_chars_bfloat16_t(char* __first, char* __last,
804  float __value,
805  chars_format __fmt) noexcept;
806 
807 #if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
808  inline to_chars_result
809  to_chars(char* __first, char* __last, _Float16 __value) noexcept
810  {
811  return __to_chars_float16_t(__first, __last, float(__value),
812  chars_format{});
813  }
814  inline to_chars_result
815  to_chars(char* __first, char* __last, _Float16 __value,
816  chars_format __fmt) noexcept
817  { return __to_chars_float16_t(__first, __last, float(__value), __fmt); }
818  inline to_chars_result
819  to_chars(char* __first, char* __last, _Float16 __value,
820  chars_format __fmt, int __precision) noexcept
821  { return to_chars(__first, __last, float(__value), __fmt, __precision); }
822 #endif
823 
824 #if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
825  inline to_chars_result
826  to_chars(char* __first, char* __last, _Float32 __value) noexcept
827  { return to_chars(__first, __last, float(__value)); }
828  inline to_chars_result
829  to_chars(char* __first, char* __last, _Float32 __value,
830  chars_format __fmt) noexcept
831  { return to_chars(__first, __last, float(__value), __fmt); }
832  inline to_chars_result
833  to_chars(char* __first, char* __last, _Float32 __value,
834  chars_format __fmt, int __precision) noexcept
835  { return to_chars(__first, __last, float(__value), __fmt, __precision); }
836 #endif
837 
838 #if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
839  inline to_chars_result
840  to_chars(char* __first, char* __last, _Float64 __value) noexcept
841  { return to_chars(__first, __last, double(__value)); }
842  inline to_chars_result
843  to_chars(char* __first, char* __last, _Float64 __value,
844  chars_format __fmt) noexcept
845  { return to_chars(__first, __last, double(__value), __fmt); }
846  inline to_chars_result
847  to_chars(char* __first, char* __last, _Float64 __value,
848  chars_format __fmt, int __precision) noexcept
849  { return to_chars(__first, __last, double(__value), __fmt, __precision); }
850 #endif
851 
852 #if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
853  inline to_chars_result
854  to_chars(char* __first, char* __last, _Float128 __value) noexcept
855  { return to_chars(__first, __last, static_cast<long double>(__value)); }
856  inline to_chars_result
857  to_chars(char* __first, char* __last, _Float128 __value,
858  chars_format __fmt) noexcept
859  {
860  return to_chars(__first, __last, static_cast<long double>(__value), __fmt);
861  }
862  inline to_chars_result
863  to_chars(char* __first, char* __last, _Float128 __value,
864  chars_format __fmt, int __precision) noexcept
865  {
866  return to_chars(__first, __last, static_cast<long double>(__value), __fmt,
867  __precision);
868  }
869 #elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH)
870 #ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
871  __extension__ to_chars_result
872  to_chars(char* __first, char* __last, __float128 __value) noexcept;
873  __extension__ to_chars_result
874  to_chars(char* __first, char* __last, __float128 __value,
875  chars_format __fmt) noexcept;
876  __extension__ to_chars_result
877  to_chars(char* __first, char* __last, __float128 __value,
878  chars_format __fmt, int __precision) noexcept;
879 
880  inline to_chars_result
881  to_chars(char* __first, char* __last, _Float128 __value) noexcept
882  {
883  return __extension__ to_chars(__first, __last,
884  static_cast<__float128>(__value));
885  }
886  inline to_chars_result
887  to_chars(char* __first, char* __last, _Float128 __value,
888  chars_format __fmt) noexcept
889  {
890 
891  return __extension__ to_chars(__first, __last,
892  static_cast<__float128>(__value), __fmt);
893  }
894  inline to_chars_result
895  to_chars(char* __first, char* __last, _Float128 __value,
896  chars_format __fmt, int __precision) noexcept
897  {
898 
899  return __extension__ to_chars(__first, __last,
900  static_cast<__float128>(__value), __fmt,
901  __precision);
902  }
903 #else
904  to_chars_result to_chars(char* __first, char* __last, _Float128 __value)
905  noexcept;
906  to_chars_result to_chars(char* __first, char* __last, _Float128 __value,
907  chars_format __fmt) noexcept;
908  to_chars_result to_chars(char* __first, char* __last, _Float128 __value,
909  chars_format __fmt, int __precision) noexcept;
910 #endif
911 #endif
912 
913 #if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
914  inline to_chars_result
915  to_chars(char* __first, char* __last,
916  __gnu_cxx::__bfloat16_t __value) noexcept
917  {
918  return __to_chars_bfloat16_t(__first, __last, float(__value),
919  chars_format{});
920  }
921  inline to_chars_result
922  to_chars(char* __first, char* __last, __gnu_cxx::__bfloat16_t __value,
923  chars_format __fmt) noexcept
924  { return __to_chars_bfloat16_t(__first, __last, float(__value), __fmt); }
925  inline to_chars_result
926  to_chars(char* __first, char* __last, __gnu_cxx::__bfloat16_t __value,
927  chars_format __fmt, int __precision) noexcept
928  { return to_chars(__first, __last, float(__value), __fmt, __precision); }
929 #endif
930 #endif
931 
932 _GLIBCXX_END_NAMESPACE_VERSION
933 } // namespace std
934 #endif // C++14
935 #endif // _GLIBCXX_CHARCONV