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