1d2748964SZhihao Yuan// -*- C++ -*- 2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===// 3d2748964SZhihao Yuan// 457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information. 657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7d2748964SZhihao Yuan// 8d2748964SZhihao Yuan//===----------------------------------------------------------------------===// 9d2748964SZhihao Yuan 10d2748964SZhihao Yuan#ifndef _LIBCPP_CHARCONV 11d2748964SZhihao Yuan#define _LIBCPP_CHARCONV 12d2748964SZhihao Yuan 13d2748964SZhihao Yuan/* 14d2748964SZhihao Yuan charconv synopsis 15d2748964SZhihao Yuan 16d2748964SZhihao Yuannamespace std { 17d2748964SZhihao Yuan 18d2748964SZhihao Yuan // floating-point format for primitive numerical conversion 19d2748964SZhihao Yuan enum class chars_format { 20d2748964SZhihao Yuan scientific = unspecified, 21d2748964SZhihao Yuan fixed = unspecified, 22d2748964SZhihao Yuan hex = unspecified, 23d2748964SZhihao Yuan general = fixed | scientific 24d2748964SZhihao Yuan }; 25d2748964SZhihao Yuan 26d2748964SZhihao Yuan // 23.20.2, primitive numerical output conversion 27d2748964SZhihao Yuan struct to_chars_result { 28d2748964SZhihao Yuan char* ptr; 29d2748964SZhihao Yuan errc ec; 303624c4d8SMark de Wever friend bool operator==(const to_chars_result&, const to_chars_result&) = default; // since C++20 31d2748964SZhihao Yuan }; 32d2748964SZhihao Yuan 33d2748964SZhihao Yuan to_chars_result to_chars(char* first, char* last, see below value, 34d2748964SZhihao Yuan int base = 10); 35a59c1a21SKonstantin Varlamov to_chars_result to_chars(char* first, char* last, bool value, 36a59c1a21SKonstantin Varlamov int base = 10) = delete; 37d2748964SZhihao Yuan 38d2748964SZhihao Yuan to_chars_result to_chars(char* first, char* last, float value); 39d2748964SZhihao Yuan to_chars_result to_chars(char* first, char* last, double value); 40d2748964SZhihao Yuan to_chars_result to_chars(char* first, char* last, long double value); 41d2748964SZhihao Yuan 42d2748964SZhihao Yuan to_chars_result to_chars(char* first, char* last, float value, 43d2748964SZhihao Yuan chars_format fmt); 44d2748964SZhihao Yuan to_chars_result to_chars(char* first, char* last, double value, 45d2748964SZhihao Yuan chars_format fmt); 46d2748964SZhihao Yuan to_chars_result to_chars(char* first, char* last, long double value, 47d2748964SZhihao Yuan chars_format fmt); 48d2748964SZhihao Yuan 49d2748964SZhihao Yuan to_chars_result to_chars(char* first, char* last, float value, 50d2748964SZhihao Yuan chars_format fmt, int precision); 51d2748964SZhihao Yuan to_chars_result to_chars(char* first, char* last, double value, 52d2748964SZhihao Yuan chars_format fmt, int precision); 53d2748964SZhihao Yuan to_chars_result to_chars(char* first, char* last, long double value, 54d2748964SZhihao Yuan chars_format fmt, int precision); 55d2748964SZhihao Yuan 56d2748964SZhihao Yuan // 23.20.3, primitive numerical input conversion 57d2748964SZhihao Yuan struct from_chars_result { 58d2748964SZhihao Yuan const char* ptr; 59d2748964SZhihao Yuan errc ec; 603624c4d8SMark de Wever friend bool operator==(const from_chars_result&, const from_chars_result&) = default; // since C++20 61d2748964SZhihao Yuan }; 62d2748964SZhihao Yuan 63d2748964SZhihao Yuan from_chars_result from_chars(const char* first, const char* last, 64d2748964SZhihao Yuan see below& value, int base = 10); 65d2748964SZhihao Yuan 66d2748964SZhihao Yuan from_chars_result from_chars(const char* first, const char* last, 67d2748964SZhihao Yuan float& value, 68d2748964SZhihao Yuan chars_format fmt = chars_format::general); 69d2748964SZhihao Yuan from_chars_result from_chars(const char* first, const char* last, 70d2748964SZhihao Yuan double& value, 71d2748964SZhihao Yuan chars_format fmt = chars_format::general); 72d2748964SZhihao Yuan from_chars_result from_chars(const char* first, const char* last, 73d2748964SZhihao Yuan long double& value, 74d2748964SZhihao Yuan chars_format fmt = chars_format::general); 75d2748964SZhihao Yuan 76d2748964SZhihao Yuan} // namespace std 77d2748964SZhihao Yuan 78d2748964SZhihao Yuan*/ 79d2748964SZhihao Yuan 80385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler 812eadbc86SLouis Dionne#include <__availability> 8296ed451fSMark de Wever#include <__bits> 83e983a659SMark de Wever#include <__charconv/chars_format.h> 84e983a659SMark de Wever#include <__charconv/from_chars_result.h> 85a15ae413SMark de Wever#include <__charconv/tables.h> 86a15ae413SMark de Wever#include <__charconv/to_chars_base_10.h> 87e983a659SMark de Wever#include <__charconv/to_chars_result.h> 88bfbd73f8SArthur O'Dwyer#include <__config> 892a8f9a5eSNikolas Klauser#include <__debug> 90d2748964SZhihao Yuan#include <__errc> 91*b7aa9c4aSNikolas Klauser#include <__type_traits/make_32_64_or_128_bit.h> 922a8f9a5eSNikolas Klauser#include <__utility/unreachable.h> 93b12ea065SArthur O'Dwyer#include <cmath> // for log2f 94b12ea065SArthur O'Dwyer#include <cstdint> 952a8f9a5eSNikolas Klauser#include <cstdlib> 96b12ea065SArthur O'Dwyer#include <cstring> 97d2748964SZhihao Yuan#include <limits> 98b12ea065SArthur O'Dwyer#include <type_traits> 99d2748964SZhihao Yuan 100de4a57cbSLouis Dionne#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES 101de4a57cbSLouis Dionne# include <iosfwd> 102de4a57cbSLouis Dionne#endif 103de4a57cbSLouis Dionne 104d2748964SZhihao Yuan#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 105d2748964SZhihao Yuan# pragma GCC system_header 106d2748964SZhihao Yuan#endif 107d2748964SZhihao Yuan 10827e9fdb2SMarshall Clow_LIBCPP_PUSH_MACROS 10927e9fdb2SMarshall Clow#include <__undef_macros> 11027e9fdb2SMarshall Clow 111d2748964SZhihao Yuan_LIBCPP_BEGIN_NAMESPACE_STD 112d2748964SZhihao Yuan 113769c2459SMarshall Clow#ifndef _LIBCPP_CXX03_LANG 114d2748964SZhihao Yuan 115bfc253c0SMark de Weverto_chars_result to_chars(char*, char*, bool, int = 10) = delete; 116bfc253c0SMark de Weverfrom_chars_result from_chars(const char*, const char*, bool, int = 10) = delete; 117d2748964SZhihao Yuan 118d2748964SZhihao Yuannamespace __itoa 119d2748964SZhihao Yuan{ 120d2748964SZhihao Yuan 121d2748964SZhihao Yuantemplate <typename _Tp, typename = void> 1223f786833SMark de Weverstruct _LIBCPP_HIDDEN __traits_base; 123d2748964SZhihao Yuan 124d2748964SZhihao Yuantemplate <typename _Tp> 1253f786833SMark de Weverstruct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) <= sizeof(uint32_t)>> 126d2748964SZhihao Yuan{ 127d2748964SZhihao Yuan using type = uint32_t; 128d2748964SZhihao Yuan 1293f786833SMark de Wever /// The width estimation using a log10 algorithm. 1303f786833SMark de Wever /// 1313f786833SMark de Wever /// The algorithm is based on 1323f786833SMark de Wever /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 1333f786833SMark de Wever /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that 1343f786833SMark de Wever /// function requires its input to have at least one bit set the value of 1353f786833SMark de Wever /// zero is set to one. This means the first element of the lookup table is 1363f786833SMark de Wever /// zero. 1373925f98dSMark de Wever static _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) 138d2748964SZhihao Yuan { 1393925f98dSMark de Wever auto __t = (32 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12; 140dea7a8e6SMark de Wever return __t - (__v < __table<>::__pow10_32[__t]) + 1; 141d2748964SZhihao Yuan } 142d2748964SZhihao Yuan 1433561ee58SMark de Wever static _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) 144d2748964SZhihao Yuan { 1453561ee58SMark de Wever return __itoa::__base_10_u32(__p, __v); 146d2748964SZhihao Yuan } 147d2748964SZhihao Yuan 148dea7a8e6SMark de Wever static _LIBCPP_HIDE_FROM_ABI decltype(__table<>::__pow10_32)& __pow() { return __table<>::__pow10_32; } 149d2748964SZhihao Yuan}; 150d2748964SZhihao Yuan 151d2748964SZhihao Yuantemplate <typename _Tp> 1523f786833SMark de Weverstruct _LIBCPP_HIDDEN 1533f786833SMark de Wever __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(uint64_t)>> { 1543f786833SMark de Wever using type = uint64_t; 1553f786833SMark de Wever 1563f786833SMark de Wever /// The width estimation using a log10 algorithm. 1573f786833SMark de Wever /// 1583f786833SMark de Wever /// The algorithm is based on 1593f786833SMark de Wever /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 1603f786833SMark de Wever /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that 1613f786833SMark de Wever /// function requires its input to have at least one bit set the value of 1623f786833SMark de Wever /// zero is set to one. This means the first element of the lookup table is 1633f786833SMark de Wever /// zero. 1643f786833SMark de Wever static _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) { 1653f786833SMark de Wever auto __t = (64 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12; 1663f786833SMark de Wever return __t - (__v < __table<>::__pow10_64[__t]) + 1; 1673f786833SMark de Wever } 1683f786833SMark de Wever 1693f786833SMark de Wever static _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) { return __itoa::__base_10_u64(__p, __v); } 1703f786833SMark de Wever 1713f786833SMark de Wever static _LIBCPP_HIDE_FROM_ABI decltype(__table<>::__pow10_64)& __pow() { return __table<>::__pow10_64; } 1723f786833SMark de Wever}; 1733f786833SMark de Wever 1743f786833SMark de Wever 1753f786833SMark de Wever# ifndef _LIBCPP_HAS_NO_INT128 1763f786833SMark de Wevertemplate <typename _Tp> 1773f786833SMark de Weverstruct _LIBCPP_HIDDEN 1783f786833SMark de Wever __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(__uint128_t)> > { 1793f786833SMark de Wever using type = __uint128_t; 1803f786833SMark de Wever 1813f786833SMark de Wever /// The width estimation using a log10 algorithm. 1823f786833SMark de Wever /// 1833f786833SMark de Wever /// The algorithm is based on 1843f786833SMark de Wever /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 1853f786833SMark de Wever /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that 1863f786833SMark de Wever /// function requires its input to have at least one bit set the value of 1873f786833SMark de Wever /// zero is set to one. This means the first element of the lookup table is 1883f786833SMark de Wever /// zero. 1893f786833SMark de Wever static _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) { 1903f786833SMark de Wever _LIBCPP_ASSERT(__v > numeric_limits<uint64_t>::max(), "The optimizations for this algorithm fail when this isn't true."); 1913f786833SMark de Wever // There's always a bit set in the upper 64-bits. 1923f786833SMark de Wever auto __t = (128 - std::__libcpp_clz(static_cast<uint64_t>(__v >> 64))) * 1233 >> 12; 1933f786833SMark de Wever _LIBCPP_ASSERT(__t >= __table<>::__pow10_128_offset, "Index out of bounds"); 1943f786833SMark de Wever // __t is adjusted since the lookup table misses the lower entries. 1953f786833SMark de Wever return __t - (__v < __table<>::__pow10_128[__t - __table<>::__pow10_128_offset]) + 1; 1963f786833SMark de Wever } 1973f786833SMark de Wever 1983f786833SMark de Wever static _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) { return __itoa::__base_10_u128(__p, __v); } 1993f786833SMark de Wever 2003f786833SMark de Wever // TODO FMT This pow function should get an index. 2013f786833SMark de Wever // By moving this to its own header it can be reused by the pow function in to_chars_base_10. 2023f786833SMark de Wever static _LIBCPP_HIDE_FROM_ABI decltype(__table<>::__pow10_128)& __pow() { return __table<>::__pow10_128; } 2033f786833SMark de Wever}; 2043f786833SMark de Wever#endif 2053f786833SMark de Wever 2063f786833SMark de Wevertemplate <typename _Tp> 2073925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI bool 208d2748964SZhihao Yuan__mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r) 209d2748964SZhihao Yuan{ 210d2748964SZhihao Yuan auto __c = __a * __b; 211d2748964SZhihao Yuan __r = __c; 21203ee4612SArthur O'Dwyer return __c > numeric_limits<unsigned char>::max(); 213d2748964SZhihao Yuan} 214d2748964SZhihao Yuan 215d2748964SZhihao Yuantemplate <typename _Tp> 2163925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI bool 217d2748964SZhihao Yuan__mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r) 218d2748964SZhihao Yuan{ 219d2748964SZhihao Yuan auto __c = __a * __b; 220d2748964SZhihao Yuan __r = __c; 22103ee4612SArthur O'Dwyer return __c > numeric_limits<unsigned short>::max(); 222d2748964SZhihao Yuan} 223d2748964SZhihao Yuan 224d2748964SZhihao Yuantemplate <typename _Tp> 2253925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI bool 226d2748964SZhihao Yuan__mul_overflowed(_Tp __a, _Tp __b, _Tp& __r) 227d2748964SZhihao Yuan{ 228d2748964SZhihao Yuan static_assert(is_unsigned<_Tp>::value, ""); 229d2748964SZhihao Yuan#if !defined(_LIBCPP_COMPILER_MSVC) 230d2748964SZhihao Yuan return __builtin_mul_overflow(__a, __b, &__r); 231d2748964SZhihao Yuan#else 23203ee4612SArthur O'Dwyer bool __did = __b && (numeric_limits<_Tp>::max() / __b) < __a; 233d2748964SZhihao Yuan __r = __a * __b; 234d2748964SZhihao Yuan return __did; 235d2748964SZhihao Yuan#endif 236d2748964SZhihao Yuan} 237d2748964SZhihao Yuan 238d2748964SZhihao Yuantemplate <typename _Tp, typename _Up> 2393925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI bool 240d2748964SZhihao Yuan__mul_overflowed(_Tp __a, _Up __b, _Tp& __r) 241d2748964SZhihao Yuan{ 242d2748964SZhihao Yuan return __mul_overflowed(__a, static_cast<_Tp>(__b), __r); 243d2748964SZhihao Yuan} 244d2748964SZhihao Yuan 245d2748964SZhihao Yuantemplate <typename _Tp> 246d2748964SZhihao Yuanstruct _LIBCPP_HIDDEN __traits : __traits_base<_Tp> 247d2748964SZhihao Yuan{ 2483925f98dSMark de Wever static constexpr int digits = numeric_limits<_Tp>::digits10 + 1; 249d2748964SZhihao Yuan using __traits_base<_Tp>::__pow; 250d2748964SZhihao Yuan using typename __traits_base<_Tp>::type; 251d2748964SZhihao Yuan 252d2748964SZhihao Yuan // precondition: at least one non-zero character available 2533925f98dSMark de Wever static _LIBCPP_HIDE_FROM_ABI char const* 254d2748964SZhihao Yuan __read(char const* __p, char const* __ep, type& __a, type& __b) 255d2748964SZhihao Yuan { 256d2748964SZhihao Yuan type __cprod[digits]; 257d2748964SZhihao Yuan int __j = digits - 1; 258d2748964SZhihao Yuan int __i = digits; 259d2748964SZhihao Yuan do 260d2748964SZhihao Yuan { 261d2748964SZhihao Yuan if (!('0' <= *__p && *__p <= '9')) 262d2748964SZhihao Yuan break; 263d2748964SZhihao Yuan __cprod[--__i] = *__p++ - '0'; 264d2748964SZhihao Yuan } while (__p != __ep && __i != 0); 265d2748964SZhihao Yuan 266d2748964SZhihao Yuan __a = __inner_product(__cprod + __i + 1, __cprod + __j, __pow() + 1, 267d2748964SZhihao Yuan __cprod[__i]); 268d2748964SZhihao Yuan if (__mul_overflowed(__cprod[__j], __pow()[__j - __i], __b)) 269d2748964SZhihao Yuan --__p; 270d2748964SZhihao Yuan return __p; 271d2748964SZhihao Yuan } 272d2748964SZhihao Yuan 273d2748964SZhihao Yuan template <typename _It1, typename _It2, class _Up> 2743925f98dSMark de Wever static _LIBCPP_HIDE_FROM_ABI _Up 275d2748964SZhihao Yuan __inner_product(_It1 __first1, _It1 __last1, _It2 __first2, _Up __init) 276d2748964SZhihao Yuan { 277d2748964SZhihao Yuan for (; __first1 < __last1; ++__first1, ++__first2) 278d2748964SZhihao Yuan __init = __init + *__first1 * *__first2; 279d2748964SZhihao Yuan return __init; 280d2748964SZhihao Yuan } 281d2748964SZhihao Yuan}; 282d2748964SZhihao Yuan 283d2748964SZhihao Yuan} // namespace __itoa 284d2748964SZhihao Yuan 285d2748964SZhihao Yuantemplate <typename _Tp> 2863925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI _Tp 287d2748964SZhihao Yuan__complement(_Tp __x) 288d2748964SZhihao Yuan{ 289d2748964SZhihao Yuan static_assert(is_unsigned<_Tp>::value, "cast to unsigned first"); 290d2748964SZhihao Yuan return _Tp(~__x + 1); 291d2748964SZhihao Yuan} 292d2748964SZhihao Yuan 293d2748964SZhihao Yuantemplate <typename _Tp> 2943925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI to_chars_result 295d2748964SZhihao Yuan__to_chars_itoa(char* __first, char* __last, _Tp __value, true_type) 296d2748964SZhihao Yuan{ 297c273f5efSMark de Wever auto __x = __to_unsigned_like(__value); 298d2748964SZhihao Yuan if (__value < 0 && __first != __last) 299d2748964SZhihao Yuan { 300d2748964SZhihao Yuan *__first++ = '-'; 301d2748964SZhihao Yuan __x = __complement(__x); 302d2748964SZhihao Yuan } 303d2748964SZhihao Yuan 304d2748964SZhihao Yuan return __to_chars_itoa(__first, __last, __x, false_type()); 305d2748964SZhihao Yuan} 306d2748964SZhihao Yuan 307d2748964SZhihao Yuantemplate <typename _Tp> 3083925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI to_chars_result 309d2748964SZhihao Yuan__to_chars_itoa(char* __first, char* __last, _Tp __value, false_type) 310d2748964SZhihao Yuan{ 311d2748964SZhihao Yuan using __tx = __itoa::__traits<_Tp>; 312d2748964SZhihao Yuan auto __diff = __last - __first; 313d2748964SZhihao Yuan 314d2748964SZhihao Yuan if (__tx::digits <= __diff || __tx::__width(__value) <= __diff) 3153561ee58SMark de Wever return {__tx::__convert(__first, __value), errc(0)}; 316d2748964SZhihao Yuan else 317d2748964SZhihao Yuan return {__last, errc::value_too_large}; 318d2748964SZhihao Yuan} 319d2748964SZhihao Yuan 3203f786833SMark de Wever# ifndef _LIBCPP_HAS_NO_INT128 3213f786833SMark de Wevertemplate <> 3223f786833SMark de Weverinline _LIBCPP_HIDE_FROM_ABI to_chars_result 3233f786833SMark de Wever__to_chars_itoa(char* __first, char* __last, __uint128_t __value, false_type) 3243f786833SMark de Wever{ 3253f786833SMark de Wever // When the value fits in 64-bits use the 64-bit code path. This reduces 3263f786833SMark de Wever // the number of expensive calculations on 128-bit values. 3273f786833SMark de Wever // 3283f786833SMark de Wever // NOTE the 128-bit code path requires this optimization. 3293f786833SMark de Wever if(__value <= numeric_limits<uint64_t>::max()) 3303f786833SMark de Wever return __to_chars_itoa(__first, __last, static_cast<uint64_t>(__value), false_type()); 3313f786833SMark de Wever 3323f786833SMark de Wever using __tx = __itoa::__traits<__uint128_t>; 3333f786833SMark de Wever auto __diff = __last - __first; 3343f786833SMark de Wever 3353f786833SMark de Wever if (__tx::digits <= __diff || __tx::__width(__value) <= __diff) 3363f786833SMark de Wever return {__tx::__convert(__first, __value), errc(0)}; 3373f786833SMark de Wever else 3383f786833SMark de Wever return {__last, errc::value_too_large}; 3393f786833SMark de Wever} 3403f786833SMark de Wever#endif 3413f786833SMark de Wever 342d2748964SZhihao Yuantemplate <typename _Tp> 3433925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI to_chars_result 344d2748964SZhihao Yuan__to_chars_integral(char* __first, char* __last, _Tp __value, int __base, 345d2748964SZhihao Yuan true_type) 346d2748964SZhihao Yuan{ 347c273f5efSMark de Wever auto __x = __to_unsigned_like(__value); 348d2748964SZhihao Yuan if (__value < 0 && __first != __last) 349d2748964SZhihao Yuan { 350d2748964SZhihao Yuan *__first++ = '-'; 351d2748964SZhihao Yuan __x = __complement(__x); 352d2748964SZhihao Yuan } 353d2748964SZhihao Yuan 354d2748964SZhihao Yuan return __to_chars_integral(__first, __last, __x, __base, false_type()); 355d2748964SZhihao Yuan} 356d2748964SZhihao Yuan 3576c11aebdSMark de Wevernamespace __itoa { 3586c11aebdSMark de Wever 3596c11aebdSMark de Wevertemplate <unsigned _Base> 3606c11aebdSMark de Weverstruct _LIBCPP_HIDDEN __integral; 3616c11aebdSMark de Wever 3626c11aebdSMark de Wevertemplate <> 3636c11aebdSMark de Weverstruct _LIBCPP_HIDDEN __integral<2> { 3646c11aebdSMark de Wever template <typename _Tp> 3656c11aebdSMark de Wever _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept { 3666c11aebdSMark de Wever // If value == 0 still need one digit. If the value != this has no 3676c11aebdSMark de Wever // effect since the code scans for the most significant bit set. (Note 3686c11aebdSMark de Wever // that __libcpp_clz doesn't work for 0.) 3696c11aebdSMark de Wever return numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1); 3706c11aebdSMark de Wever } 3716c11aebdSMark de Wever 3726c11aebdSMark de Wever template <typename _Tp> 3736c11aebdSMark de Wever _LIBCPP_HIDE_FROM_ABI static to_chars_result __to_chars(char* __first, char* __last, _Tp __value) { 3746c11aebdSMark de Wever ptrdiff_t __cap = __last - __first; 3756c11aebdSMark de Wever int __n = __width(__value); 3766c11aebdSMark de Wever if (__n > __cap) 3776c11aebdSMark de Wever return {__last, errc::value_too_large}; 3786c11aebdSMark de Wever 3796c11aebdSMark de Wever __last = __first + __n; 3806c11aebdSMark de Wever char* __p = __last; 3816c11aebdSMark de Wever const unsigned __divisor = 16; 3826c11aebdSMark de Wever while (__value > __divisor) { 3836c11aebdSMark de Wever unsigned __c = __value % __divisor; 3846c11aebdSMark de Wever __value /= __divisor; 3856c11aebdSMark de Wever __p -= 4; 386dea7a8e6SMark de Wever std::memcpy(__p, &__table<>::__base_2_lut[4 * __c], 4); 3876c11aebdSMark de Wever } 3886c11aebdSMark de Wever do { 3896c11aebdSMark de Wever unsigned __c = __value % 2; 3906c11aebdSMark de Wever __value /= 2; 3916c11aebdSMark de Wever *--__p = "01"[__c]; 3926c11aebdSMark de Wever } while (__value != 0); 3936c11aebdSMark de Wever return {__last, errc(0)}; 3946c11aebdSMark de Wever } 3956c11aebdSMark de Wever}; 3966c11aebdSMark de Wever 3976c11aebdSMark de Wevertemplate <> 3986c11aebdSMark de Weverstruct _LIBCPP_HIDDEN __integral<8> { 3996c11aebdSMark de Wever template <typename _Tp> 4006c11aebdSMark de Wever _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept { 4016c11aebdSMark de Wever // If value == 0 still need one digit. If the value != this has no 4026c11aebdSMark de Wever // effect since the code scans for the most significat bit set. (Note 4036c11aebdSMark de Wever // that __libcpp_clz doesn't work for 0.) 4046c11aebdSMark de Wever return ((numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1)) + 2) / 3; 4056c11aebdSMark de Wever } 4066c11aebdSMark de Wever 4076c11aebdSMark de Wever template <typename _Tp> 4086c11aebdSMark de Wever _LIBCPP_HIDE_FROM_ABI static to_chars_result __to_chars(char* __first, char* __last, _Tp __value) { 4096c11aebdSMark de Wever ptrdiff_t __cap = __last - __first; 4106c11aebdSMark de Wever int __n = __width(__value); 4116c11aebdSMark de Wever if (__n > __cap) 4126c11aebdSMark de Wever return {__last, errc::value_too_large}; 4136c11aebdSMark de Wever 4146c11aebdSMark de Wever __last = __first + __n; 4156c11aebdSMark de Wever char* __p = __last; 4166c11aebdSMark de Wever unsigned __divisor = 64; 4176c11aebdSMark de Wever while (__value > __divisor) { 4186c11aebdSMark de Wever unsigned __c = __value % __divisor; 4196c11aebdSMark de Wever __value /= __divisor; 4206c11aebdSMark de Wever __p -= 2; 421dea7a8e6SMark de Wever std::memcpy(__p, &__table<>::__base_8_lut[2 * __c], 2); 4226c11aebdSMark de Wever } 4236c11aebdSMark de Wever do { 4246c11aebdSMark de Wever unsigned __c = __value % 8; 4256c11aebdSMark de Wever __value /= 8; 4266c11aebdSMark de Wever *--__p = "01234567"[__c]; 4276c11aebdSMark de Wever } while (__value != 0); 4286c11aebdSMark de Wever return {__last, errc(0)}; 4296c11aebdSMark de Wever } 4306c11aebdSMark de Wever 4316c11aebdSMark de Wever}; 4326c11aebdSMark de Wever 4336c11aebdSMark de Wevertemplate <> 4346c11aebdSMark de Weverstruct _LIBCPP_HIDDEN __integral<16> { 4356c11aebdSMark de Wever template <typename _Tp> 4366c11aebdSMark de Wever _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept { 4376c11aebdSMark de Wever // If value == 0 still need one digit. If the value != this has no 4386c11aebdSMark de Wever // effect since the code scans for the most significat bit set. (Note 4396c11aebdSMark de Wever // that __libcpp_clz doesn't work for 0.) 4406c11aebdSMark de Wever return (numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1) + 3) / 4; 4416c11aebdSMark de Wever } 4426c11aebdSMark de Wever 4436c11aebdSMark de Wever template <typename _Tp> 4446c11aebdSMark de Wever _LIBCPP_HIDE_FROM_ABI static to_chars_result __to_chars(char* __first, char* __last, _Tp __value) { 4456c11aebdSMark de Wever ptrdiff_t __cap = __last - __first; 4466c11aebdSMark de Wever int __n = __width(__value); 4476c11aebdSMark de Wever if (__n > __cap) 4486c11aebdSMark de Wever return {__last, errc::value_too_large}; 4496c11aebdSMark de Wever 4506c11aebdSMark de Wever __last = __first + __n; 4516c11aebdSMark de Wever char* __p = __last; 4526c11aebdSMark de Wever unsigned __divisor = 256; 4536c11aebdSMark de Wever while (__value > __divisor) { 4546c11aebdSMark de Wever unsigned __c = __value % __divisor; 4556c11aebdSMark de Wever __value /= __divisor; 4566c11aebdSMark de Wever __p -= 2; 457dea7a8e6SMark de Wever std::memcpy(__p, &__table<>::__base_16_lut[2 * __c], 2); 4586c11aebdSMark de Wever } 4596c11aebdSMark de Wever if (__first != __last) 4606c11aebdSMark de Wever do { 4616c11aebdSMark de Wever unsigned __c = __value % 16; 4626c11aebdSMark de Wever __value /= 16; 4636c11aebdSMark de Wever *--__p = "0123456789abcdef"[__c]; 4646c11aebdSMark de Wever } while (__value != 0); 4656c11aebdSMark de Wever return {__last, errc(0)}; 4666c11aebdSMark de Wever } 4676c11aebdSMark de Wever}; 4686c11aebdSMark de Wever 4696c11aebdSMark de Wever} // namespace __itoa 4706c11aebdSMark de Wever 4716c11aebdSMark de Wevertemplate <unsigned _Base, typename _Tp, 4726c11aebdSMark de Wever typename enable_if<(sizeof(_Tp) >= sizeof(unsigned)), int>::type = 0> 4736c11aebdSMark de Wever_LIBCPP_HIDE_FROM_ABI int 4746c11aebdSMark de Wever__to_chars_integral_width(_Tp __value) { 4756c11aebdSMark de Wever return __itoa::__integral<_Base>::__width(__value); 4766c11aebdSMark de Wever} 4776c11aebdSMark de Wever 4786c11aebdSMark de Wevertemplate <unsigned _Base, typename _Tp, 4796c11aebdSMark de Wever typename enable_if<(sizeof(_Tp) < sizeof(unsigned)), int>::type = 0> 4806c11aebdSMark de Wever_LIBCPP_HIDE_FROM_ABI int 4816c11aebdSMark de Wever__to_chars_integral_width(_Tp __value) { 4826c11aebdSMark de Wever return std::__to_chars_integral_width<_Base>(static_cast<unsigned>(__value)); 4836c11aebdSMark de Wever} 4846c11aebdSMark de Wever 4856c11aebdSMark de Wevertemplate <unsigned _Base, typename _Tp, 4866c11aebdSMark de Wever typename enable_if<(sizeof(_Tp) >= sizeof(unsigned)), int>::type = 0> 4876c11aebdSMark de Wever_LIBCPP_HIDE_FROM_ABI to_chars_result 4886c11aebdSMark de Wever__to_chars_integral(char* __first, char* __last, _Tp __value) { 4896c11aebdSMark de Wever return __itoa::__integral<_Base>::__to_chars(__first, __last, __value); 4906c11aebdSMark de Wever} 4916c11aebdSMark de Wever 4926c11aebdSMark de Wevertemplate <unsigned _Base, typename _Tp, 4936c11aebdSMark de Wever typename enable_if<(sizeof(_Tp) < sizeof(unsigned)), int>::type = 0> 4946c11aebdSMark de Wever_LIBCPP_HIDE_FROM_ABI to_chars_result 4956c11aebdSMark de Wever__to_chars_integral(char* __first, char* __last, _Tp __value) { 4966c11aebdSMark de Wever return std::__to_chars_integral<_Base>(__first, __last, static_cast<unsigned>(__value)); 4976c11aebdSMark de Wever} 4986c11aebdSMark de Wever 499d2748964SZhihao Yuantemplate <typename _Tp> 500b968c345SMark de Wever_LIBCPP_HIDE_FROM_ABI int 5013925f98dSMark de Wever__to_chars_integral_width(_Tp __value, unsigned __base) { 5029393060fSMark de Wever _LIBCPP_ASSERT(__value >= 0, "The function requires a non-negative value."); 5039393060fSMark de Wever 5049393060fSMark de Wever unsigned __base_2 = __base * __base; 5059393060fSMark de Wever unsigned __base_3 = __base_2 * __base; 5069393060fSMark de Wever unsigned __base_4 = __base_2 * __base_2; 5079393060fSMark de Wever 5089393060fSMark de Wever int __r = 0; 5099393060fSMark de Wever while (true) { 5109393060fSMark de Wever if (__value < __base) 5119393060fSMark de Wever return __r + 1; 5129393060fSMark de Wever if (__value < __base_2) 5139393060fSMark de Wever return __r + 2; 5149393060fSMark de Wever if (__value < __base_3) 5159393060fSMark de Wever return __r + 3; 5169393060fSMark de Wever if (__value < __base_4) 5179393060fSMark de Wever return __r + 4; 5189393060fSMark de Wever 5199393060fSMark de Wever __value /= __base_4; 5209393060fSMark de Wever __r += 4; 5219393060fSMark de Wever } 5229393060fSMark de Wever 5232a8f9a5eSNikolas Klauser __libcpp_unreachable(); 5249393060fSMark de Wever} 5259393060fSMark de Wever 5269393060fSMark de Wevertemplate <typename _Tp> 5273925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI to_chars_result 528d2748964SZhihao Yuan__to_chars_integral(char* __first, char* __last, _Tp __value, int __base, 529d2748964SZhihao Yuan false_type) 530d2748964SZhihao Yuan{ 5316c11aebdSMark de Wever if (__base == 10) [[likely]] 532d2748964SZhihao Yuan return __to_chars_itoa(__first, __last, __value, false_type()); 533d2748964SZhihao Yuan 5346c11aebdSMark de Wever switch (__base) { 5356c11aebdSMark de Wever case 2: 5366c11aebdSMark de Wever return __to_chars_integral<2>(__first, __last, __value); 5376c11aebdSMark de Wever case 8: 5386c11aebdSMark de Wever return __to_chars_integral<8>(__first, __last, __value); 5396c11aebdSMark de Wever case 16: 5406c11aebdSMark de Wever return __to_chars_integral<16>(__first, __last, __value); 5416c11aebdSMark de Wever } 5426c11aebdSMark de Wever 5439393060fSMark de Wever ptrdiff_t __cap = __last - __first; 5449393060fSMark de Wever int __n = __to_chars_integral_width(__value, __base); 5459393060fSMark de Wever if (__n > __cap) 5469393060fSMark de Wever return {__last, errc::value_too_large}; 5479393060fSMark de Wever 5489393060fSMark de Wever __last = __first + __n; 5499393060fSMark de Wever char* __p = __last; 5509393060fSMark de Wever do { 5519393060fSMark de Wever unsigned __c = __value % __base; 552d2748964SZhihao Yuan __value /= __base; 553d2748964SZhihao Yuan *--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c]; 5549393060fSMark de Wever } while (__value != 0); 5559393060fSMark de Wever return {__last, errc(0)}; 556d2748964SZhihao Yuan} 557d2748964SZhihao Yuan 558769c2459SMarshall Clowtemplate <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> 5593925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI to_chars_result 560d2748964SZhihao Yuanto_chars(char* __first, char* __last, _Tp __value) 561d2748964SZhihao Yuan{ 562cf927669SMark de Wever using _Type = __make_32_64_or_128_bit_t<_Tp>; 563cf927669SMark de Wever static_assert(!is_same<_Type, void>::value, "unsupported integral type used in to_chars"); 564cf927669SMark de Wever return std::__to_chars_itoa(__first, __last, static_cast<_Type>(__value), is_signed<_Tp>()); 565d2748964SZhihao Yuan} 566d2748964SZhihao Yuan 567769c2459SMarshall Clowtemplate <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> 5683925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI to_chars_result 569d2748964SZhihao Yuanto_chars(char* __first, char* __last, _Tp __value, int __base) 570d2748964SZhihao Yuan{ 571d2748964SZhihao Yuan _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]"); 572cf927669SMark de Wever 573cf927669SMark de Wever using _Type = __make_32_64_or_128_bit_t<_Tp>; 574cf927669SMark de Wever return std::__to_chars_integral(__first, __last, static_cast<_Type>(__value), __base, is_signed<_Tp>()); 575d2748964SZhihao Yuan} 576d2748964SZhihao Yuan 577d2748964SZhihao Yuantemplate <typename _It, typename _Tp, typename _Fn, typename... _Ts> 5783925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI from_chars_result 579d2748964SZhihao Yuan__sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args) 580d2748964SZhihao Yuan{ 581d2748964SZhihao Yuan using __tl = numeric_limits<_Tp>; 582c273f5efSMark de Wever decltype(__to_unsigned_like(__value)) __x; 583d2748964SZhihao Yuan 584d2748964SZhihao Yuan bool __neg = (__first != __last && *__first == '-'); 585d2748964SZhihao Yuan auto __r = __f(__neg ? __first + 1 : __first, __last, __x, __args...); 586d2748964SZhihao Yuan switch (__r.ec) 587d2748964SZhihao Yuan { 588d2748964SZhihao Yuan case errc::invalid_argument: 589d2748964SZhihao Yuan return {__first, __r.ec}; 590d2748964SZhihao Yuan case errc::result_out_of_range: 591d2748964SZhihao Yuan return __r; 592d2748964SZhihao Yuan default: 593d2748964SZhihao Yuan break; 594d2748964SZhihao Yuan } 595d2748964SZhihao Yuan 596d2748964SZhihao Yuan if (__neg) 597d2748964SZhihao Yuan { 598c273f5efSMark de Wever if (__x <= __complement(__to_unsigned_like(__tl::min()))) 599d2748964SZhihao Yuan { 600d2748964SZhihao Yuan __x = __complement(__x); 6013925f98dSMark de Wever std::memcpy(&__value, &__x, sizeof(__x)); 602d2748964SZhihao Yuan return __r; 603d2748964SZhihao Yuan } 604d2748964SZhihao Yuan } 605d2748964SZhihao Yuan else 606d2748964SZhihao Yuan { 607e39095a3SLouis Dionne if (__x <= __to_unsigned_like(__tl::max())) 608d2748964SZhihao Yuan { 609d2748964SZhihao Yuan __value = __x; 610d2748964SZhihao Yuan return __r; 611d2748964SZhihao Yuan } 612d2748964SZhihao Yuan } 613d2748964SZhihao Yuan 614d2748964SZhihao Yuan return {__r.ptr, errc::result_out_of_range}; 615d2748964SZhihao Yuan} 616d2748964SZhihao Yuan 617d2748964SZhihao Yuantemplate <typename _Tp> 6183925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI bool 619d2748964SZhihao Yuan__in_pattern(_Tp __c) 620d2748964SZhihao Yuan{ 621d2748964SZhihao Yuan return '0' <= __c && __c <= '9'; 622d2748964SZhihao Yuan} 623d2748964SZhihao Yuan 624d2748964SZhihao Yuanstruct _LIBCPP_HIDDEN __in_pattern_result 625d2748964SZhihao Yuan{ 626d2748964SZhihao Yuan bool __ok; 627d2748964SZhihao Yuan int __val; 628d2748964SZhihao Yuan 6293925f98dSMark de Wever explicit _LIBCPP_HIDE_FROM_ABI operator bool() const { return __ok; } 630d2748964SZhihao Yuan}; 631d2748964SZhihao Yuan 632d2748964SZhihao Yuantemplate <typename _Tp> 6333925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI __in_pattern_result 634d2748964SZhihao Yuan__in_pattern(_Tp __c, int __base) 635d2748964SZhihao Yuan{ 636d2748964SZhihao Yuan if (__base <= 10) 637d2748964SZhihao Yuan return {'0' <= __c && __c < '0' + __base, __c - '0'}; 638d2748964SZhihao Yuan else if (__in_pattern(__c)) 639d2748964SZhihao Yuan return {true, __c - '0'}; 640d2748964SZhihao Yuan else if ('a' <= __c && __c < 'a' + __base - 10) 641d2748964SZhihao Yuan return {true, __c - 'a' + 10}; 642d2748964SZhihao Yuan else 643d2748964SZhihao Yuan return {'A' <= __c && __c < 'A' + __base - 10, __c - 'A' + 10}; 644d2748964SZhihao Yuan} 645d2748964SZhihao Yuan 646d2748964SZhihao Yuantemplate <typename _It, typename _Tp, typename _Fn, typename... _Ts> 6473925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI from_chars_result 648d2748964SZhihao Yuan__subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, 649d2748964SZhihao Yuan _Ts... __args) 650d2748964SZhihao Yuan{ 651e39095a3SLouis Dionne auto __find_non_zero = [](_It __firstit, _It __lastit) { 652e39095a3SLouis Dionne for (; __firstit != __lastit; ++__firstit) 653e39095a3SLouis Dionne if (*__firstit != '0') 654d2748964SZhihao Yuan break; 655e39095a3SLouis Dionne return __firstit; 656d2748964SZhihao Yuan }; 657d2748964SZhihao Yuan 658d2748964SZhihao Yuan auto __p = __find_non_zero(__first, __last); 659d2748964SZhihao Yuan if (__p == __last || !__in_pattern(*__p, __args...)) 660d2748964SZhihao Yuan { 661d2748964SZhihao Yuan if (__p == __first) 662d2748964SZhihao Yuan return {__first, errc::invalid_argument}; 663d2748964SZhihao Yuan else 664d2748964SZhihao Yuan { 665d2748964SZhihao Yuan __value = 0; 666d2748964SZhihao Yuan return {__p, {}}; 667d2748964SZhihao Yuan } 668d2748964SZhihao Yuan } 669d2748964SZhihao Yuan 670d2748964SZhihao Yuan auto __r = __f(__p, __last, __value, __args...); 671d2748964SZhihao Yuan if (__r.ec == errc::result_out_of_range) 672d2748964SZhihao Yuan { 673d2748964SZhihao Yuan for (; __r.ptr != __last; ++__r.ptr) 674d2748964SZhihao Yuan { 675d2748964SZhihao Yuan if (!__in_pattern(*__r.ptr, __args...)) 676d2748964SZhihao Yuan break; 677d2748964SZhihao Yuan } 678d2748964SZhihao Yuan } 679d2748964SZhihao Yuan 680d2748964SZhihao Yuan return __r; 681d2748964SZhihao Yuan} 682d2748964SZhihao Yuan 683769c2459SMarshall Clowtemplate <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0> 6843925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI from_chars_result 685d2748964SZhihao Yuan__from_chars_atoi(const char* __first, const char* __last, _Tp& __value) 686d2748964SZhihao Yuan{ 687d2748964SZhihao Yuan using __tx = __itoa::__traits<_Tp>; 688d2748964SZhihao Yuan using __output_type = typename __tx::type; 689d2748964SZhihao Yuan 690d2748964SZhihao Yuan return __subject_seq_combinator( 691d2748964SZhihao Yuan __first, __last, __value, 692b48c5010SNikolas Klauser [](const char* __f, const char* __l, 693e39095a3SLouis Dionne _Tp& __val) -> from_chars_result { 694d2748964SZhihao Yuan __output_type __a, __b; 695b48c5010SNikolas Klauser auto __p = __tx::__read(__f, __l, __a, __b); 696b48c5010SNikolas Klauser if (__p == __l || !__in_pattern(*__p)) 697d2748964SZhihao Yuan { 69803ee4612SArthur O'Dwyer __output_type __m = numeric_limits<_Tp>::max(); 699d2748964SZhihao Yuan if (__m >= __a && __m - __a >= __b) 700d2748964SZhihao Yuan { 701e39095a3SLouis Dionne __val = __a + __b; 702d2748964SZhihao Yuan return {__p, {}}; 703d2748964SZhihao Yuan } 704d2748964SZhihao Yuan } 705d2748964SZhihao Yuan return {__p, errc::result_out_of_range}; 706d2748964SZhihao Yuan }); 707d2748964SZhihao Yuan} 708d2748964SZhihao Yuan 709769c2459SMarshall Clowtemplate <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0> 7103925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI from_chars_result 711d2748964SZhihao Yuan__from_chars_atoi(const char* __first, const char* __last, _Tp& __value) 712d2748964SZhihao Yuan{ 713c273f5efSMark de Wever using __t = decltype(__to_unsigned_like(__value)); 714d2748964SZhihao Yuan return __sign_combinator(__first, __last, __value, __from_chars_atoi<__t>); 715d2748964SZhihao Yuan} 716d2748964SZhihao Yuan 717769c2459SMarshall Clowtemplate <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0> 7183925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI from_chars_result 719d2748964SZhihao Yuan__from_chars_integral(const char* __first, const char* __last, _Tp& __value, 720d2748964SZhihao Yuan int __base) 721d2748964SZhihao Yuan{ 722d2748964SZhihao Yuan if (__base == 10) 723d2748964SZhihao Yuan return __from_chars_atoi(__first, __last, __value); 724d2748964SZhihao Yuan 725d2748964SZhihao Yuan return __subject_seq_combinator( 726d2748964SZhihao Yuan __first, __last, __value, 727e39095a3SLouis Dionne [](const char* __p, const char* __lastp, _Tp& __val, 728b48c5010SNikolas Klauser int __b) -> from_chars_result { 729d2748964SZhihao Yuan using __tl = numeric_limits<_Tp>; 730b48c5010SNikolas Klauser auto __digits = __tl::digits / log2f(float(__b)); 731b48c5010SNikolas Klauser _Tp __x = __in_pattern(*__p++, __b).__val, __y = 0; 732d2748964SZhihao Yuan 733e39095a3SLouis Dionne for (int __i = 1; __p != __lastp; ++__i, ++__p) 734d2748964SZhihao Yuan { 735b48c5010SNikolas Klauser if (auto __c = __in_pattern(*__p, __b)) 736d2748964SZhihao Yuan { 737d2748964SZhihao Yuan if (__i < __digits - 1) 738b48c5010SNikolas Klauser __x = __x * __b + __c.__val; 739d2748964SZhihao Yuan else 740d2748964SZhihao Yuan { 741b48c5010SNikolas Klauser if (!__itoa::__mul_overflowed(__x, __b, __x)) 742d2748964SZhihao Yuan ++__p; 743b48c5010SNikolas Klauser __y = __c.__val; 744d2748964SZhihao Yuan break; 745d2748964SZhihao Yuan } 746d2748964SZhihao Yuan } 747d2748964SZhihao Yuan else 748d2748964SZhihao Yuan break; 749d2748964SZhihao Yuan } 750d2748964SZhihao Yuan 751b48c5010SNikolas Klauser if (__p == __lastp || !__in_pattern(*__p, __b)) 752d2748964SZhihao Yuan { 753b48c5010SNikolas Klauser if (__tl::max() - __x >= __y) 754d2748964SZhihao Yuan { 755b48c5010SNikolas Klauser __val = __x + __y; 756d2748964SZhihao Yuan return {__p, {}}; 757d2748964SZhihao Yuan } 758d2748964SZhihao Yuan } 759d2748964SZhihao Yuan return {__p, errc::result_out_of_range}; 760d2748964SZhihao Yuan }, 761d2748964SZhihao Yuan __base); 762d2748964SZhihao Yuan} 763d2748964SZhihao Yuan 764769c2459SMarshall Clowtemplate <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0> 7653925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI from_chars_result 766d2748964SZhihao Yuan__from_chars_integral(const char* __first, const char* __last, _Tp& __value, 767d2748964SZhihao Yuan int __base) 768d2748964SZhihao Yuan{ 769c273f5efSMark de Wever using __t = decltype(__to_unsigned_like(__value)); 770d2748964SZhihao Yuan return __sign_combinator(__first, __last, __value, 771d2748964SZhihao Yuan __from_chars_integral<__t>, __base); 772d2748964SZhihao Yuan} 773d2748964SZhihao Yuan 774769c2459SMarshall Clowtemplate <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> 7753925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI from_chars_result 776d2748964SZhihao Yuanfrom_chars(const char* __first, const char* __last, _Tp& __value) 777d2748964SZhihao Yuan{ 778d2748964SZhihao Yuan return __from_chars_atoi(__first, __last, __value); 779d2748964SZhihao Yuan} 780d2748964SZhihao Yuan 781769c2459SMarshall Clowtemplate <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> 7823925f98dSMark de Weverinline _LIBCPP_HIDE_FROM_ABI from_chars_result 783d2748964SZhihao Yuanfrom_chars(const char* __first, const char* __last, _Tp& __value, int __base) 784d2748964SZhihao Yuan{ 785d2748964SZhihao Yuan _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]"); 786d2748964SZhihao Yuan return __from_chars_integral(__first, __last, __value, __base); 787d2748964SZhihao Yuan} 788d2748964SZhihao Yuan 789abb5dd6eSMark de Wever// Floating-point implementation starts here. 790abb5dd6eSMark de Wever// Unlike the other parts of charconv this is only available in C++17 and newer. 791abb5dd6eSMark de Wever#if _LIBCPP_STD_VER > 14 792abb5dd6eSMark de Wever 793abb5dd6eSMark de Wever_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS 794abb5dd6eSMark de Weverto_chars_result to_chars(char* __first, char* __last, float __value); 795abb5dd6eSMark de Wever 796abb5dd6eSMark de Wever_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS 797abb5dd6eSMark de Weverto_chars_result to_chars(char* __first, char* __last, double __value); 798abb5dd6eSMark de Wever 799abb5dd6eSMark de Wever_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS 800abb5dd6eSMark de Weverto_chars_result to_chars(char* __first, char* __last, long double __value); 801abb5dd6eSMark de Wever 802abb5dd6eSMark de Wever_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS 803abb5dd6eSMark de Weverto_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt); 804abb5dd6eSMark de Wever 805abb5dd6eSMark de Wever_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS 806abb5dd6eSMark de Weverto_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt); 807abb5dd6eSMark de Wever 808abb5dd6eSMark de Wever_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS 809abb5dd6eSMark de Weverto_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt); 810abb5dd6eSMark de Wever 811abb5dd6eSMark de Wever_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS 812abb5dd6eSMark de Weverto_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt, int __precision); 813abb5dd6eSMark de Wever 814abb5dd6eSMark de Wever_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS 815abb5dd6eSMark de Weverto_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt, int __precision); 816abb5dd6eSMark de Wever 817abb5dd6eSMark de Wever_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS 818abb5dd6eSMark de Weverto_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt, int __precision); 819abb5dd6eSMark de Wever 820abb5dd6eSMark de Wever# endif // _LIBCPP_STD_VER > 14 821769c2459SMarshall Clow#endif // _LIBCPP_CXX03_LANG 822d2748964SZhihao Yuan 823d2748964SZhihao Yuan_LIBCPP_END_NAMESPACE_STD 824d2748964SZhihao Yuan 82527e9fdb2SMarshall Clow_LIBCPP_POP_MACROS 82627e9fdb2SMarshall Clow 827d2748964SZhihao Yuan#endif // _LIBCPP_CHARCONV 828