comparison libcxx/include/charconv @ 236:c4bab56944e8 llvm-original

LLVM 16
author kono
date Wed, 09 Nov 2022 17:45:10 +0900
parents 79ff65ed7e25
children 1f2b6ac9f198
comparison
equal deleted inserted replaced
232:70dce7da266c 236:c4bab56944e8
1 // -*- C++ -*- 1 // -*- C++ -*-
2 //===------------------------------ charconv ------------------------------===// 2 //===----------------------------------------------------------------------===//
3 // 3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information. 5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 // 7 //
25 25
26 // 23.20.2, primitive numerical output conversion 26 // 23.20.2, primitive numerical output conversion
27 struct to_chars_result { 27 struct to_chars_result {
28 char* ptr; 28 char* ptr;
29 errc ec; 29 errc ec;
30 friend bool operator==(const to_chars_result&, const to_chars_result&) = default; // since C++20
30 }; 31 };
31 32
32 to_chars_result to_chars(char* first, char* last, see below value, 33 constexpr to_chars_result to_chars(char* first, char* last, see below value,
33 int base = 10); 34 int base = 10); // constexpr since C++23
35 to_chars_result to_chars(char* first, char* last, bool value,
36 int base = 10) = delete;
34 37
35 to_chars_result to_chars(char* first, char* last, float value); 38 to_chars_result to_chars(char* first, char* last, float value);
36 to_chars_result to_chars(char* first, char* last, double value); 39 to_chars_result to_chars(char* first, char* last, double value);
37 to_chars_result to_chars(char* first, char* last, long double value); 40 to_chars_result to_chars(char* first, char* last, long double value);
38 41
52 55
53 // 23.20.3, primitive numerical input conversion 56 // 23.20.3, primitive numerical input conversion
54 struct from_chars_result { 57 struct from_chars_result {
55 const char* ptr; 58 const char* ptr;
56 errc ec; 59 errc ec;
60 friend bool operator==(const from_chars_result&, const from_chars_result&) = default; // since C++20
57 }; 61 };
58 62
59 from_chars_result from_chars(const char* first, const char* last, 63 constexpr from_chars_result from_chars(const char* first, const char* last,
60 see below& value, int base = 10); 64 see below& value, int base = 10); // constexpr since C++23
61 65
62 from_chars_result from_chars(const char* first, const char* last, 66 from_chars_result from_chars(const char* first, const char* last,
63 float& value, 67 float& value,
64 chars_format fmt = chars_format::general); 68 chars_format fmt = chars_format::general);
65 from_chars_result from_chars(const char* first, const char* last, 69 from_chars_result from_chars(const char* first, const char* last,
71 75
72 } // namespace std 76 } // namespace std
73 77
74 */ 78 */
75 79
80 #include <__algorithm/copy_n.h>
81 #include <__assert> // all public C++ headers provide the assertion handler
76 #include <__availability> 82 #include <__availability>
83 #include <__bits>
84 #include <__charconv/chars_format.h>
85 #include <__charconv/from_chars_result.h>
86 #include <__charconv/tables.h>
87 #include <__charconv/to_chars_base_10.h>
88 #include <__charconv/to_chars_result.h>
77 #include <__config> 89 #include <__config>
90 #include <__debug>
78 #include <__errc> 91 #include <__errc>
79 #include <__utility/to_underlying.h> 92 #include <__memory/addressof.h>
93 #include <__type_traits/make_32_64_or_128_bit.h>
94 #include <__utility/unreachable.h>
80 #include <cmath> // for log2f 95 #include <cmath> // for log2f
81 #include <cstdint> 96 #include <cstdint>
82 #include <cstdlib> // for _LIBCPP_UNREACHABLE 97 #include <cstdlib>
83 #include <cstring> 98 #include <cstring>
84 #include <limits> 99 #include <limits>
85 #include <type_traits> 100 #include <type_traits>
86 101
87 #include <__debug>
88
89 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 102 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
90 #pragma GCC system_header 103 # pragma GCC system_header
91 #endif 104 #endif
92 105
93 _LIBCPP_PUSH_MACROS 106 _LIBCPP_PUSH_MACROS
94 #include <__undef_macros> 107 #include <__undef_macros>
95 108
96 _LIBCPP_BEGIN_NAMESPACE_STD 109 _LIBCPP_BEGIN_NAMESPACE_STD
97 110
98 namespace __itoa { 111 #if _LIBCPP_STD_VER > 14
99 _LIBCPP_AVAILABILITY_TO_CHARS _LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer) _NOEXCEPT; 112
100 _LIBCPP_AVAILABILITY_TO_CHARS _LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer) _NOEXCEPT; 113 to_chars_result to_chars(char*, char*, bool, int = 10) = delete;
101 } 114 from_chars_result from_chars(const char*, const char*, bool, int = 10) = delete;
102 115
103 #ifndef _LIBCPP_CXX03_LANG 116 namespace __itoa
104 117 {
105 enum class _LIBCPP_ENUM_VIS chars_format 118
106 { 119 template <typename _Tp, typename = void>
107 scientific = 0x1, 120 struct _LIBCPP_HIDDEN __traits_base;
108 fixed = 0x2, 121
109 hex = 0x4, 122 template <typename _Tp>
110 general = fixed | scientific 123 struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) <= sizeof(uint32_t)>>
124 {
125 using type = uint32_t;
126
127 /// The width estimation using a log10 algorithm.
128 ///
129 /// The algorithm is based on
130 /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
131 /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that
132 /// function requires its input to have at least one bit set the value of
133 /// zero is set to one. This means the first element of the lookup table is
134 /// zero.
135 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v)
136 {
137 auto __t = (32 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
138 return __t - (__v < __itoa::__pow10_32[__t]) + 1;
139 }
140
141 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v)
142 {
143 return __itoa::__base_10_u32(__p, __v);
144 }
145
146 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_32)& __pow() { return __itoa::__pow10_32; }
111 }; 147 };
112 148
113 inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format 149 template <typename _Tp>
114 operator~(chars_format __x) { 150 struct _LIBCPP_HIDDEN
115 return chars_format(~_VSTD::__to_underlying(__x)); 151 __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(uint64_t)>> {
116 } 152 using type = uint64_t;
117 153
118 inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format 154 /// The width estimation using a log10 algorithm.
119 operator&(chars_format __x, chars_format __y) { 155 ///
120 return chars_format(_VSTD::__to_underlying(__x) & 156 /// The algorithm is based on
121 _VSTD::__to_underlying(__y)); 157 /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
122 } 158 /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that
123 159 /// function requires its input to have at least one bit set the value of
124 inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format 160 /// zero is set to one. This means the first element of the lookup table is
125 operator|(chars_format __x, chars_format __y) { 161 /// zero.
126 return chars_format(_VSTD::__to_underlying(__x) | 162 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) {
127 _VSTD::__to_underlying(__y)); 163 auto __t = (64 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12;
128 } 164 return __t - (__v < __itoa::__pow10_64[__t]) + 1;
129 165 }
130 inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format 166
131 operator^(chars_format __x, chars_format __y) { 167 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) { return __itoa::__base_10_u64(__p, __v); }
132 return chars_format(_VSTD::__to_underlying(__x) ^ 168
133 _VSTD::__to_underlying(__y)); 169 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_64)& __pow() { return __itoa::__pow10_64; }
134 }
135
136 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 chars_format&
137 operator&=(chars_format& __x, chars_format __y) {
138 __x = __x & __y;
139 return __x;
140 }
141
142 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 chars_format&
143 operator|=(chars_format& __x, chars_format __y) {
144 __x = __x | __y;
145 return __x;
146 }
147
148 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 chars_format&
149 operator^=(chars_format& __x, chars_format __y) {
150 __x = __x ^ __y;
151 return __x;
152 }
153
154 struct _LIBCPP_TYPE_VIS to_chars_result
155 {
156 char* ptr;
157 errc ec;
158 }; 170 };
159 171
160 struct _LIBCPP_TYPE_VIS from_chars_result 172
161 { 173 # ifndef _LIBCPP_HAS_NO_INT128
162 const char* ptr; 174 template <typename _Tp>
163 errc ec; 175 struct _LIBCPP_HIDDEN
176 __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(__uint128_t)> > {
177 using type = __uint128_t;
178
179 /// The width estimation using a log10 algorithm.
180 ///
181 /// The algorithm is based on
182 /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
183 /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that
184 /// function requires its input to have at least one bit set the value of
185 /// zero is set to one. This means the first element of the lookup table is
186 /// zero.
187 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) {
188 _LIBCPP_ASSERT(__v > numeric_limits<uint64_t>::max(), "The optimizations for this algorithm fail when this isn't true.");
189 // There's always a bit set in the upper 64-bits.
190 auto __t = (128 - std::__libcpp_clz(static_cast<uint64_t>(__v >> 64))) * 1233 >> 12;
191 _LIBCPP_ASSERT(__t >= __itoa::__pow10_128_offset, "Index out of bounds");
192 // __t is adjusted since the lookup table misses the lower entries.
193 return __t - (__v < __itoa::__pow10_128[__t - __itoa::__pow10_128_offset]) + 1;
194 }
195
196 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) { return __itoa::__base_10_u128(__p, __v); }
197
198 // TODO FMT This pow function should get an index.
199 // By moving this to its own header it can be reused by the pow function in to_chars_base_10.
200 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_128)& __pow() { return __itoa::__pow10_128; }
164 }; 201 };
165
166 void to_chars(char*, char*, bool, int = 10) = delete;
167 void from_chars(const char*, const char*, bool, int = 10) = delete;
168
169 namespace __itoa
170 {
171
172 static _LIBCPP_CONSTEXPR uint64_t __pow10_64[] = {
173 UINT64_C(0),
174 UINT64_C(10),
175 UINT64_C(100),
176 UINT64_C(1000),
177 UINT64_C(10000),
178 UINT64_C(100000),
179 UINT64_C(1000000),
180 UINT64_C(10000000),
181 UINT64_C(100000000),
182 UINT64_C(1000000000),
183 UINT64_C(10000000000),
184 UINT64_C(100000000000),
185 UINT64_C(1000000000000),
186 UINT64_C(10000000000000),
187 UINT64_C(100000000000000),
188 UINT64_C(1000000000000000),
189 UINT64_C(10000000000000000),
190 UINT64_C(100000000000000000),
191 UINT64_C(1000000000000000000),
192 UINT64_C(10000000000000000000),
193 };
194
195 static _LIBCPP_CONSTEXPR uint32_t __pow10_32[] = {
196 UINT32_C(0), UINT32_C(10), UINT32_C(100),
197 UINT32_C(1000), UINT32_C(10000), UINT32_C(100000),
198 UINT32_C(1000000), UINT32_C(10000000), UINT32_C(100000000),
199 UINT32_C(1000000000),
200 };
201
202 template <typename _Tp, typename = void>
203 struct _LIBCPP_HIDDEN __traits_base
204 {
205 using type = uint64_t;
206
207 #if !defined(_LIBCPP_COMPILER_MSVC)
208 static _LIBCPP_INLINE_VISIBILITY int __width(_Tp __v)
209 {
210 auto __t = (64 - __builtin_clzll(__v | 1)) * 1233 >> 12;
211 return __t - (__v < __pow10_64[__t]) + 1;
212 }
213 #endif 202 #endif
214 203
215 _LIBCPP_AVAILABILITY_TO_CHARS 204 template <typename _Tp>
216 static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p) 205 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
217 {
218 return __u64toa(__v, __p);
219 }
220
221 static _LIBCPP_INLINE_VISIBILITY decltype(__pow10_64)& __pow() { return __pow10_64; }
222 };
223
224 template <typename _Tp>
225 struct _LIBCPP_HIDDEN
226 __traits_base<_Tp, decltype(void(uint32_t{declval<_Tp>()}))>
227 {
228 using type = uint32_t;
229
230 #if !defined(_LIBCPP_COMPILER_MSVC)
231 static _LIBCPP_INLINE_VISIBILITY int __width(_Tp __v)
232 {
233 auto __t = (32 - __builtin_clz(__v | 1)) * 1233 >> 12;
234 return __t - (__v < __pow10_32[__t]) + 1;
235 }
236 #endif
237
238 _LIBCPP_AVAILABILITY_TO_CHARS
239 static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p)
240 {
241 return __u32toa(__v, __p);
242 }
243
244 static _LIBCPP_INLINE_VISIBILITY decltype(__pow10_32)& __pow() { return __pow10_32; }
245 };
246
247 template <typename _Tp>
248 inline _LIBCPP_INLINE_VISIBILITY bool
249 __mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r) 206 __mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r)
250 { 207 {
251 auto __c = __a * __b; 208 auto __c = __a * __b;
252 __r = __c; 209 __r = __c;
253 return __c > numeric_limits<unsigned char>::max(); 210 return __c > numeric_limits<unsigned char>::max();
254 } 211 }
255 212
256 template <typename _Tp> 213 template <typename _Tp>
257 inline _LIBCPP_INLINE_VISIBILITY bool 214 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
258 __mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r) 215 __mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r)
259 { 216 {
260 auto __c = __a * __b; 217 auto __c = __a * __b;
261 __r = __c; 218 __r = __c;
262 return __c > numeric_limits<unsigned short>::max(); 219 return __c > numeric_limits<unsigned short>::max();
263 } 220 }
264 221
265 template <typename _Tp> 222 template <typename _Tp>
266 inline _LIBCPP_INLINE_VISIBILITY bool 223 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
267 __mul_overflowed(_Tp __a, _Tp __b, _Tp& __r) 224 __mul_overflowed(_Tp __a, _Tp __b, _Tp& __r)
268 { 225 {
269 static_assert(is_unsigned<_Tp>::value, ""); 226 static_assert(is_unsigned<_Tp>::value, "");
270 #if !defined(_LIBCPP_COMPILER_MSVC)
271 return __builtin_mul_overflow(__a, __b, &__r); 227 return __builtin_mul_overflow(__a, __b, &__r);
272 #else
273 bool __did = __b && (numeric_limits<_Tp>::max() / __b) < __a;
274 __r = __a * __b;
275 return __did;
276 #endif
277 } 228 }
278 229
279 template <typename _Tp, typename _Up> 230 template <typename _Tp, typename _Up>
280 inline _LIBCPP_INLINE_VISIBILITY bool 231 inline _LIBCPP_HIDE_FROM_ABI bool
281 __mul_overflowed(_Tp __a, _Up __b, _Tp& __r) 232 _LIBCPP_CONSTEXPR_SINCE_CXX23 __mul_overflowed(_Tp __a, _Up __b, _Tp& __r)
282 { 233 {
283 return __mul_overflowed(__a, static_cast<_Tp>(__b), __r); 234 return __mul_overflowed(__a, static_cast<_Tp>(__b), __r);
284 } 235 }
285 236
286 template <typename _Tp> 237 template <typename _Tp>
287 struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp> 238 struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp>
288 { 239 {
289 static _LIBCPP_CONSTEXPR int digits = numeric_limits<_Tp>::digits10 + 1; 240 static constexpr int digits = numeric_limits<_Tp>::digits10 + 1;
290 using __traits_base<_Tp>::__pow; 241 using __traits_base<_Tp>::__pow;
291 using typename __traits_base<_Tp>::type; 242 using typename __traits_base<_Tp>::type;
292 243
293 // precondition: at least one non-zero character available 244 // precondition: at least one non-zero character available
294 static _LIBCPP_INLINE_VISIBILITY char const* 245 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char const*
295 __read(char const* __p, char const* __ep, type& __a, type& __b) 246 __read(char const* __p, char const* __ep, type& __a, type& __b)
296 { 247 {
297 type __cprod[digits]; 248 type __cprod[digits];
298 int __j = digits - 1; 249 int __j = digits - 1;
299 int __i = digits; 250 int __i = digits;
310 --__p; 261 --__p;
311 return __p; 262 return __p;
312 } 263 }
313 264
314 template <typename _It1, typename _It2, class _Up> 265 template <typename _It1, typename _It2, class _Up>
315 static _LIBCPP_INLINE_VISIBILITY _Up 266 static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _Up
316 __inner_product(_It1 __first1, _It1 __last1, _It2 __first2, _Up __init) 267 __inner_product(_It1 __first1, _It1 __last1, _It2 __first2, _Up __init)
317 { 268 {
318 for (; __first1 < __last1; ++__first1, ++__first2) 269 for (; __first1 < __last1; ++__first1, ++__first2)
319 __init = __init + *__first1 * *__first2; 270 __init = __init + *__first1 * *__first2;
320 return __init; 271 return __init;
322 }; 273 };
323 274
324 } // namespace __itoa 275 } // namespace __itoa
325 276
326 template <typename _Tp> 277 template <typename _Tp>
327 inline _LIBCPP_INLINE_VISIBILITY _Tp 278 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _Tp
328 __complement(_Tp __x) 279 __complement(_Tp __x)
329 { 280 {
330 static_assert(is_unsigned<_Tp>::value, "cast to unsigned first"); 281 static_assert(is_unsigned<_Tp>::value, "cast to unsigned first");
331 return _Tp(~__x + 1); 282 return _Tp(~__x + 1);
332 } 283 }
333 284
334 template <typename _Tp> 285 template <typename _Tp>
335 _LIBCPP_AVAILABILITY_TO_CHARS 286 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
336 inline _LIBCPP_INLINE_VISIBILITY to_chars_result
337 __to_chars_itoa(char* __first, char* __last, _Tp __value, true_type) 287 __to_chars_itoa(char* __first, char* __last, _Tp __value, true_type)
338 { 288 {
339 auto __x = __to_unsigned_like(__value); 289 auto __x = __to_unsigned_like(__value);
340 if (__value < 0 && __first != __last) 290 if (__value < 0 && __first != __last)
341 { 291 {
345 295
346 return __to_chars_itoa(__first, __last, __x, false_type()); 296 return __to_chars_itoa(__first, __last, __x, false_type());
347 } 297 }
348 298
349 template <typename _Tp> 299 template <typename _Tp>
350 _LIBCPP_AVAILABILITY_TO_CHARS 300 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
351 inline _LIBCPP_INLINE_VISIBILITY to_chars_result
352 __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type) 301 __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type)
353 { 302 {
354 using __tx = __itoa::__traits<_Tp>; 303 using __tx = __itoa::__traits<_Tp>;
355 auto __diff = __last - __first; 304 auto __diff = __last - __first;
356 305
357 #if !defined(_LIBCPP_COMPILER_MSVC)
358 if (__tx::digits <= __diff || __tx::__width(__value) <= __diff) 306 if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
359 return {__tx::__convert(__value, __first), errc(0)}; 307 return {__tx::__convert(__first, __value), errc(0)};
360 else 308 else
361 return {__last, errc::value_too_large}; 309 return {__last, errc::value_too_large};
362 #else 310 }
363 if (__tx::digits <= __diff) 311
364 return {__tx::__convert(__value, __first), {}}; 312 # ifndef _LIBCPP_HAS_NO_INT128
313 template <>
314 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
315 __to_chars_itoa(char* __first, char* __last, __uint128_t __value, false_type)
316 {
317 // When the value fits in 64-bits use the 64-bit code path. This reduces
318 // the number of expensive calculations on 128-bit values.
319 //
320 // NOTE the 128-bit code path requires this optimization.
321 if(__value <= numeric_limits<uint64_t>::max())
322 return __to_chars_itoa(__first, __last, static_cast<uint64_t>(__value), false_type());
323
324 using __tx = __itoa::__traits<__uint128_t>;
325 auto __diff = __last - __first;
326
327 if (__tx::digits <= __diff || __tx::__width(__value) <= __diff)
328 return {__tx::__convert(__first, __value), errc(0)};
365 else 329 else
366 { 330 return {__last, errc::value_too_large};
367 char __buf[__tx::digits]; 331 }
368 auto __p = __tx::__convert(__value, __buf);
369 auto __len = __p - __buf;
370 if (__len <= __diff)
371 {
372 _VSTD::memcpy(__first, __buf, __len);
373 return {__first + __len, {}};
374 }
375 else
376 return {__last, errc::value_too_large};
377 }
378 #endif 332 #endif
379 } 333
380 334 template <typename _Tp>
381 template <typename _Tp> 335 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
382 _LIBCPP_AVAILABILITY_TO_CHARS
383 inline _LIBCPP_INLINE_VISIBILITY to_chars_result
384 __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, 336 __to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
385 true_type) 337 true_type)
386 { 338 {
387 auto __x = __to_unsigned_like(__value); 339 auto __x = __to_unsigned_like(__value);
388 if (__value < 0 && __first != __last) 340 if (__value < 0 && __first != __last)
392 } 344 }
393 345
394 return __to_chars_integral(__first, __last, __x, __base, false_type()); 346 return __to_chars_integral(__first, __last, __x, __base, false_type());
395 } 347 }
396 348
397 template <typename _Tp> 349 namespace __itoa {
398 _LIBCPP_AVAILABILITY_TO_CHARS _LIBCPP_INLINE_VISIBILITY int __to_chars_integral_width(_Tp __value, unsigned __base) { 350
351 template <unsigned _Base>
352 struct _LIBCPP_HIDDEN __integral;
353
354 template <>
355 struct _LIBCPP_HIDDEN __integral<2> {
356 template <typename _Tp>
357 _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
358 // If value == 0 still need one digit. If the value != this has no
359 // effect since the code scans for the most significant bit set. (Note
360 // that __libcpp_clz doesn't work for 0.)
361 return numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1);
362 }
363
364 template <typename _Tp>
365 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result __to_chars(char* __first, char* __last, _Tp __value) {
366 ptrdiff_t __cap = __last - __first;
367 int __n = __width(__value);
368 if (__n > __cap)
369 return {__last, errc::value_too_large};
370
371 __last = __first + __n;
372 char* __p = __last;
373 const unsigned __divisor = 16;
374 while (__value > __divisor) {
375 unsigned __c = __value % __divisor;
376 __value /= __divisor;
377 __p -= 4;
378 std::copy_n(&__base_2_lut[4 * __c], 4, __p);
379 }
380 do {
381 unsigned __c = __value % 2;
382 __value /= 2;
383 *--__p = "01"[__c];
384 } while (__value != 0);
385 return {__last, errc(0)};
386 }
387 };
388
389 template <>
390 struct _LIBCPP_HIDDEN __integral<8> {
391 template <typename _Tp>
392 _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
393 // If value == 0 still need one digit. If the value != this has no
394 // effect since the code scans for the most significat bit set. (Note
395 // that __libcpp_clz doesn't work for 0.)
396 return ((numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1)) + 2) / 3;
397 }
398
399 template <typename _Tp>
400 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result __to_chars(char* __first, char* __last, _Tp __value) {
401 ptrdiff_t __cap = __last - __first;
402 int __n = __width(__value);
403 if (__n > __cap)
404 return {__last, errc::value_too_large};
405
406 __last = __first + __n;
407 char* __p = __last;
408 unsigned __divisor = 64;
409 while (__value > __divisor) {
410 unsigned __c = __value % __divisor;
411 __value /= __divisor;
412 __p -= 2;
413 std::copy_n(&__base_8_lut[2 * __c], 2, __p);
414 }
415 do {
416 unsigned __c = __value % 8;
417 __value /= 8;
418 *--__p = "01234567"[__c];
419 } while (__value != 0);
420 return {__last, errc(0)};
421 }
422
423 };
424
425 template <>
426 struct _LIBCPP_HIDDEN __integral<16> {
427 template <typename _Tp>
428 _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept {
429 // If value == 0 still need one digit. If the value != this has no
430 // effect since the code scans for the most significat bit set. (Note
431 // that __libcpp_clz doesn't work for 0.)
432 return (numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1) + 3) / 4;
433 }
434
435 template <typename _Tp>
436 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result __to_chars(char* __first, char* __last, _Tp __value) {
437 ptrdiff_t __cap = __last - __first;
438 int __n = __width(__value);
439 if (__n > __cap)
440 return {__last, errc::value_too_large};
441
442 __last = __first + __n;
443 char* __p = __last;
444 unsigned __divisor = 256;
445 while (__value > __divisor) {
446 unsigned __c = __value % __divisor;
447 __value /= __divisor;
448 __p -= 2;
449 std::copy_n(&__base_16_lut[2 * __c], 2, __p);
450 }
451 if (__first != __last)
452 do {
453 unsigned __c = __value % 16;
454 __value /= 16;
455 *--__p = "0123456789abcdef"[__c];
456 } while (__value != 0);
457 return {__last, errc(0)};
458 }
459 };
460
461 } // namespace __itoa
462
463 template <unsigned _Base, typename _Tp,
464 typename enable_if<(sizeof(_Tp) >= sizeof(unsigned)), int>::type = 0>
465 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int
466 __to_chars_integral_width(_Tp __value) {
467 return __itoa::__integral<_Base>::__width(__value);
468 }
469
470 template <unsigned _Base, typename _Tp,
471 typename enable_if<(sizeof(_Tp) < sizeof(unsigned)), int>::type = 0>
472 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int
473 __to_chars_integral_width(_Tp __value) {
474 return std::__to_chars_integral_width<_Base>(static_cast<unsigned>(__value));
475 }
476
477 template <unsigned _Base, typename _Tp,
478 typename enable_if<(sizeof(_Tp) >= sizeof(unsigned)), int>::type = 0>
479 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
480 __to_chars_integral(char* __first, char* __last, _Tp __value) {
481 return __itoa::__integral<_Base>::__to_chars(__first, __last, __value);
482 }
483
484 template <unsigned _Base, typename _Tp,
485 typename enable_if<(sizeof(_Tp) < sizeof(unsigned)), int>::type = 0>
486 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
487 __to_chars_integral(char* __first, char* __last, _Tp __value) {
488 return std::__to_chars_integral<_Base>(__first, __last, static_cast<unsigned>(__value));
489 }
490
491 template <typename _Tp>
492 _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int
493 __to_chars_integral_width(_Tp __value, unsigned __base) {
399 _LIBCPP_ASSERT(__value >= 0, "The function requires a non-negative value."); 494 _LIBCPP_ASSERT(__value >= 0, "The function requires a non-negative value.");
400 495
401 unsigned __base_2 = __base * __base; 496 unsigned __base_2 = __base * __base;
402 unsigned __base_3 = __base_2 * __base; 497 unsigned __base_3 = __base_2 * __base;
403 unsigned __base_4 = __base_2 * __base_2; 498 unsigned __base_4 = __base_2 * __base_2;
415 510
416 __value /= __base_4; 511 __value /= __base_4;
417 __r += 4; 512 __r += 4;
418 } 513 }
419 514
420 _LIBCPP_UNREACHABLE(); 515 __libcpp_unreachable();
421 } 516 }
422 517
423 template <typename _Tp> 518 template <typename _Tp>
424 _LIBCPP_AVAILABILITY_TO_CHARS 519 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
425 inline _LIBCPP_INLINE_VISIBILITY to_chars_result
426 __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, 520 __to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
427 false_type) 521 false_type)
428 { 522 {
429 if (__base == 10) 523 if (__base == 10) [[likely]]
430 return __to_chars_itoa(__first, __last, __value, false_type()); 524 return __to_chars_itoa(__first, __last, __value, false_type());
525
526 switch (__base) {
527 case 2:
528 return __to_chars_integral<2>(__first, __last, __value);
529 case 8:
530 return __to_chars_integral<8>(__first, __last, __value);
531 case 16:
532 return __to_chars_integral<16>(__first, __last, __value);
533 }
431 534
432 ptrdiff_t __cap = __last - __first; 535 ptrdiff_t __cap = __last - __first;
433 int __n = __to_chars_integral_width(__value, __base); 536 int __n = __to_chars_integral_width(__value, __base);
434 if (__n > __cap) 537 if (__n > __cap)
435 return {__last, errc::value_too_large}; 538 return {__last, errc::value_too_large};
443 } while (__value != 0); 546 } while (__value != 0);
444 return {__last, errc(0)}; 547 return {__last, errc(0)};
445 } 548 }
446 549
447 template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> 550 template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
448 _LIBCPP_AVAILABILITY_TO_CHARS 551 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
449 inline _LIBCPP_INLINE_VISIBILITY to_chars_result
450 to_chars(char* __first, char* __last, _Tp __value) 552 to_chars(char* __first, char* __last, _Tp __value)
451 { 553 {
452 return __to_chars_itoa(__first, __last, __value, is_signed<_Tp>()); 554 using _Type = __make_32_64_or_128_bit_t<_Tp>;
555 static_assert(!is_same<_Type, void>::value, "unsupported integral type used in to_chars");
556 return std::__to_chars_itoa(__first, __last, static_cast<_Type>(__value), is_signed<_Tp>());
453 } 557 }
454 558
455 template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> 559 template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
456 _LIBCPP_AVAILABILITY_TO_CHARS 560 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
457 inline _LIBCPP_INLINE_VISIBILITY to_chars_result
458 to_chars(char* __first, char* __last, _Tp __value, int __base) 561 to_chars(char* __first, char* __last, _Tp __value, int __base)
459 { 562 {
460 _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]"); 563 _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
461 return __to_chars_integral(__first, __last, __value, __base, 564
462 is_signed<_Tp>()); 565 using _Type = __make_32_64_or_128_bit_t<_Tp>;
566 return std::__to_chars_integral(__first, __last, static_cast<_Type>(__value), __base, is_signed<_Tp>());
463 } 567 }
464 568
465 template <typename _It, typename _Tp, typename _Fn, typename... _Ts> 569 template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
466 inline _LIBCPP_INLINE_VISIBILITY from_chars_result 570 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
467 __sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args) 571 __sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args)
468 { 572 {
469 using __tl = numeric_limits<_Tp>; 573 using __tl = numeric_limits<_Tp>;
470 decltype(__to_unsigned_like(__value)) __x; 574 decltype(__to_unsigned_like(__value)) __x;
471 575
484 if (__neg) 588 if (__neg)
485 { 589 {
486 if (__x <= __complement(__to_unsigned_like(__tl::min()))) 590 if (__x <= __complement(__to_unsigned_like(__tl::min())))
487 { 591 {
488 __x = __complement(__x); 592 __x = __complement(__x);
489 _VSTD::memcpy(&__value, &__x, sizeof(__x)); 593 std::copy_n(std::addressof(__x), 1, std::addressof(__value));
490 return __r; 594 return __r;
491 } 595 }
492 } 596 }
493 else 597 else
494 { 598 {
495 if (__x <= __tl::max()) 599 if (__x <= __to_unsigned_like(__tl::max()))
496 { 600 {
497 __value = __x; 601 __value = __x;
498 return __r; 602 return __r;
499 } 603 }
500 } 604 }
501 605
502 return {__r.ptr, errc::result_out_of_range}; 606 return {__r.ptr, errc::result_out_of_range};
503 } 607 }
504 608
505 template <typename _Tp> 609 template <typename _Tp>
506 inline _LIBCPP_INLINE_VISIBILITY bool 610 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool
507 __in_pattern(_Tp __c) 611 __in_pattern(_Tp __c)
508 { 612 {
509 return '0' <= __c && __c <= '9'; 613 return '0' <= __c && __c <= '9';
510 } 614 }
511 615
512 struct _LIBCPP_HIDDEN __in_pattern_result 616 struct _LIBCPP_HIDDEN __in_pattern_result
513 { 617 {
514 bool __ok; 618 bool __ok;
515 int __val; 619 int __val;
516 620
517 explicit _LIBCPP_INLINE_VISIBILITY operator bool() const { return __ok; } 621 explicit _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI operator bool() const { return __ok; }
518 }; 622 };
519 623
520 template <typename _Tp> 624 template <typename _Tp>
521 inline _LIBCPP_INLINE_VISIBILITY __in_pattern_result 625 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI __in_pattern_result
522 __in_pattern(_Tp __c, int __base) 626 __in_pattern(_Tp __c, int __base)
523 { 627 {
524 if (__base <= 10) 628 if (__base <= 10)
525 return {'0' <= __c && __c < '0' + __base, __c - '0'}; 629 return {'0' <= __c && __c < '0' + __base, __c - '0'};
526 else if (__in_pattern(__c)) 630 else if (__in_pattern(__c))
530 else 634 else
531 return {'A' <= __c && __c < 'A' + __base - 10, __c - 'A' + 10}; 635 return {'A' <= __c && __c < 'A' + __base - 10, __c - 'A' + 10};
532 } 636 }
533 637
534 template <typename _It, typename _Tp, typename _Fn, typename... _Ts> 638 template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
535 inline _LIBCPP_INLINE_VISIBILITY from_chars_result 639 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
536 __subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, 640 __subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f,
537 _Ts... __args) 641 _Ts... __args)
538 { 642 {
539 auto __find_non_zero = [](_It __first, _It __last) { 643 auto __find_non_zero = [](_It __firstit, _It __lastit) {
540 for (; __first != __last; ++__first) 644 for (; __firstit != __lastit; ++__firstit)
541 if (*__first != '0') 645 if (*__firstit != '0')
542 break; 646 break;
543 return __first; 647 return __firstit;
544 }; 648 };
545 649
546 auto __p = __find_non_zero(__first, __last); 650 auto __p = __find_non_zero(__first, __last);
547 if (__p == __last || !__in_pattern(*__p, __args...)) 651 if (__p == __last || !__in_pattern(*__p, __args...))
548 { 652 {
567 671
568 return __r; 672 return __r;
569 } 673 }
570 674
571 template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0> 675 template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0>
572 inline _LIBCPP_INLINE_VISIBILITY from_chars_result 676 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
573 __from_chars_atoi(const char* __first, const char* __last, _Tp& __value) 677 __from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
574 { 678 {
575 using __tx = __itoa::__traits<_Tp>; 679 using __tx = __itoa::__traits<_Tp>;
576 using __output_type = typename __tx::type; 680 using __output_type = typename __tx::type;
577 681
578 return __subject_seq_combinator( 682 return __subject_seq_combinator(
579 __first, __last, __value, 683 __first, __last, __value,
580 [](const char* __first, const char* __last, 684 [](const char* __f, const char* __l,
581 _Tp& __value) -> from_chars_result { 685 _Tp& __val) -> from_chars_result {
582 __output_type __a, __b; 686 __output_type __a, __b;
583 auto __p = __tx::__read(__first, __last, __a, __b); 687 auto __p = __tx::__read(__f, __l, __a, __b);
584 if (__p == __last || !__in_pattern(*__p)) 688 if (__p == __l || !__in_pattern(*__p))
585 { 689 {
586 __output_type __m = numeric_limits<_Tp>::max(); 690 __output_type __m = numeric_limits<_Tp>::max();
587 if (__m >= __a && __m - __a >= __b) 691 if (__m >= __a && __m - __a >= __b)
588 { 692 {
589 __value = __a + __b; 693 __val = __a + __b;
590 return {__p, {}}; 694 return {__p, {}};
591 } 695 }
592 } 696 }
593 return {__p, errc::result_out_of_range}; 697 return {__p, errc::result_out_of_range};
594 }); 698 });
595 } 699 }
596 700
597 template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0> 701 template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0>
598 inline _LIBCPP_INLINE_VISIBILITY from_chars_result 702 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
599 __from_chars_atoi(const char* __first, const char* __last, _Tp& __value) 703 __from_chars_atoi(const char* __first, const char* __last, _Tp& __value)
600 { 704 {
601 using __t = decltype(__to_unsigned_like(__value)); 705 using __t = decltype(__to_unsigned_like(__value));
602 return __sign_combinator(__first, __last, __value, __from_chars_atoi<__t>); 706 return __sign_combinator(__first, __last, __value, __from_chars_atoi<__t>);
603 } 707 }
604 708
709
710 /*
711 // Code used to generate __from_chars_log2f_lut.
712 #include <cmath>
713 #include <iostream>
714 #include <format>
715
716 int main() {
717 for (int i = 2; i <= 36; ++i)
718 std::cout << std::format("{},\n", log2f(i));
719 }
720 */
721 /// log2f table for bases [2, 36].
722 inline constexpr float __from_chars_log2f_lut[35] = {
723 1, 1.5849625, 2, 2.321928, 2.5849626, 2.807355, 3, 3.169925, 3.321928,
724 3.4594316, 3.5849626, 3.7004397, 3.807355, 3.9068906, 4, 4.087463, 4.169925, 4.2479277,
725 4.321928, 4.3923173, 4.4594316, 4.523562, 4.5849624, 4.643856, 4.70044, 4.7548876, 4.807355,
726 4.857981, 4.9068904, 4.9541965, 5, 5.044394, 5.087463, 5.129283, 5.169925};
727
605 template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0> 728 template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0>
606 inline _LIBCPP_INLINE_VISIBILITY from_chars_result 729 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
607 __from_chars_integral(const char* __first, const char* __last, _Tp& __value, 730 __from_chars_integral(const char* __first, const char* __last, _Tp& __value,
608 int __base) 731 int __base)
609 { 732 {
610 if (__base == 10) 733 if (__base == 10)
611 return __from_chars_atoi(__first, __last, __value); 734 return __from_chars_atoi(__first, __last, __value);
612 735
613 return __subject_seq_combinator( 736 return __subject_seq_combinator(
614 __first, __last, __value, 737 __first, __last, __value,
615 [](const char* __p, const char* __last, _Tp& __value, 738 [](const char* __p, const char* __lastp, _Tp& __val,
616 int __base) -> from_chars_result { 739 int __b) -> from_chars_result {
617 using __tl = numeric_limits<_Tp>; 740 using __tl = numeric_limits<_Tp>;
618 auto __digits = __tl::digits / log2f(float(__base)); 741 // __base is always between 2 and 36 inclusive.
619 _Tp __a = __in_pattern(*__p++, __base).__val, __b = 0; 742 auto __digits = __tl::digits / __from_chars_log2f_lut[__b - 2];
620 743 _Tp __x = __in_pattern(*__p++, __b).__val, __y = 0;
621 for (int __i = 1; __p != __last; ++__i, ++__p) 744
745 for (int __i = 1; __p != __lastp; ++__i, ++__p)
622 { 746 {
623 if (auto __c = __in_pattern(*__p, __base)) 747 if (auto __c = __in_pattern(*__p, __b))
624 { 748 {
625 if (__i < __digits - 1) 749 if (__i < __digits - 1)
626 __a = __a * __base + __c.__val; 750 __x = __x * __b + __c.__val;
627 else 751 else
628 { 752 {
629 if (!__itoa::__mul_overflowed(__a, __base, __a)) 753 if (!__itoa::__mul_overflowed(__x, __b, __x))
630 ++__p; 754 ++__p;
631 __b = __c.__val; 755 __y = __c.__val;
632 break; 756 break;
633 } 757 }
634 } 758 }
635 else 759 else
636 break; 760 break;
637 } 761 }
638 762
639 if (__p == __last || !__in_pattern(*__p, __base)) 763 if (__p == __lastp || !__in_pattern(*__p, __b))
640 { 764 {
641 if (__tl::max() - __a >= __b) 765 if (__tl::max() - __x >= __y)
642 { 766 {
643 __value = __a + __b; 767 __val = __x + __y;
644 return {__p, {}}; 768 return {__p, {}};
645 } 769 }
646 } 770 }
647 return {__p, errc::result_out_of_range}; 771 return {__p, errc::result_out_of_range};
648 }, 772 },
649 __base); 773 __base);
650 } 774 }
651 775
652 template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0> 776 template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0>
653 inline _LIBCPP_INLINE_VISIBILITY from_chars_result 777 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
654 __from_chars_integral(const char* __first, const char* __last, _Tp& __value, 778 __from_chars_integral(const char* __first, const char* __last, _Tp& __value,
655 int __base) 779 int __base)
656 { 780 {
657 using __t = decltype(__to_unsigned_like(__value)); 781 using __t = decltype(__to_unsigned_like(__value));
658 return __sign_combinator(__first, __last, __value, 782 return __sign_combinator(__first, __last, __value,
659 __from_chars_integral<__t>, __base); 783 __from_chars_integral<__t>, __base);
660 } 784 }
661 785
662 template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> 786 template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
663 inline _LIBCPP_INLINE_VISIBILITY from_chars_result 787 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
664 from_chars(const char* __first, const char* __last, _Tp& __value) 788 from_chars(const char* __first, const char* __last, _Tp& __value)
665 { 789 {
666 return __from_chars_atoi(__first, __last, __value); 790 return __from_chars_atoi(__first, __last, __value);
667 } 791 }
668 792
669 template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> 793 template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
670 inline _LIBCPP_INLINE_VISIBILITY from_chars_result 794 inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result
671 from_chars(const char* __first, const char* __last, _Tp& __value, int __base) 795 from_chars(const char* __first, const char* __last, _Tp& __value, int __base)
672 { 796 {
673 _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]"); 797 _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]");
674 return __from_chars_integral(__first, __last, __value, __base); 798 return __from_chars_integral(__first, __last, __value, __base);
675 } 799 }
676 800
677 #endif // _LIBCPP_CXX03_LANG 801 _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
802 to_chars_result to_chars(char* __first, char* __last, float __value);
803
804 _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
805 to_chars_result to_chars(char* __first, char* __last, double __value);
806
807 _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
808 to_chars_result to_chars(char* __first, char* __last, long double __value);
809
810 _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
811 to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt);
812
813 _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
814 to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt);
815
816 _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
817 to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt);
818
819 _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
820 to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt, int __precision);
821
822 _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
823 to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt, int __precision);
824
825 _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
826 to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt, int __precision);
827
828 #endif // _LIBCPP_STD_VER > 14
678 829
679 _LIBCPP_END_NAMESPACE_STD 830 _LIBCPP_END_NAMESPACE_STD
680 831
681 _LIBCPP_POP_MACROS 832 _LIBCPP_POP_MACROS
682 833
834 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
835 # include <iosfwd>
836 #endif
837
683 #endif // _LIBCPP_CHARCONV 838 #endif // _LIBCPP_CHARCONV