Mercurial > hg > CbC > CbC_llvm
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 |