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