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 51namespace 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 79namespace __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; 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 398namespace __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(__base); 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); 514 515 const int __bits_per_digit = __bit_width(__base); 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