1// Primitive numeric conversions (to_chars and from_chars) -*- C++ -*- 2 3// Copyright (C) 2017-2020 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// FIXME: Define when floating point is supported: 47// #define __cpp_lib_to_chars 201611L 48 49namespace std _GLIBCXX_VISIBILITY(default) 50{ 51_GLIBCXX_BEGIN_NAMESPACE_VERSION 52 53 /// Result type of std::to_chars 54 struct to_chars_result 55 { 56 char* ptr; 57 errc ec; 58 59#if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L 60 friend bool 61 operator==(const to_chars_result&, const to_chars_result&) = default; 62#endif 63 }; 64 65 /// Result type of std::from_chars 66 struct from_chars_result 67 { 68 const char* ptr; 69 errc ec; 70 71#if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L 72 friend bool 73 operator==(const from_chars_result&, const from_chars_result&) = default; 74#endif 75 }; 76 77namespace __detail 78{ 79 template<typename _Tp> 80 using __integer_to_chars_result_type 81 = enable_if_t<__or_<__is_signed_integer<_Tp>, 82 __is_unsigned_integer<_Tp>, 83 is_same<char, remove_cv_t<_Tp>>>::value, 84 to_chars_result>; 85 86 // Pick an unsigned type of suitable size. This is used to reduce the 87 // number of specializations of __to_chars_len, __to_chars etc. that 88 // get instantiated. For example, to_chars<char> and to_chars<short> 89 // and to_chars<unsigned> will all use the same code, and so will 90 // to_chars<long> when sizeof(int) == sizeof(long). 91 template<typename _Tp> 92 struct __to_chars_unsigned_type : __make_unsigned_selector_base 93 { 94 using _UInts = _List<unsigned int, unsigned long, unsigned long long 95#if _GLIBCXX_USE_INT128 96 , unsigned __int128 97#endif 98 >; 99 using type = typename __select<sizeof(_Tp), _UInts>::__type; 100 }; 101 102 template<typename _Tp> 103 using __unsigned_least_t = typename __to_chars_unsigned_type<_Tp>::type; 104 105 // Generic implementation for arbitrary bases. 106 // Defined in <bits/charconv.h>. 107 template<typename _Tp> 108 constexpr unsigned 109 __to_chars_len(_Tp __value, int __base /* = 10 */) noexcept; 110 111 template<typename _Tp> 112 constexpr unsigned 113 __to_chars_len_2(_Tp __value) noexcept 114 { return std::__bit_width(__value); } 115 116 // Generic implementation for arbitrary bases. 117 template<typename _Tp> 118 to_chars_result 119 __to_chars(char* __first, char* __last, _Tp __val, int __base) noexcept 120 { 121 static_assert(is_integral<_Tp>::value, "implementation bug"); 122 static_assert(is_unsigned<_Tp>::value, "implementation bug"); 123 124 to_chars_result __res; 125 126 const unsigned __len = __to_chars_len(__val, __base); 127 128 if (__builtin_expect((__last - __first) < __len, 0)) 129 { 130 __res.ptr = __last; 131 __res.ec = errc::value_too_large; 132 return __res; 133 } 134 135 unsigned __pos = __len - 1; 136 137 static constexpr char __digits[] = { 138 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 139 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 140 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 141 'u', 'v', 'w', 'x', 'y', 'z' 142 }; 143 144 while (__val >= (unsigned)__base) 145 { 146 auto const __quo = __val / __base; 147 auto const __rem = __val % __base; 148 __first[__pos--] = __digits[__rem]; 149 __val = __quo; 150 } 151 *__first = __digits[__val]; 152 153 __res.ptr = __first + __len; 154 __res.ec = {}; 155 return __res; 156 } 157 158 template<typename _Tp> 159 __integer_to_chars_result_type<_Tp> 160 __to_chars_16(char* __first, char* __last, _Tp __val) noexcept 161 { 162 static_assert(is_integral<_Tp>::value, "implementation bug"); 163 static_assert(is_unsigned<_Tp>::value, "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 static 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 inline __integer_to_chars_result_type<_Tp> 207 __to_chars_10(char* __first, char* __last, _Tp __val) noexcept 208 { 209 static_assert(is_integral<_Tp>::value, "implementation bug"); 210 static_assert(is_unsigned<_Tp>::value, "implementation bug"); 211 212 to_chars_result __res; 213 214 const unsigned __len = __to_chars_len(__val, 10); 215 216 if (__builtin_expect((__last - __first) < __len, 0)) 217 { 218 __res.ptr = __last; 219 __res.ec = errc::value_too_large; 220 return __res; 221 } 222 223 __detail::__to_chars_10_impl(__first, __len, __val); 224 __res.ptr = __first + __len; 225 __res.ec = {}; 226 return __res; 227 } 228 229 template<typename _Tp> 230 __integer_to_chars_result_type<_Tp> 231 __to_chars_8(char* __first, char* __last, _Tp __val) noexcept 232 { 233 static_assert(is_integral<_Tp>::value, "implementation bug"); 234 static_assert(is_unsigned<_Tp>::value, "implementation bug"); 235 236 to_chars_result __res; 237 unsigned __len; 238 239 if _GLIBCXX17_CONSTEXPR (__gnu_cxx::__int_traits<_Tp>::__digits <= 16) 240 { 241 __len = __val > 077777u ? 6u 242 : __val > 07777u ? 5u 243 : __val > 0777u ? 4u 244 : __val > 077u ? 3u 245 : __val > 07u ? 2u 246 : 1u; 247 } 248 else 249 __len = (__to_chars_len_2(__val) + 2) / 3; 250 251 if (__builtin_expect((__last - __first) < __len, 0)) 252 { 253 __res.ptr = __last; 254 __res.ec = errc::value_too_large; 255 return __res; 256 } 257 258 unsigned __pos = __len - 1; 259 while (__val >= 0100) 260 { 261 auto __num = __val & 7; 262 __val >>= 3; 263 __first[__pos] = '0' + __num; 264 __num = __val & 7; 265 __val >>= 3; 266 __first[__pos - 1] = '0' + __num; 267 __pos -= 2; 268 } 269 if (__val >= 010) 270 { 271 auto const __num = __val & 7; 272 __val >>= 3; 273 __first[1] = '0' + __num; 274 __first[0] = '0' + __val; 275 } 276 else 277 __first[0] = '0' + __val; 278 __res.ptr = __first + __len; 279 __res.ec = {}; 280 return __res; 281 } 282 283 template<typename _Tp> 284 __integer_to_chars_result_type<_Tp> 285 __to_chars_2(char* __first, char* __last, _Tp __val) noexcept 286 { 287 static_assert(is_integral<_Tp>::value, "implementation bug"); 288 static_assert(is_unsigned<_Tp>::value, "implementation bug"); 289 290 to_chars_result __res; 291 292 const unsigned __len = __to_chars_len_2(__val); 293 294 if (__builtin_expect((__last - __first) < __len, 0)) 295 { 296 __res.ptr = __last; 297 __res.ec = errc::value_too_large; 298 return __res; 299 } 300 301 unsigned __pos = __len - 1; 302 303 while (__pos) 304 { 305 __first[__pos--] = '0' + (__val & 1); 306 __val >>= 1; 307 } 308 // First digit is always '1' because __to_chars_len_2 skips 309 // leading zero bits and std::to_chars handles zero values 310 // directly. 311 __first[0] = '1'; 312 313 __res.ptr = __first + __len; 314 __res.ec = {}; 315 return __res; 316 } 317 318} // namespace __detail 319 320 template<typename _Tp> 321 __detail::__integer_to_chars_result_type<_Tp> 322 __to_chars_i(char* __first, char* __last, _Tp __value, int __base = 10) 323 { 324 __glibcxx_assert(2 <= __base && __base <= 36); 325 326 using _Up = __detail::__unsigned_least_t<_Tp>; 327 _Up __unsigned_val = __value; 328 329 if (__first == __last) [[__unlikely__]] 330 return { __last, errc::value_too_large }; 331 332 if (__value == 0) 333 { 334 *__first = '0'; 335 return { __first + 1, errc{} }; 336 } 337 else if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value) 338 if (__value < 0) 339 { 340 *__first++ = '-'; 341 __unsigned_val = _Up(~__value) + _Up(1); 342 } 343 344 switch (__base) 345 { 346 case 16: 347 return __detail::__to_chars_16(__first, __last, __unsigned_val); 348 case 10: 349 return __detail::__to_chars_10(__first, __last, __unsigned_val); 350 case 8: 351 return __detail::__to_chars_8(__first, __last, __unsigned_val); 352 case 2: 353 return __detail::__to_chars_2(__first, __last, __unsigned_val); 354 default: 355 return __detail::__to_chars(__first, __last, __unsigned_val, __base); 356 } 357 } 358 359#define _GLIBCXX_TO_CHARS(T) \ 360 inline to_chars_result \ 361 to_chars(char* __first, char* __last, T __value, int __base = 10) \ 362 { return std::__to_chars_i<T>(__first, __last, __value, __base); } 363_GLIBCXX_TO_CHARS(char) 364_GLIBCXX_TO_CHARS(signed char) 365_GLIBCXX_TO_CHARS(unsigned char) 366_GLIBCXX_TO_CHARS(signed short) 367_GLIBCXX_TO_CHARS(unsigned short) 368_GLIBCXX_TO_CHARS(signed int) 369_GLIBCXX_TO_CHARS(unsigned int) 370_GLIBCXX_TO_CHARS(signed long) 371_GLIBCXX_TO_CHARS(unsigned long) 372_GLIBCXX_TO_CHARS(signed long long) 373_GLIBCXX_TO_CHARS(unsigned long long) 374#if defined(__GLIBCXX_TYPE_INT_N_0) 375_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_0) 376_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_0) 377#endif 378#if defined(__GLIBCXX_TYPE_INT_N_1) 379_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_1) 380_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_1) 381#endif 382#if defined(__GLIBCXX_TYPE_INT_N_2) 383_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_2) 384_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_2) 385#endif 386#if defined(__GLIBCXX_TYPE_INT_N_3) 387_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_3) 388_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_3) 389#endif 390#undef _GLIBCXX_TO_CHARS 391 392 // _GLIBCXX_RESOLVE_LIB_DEFECTS 393 // 3266. to_chars(bool) should be deleted 394 to_chars_result to_chars(char*, char*, bool, int = 10) = delete; 395 396namespace __detail 397{ 398 template<typename _Tp> 399 bool 400 __raise_and_add(_Tp& __val, int __base, unsigned char __c) 401 { 402 if (__builtin_mul_overflow(__val, __base, &__val) 403 || __builtin_add_overflow(__val, __c, &__val)) 404 return false; 405 return true; 406 } 407 408 /// std::from_chars implementation for integers in base 2. 409 template<typename _Tp> 410 bool 411 __from_chars_binary(const char*& __first, const char* __last, _Tp& __val) 412 { 413 static_assert(is_integral<_Tp>::value, "implementation bug"); 414 static_assert(is_unsigned<_Tp>::value, "implementation bug"); 415 416 const ptrdiff_t __len = __last - __first; 417 ptrdiff_t __i = 0; 418 while (__i < __len && __first[__i] == '0') 419 ++__i; 420 const ptrdiff_t __leading_zeroes = __i; 421 422 while (__i < __len) 423 { 424 const unsigned char __c = (unsigned)__first[__i] - '0'; 425 if (__c < 2) 426 __val = (__val << 1) | __c; 427 else 428 break; 429 __i++; 430 } 431 __first += __i; 432 return (__i - __leading_zeroes) <= __gnu_cxx::__int_traits<_Tp>::__digits; 433 } 434 435 /// std::from_chars implementation for integers in bases 3 to 10. 436 template<typename _Tp> 437 bool 438 __from_chars_digit(const char*& __first, const char* __last, _Tp& __val, 439 int __base) 440 { 441 static_assert(is_integral<_Tp>::value, "implementation bug"); 442 static_assert(is_unsigned<_Tp>::value, "implementation bug"); 443 444 auto __matches = [__base](char __c) { 445 return '0' <= __c && __c <= ('0' + (__base - 1)); 446 }; 447 448 while (__first != __last) 449 { 450 const char __c = *__first; 451 if (__matches(__c)) 452 { 453 if (!__raise_and_add(__val, __base, __c - '0')) 454 { 455 while (++__first != __last && __matches(*__first)) 456 ; 457 return false; 458 } 459 __first++; 460 } 461 else 462 return true; 463 } 464 return true; 465 } 466 467 constexpr char 468 __from_chars_alpha_to_num(char __c) 469 { 470 switch (__c) 471 { 472 case 'a': 473 case 'A': 474 return 10; 475 case 'b': 476 case 'B': 477 return 11; 478 case 'c': 479 case 'C': 480 return 12; 481 case 'd': 482 case 'D': 483 return 13; 484 case 'e': 485 case 'E': 486 return 14; 487 case 'f': 488 case 'F': 489 return 15; 490 case 'g': 491 case 'G': 492 return 16; 493 case 'h': 494 case 'H': 495 return 17; 496 case 'i': 497 case 'I': 498 return 18; 499 case 'j': 500 case 'J': 501 return 19; 502 case 'k': 503 case 'K': 504 return 20; 505 case 'l': 506 case 'L': 507 return 21; 508 case 'm': 509 case 'M': 510 return 22; 511 case 'n': 512 case 'N': 513 return 23; 514 case 'o': 515 case 'O': 516 return 24; 517 case 'p': 518 case 'P': 519 return 25; 520 case 'q': 521 case 'Q': 522 return 26; 523 case 'r': 524 case 'R': 525 return 27; 526 case 's': 527 case 'S': 528 return 28; 529 case 't': 530 case 'T': 531 return 29; 532 case 'u': 533 case 'U': 534 return 30; 535 case 'v': 536 case 'V': 537 return 31; 538 case 'w': 539 case 'W': 540 return 32; 541 case 'x': 542 case 'X': 543 return 33; 544 case 'y': 545 case 'Y': 546 return 34; 547 case 'z': 548 case 'Z': 549 return 35; 550 } 551 return 127; 552 } 553 554 /// std::from_chars implementation for integers in bases 11 to 36. 555 template<typename _Tp> 556 bool 557 __from_chars_alnum(const char*& __first, const char* __last, _Tp& __val, 558 int __base) 559 { 560 bool __valid = true; 561 while (__first != __last) 562 { 563 char __c = *__first; 564 if ('0' <= __c && __c <= '9') // isdigit 565 __c -= '0'; 566 else 567 { 568 __c = __from_chars_alpha_to_num(__c); 569 if (__c >= __base) 570 break; 571 } 572 573 if (__builtin_expect(__valid, 1)) 574 __valid = __raise_and_add(__val, __base, __c); 575 __first++; 576 } 577 return __valid; 578 } 579 580 template<typename _Tp> 581 using __integer_from_chars_result_type 582 = enable_if_t<__or_<__is_signed_integer<_Tp>, 583 __is_unsigned_integer<_Tp>, 584 is_same<char, remove_cv_t<_Tp>>>::value, 585 from_chars_result>; 586 587} // namespace __detail 588 589 /// std::from_chars for integral types. 590 template<typename _Tp> 591 __detail::__integer_from_chars_result_type<_Tp> 592 from_chars(const char* __first, const char* __last, _Tp& __value, 593 int __base = 10) 594 { 595 __glibcxx_assert(2 <= __base && __base <= 36); 596 597 from_chars_result __res{__first, {}}; 598 599 int __sign = 1; 600 if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value) 601 if (__first != __last && *__first == '-') 602 { 603 __sign = -1; 604 ++__first; 605 } 606 607 using _Up = __detail::__unsigned_least_t<_Tp>; 608 _Up __val = 0; 609 610 const auto __start = __first; 611 bool __valid; 612 if (__base == 2) 613 __valid = __detail::__from_chars_binary(__first, __last, __val); 614 else if (__base <= 10) 615 __valid = __detail::__from_chars_digit(__first, __last, __val, __base); 616 else 617 __valid = __detail::__from_chars_alnum(__first, __last, __val, __base); 618 619 if (__builtin_expect(__first == __start, 0)) 620 __res.ec = errc::invalid_argument; 621 else 622 { 623 __res.ptr = __first; 624 if (!__valid) 625 __res.ec = errc::result_out_of_range; 626 else 627 { 628 if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value) 629 { 630 _Tp __tmp; 631 if (__builtin_mul_overflow(__val, __sign, &__tmp)) 632 __res.ec = errc::result_out_of_range; 633 else 634 __value = __tmp; 635 } 636 else 637 { 638 if _GLIBCXX17_CONSTEXPR (__gnu_cxx::__int_traits<_Up>::__max 639 > __gnu_cxx::__int_traits<_Tp>::__max) 640 { 641 if (__val > __gnu_cxx::__int_traits<_Tp>::__max) 642 __res.ec = errc::result_out_of_range; 643 else 644 __value = __val; 645 } 646 else 647 __value = __val; 648 } 649 } 650 } 651 return __res; 652 } 653 654 /// floating-point format for primitive numerical conversion 655 enum class chars_format 656 { 657 scientific = 1, fixed = 2, hex = 4, general = fixed | scientific 658 }; 659 660 constexpr chars_format 661 operator|(chars_format __lhs, chars_format __rhs) noexcept 662 { return (chars_format)((unsigned)__lhs | (unsigned)__rhs); } 663 664 constexpr chars_format 665 operator&(chars_format __lhs, chars_format __rhs) noexcept 666 { return (chars_format)((unsigned)__lhs & (unsigned)__rhs); } 667 668 constexpr chars_format 669 operator^(chars_format __lhs, chars_format __rhs) noexcept 670 { return (chars_format)((unsigned)__lhs ^ (unsigned)__rhs); } 671 672 constexpr chars_format 673 operator~(chars_format __fmt) noexcept 674 { return (chars_format)~(unsigned)__fmt; } 675 676 constexpr chars_format& 677 operator|=(chars_format& __lhs, chars_format __rhs) noexcept 678 { return __lhs = __lhs | __rhs; } 679 680 constexpr chars_format& 681 operator&=(chars_format& __lhs, chars_format __rhs) noexcept 682 { return __lhs = __lhs & __rhs; } 683 684 constexpr chars_format& 685 operator^=(chars_format& __lhs, chars_format __rhs) noexcept 686 { return __lhs = __lhs ^ __rhs; } 687 688_GLIBCXX_END_NAMESPACE_VERSION 689} // namespace std 690#endif // C++14 691#endif // _GLIBCXX_CHARCONV 692