Home | History | Annotate | Line # | Download | only in std
      1 // Primitive numeric conversions (to_chars and from_chars) -*- C++ -*-
      2 
      3 // Copyright (C) 2017-2022 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 // As an extension we support <charconv> in C++14, but this header should not
     35 // be included by any other library headers in C++14 mode. This ensures that
     36 // the names defined in this header are not added to namespace std unless a
     37 // user explicitly includes <charconv> in C++14 code.
     38 #if __cplusplus >= 201402L
     39 
     40 #include <type_traits>
     41 #include <bit>			// for __bit_width
     42 #include <bits/charconv.h>	// for __to_chars_len, __to_chars_10_impl
     43 #include <bits/error_constants.h> // for std::errc
     44 #include <ext/numeric_traits.h>
     45 
     46 #if _GLIBCXX_FLOAT_IS_IEEE_BINARY32 && _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 \
     47     && __SIZE_WIDTH__ >= 32
     48 # define __cpp_lib_to_chars 201611L
     49 #endif
     50 
     51 namespace std _GLIBCXX_VISIBILITY(default)
     52 {
     53 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     54 
     55   /// Result type of std::to_chars
     56   struct to_chars_result
     57   {
     58     char* ptr;
     59     errc ec;
     60 
     61 #if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L
     62     friend bool
     63     operator==(const to_chars_result&, const to_chars_result&) = default;
     64 #endif
     65   };
     66 
     67   /// Result type of std::from_chars
     68   struct from_chars_result
     69   {
     70     const char* ptr;
     71     errc ec;
     72 
     73 #if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L
     74     friend bool
     75     operator==(const from_chars_result&, const from_chars_result&) = default;
     76 #endif
     77   };
     78 
     79 namespace __detail
     80 {
     81   template<typename _Tp>
     82     using __integer_to_chars_result_type
     83       = enable_if_t<__or_<__is_signed_integer<_Tp>,
     84 			  __is_unsigned_integer<_Tp>,
     85 			  is_same<char, remove_cv_t<_Tp>>>::value,
     86 		    to_chars_result>;
     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     to_chars_result
    121     __to_chars(char* __first, char* __last, _Tp __val, int __base) noexcept
    122     {
    123       static_assert(is_integral<_Tp>::value, "implementation bug");
    124       static_assert(is_unsigned<_Tp>::value, "implementation bug");
    125 
    126       to_chars_result __res;
    127 
    128       const unsigned __len = __to_chars_len(__val, __base);
    129 
    130       if (__builtin_expect((__last - __first) < __len, 0))
    131 	{
    132 	  __res.ptr = __last;
    133 	  __res.ec = errc::value_too_large;
    134 	  return __res;
    135 	}
    136 
    137       unsigned __pos = __len - 1;
    138 
    139       static constexpr char __digits[] = {
    140 	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    141 	'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
    142 	'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
    143 	'u', 'v', 'w', 'x', 'y', 'z'
    144       };
    145 
    146       while (__val >= (unsigned)__base)
    147 	{
    148 	  auto const __quo = __val / __base;
    149 	  auto const __rem = __val % __base;
    150 	  __first[__pos--] = __digits[__rem];
    151 	  __val = __quo;
    152 	}
    153       *__first = __digits[__val];
    154 
    155       __res.ptr = __first + __len;
    156       __res.ec = {};
    157       return __res;
    158     }
    159 
    160   template<typename _Tp>
    161     __integer_to_chars_result_type<_Tp>
    162     __to_chars_16(char* __first, char* __last, _Tp __val) noexcept
    163     {
    164       static_assert(is_integral<_Tp>::value, "implementation bug");
    165       static_assert(is_unsigned<_Tp>::value, "implementation bug");
    166 
    167       to_chars_result __res;
    168 
    169       const unsigned __len = (__to_chars_len_2(__val) + 3) / 4;
    170 
    171       if (__builtin_expect((__last - __first) < __len, 0))
    172 	{
    173 	  __res.ptr = __last;
    174 	  __res.ec = errc::value_too_large;
    175 	  return __res;
    176 	}
    177 
    178       static constexpr char __digits[] = {
    179 	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    180 	'a', 'b', 'c', 'd', 'e', 'f'
    181       };
    182       unsigned __pos = __len - 1;
    183       while (__val >= 0x100)
    184 	{
    185 	  auto __num = __val & 0xF;
    186 	  __val >>= 4;
    187 	  __first[__pos] = __digits[__num];
    188 	  __num = __val & 0xF;
    189 	  __val >>= 4;
    190 	  __first[__pos - 1] = __digits[__num];
    191 	  __pos -= 2;
    192 	}
    193       if (__val >= 0x10)
    194 	{
    195 	  const auto __num = __val & 0xF;
    196 	  __val >>= 4;
    197 	  __first[1] = __digits[__num];
    198 	  __first[0] = __digits[__val];
    199 	}
    200       else
    201 	__first[0] = __digits[__val];
    202       __res.ptr = __first + __len;
    203       __res.ec = {};
    204       return __res;
    205     }
    206 
    207   template<typename _Tp>
    208     inline __integer_to_chars_result_type<_Tp>
    209     __to_chars_10(char* __first, char* __last, _Tp __val) noexcept
    210     {
    211       static_assert(is_integral<_Tp>::value, "implementation bug");
    212       static_assert(is_unsigned<_Tp>::value, "implementation bug");
    213 
    214       to_chars_result __res;
    215 
    216       const unsigned __len = __to_chars_len(__val, 10);
    217 
    218       if (__builtin_expect((__last - __first) < __len, 0))
    219 	{
    220 	  __res.ptr = __last;
    221 	  __res.ec = errc::value_too_large;
    222 	  return __res;
    223 	}
    224 
    225       __detail::__to_chars_10_impl(__first, __len, __val);
    226       __res.ptr = __first + __len;
    227       __res.ec = {};
    228       return __res;
    229     }
    230 
    231   template<typename _Tp>
    232     __integer_to_chars_result_type<_Tp>
    233     __to_chars_8(char* __first, char* __last, _Tp __val) noexcept
    234     {
    235       static_assert(is_integral<_Tp>::value, "implementation bug");
    236       static_assert(is_unsigned<_Tp>::value, "implementation bug");
    237 
    238       to_chars_result __res;
    239       unsigned __len = 0;
    240 
    241       if _GLIBCXX17_CONSTEXPR (__gnu_cxx::__int_traits<_Tp>::__digits <= 16)
    242 	{
    243 	  __len = __val > 077777u ? 6u
    244 	    : __val > 07777u ? 5u
    245 	    : __val > 0777u ? 4u
    246 	    : __val > 077u ? 3u
    247 	    : __val > 07u ? 2u
    248 	    : 1u;
    249 	}
    250       else
    251 	__len = (__to_chars_len_2(__val) + 2) / 3;
    252 
    253       if (__builtin_expect((__last - __first) < __len, 0))
    254 	{
    255 	  __res.ptr = __last;
    256 	  __res.ec = errc::value_too_large;
    257 	  return __res;
    258 	}
    259 
    260       unsigned __pos = __len - 1;
    261       while (__val >= 0100)
    262 	{
    263 	  auto __num = __val & 7;
    264 	  __val >>= 3;
    265 	  __first[__pos] = '0' + __num;
    266 	  __num = __val & 7;
    267 	  __val >>= 3;
    268 	  __first[__pos - 1] = '0' + __num;
    269 	  __pos -= 2;
    270 	}
    271       if (__val >= 010)
    272 	{
    273 	  auto const __num = __val & 7;
    274 	  __val >>= 3;
    275 	  __first[1] = '0' + __num;
    276 	  __first[0] = '0' + __val;
    277 	}
    278       else
    279 	__first[0] = '0' + __val;
    280       __res.ptr = __first + __len;
    281       __res.ec = {};
    282       return __res;
    283     }
    284 
    285   template<typename _Tp>
    286     __integer_to_chars_result_type<_Tp>
    287     __to_chars_2(char* __first, char* __last, _Tp __val) noexcept
    288     {
    289       static_assert(is_integral<_Tp>::value, "implementation bug");
    290       static_assert(is_unsigned<_Tp>::value, "implementation bug");
    291 
    292       to_chars_result __res;
    293 
    294       const unsigned __len = __to_chars_len_2(__val);
    295 
    296       if (__builtin_expect((__last - __first) < __len, 0))
    297 	{
    298 	  __res.ptr = __last;
    299 	  __res.ec = errc::value_too_large;
    300 	  return __res;
    301 	}
    302 
    303       unsigned __pos = __len - 1;
    304 
    305       while (__pos)
    306 	{
    307 	  __first[__pos--] = '0' + (__val & 1);
    308 	  __val >>= 1;
    309 	}
    310       // First digit is always '1' because __to_chars_len_2 skips
    311       // leading zero bits and std::to_chars handles zero values
    312       // directly.
    313       __first[0] = '1';
    314 
    315       __res.ptr = __first + __len;
    316       __res.ec = {};
    317       return __res;
    318     }
    319 
    320 } // namespace __detail
    321 
    322   template<typename _Tp>
    323     __detail::__integer_to_chars_result_type<_Tp>
    324     __to_chars_i(char* __first, char* __last, _Tp __value, int __base = 10)
    325     {
    326       __glibcxx_assert(2 <= __base && __base <= 36);
    327 
    328       using _Up = __detail::__unsigned_least_t<_Tp>;
    329       _Up __unsigned_val = __value;
    330 
    331       if (__first == __last) [[__unlikely__]]
    332 	return { __last, errc::value_too_large };
    333 
    334       if (__value == 0)
    335 	{
    336 	  *__first = '0';
    337 	  return { __first + 1, errc{} };
    338 	}
    339       else if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
    340 	if (__value < 0)
    341 	  {
    342 	    *__first++ = '-';
    343 	    __unsigned_val = _Up(~__value) + _Up(1);
    344 	  }
    345 
    346       switch (__base)
    347       {
    348       case 16:
    349 	return __detail::__to_chars_16(__first, __last, __unsigned_val);
    350       case 10:
    351 	return __detail::__to_chars_10(__first, __last, __unsigned_val);
    352       case 8:
    353 	return __detail::__to_chars_8(__first, __last, __unsigned_val);
    354       case 2:
    355 	return __detail::__to_chars_2(__first, __last, __unsigned_val);
    356       default:
    357 	return __detail::__to_chars(__first, __last, __unsigned_val, __base);
    358       }
    359     }
    360 
    361 #define _GLIBCXX_TO_CHARS(T) \
    362   inline to_chars_result \
    363   to_chars(char* __first, char* __last, T __value, int __base = 10) \
    364   { return std::__to_chars_i<T>(__first, __last, __value, __base); }
    365 _GLIBCXX_TO_CHARS(char)
    366 _GLIBCXX_TO_CHARS(signed char)
    367 _GLIBCXX_TO_CHARS(unsigned char)
    368 _GLIBCXX_TO_CHARS(signed short)
    369 _GLIBCXX_TO_CHARS(unsigned short)
    370 _GLIBCXX_TO_CHARS(signed int)
    371 _GLIBCXX_TO_CHARS(unsigned int)
    372 _GLIBCXX_TO_CHARS(signed long)
    373 _GLIBCXX_TO_CHARS(unsigned long)
    374 _GLIBCXX_TO_CHARS(signed long long)
    375 _GLIBCXX_TO_CHARS(unsigned long long)
    376 #if defined(__GLIBCXX_TYPE_INT_N_0)
    377 _GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_0)
    378 _GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_0)
    379 #endif
    380 #if defined(__GLIBCXX_TYPE_INT_N_1)
    381 _GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_1)
    382 _GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_1)
    383 #endif
    384 #if defined(__GLIBCXX_TYPE_INT_N_2)
    385 _GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_2)
    386 _GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_2)
    387 #endif
    388 #if defined(__GLIBCXX_TYPE_INT_N_3)
    389 _GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_3)
    390 _GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_3)
    391 #endif
    392 #undef _GLIBCXX_TO_CHARS
    393 
    394   // _GLIBCXX_RESOLVE_LIB_DEFECTS
    395   // 3266. to_chars(bool) should be deleted
    396   to_chars_result to_chars(char*, char*, bool, int = 10) = delete;
    397 
    398 namespace __detail
    399 {
    400   template<typename _Tp>
    401     bool
    402     __raise_and_add(_Tp& __val, int __base, unsigned char __c)
    403     {
    404       if (__builtin_mul_overflow(__val, __base, &__val)
    405 	  || __builtin_add_overflow(__val, __c, &__val))
    406 	return false;
    407       return true;
    408     }
    409 
    410   // 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   constexpr auto
    413   __from_chars_alnum_to_val_table()
    414   {
    415     constexpr unsigned char __lower_letters[27] = "abcdefghijklmnopqrstuvwxyz";
    416     constexpr unsigned char __upper_letters[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    417     struct { unsigned char __data[1u << __CHAR_BIT__] = {}; } __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   // If _DecOnly is true: if the character is a decimal digit, then
    431   // return its corresponding base-10 value, otherwise return a value >= 127.
    432   // If _DecOnly is false: if the character is an alphanumeric digit, then
    433   // return its corresponding base-36 value, otherwise return a value >= 127.
    434   template<bool _DecOnly = false>
    435     unsigned char
    436     __from_chars_alnum_to_val(unsigned char __c)
    437     {
    438       if _GLIBCXX17_CONSTEXPR (_DecOnly)
    439 	return static_cast<unsigned char>(__c - '0');
    440       else
    441 	{
    442 	  // This initializer is deliberately made dependent in order to work
    443 	  // around modules bug PR105322.
    444 	  static constexpr auto __table = (_DecOnly, __from_chars_alnum_to_val_table());
    445 	  return __table.__data[__c];
    446 	}
    447     }
    448 
    449   /// std::from_chars implementation for integers in a power-of-two base.
    450   /// If _DecOnly is true, then we may assume __base is at most 8.
    451   template<bool _DecOnly, typename _Tp>
    452     bool
    453     __from_chars_pow2_base(const char*& __first, const char* __last, _Tp& __val,
    454 			   int __base)
    455     {
    456       static_assert(is_integral<_Tp>::value, "implementation bug");
    457       static_assert(is_unsigned<_Tp>::value, "implementation bug");
    458 
    459       // __glibcxx_assert((__base & (__base - 1)) == 0);
    460       // __glibcxx_assert(_DecOnly ? __base <= 8 : __base <= 32);
    461       const int __log2_base = __countr_zero(unsigned(__base & 0x3f));
    462 
    463       const ptrdiff_t __len = __last - __first;
    464       ptrdiff_t __i = 0;
    465       while (__i < __len && __first[__i] == '0')
    466 	++__i;
    467       const ptrdiff_t __leading_zeroes = __i;
    468       if (__i >= __len) [[__unlikely__]]
    469 	{
    470 	  __first += __i;
    471 	  return true;
    472 	}
    473 
    474       // Remember the leading significant digit value if necessary.
    475       unsigned char __leading_c = 0;
    476       if (__base != 2)
    477 	{
    478 	  __leading_c = __from_chars_alnum_to_val<_DecOnly>(__first[__i]);
    479 	  // __glibcxx_assert(__leading_c != 0);
    480 	  if (__leading_c >= __base) [[__unlikely__]]
    481 	    {
    482 	      __first += __i;
    483 	      return true;
    484 	    }
    485 	  __val = __leading_c;
    486 	  ++__i;
    487 	}
    488 
    489       for (; __i < __len; ++__i)
    490 	{
    491 	  const unsigned char __c = __from_chars_alnum_to_val<_DecOnly>(__first[__i]);
    492 	  if (__c >= __base)
    493 	    break;
    494 	  __val = (__val << __log2_base) | __c;
    495 	}
    496       __first += __i;
    497       auto __significant_bits = (__i - __leading_zeroes) * __log2_base;
    498       if (__base != 2)
    499 	// Compensate for a leading significant digit that didn't use all
    500 	// of its available bits.
    501 	__significant_bits -= __log2_base - __bit_width(__leading_c);
    502       // __glibcxx_assert(__significant_bits >= 0);
    503       return __significant_bits <= __gnu_cxx::__int_traits<_Tp>::__digits;
    504     }
    505 
    506   /// std::from_chars implementation for integers in any base.
    507   /// If _DecOnly is true, then we may assume __base is at most 10.
    508   template<bool _DecOnly, typename _Tp>
    509     bool
    510     __from_chars_alnum(const char*& __first, const char* __last, _Tp& __val,
    511 		       int __base)
    512     {
    513       // __glibcxx_assert(_DecOnly ? __base <= 10 : __base <= 36);
    514 
    515       const int __bits_per_digit = __bit_width(unsigned(__base & 0x3f));
    516       int __unused_bits_lower_bound = __gnu_cxx::__int_traits<_Tp>::__digits;
    517       for (; __first != __last; ++__first)
    518 	{
    519 	  const unsigned char __c = __from_chars_alnum_to_val<_DecOnly>(*__first);
    520 	  if (__c >= __base)
    521 	    return true;
    522 
    523 	  __unused_bits_lower_bound -= __bits_per_digit;
    524 	  if (__unused_bits_lower_bound >= 0) [[__likely__]]
    525 	    // We're definitely not going to overflow.
    526 	    __val = __val * __base + __c;
    527 	  else if (!__raise_and_add(__val, __base, __c)) [[__unlikely__]]
    528 	    {
    529 	      while (++__first != __last
    530 		     && __from_chars_alnum_to_val<_DecOnly>(*__first) < __base)
    531 		;
    532 	      return false;
    533 	    }
    534 	}
    535       return true;
    536     }
    537 
    538   template<typename _Tp>
    539     using __integer_from_chars_result_type
    540       = enable_if_t<__or_<__is_signed_integer<_Tp>,
    541 			  __is_unsigned_integer<_Tp>,
    542 			  is_same<char, remove_cv_t<_Tp>>>::value,
    543 		    from_chars_result>;
    544 
    545 } // namespace __detail
    546 
    547   /// std::from_chars for integral types.
    548   template<typename _Tp>
    549     __detail::__integer_from_chars_result_type<_Tp>
    550     from_chars(const char* __first, const char* __last, _Tp& __value,
    551 	       int __base = 10)
    552     {
    553       __glibcxx_assert(2 <= __base && __base <= 36);
    554 
    555       from_chars_result __res{__first, {}};
    556 
    557       int __sign = 1;
    558       if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
    559 	if (__first != __last && *__first == '-')
    560 	  {
    561 	    __sign = -1;
    562 	    ++__first;
    563 	  }
    564 
    565       using _Up = __detail::__unsigned_least_t<_Tp>;
    566       _Up __val = 0;
    567 
    568       const auto __start = __first;
    569       bool __valid;
    570       if ((__base & (__base - 1)) == 0)
    571 	{
    572 	  if (__base <= 8)
    573 	    __valid = __detail::__from_chars_pow2_base<true>(__first, __last, __val, __base);
    574 	  else
    575 	    __valid = __detail::__from_chars_pow2_base<false>(__first, __last, __val, __base);
    576 	}
    577       else if (__base <= 10)
    578 	__valid = __detail::__from_chars_alnum<true>(__first, __last, __val, __base);
    579       else
    580 	__valid = __detail::__from_chars_alnum<false>(__first, __last, __val, __base);
    581 
    582       if (__builtin_expect(__first == __start, 0))
    583 	__res.ec = errc::invalid_argument;
    584       else
    585 	{
    586 	  __res.ptr = __first;
    587 	  if (!__valid)
    588 	    __res.ec = errc::result_out_of_range;
    589 	  else
    590 	    {
    591 	      if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value)
    592 		{
    593 		  _Tp __tmp;
    594 		  if (__builtin_mul_overflow(__val, __sign, &__tmp))
    595 		    __res.ec = errc::result_out_of_range;
    596 		  else
    597 		    __value = __tmp;
    598 		}
    599 	      else
    600 		{
    601 		  if _GLIBCXX17_CONSTEXPR (__gnu_cxx::__int_traits<_Up>::__max
    602 		      > __gnu_cxx::__int_traits<_Tp>::__max)
    603 		    {
    604 		      if (__val > __gnu_cxx::__int_traits<_Tp>::__max)
    605 			__res.ec = errc::result_out_of_range;
    606 		      else
    607 			__value = __val;
    608 		    }
    609 		  else
    610 		    __value = __val;
    611 		}
    612 	    }
    613 	}
    614       return __res;
    615     }
    616 
    617   /// floating-point format for primitive numerical conversion
    618   enum class chars_format
    619   {
    620     scientific = 1, fixed = 2, hex = 4, general = fixed | scientific
    621   };
    622 
    623   constexpr chars_format
    624   operator|(chars_format __lhs, chars_format __rhs) noexcept
    625   { return (chars_format)((unsigned)__lhs | (unsigned)__rhs); }
    626 
    627   constexpr chars_format
    628   operator&(chars_format __lhs, chars_format __rhs) noexcept
    629   { return (chars_format)((unsigned)__lhs & (unsigned)__rhs); }
    630 
    631   constexpr chars_format
    632   operator^(chars_format __lhs, chars_format __rhs) noexcept
    633   { return (chars_format)((unsigned)__lhs ^ (unsigned)__rhs); }
    634 
    635   constexpr chars_format
    636   operator~(chars_format __fmt) noexcept
    637   { return (chars_format)~(unsigned)__fmt; }
    638 
    639   constexpr chars_format&
    640   operator|=(chars_format& __lhs, chars_format __rhs) noexcept
    641   { return __lhs = __lhs | __rhs; }
    642 
    643   constexpr chars_format&
    644   operator&=(chars_format& __lhs, chars_format __rhs) noexcept
    645   { return __lhs = __lhs & __rhs; }
    646 
    647   constexpr chars_format&
    648   operator^=(chars_format& __lhs, chars_format __rhs) noexcept
    649   { return __lhs = __lhs ^ __rhs; }
    650 
    651 #if defined __cpp_lib_to_chars || _GLIBCXX_HAVE_USELOCALE
    652   from_chars_result
    653   from_chars(const char* __first, const char* __last, float& __value,
    654 	     chars_format __fmt = chars_format::general) noexcept;
    655 
    656   from_chars_result
    657   from_chars(const char* __first, const char* __last, double& __value,
    658 	     chars_format __fmt = chars_format::general) noexcept;
    659 
    660   from_chars_result
    661   from_chars(const char* __first, const char* __last, long double& __value,
    662 	     chars_format __fmt = chars_format::general) noexcept;
    663 #endif
    664 
    665 #if defined __cpp_lib_to_chars
    666   // Floating-point std::to_chars
    667 
    668   // Overloads for float.
    669   to_chars_result to_chars(char* __first, char* __last, float __value) noexcept;
    670   to_chars_result to_chars(char* __first, char* __last, float __value,
    671 			   chars_format __fmt) noexcept;
    672   to_chars_result to_chars(char* __first, char* __last, float __value,
    673 			   chars_format __fmt, int __precision) noexcept;
    674 
    675   // Overloads for double.
    676   to_chars_result to_chars(char* __first, char* __last, double __value) noexcept;
    677   to_chars_result to_chars(char* __first, char* __last, double __value,
    678 			   chars_format __fmt) noexcept;
    679   to_chars_result to_chars(char* __first, char* __last, double __value,
    680 			   chars_format __fmt, int __precision) noexcept;
    681 
    682   // Overloads for long double.
    683   to_chars_result to_chars(char* __first, char* __last, long double __value)
    684     noexcept;
    685   to_chars_result to_chars(char* __first, char* __last, long double __value,
    686 			   chars_format __fmt) noexcept;
    687   to_chars_result to_chars(char* __first, char* __last, long double __value,
    688 			   chars_format __fmt, int __precision) noexcept;
    689 #endif
    690 
    691 _GLIBCXX_END_NAMESPACE_VERSION
    692 } // namespace std
    693 #endif // C++14
    694 #endif // _GLIBCXX_CHARCONV
    695