Home | History | Annotate | Line # | Download | only in std
      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
    936