1*38fd1498Szrj// Primitive numeric conversions (to_chars and from_chars) -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj// Copyright (C) 2017-2018 Free Software Foundation, Inc. 4*38fd1498Szrj// 5*38fd1498Szrj// This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj// software; you can redistribute it and/or modify it under the 7*38fd1498Szrj// terms of the GNU General Public License as published by the 8*38fd1498Szrj// Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj// any later version. 10*38fd1498Szrj 11*38fd1498Szrj// This library is distributed in the hope that it will be useful, 12*38fd1498Szrj// but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj// GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj// Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj// permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj// 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj// You should have received a copy of the GNU General Public License and 21*38fd1498Szrj// a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj// <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj/** @file include/charconv 26*38fd1498Szrj * This is a Standard C++ Library header. 27*38fd1498Szrj */ 28*38fd1498Szrj 29*38fd1498Szrj#ifndef _GLIBCXX_CHARCONV 30*38fd1498Szrj#define _GLIBCXX_CHARCONV 1 31*38fd1498Szrj 32*38fd1498Szrj#pragma GCC system_header 33*38fd1498Szrj 34*38fd1498Szrj#if __cplusplus >= 201402L 35*38fd1498Szrj 36*38fd1498Szrj#include <type_traits> 37*38fd1498Szrj#include <limits> 38*38fd1498Szrj#include <cctype> 39*38fd1498Szrj#include <bits/error_constants.h> // for std::errc 40*38fd1498Szrj 41*38fd1498Szrjnamespace std _GLIBCXX_VISIBILITY(default) 42*38fd1498Szrj{ 43*38fd1498Szrj_GLIBCXX_BEGIN_NAMESPACE_VERSION 44*38fd1498Szrj 45*38fd1498Szrj /// Result type of std::to_chars 46*38fd1498Szrj struct to_chars_result 47*38fd1498Szrj { 48*38fd1498Szrj char* ptr; 49*38fd1498Szrj errc ec; 50*38fd1498Szrj }; 51*38fd1498Szrj 52*38fd1498Szrj /// Result type of std::from_chars 53*38fd1498Szrj struct from_chars_result 54*38fd1498Szrj { 55*38fd1498Szrj const char* ptr; 56*38fd1498Szrj errc ec; 57*38fd1498Szrj }; 58*38fd1498Szrj 59*38fd1498Szrjnamespace __detail 60*38fd1498Szrj{ 61*38fd1498Szrj template<typename _Tp, typename... _Types> 62*38fd1498Szrj using __is_one_of = __or_<is_same<_Tp, _Types>...>; 63*38fd1498Szrj 64*38fd1498Szrj template<typename _Tp> 65*38fd1498Szrj using __is_int_to_chars_type = __and_<is_integral<_Tp>, 66*38fd1498Szrj __not_<__is_one_of<_Tp, bool, char16_t, char32_t 67*38fd1498Szrj#if _GLIBCXX_USE_WCHAR_T 68*38fd1498Szrj , wchar_t 69*38fd1498Szrj#endif 70*38fd1498Szrj >>>; 71*38fd1498Szrj 72*38fd1498Szrj template<typename _Tp> 73*38fd1498Szrj using __integer_to_chars_result_type 74*38fd1498Szrj = enable_if_t<__is_int_to_chars_type<_Tp>::value, to_chars_result>; 75*38fd1498Szrj 76*38fd1498Szrj template<typename _Tp> 77*38fd1498Szrj using __unsigned_least_t 78*38fd1498Szrj = conditional_t<(sizeof(_Tp) <= sizeof(int)), unsigned int, 79*38fd1498Szrj conditional_t<(sizeof(_Tp) <= sizeof(long)), unsigned long, 80*38fd1498Szrj conditional_t<(sizeof(_Tp) <= sizeof(long long)), unsigned long long, 81*38fd1498Szrj#if _GLIBCXX_USE_INT128 82*38fd1498Szrj conditional_t<(sizeof(_Tp) <= sizeof(__int128)), unsigned __int128, 83*38fd1498Szrj#endif 84*38fd1498Szrj void 85*38fd1498Szrj#if _GLIBCXX_USE_INT128 86*38fd1498Szrj > 87*38fd1498Szrj#endif 88*38fd1498Szrj >>>; 89*38fd1498Szrj 90*38fd1498Szrj // Generic implementation for arbitrary bases. 91*38fd1498Szrj template<typename _Tp> 92*38fd1498Szrj constexpr unsigned 93*38fd1498Szrj __to_chars_len(_Tp __value, int __base = 10) noexcept 94*38fd1498Szrj { 95*38fd1498Szrj static_assert(is_integral<_Tp>::value, "implementation bug"); 96*38fd1498Szrj static_assert(is_unsigned<_Tp>::value, "implementation bug"); 97*38fd1498Szrj 98*38fd1498Szrj unsigned __n = 1; 99*38fd1498Szrj const int __b2 = __base * __base; 100*38fd1498Szrj const int __b3 = __b2 * __base; 101*38fd1498Szrj const int __b4 = __b3 * __base; 102*38fd1498Szrj for (;;) 103*38fd1498Szrj { 104*38fd1498Szrj if (__value < __base) return __n; 105*38fd1498Szrj if (__value < __b2) return __n + 1; 106*38fd1498Szrj if (__value < __b3) return __n + 2; 107*38fd1498Szrj if (__value < __b4) return __n + 3; 108*38fd1498Szrj __value /= (unsigned)__b4; 109*38fd1498Szrj __n += 4; 110*38fd1498Szrj } 111*38fd1498Szrj } 112*38fd1498Szrj 113*38fd1498Szrj template<typename _Tp> 114*38fd1498Szrj constexpr unsigned 115*38fd1498Szrj __to_chars_len_2(_Tp __value) noexcept 116*38fd1498Szrj { 117*38fd1498Szrj static_assert(is_integral<_Tp>::value, "implementation bug"); 118*38fd1498Szrj static_assert(is_unsigned<_Tp>::value, "implementation bug"); 119*38fd1498Szrj 120*38fd1498Szrj constexpr size_t __nbits = __CHAR_BIT__ * sizeof(_Tp); 121*38fd1498Szrj 122*38fd1498Szrj // N.B. __builtin_clzll is undefined if __value == 0, but std::to_chars 123*38fd1498Szrj // handles zero values directly. 124*38fd1498Szrj 125*38fd1498Szrj // For sizeof(_Tp) > 1 this is an order of magnitude faster than 126*38fd1498Szrj // the generic __to_chars_len. 127*38fd1498Szrj return __nbits 128*38fd1498Szrj - (__builtin_clzll(__value) 129*38fd1498Szrj - ((__CHAR_BIT__ * sizeof(long long)) - __nbits)); 130*38fd1498Szrj } 131*38fd1498Szrj 132*38fd1498Szrj template<typename _Tp> 133*38fd1498Szrj constexpr unsigned 134*38fd1498Szrj __to_chars_len_8(_Tp __value) noexcept 135*38fd1498Szrj { 136*38fd1498Szrj static_assert(is_integral<_Tp>::value, "implementation bug"); 137*38fd1498Szrj static_assert(is_unsigned<_Tp>::value, "implementation bug"); 138*38fd1498Szrj 139*38fd1498Szrj constexpr size_t __nbits = __CHAR_BIT__ * sizeof(_Tp); 140*38fd1498Szrj 141*38fd1498Szrj if _GLIBCXX17_CONSTEXPR (__nbits <= 16) 142*38fd1498Szrj { 143*38fd1498Szrj return __value > 077777u ? 6u 144*38fd1498Szrj : __value > 07777u ? 5u 145*38fd1498Szrj : __value > 0777u ? 4u 146*38fd1498Szrj : __value > 077u ? 3u 147*38fd1498Szrj : __value > 07u ? 2u 148*38fd1498Szrj : 1u; 149*38fd1498Szrj } 150*38fd1498Szrj else 151*38fd1498Szrj return __to_chars_len(__value, 8); 152*38fd1498Szrj } 153*38fd1498Szrj 154*38fd1498Szrj // Generic implementation for arbitrary bases. 155*38fd1498Szrj template<typename _Tp> 156*38fd1498Szrj to_chars_result 157*38fd1498Szrj __to_chars(char* __first, char* __last, _Tp __val, int __base) noexcept 158*38fd1498Szrj { 159*38fd1498Szrj static_assert(is_integral<_Tp>::value, "implementation bug"); 160*38fd1498Szrj static_assert(is_unsigned<_Tp>::value, "implementation bug"); 161*38fd1498Szrj 162*38fd1498Szrj to_chars_result __res; 163*38fd1498Szrj 164*38fd1498Szrj const unsigned __len = __to_chars_len(__val, __base); 165*38fd1498Szrj 166*38fd1498Szrj if (__builtin_expect((__last - __first) < __len, 0)) 167*38fd1498Szrj { 168*38fd1498Szrj __res.ptr = __last; 169*38fd1498Szrj __res.ec = errc::value_too_large; 170*38fd1498Szrj return __res; 171*38fd1498Szrj } 172*38fd1498Szrj 173*38fd1498Szrj unsigned __pos = __len - 1; 174*38fd1498Szrj 175*38fd1498Szrj static constexpr char __digits[] 176*38fd1498Szrj = "0123456789abcdefghijklmnopqrstuvwxyz"; 177*38fd1498Szrj 178*38fd1498Szrj while (__val >= __base) 179*38fd1498Szrj { 180*38fd1498Szrj auto const __quo = __val / __base; 181*38fd1498Szrj auto const __rem = __val % __base; 182*38fd1498Szrj __first[__pos--] = __digits[__rem]; 183*38fd1498Szrj __val = __quo; 184*38fd1498Szrj } 185*38fd1498Szrj *__first = __digits[__val]; 186*38fd1498Szrj 187*38fd1498Szrj __res.ptr = __first + __len; 188*38fd1498Szrj __res.ec = {}; 189*38fd1498Szrj return __res; 190*38fd1498Szrj } 191*38fd1498Szrj 192*38fd1498Szrj template<typename _Tp> 193*38fd1498Szrj __integer_to_chars_result_type<_Tp> 194*38fd1498Szrj __to_chars_16(char* __first, char* __last, _Tp __val) noexcept 195*38fd1498Szrj { 196*38fd1498Szrj static_assert(is_integral<_Tp>::value, "implementation bug"); 197*38fd1498Szrj static_assert(is_unsigned<_Tp>::value, "implementation bug"); 198*38fd1498Szrj 199*38fd1498Szrj to_chars_result __res; 200*38fd1498Szrj 201*38fd1498Szrj const unsigned __len = __to_chars_len(__val, 0x10); 202*38fd1498Szrj 203*38fd1498Szrj if (__builtin_expect((__last - __first) < __len, 0)) 204*38fd1498Szrj { 205*38fd1498Szrj __res.ptr = __last; 206*38fd1498Szrj __res.ec = errc::value_too_large; 207*38fd1498Szrj return __res; 208*38fd1498Szrj } 209*38fd1498Szrj 210*38fd1498Szrj static constexpr char __digits[513] = 211*38fd1498Szrj "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" 212*38fd1498Szrj "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" 213*38fd1498Szrj "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" 214*38fd1498Szrj "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" 215*38fd1498Szrj "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" 216*38fd1498Szrj "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf" 217*38fd1498Szrj "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf" 218*38fd1498Szrj "e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; 219*38fd1498Szrj unsigned __pos = __len - 1; 220*38fd1498Szrj while (__val >= 0x100) 221*38fd1498Szrj { 222*38fd1498Szrj auto const __num = (__val % 0x100) * 2; 223*38fd1498Szrj __val /= 0x100; 224*38fd1498Szrj __first[__pos] = __digits[__num + 1]; 225*38fd1498Szrj __first[__pos - 1] = __digits[__num]; 226*38fd1498Szrj __pos -= 2; 227*38fd1498Szrj } 228*38fd1498Szrj if (__val >= 0x10) 229*38fd1498Szrj { 230*38fd1498Szrj auto const __num = __val * 2; 231*38fd1498Szrj __first[__pos] = __digits[__num + 1]; 232*38fd1498Szrj __first[__pos - 1] = __digits[__num]; 233*38fd1498Szrj } 234*38fd1498Szrj else 235*38fd1498Szrj __first[__pos] = "0123456789abcdef"[__val]; 236*38fd1498Szrj __res.ptr = __first + __len; 237*38fd1498Szrj __res.ec = {}; 238*38fd1498Szrj return __res; 239*38fd1498Szrj } 240*38fd1498Szrj 241*38fd1498Szrj template<typename _Tp> 242*38fd1498Szrj __integer_to_chars_result_type<_Tp> 243*38fd1498Szrj __to_chars_10(char* __first, char* __last, _Tp __val) noexcept 244*38fd1498Szrj { 245*38fd1498Szrj static_assert(is_integral<_Tp>::value, "implementation bug"); 246*38fd1498Szrj static_assert(is_unsigned<_Tp>::value, "implementation bug"); 247*38fd1498Szrj 248*38fd1498Szrj to_chars_result __res; 249*38fd1498Szrj 250*38fd1498Szrj const unsigned __len = __to_chars_len(__val, 10); 251*38fd1498Szrj 252*38fd1498Szrj if (__builtin_expect((__last - __first) < __len, 0)) 253*38fd1498Szrj { 254*38fd1498Szrj __res.ptr = __last; 255*38fd1498Szrj __res.ec = errc::value_too_large; 256*38fd1498Szrj return __res; 257*38fd1498Szrj } 258*38fd1498Szrj 259*38fd1498Szrj static constexpr char __digits[201] = 260*38fd1498Szrj "0001020304050607080910111213141516171819" 261*38fd1498Szrj "2021222324252627282930313233343536373839" 262*38fd1498Szrj "4041424344454647484950515253545556575859" 263*38fd1498Szrj "6061626364656667686970717273747576777879" 264*38fd1498Szrj "8081828384858687888990919293949596979899"; 265*38fd1498Szrj unsigned __pos = __len - 1; 266*38fd1498Szrj while (__val >= 100) 267*38fd1498Szrj { 268*38fd1498Szrj auto const __num = (__val % 100) * 2; 269*38fd1498Szrj __val /= 100; 270*38fd1498Szrj __first[__pos] = __digits[__num + 1]; 271*38fd1498Szrj __first[__pos - 1] = __digits[__num]; 272*38fd1498Szrj __pos -= 2; 273*38fd1498Szrj } 274*38fd1498Szrj if (__val >= 10) 275*38fd1498Szrj { 276*38fd1498Szrj auto const __num = __val * 2; 277*38fd1498Szrj __first[__pos] = __digits[__num + 1]; 278*38fd1498Szrj __first[__pos - 1] = __digits[__num]; 279*38fd1498Szrj } 280*38fd1498Szrj else 281*38fd1498Szrj __first[__pos] = '0' + __val; 282*38fd1498Szrj __res.ptr = __first + __len; 283*38fd1498Szrj __res.ec = {}; 284*38fd1498Szrj return __res; 285*38fd1498Szrj } 286*38fd1498Szrj 287*38fd1498Szrj template<typename _Tp> 288*38fd1498Szrj __integer_to_chars_result_type<_Tp> 289*38fd1498Szrj __to_chars_8(char* __first, char* __last, _Tp __val) noexcept 290*38fd1498Szrj { 291*38fd1498Szrj static_assert(is_integral<_Tp>::value, "implementation bug"); 292*38fd1498Szrj static_assert(is_unsigned<_Tp>::value, "implementation bug"); 293*38fd1498Szrj 294*38fd1498Szrj to_chars_result __res; 295*38fd1498Szrj 296*38fd1498Szrj const unsigned __len = __to_chars_len_8(__val); 297*38fd1498Szrj 298*38fd1498Szrj if (__builtin_expect((__last - __first) < __len, 0)) 299*38fd1498Szrj { 300*38fd1498Szrj __res.ptr = __last; 301*38fd1498Szrj __res.ec = errc::value_too_large; 302*38fd1498Szrj return __res; 303*38fd1498Szrj } 304*38fd1498Szrj 305*38fd1498Szrj static constexpr char __digits[129] = 306*38fd1498Szrj "00010203040506071011121314151617" 307*38fd1498Szrj "20212223242526273031323334353637" 308*38fd1498Szrj "40414243444546475051525354555657" 309*38fd1498Szrj "60616263646566677071727374757677"; 310*38fd1498Szrj unsigned __pos = __len - 1; 311*38fd1498Szrj while (__val >= 0100) 312*38fd1498Szrj { 313*38fd1498Szrj auto const __num = (__val % 0100) * 2; 314*38fd1498Szrj __val /= 0100; 315*38fd1498Szrj __first[__pos] = __digits[__num + 1]; 316*38fd1498Szrj __first[__pos - 1] = __digits[__num]; 317*38fd1498Szrj __pos -= 2; 318*38fd1498Szrj } 319*38fd1498Szrj if (__val >= 010) 320*38fd1498Szrj { 321*38fd1498Szrj auto const __num = __val * 2; 322*38fd1498Szrj __first[__pos] = __digits[__num + 1]; 323*38fd1498Szrj __first[__pos - 1] = __digits[__num]; 324*38fd1498Szrj } 325*38fd1498Szrj else 326*38fd1498Szrj __first[__pos] = '0' + __val; 327*38fd1498Szrj __res.ptr = __first + __len; 328*38fd1498Szrj __res.ec = {}; 329*38fd1498Szrj return __res; 330*38fd1498Szrj } 331*38fd1498Szrj 332*38fd1498Szrj template<typename _Tp> 333*38fd1498Szrj __integer_to_chars_result_type<_Tp> 334*38fd1498Szrj __to_chars_2(char* __first, char* __last, _Tp __val) noexcept 335*38fd1498Szrj { 336*38fd1498Szrj static_assert(is_integral<_Tp>::value, "implementation bug"); 337*38fd1498Szrj static_assert(is_unsigned<_Tp>::value, "implementation bug"); 338*38fd1498Szrj 339*38fd1498Szrj to_chars_result __res; 340*38fd1498Szrj 341*38fd1498Szrj const unsigned __len = __to_chars_len_2(__val); 342*38fd1498Szrj 343*38fd1498Szrj if (__builtin_expect((__last - __first) < __len, 0)) 344*38fd1498Szrj { 345*38fd1498Szrj __res.ptr = __last; 346*38fd1498Szrj __res.ec = errc::value_too_large; 347*38fd1498Szrj return __res; 348*38fd1498Szrj } 349*38fd1498Szrj 350*38fd1498Szrj unsigned __pos = __len - 1; 351*38fd1498Szrj 352*38fd1498Szrj while (__pos) 353*38fd1498Szrj { 354*38fd1498Szrj __first[__pos--] = '0' + (__val & 1); 355*38fd1498Szrj __val >>= 1; 356*38fd1498Szrj } 357*38fd1498Szrj *__first = '0' + (__val & 1); 358*38fd1498Szrj 359*38fd1498Szrj __res.ptr = __first + __len; 360*38fd1498Szrj __res.ec = {}; 361*38fd1498Szrj return __res; 362*38fd1498Szrj } 363*38fd1498Szrj 364*38fd1498Szrj} // namespace __detail 365*38fd1498Szrj 366*38fd1498Szrj template<typename _Tp> 367*38fd1498Szrj __detail::__integer_to_chars_result_type<_Tp> 368*38fd1498Szrj to_chars(char* __first, char* __last, _Tp __value, int __base = 10) 369*38fd1498Szrj { 370*38fd1498Szrj __glibcxx_assert(2 <= __base && __base <= 36); 371*38fd1498Szrj 372*38fd1498Szrj using _Up = __detail::__unsigned_least_t<_Tp>; 373*38fd1498Szrj _Up __unsigned_val = __value; 374*38fd1498Szrj 375*38fd1498Szrj if (__value == 0 && __first != __last) 376*38fd1498Szrj { 377*38fd1498Szrj *__first = '0'; 378*38fd1498Szrj return { __first + 1, errc{} }; 379*38fd1498Szrj } 380*38fd1498Szrj 381*38fd1498Szrj if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value) 382*38fd1498Szrj if (__value < 0) 383*38fd1498Szrj { 384*38fd1498Szrj if (__builtin_expect(__first != __last, 1)) 385*38fd1498Szrj *__first++ = '-'; 386*38fd1498Szrj __unsigned_val = _Up(~__value) + _Up(1); 387*38fd1498Szrj } 388*38fd1498Szrj 389*38fd1498Szrj switch (__base) 390*38fd1498Szrj { 391*38fd1498Szrj case 16: 392*38fd1498Szrj return __detail::__to_chars_16(__first, __last, __unsigned_val); 393*38fd1498Szrj case 10: 394*38fd1498Szrj return __detail::__to_chars_10(__first, __last, __unsigned_val); 395*38fd1498Szrj case 8: 396*38fd1498Szrj return __detail::__to_chars_8(__first, __last, __unsigned_val); 397*38fd1498Szrj case 2: 398*38fd1498Szrj return __detail::__to_chars_2(__first, __last, __unsigned_val); 399*38fd1498Szrj default: 400*38fd1498Szrj return __detail::__to_chars(__first, __last, __unsigned_val, __base); 401*38fd1498Szrj } 402*38fd1498Szrj } 403*38fd1498Szrj 404*38fd1498Szrjnamespace __detail 405*38fd1498Szrj{ 406*38fd1498Szrj template<typename _Tp> 407*38fd1498Szrj bool 408*38fd1498Szrj __raise_and_add(_Tp& __val, int __base, unsigned char __c) 409*38fd1498Szrj { 410*38fd1498Szrj if (__builtin_mul_overflow(__val, __base, &__val) 411*38fd1498Szrj || __builtin_add_overflow(__val, __c, &__val)) 412*38fd1498Szrj return false; 413*38fd1498Szrj return true; 414*38fd1498Szrj } 415*38fd1498Szrj 416*38fd1498Szrj /// std::from_chars implementation for integers in base 2. 417*38fd1498Szrj template<typename _Tp> 418*38fd1498Szrj bool 419*38fd1498Szrj __from_chars_binary(const char*& __first, const char* __last, _Tp& __val) 420*38fd1498Szrj { 421*38fd1498Szrj static_assert(is_integral<_Tp>::value, "implementation bug"); 422*38fd1498Szrj static_assert(is_unsigned<_Tp>::value, "implementation bug"); 423*38fd1498Szrj 424*38fd1498Szrj const ptrdiff_t __len = __last - __first; 425*38fd1498Szrj int __i = 0; 426*38fd1498Szrj while (__i < __len) 427*38fd1498Szrj { 428*38fd1498Szrj const unsigned char __c = (unsigned)__first[__i] - '0'; 429*38fd1498Szrj if (__c < 2) 430*38fd1498Szrj __val = (__val << 1) | __c; 431*38fd1498Szrj else 432*38fd1498Szrj break; 433*38fd1498Szrj __i++; 434*38fd1498Szrj } 435*38fd1498Szrj __first += __i; 436*38fd1498Szrj return __i <= (sizeof(_Tp) * __CHAR_BIT__); 437*38fd1498Szrj } 438*38fd1498Szrj 439*38fd1498Szrj /// std::from_chars implementation for integers in bases 3 to 10. 440*38fd1498Szrj template<typename _Tp> 441*38fd1498Szrj bool 442*38fd1498Szrj __from_chars_digit(const char*& __first, const char* __last, _Tp& __val, 443*38fd1498Szrj int __base) 444*38fd1498Szrj { 445*38fd1498Szrj static_assert(is_integral<_Tp>::value, "implementation bug"); 446*38fd1498Szrj static_assert(is_unsigned<_Tp>::value, "implementation bug"); 447*38fd1498Szrj 448*38fd1498Szrj auto __matches = [__base](char __c) { 449*38fd1498Szrj return '0' <= __c && __c <= ('0' + (__base - 1)); 450*38fd1498Szrj }; 451*38fd1498Szrj 452*38fd1498Szrj while (__first != __last) 453*38fd1498Szrj { 454*38fd1498Szrj const char __c = *__first; 455*38fd1498Szrj if (__matches(__c)) 456*38fd1498Szrj { 457*38fd1498Szrj if (!__raise_and_add(__val, __base, __c - '0')) 458*38fd1498Szrj { 459*38fd1498Szrj while (++__first != __last && __matches(*__first)) 460*38fd1498Szrj ; 461*38fd1498Szrj return false; 462*38fd1498Szrj } 463*38fd1498Szrj __first++; 464*38fd1498Szrj } 465*38fd1498Szrj else 466*38fd1498Szrj return true; 467*38fd1498Szrj } 468*38fd1498Szrj return true; 469*38fd1498Szrj } 470*38fd1498Szrj 471*38fd1498Szrj constexpr unsigned char 472*38fd1498Szrj __from_chars_alpha_to_num(char __c) 473*38fd1498Szrj { 474*38fd1498Szrj switch (__c) 475*38fd1498Szrj { 476*38fd1498Szrj case 'a': 477*38fd1498Szrj case 'A': 478*38fd1498Szrj return 10; 479*38fd1498Szrj case 'b': 480*38fd1498Szrj case 'B': 481*38fd1498Szrj return 11; 482*38fd1498Szrj case 'c': 483*38fd1498Szrj case 'C': 484*38fd1498Szrj return 12; 485*38fd1498Szrj case 'd': 486*38fd1498Szrj case 'D': 487*38fd1498Szrj return 13; 488*38fd1498Szrj case 'e': 489*38fd1498Szrj case 'E': 490*38fd1498Szrj return 14; 491*38fd1498Szrj case 'f': 492*38fd1498Szrj case 'F': 493*38fd1498Szrj return 15; 494*38fd1498Szrj case 'g': 495*38fd1498Szrj case 'G': 496*38fd1498Szrj return 16; 497*38fd1498Szrj case 'h': 498*38fd1498Szrj case 'H': 499*38fd1498Szrj return 17; 500*38fd1498Szrj case 'i': 501*38fd1498Szrj case 'I': 502*38fd1498Szrj return 18; 503*38fd1498Szrj case 'j': 504*38fd1498Szrj case 'J': 505*38fd1498Szrj return 19; 506*38fd1498Szrj case 'k': 507*38fd1498Szrj case 'K': 508*38fd1498Szrj return 20; 509*38fd1498Szrj case 'l': 510*38fd1498Szrj case 'L': 511*38fd1498Szrj return 21; 512*38fd1498Szrj case 'm': 513*38fd1498Szrj case 'M': 514*38fd1498Szrj return 22; 515*38fd1498Szrj case 'n': 516*38fd1498Szrj case 'N': 517*38fd1498Szrj return 23; 518*38fd1498Szrj case 'o': 519*38fd1498Szrj case 'O': 520*38fd1498Szrj return 24; 521*38fd1498Szrj case 'p': 522*38fd1498Szrj case 'P': 523*38fd1498Szrj return 25; 524*38fd1498Szrj case 'q': 525*38fd1498Szrj case 'Q': 526*38fd1498Szrj return 26; 527*38fd1498Szrj case 'r': 528*38fd1498Szrj case 'R': 529*38fd1498Szrj return 27; 530*38fd1498Szrj case 's': 531*38fd1498Szrj case 'S': 532*38fd1498Szrj return 28; 533*38fd1498Szrj case 't': 534*38fd1498Szrj case 'T': 535*38fd1498Szrj return 29; 536*38fd1498Szrj case 'u': 537*38fd1498Szrj case 'U': 538*38fd1498Szrj return 30; 539*38fd1498Szrj case 'v': 540*38fd1498Szrj case 'V': 541*38fd1498Szrj return 31; 542*38fd1498Szrj case 'w': 543*38fd1498Szrj case 'W': 544*38fd1498Szrj return 32; 545*38fd1498Szrj case 'x': 546*38fd1498Szrj case 'X': 547*38fd1498Szrj return 33; 548*38fd1498Szrj case 'y': 549*38fd1498Szrj case 'Y': 550*38fd1498Szrj return 34; 551*38fd1498Szrj case 'z': 552*38fd1498Szrj case 'Z': 553*38fd1498Szrj return 35; 554*38fd1498Szrj } 555*38fd1498Szrj return std::numeric_limits<unsigned char>::max(); 556*38fd1498Szrj } 557*38fd1498Szrj 558*38fd1498Szrj /// std::from_chars implementation for integers in bases 11 to 26. 559*38fd1498Szrj template<typename _Tp> 560*38fd1498Szrj bool 561*38fd1498Szrj __from_chars_alnum(const char*& __first, const char* __last, _Tp& __val, 562*38fd1498Szrj int __base) 563*38fd1498Szrj { 564*38fd1498Szrj bool __valid = true; 565*38fd1498Szrj while (__first != __last) 566*38fd1498Szrj { 567*38fd1498Szrj unsigned char __c = *__first; 568*38fd1498Szrj if (std::isdigit(__c)) 569*38fd1498Szrj __c -= '0'; 570*38fd1498Szrj else 571*38fd1498Szrj { 572*38fd1498Szrj __c = __from_chars_alpha_to_num(__c); 573*38fd1498Szrj if (__c >= __base) 574*38fd1498Szrj break; 575*38fd1498Szrj } 576*38fd1498Szrj 577*38fd1498Szrj if (__builtin_expect(__valid, 1)) 578*38fd1498Szrj __valid = __raise_and_add(__val, __base, __c); 579*38fd1498Szrj __first++; 580*38fd1498Szrj } 581*38fd1498Szrj return __valid; 582*38fd1498Szrj } 583*38fd1498Szrj 584*38fd1498Szrj template<typename _Tp> 585*38fd1498Szrj using __integer_from_chars_result_type 586*38fd1498Szrj = enable_if_t<__is_int_to_chars_type<_Tp>::value, from_chars_result>; 587*38fd1498Szrj 588*38fd1498Szrj} // namespace __detail 589*38fd1498Szrj 590*38fd1498Szrj /// std::from_chars for integral types. 591*38fd1498Szrj template<typename _Tp> 592*38fd1498Szrj __detail::__integer_from_chars_result_type<_Tp> 593*38fd1498Szrj from_chars(const char* __first, const char* __last, _Tp& __value, 594*38fd1498Szrj int __base = 10) 595*38fd1498Szrj { 596*38fd1498Szrj __glibcxx_assert(2 <= __base && __base <= 36); 597*38fd1498Szrj 598*38fd1498Szrj from_chars_result __res{__first, {}}; 599*38fd1498Szrj 600*38fd1498Szrj int __sign = 1; 601*38fd1498Szrj if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value) 602*38fd1498Szrj if (__first != __last && *__first == '-') 603*38fd1498Szrj { 604*38fd1498Szrj __sign = -1; 605*38fd1498Szrj ++__first; 606*38fd1498Szrj } 607*38fd1498Szrj 608*38fd1498Szrj using _Up = __detail::__unsigned_least_t<_Tp>; 609*38fd1498Szrj _Up __val = 0; 610*38fd1498Szrj 611*38fd1498Szrj const auto __start = __first; 612*38fd1498Szrj bool __valid; 613*38fd1498Szrj if (__base == 2) 614*38fd1498Szrj __valid = __detail::__from_chars_binary(__first, __last, __val); 615*38fd1498Szrj else if (__base <= 10) 616*38fd1498Szrj __valid = __detail::__from_chars_digit(__first, __last, __val, __base); 617*38fd1498Szrj else 618*38fd1498Szrj __valid = __detail::__from_chars_alnum(__first, __last, __val, __base); 619*38fd1498Szrj 620*38fd1498Szrj if (__builtin_expect(__first == __start, 0)) 621*38fd1498Szrj __res.ec = errc::invalid_argument; 622*38fd1498Szrj else 623*38fd1498Szrj { 624*38fd1498Szrj __res.ptr = __first; 625*38fd1498Szrj if (!__valid) 626*38fd1498Szrj __res.ec = errc::result_out_of_range; 627*38fd1498Szrj else 628*38fd1498Szrj { 629*38fd1498Szrj if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value) 630*38fd1498Szrj { 631*38fd1498Szrj _Tp __tmp; 632*38fd1498Szrj if (__builtin_mul_overflow(__val, __sign, &__tmp)) 633*38fd1498Szrj __res.ec = errc::result_out_of_range; 634*38fd1498Szrj else 635*38fd1498Szrj __value = __tmp; 636*38fd1498Szrj } 637*38fd1498Szrj else 638*38fd1498Szrj { 639*38fd1498Szrj if _GLIBCXX17_CONSTEXPR 640*38fd1498Szrj (numeric_limits<_Up>::max() > numeric_limits<_Tp>::max()) 641*38fd1498Szrj { 642*38fd1498Szrj if (__val > numeric_limits<_Tp>::max()) 643*38fd1498Szrj __res.ec = errc::result_out_of_range; 644*38fd1498Szrj else 645*38fd1498Szrj __value = __val; 646*38fd1498Szrj } 647*38fd1498Szrj else 648*38fd1498Szrj __value = __val; 649*38fd1498Szrj } 650*38fd1498Szrj } 651*38fd1498Szrj } 652*38fd1498Szrj return __res; 653*38fd1498Szrj } 654*38fd1498Szrj 655*38fd1498Szrj_GLIBCXX_END_NAMESPACE_VERSION 656*38fd1498Szrj} // namespace std 657*38fd1498Szrj#endif // C++14 658*38fd1498Szrj#endif // _GLIBCXX_CHARCONV 659