/src/rust-lexical/lexical-parse-float/src/parse.rs
Line | Count | Source |
1 | | //! Shared trait and methods for parsing floats. |
2 | | //! |
3 | | //! This is adapted from [fast-float-rust](https://github.com/aldanor/fast-float-rust), |
4 | | //! a port of [fast_float](https://github.com/fastfloat/fast_float) to Rust. |
5 | | |
6 | | // NOTE: We never want to disable multi-digit optimizations when parsing our floats, |
7 | | // since the nanoseconds it saves on branching is irrelevant when considering decimal |
8 | | // points and fractional digits and it majorly improves longer floats. |
9 | | |
10 | | #![doc(hidden)] |
11 | | |
12 | | #[cfg(not(feature = "compact"))] |
13 | | use lexical_parse_integer::algorithm; |
14 | | #[cfg(feature = "f16")] |
15 | | use lexical_util::bf16::bf16; |
16 | | use lexical_util::digit::{char_to_digit_const, char_to_valid_digit_const}; |
17 | | use lexical_util::error::Error; |
18 | | #[cfg(feature = "f16")] |
19 | | use lexical_util::f16::f16; |
20 | | use lexical_util::format::NumberFormat; |
21 | | use lexical_util::iterator::{AsBytes, Bytes, DigitsIter, Iter}; |
22 | | use lexical_util::result::Result; |
23 | | use lexical_util::step::u64_step; |
24 | | |
25 | | #[cfg(any(feature = "compact", feature = "radix"))] |
26 | | use crate::bellerophon::bellerophon; |
27 | | #[cfg(feature = "power-of-two")] |
28 | | use crate::binary::{binary, slow_binary}; |
29 | | use crate::float::{extended_to_float, ExtendedFloat80, LemireFloat}; |
30 | | #[cfg(not(feature = "compact"))] |
31 | | use crate::lemire::lemire; |
32 | | use crate::number::Number; |
33 | | use crate::options::Options; |
34 | | use crate::shared; |
35 | | use crate::slow::slow_radix; |
36 | | |
37 | | // API |
38 | | // --- |
39 | | |
40 | | /// Check if the radix is a power-of-2. |
41 | | #[cfg(feature = "power-of-two")] |
42 | | macro_rules! is_power_two { |
43 | | ($radix:expr) => { |
44 | | matches!($radix, 2 | 4 | 8 | 16 | 32) |
45 | | }; |
46 | | } |
47 | | |
48 | | /// Check if the radix is valid and error otherwise |
49 | | #[cfg(feature = "power-of-two")] |
50 | | macro_rules! check_radix { |
51 | | ($format:ident) => {{ |
52 | | let format = NumberFormat::<{ $format }> {}; |
53 | | if format.error() != Error::Success { |
54 | | return Err(Error::InvalidRadix); |
55 | | } else if format.radix() != format.exponent_base() { |
56 | | let valid_radix = matches!( |
57 | | (format.radix(), format.exponent_base()), |
58 | | (4, 2) | (8, 2) | (16, 2) | (32, 2) | (16, 4) |
59 | | ); |
60 | | if !valid_radix { |
61 | | return Err(Error::InvalidRadix); |
62 | | } |
63 | | } |
64 | | }}; |
65 | | } |
66 | | |
67 | | /// Check if the decimal radix is valid and error otherwise. |
68 | | #[cfg(not(feature = "power-of-two"))] |
69 | | macro_rules! check_radix { |
70 | | ($format:ident) => {{ |
71 | | let format = NumberFormat::<{ $format }> {}; |
72 | | if format.error() != Error::Success { |
73 | | return Err(Error::InvalidRadix); |
74 | | } |
75 | | }}; |
76 | | } |
77 | | |
78 | | /// Parse integer trait, implemented in terms of the optimized back-end. |
79 | | pub trait ParseFloat: LemireFloat { |
80 | | /// Forward complete parser parameters to the backend. |
81 | | #[cfg_attr(not(feature = "compact"), inline(always))] |
82 | 5.06k | fn parse_complete<const FORMAT: u128>(bytes: &[u8], options: &Options) -> Result<Self> { |
83 | 5.06k | check_radix!(FORMAT); |
84 | 5.06k | parse_complete::<Self, FORMAT>(bytes, options) |
85 | 5.06k | } <f32 as lexical_parse_float::parse::ParseFloat>::parse_complete::<0xa0000000000000000000000000c> Line | Count | Source | 82 | 2.09k | fn parse_complete<const FORMAT: u128>(bytes: &[u8], options: &Options) -> Result<Self> { | 83 | 2.09k | check_radix!(FORMAT); | 84 | 2.09k | parse_complete::<Self, FORMAT>(bytes, options) | 85 | 2.09k | } |
Unexecuted instantiation: <_ as lexical_parse_float::parse::ParseFloat>::parse_complete::<_> <f64 as lexical_parse_float::parse::ParseFloat>::parse_complete::<0xa0000000000000000000000000c> Line | Count | Source | 82 | 2.97k | fn parse_complete<const FORMAT: u128>(bytes: &[u8], options: &Options) -> Result<Self> { | 83 | 2.97k | check_radix!(FORMAT); | 84 | 2.97k | parse_complete::<Self, FORMAT>(bytes, options) | 85 | 2.97k | } |
|
86 | | |
87 | | /// Forward partial parser parameters to the backend. |
88 | | #[cfg_attr(not(feature = "compact"), inline(always))] |
89 | 0 | fn parse_partial<const FORMAT: u128>(bytes: &[u8], options: &Options) -> Result<(Self, usize)> { |
90 | 0 | check_radix!(FORMAT); |
91 | 0 | parse_partial::<Self, FORMAT>(bytes, options) |
92 | 0 | } |
93 | | |
94 | | /// Forward complete parser parameters to the backend, using only the fast |
95 | | /// path. |
96 | | #[cfg_attr(not(feature = "compact"), inline(always))] |
97 | 0 | fn fast_path_complete<const FORMAT: u128>(bytes: &[u8], options: &Options) -> Result<Self> { |
98 | 0 | check_radix!(FORMAT); |
99 | 0 | fast_path_complete::<Self, FORMAT>(bytes, options) |
100 | 0 | } |
101 | | |
102 | | /// Forward partial parser parameters to the backend, using only the fast |
103 | | /// path. |
104 | | #[cfg_attr(not(feature = "compact"), inline(always))] |
105 | 0 | fn fast_path_partial<const FORMAT: u128>( |
106 | 0 | bytes: &[u8], |
107 | 0 | options: &Options, |
108 | 0 | ) -> Result<(Self, usize)> { |
109 | 0 | check_radix!(FORMAT); |
110 | 0 | fast_path_partial::<Self, FORMAT>(bytes, options) |
111 | 0 | } |
112 | | } |
113 | | |
114 | | macro_rules! parse_float_impl { |
115 | | ($($t:ty)*) => ($( |
116 | | impl ParseFloat for $t {} |
117 | | )*) |
118 | | } |
119 | | |
120 | | parse_float_impl! { f32 f64 } |
121 | | |
122 | | #[cfg(feature = "f16")] |
123 | | macro_rules! parse_float_as_f32 { |
124 | | ($($t:ty)*) => ($( |
125 | | impl ParseFloat for $t { |
126 | | #[cfg_attr(not(feature = "compact"), inline(always))] |
127 | | fn parse_complete<const FORMAT: u128>(bytes: &[u8], options: &Options) |
128 | | -> Result<Self> |
129 | | { |
130 | | Ok(Self::from_f32(parse_complete::<f32, FORMAT>(bytes, options)?)) |
131 | | } |
132 | | |
133 | | #[cfg_attr(not(feature = "compact"), inline(always))] |
134 | | fn parse_partial<const FORMAT: u128>(bytes: &[u8], options: &Options) |
135 | | -> Result<(Self, usize)> |
136 | | { |
137 | | let (float, count) = parse_partial::<f32, FORMAT>(bytes, options)?; |
138 | | Ok((Self::from_f32(float), count)) |
139 | | } |
140 | | |
141 | | #[cfg_attr(not(feature = "compact"), inline(always))] |
142 | | fn fast_path_complete<const FORMAT: u128>(bytes: &[u8], options: &Options) |
143 | | -> Result<Self> |
144 | | { |
145 | | Ok(Self::from_f32(fast_path_complete::<f32, FORMAT>(bytes, options)?)) |
146 | | } |
147 | | |
148 | | #[cfg_attr(not(feature = "compact"), inline(always))] |
149 | | fn fast_path_partial<const FORMAT: u128>(bytes: &[u8], options: &Options) |
150 | | -> Result<(Self, usize)> |
151 | | { |
152 | | let (float, count) = fast_path_partial::<f32, FORMAT>(bytes, options)?; |
153 | | Ok((Self::from_f32(float), count)) |
154 | | } |
155 | | } |
156 | | )*) |
157 | | } |
158 | | |
159 | | #[cfg(feature = "f16")] |
160 | | parse_float_as_f32! { bf16 f16 } |
161 | | |
162 | | // PARSE |
163 | | // ----- |
164 | | |
165 | | // NOTE: |
166 | | // The partial and complete parsers are done separately because it provides |
167 | | // minor optimizations when parsing invalid input, and the logic is slightly |
168 | | // different internally. Most of the code is shared, so the duplicated |
169 | | // code is only like 30 lines. |
170 | | |
171 | | /// Parse the sign from the leading digits. |
172 | | #[cfg_attr(not(feature = "compact"), inline(always))] |
173 | 5.06k | pub fn parse_mantissa_sign<const FORMAT: u128>(byte: &mut Bytes<'_, FORMAT>) -> Result<bool> { |
174 | 5.06k | let format = NumberFormat::<{ FORMAT }> {}; |
175 | 5.06k | parse_sign!( |
176 | | byte, |
177 | 55 | true, |
178 | 0 | format.no_positive_mantissa_sign(), |
179 | 4.98k | format.required_mantissa_sign(), |
180 | | InvalidPositiveSign, |
181 | | MissingSign |
182 | | ) |
183 | 5.06k | } lexical_parse_float::parse::parse_mantissa_sign::<0xa0000000000000000000000000c> Line | Count | Source | 173 | 2.09k | pub fn parse_mantissa_sign<const FORMAT: u128>(byte: &mut Bytes<'_, FORMAT>) -> Result<bool> { | 174 | 2.09k | let format = NumberFormat::<{ FORMAT }> {}; | 175 | 2.09k | parse_sign!( | 176 | | byte, | 177 | 24 | true, | 178 | 0 | format.no_positive_mantissa_sign(), | 179 | 2.06k | format.required_mantissa_sign(), | 180 | | InvalidPositiveSign, | 181 | | MissingSign | 182 | | ) | 183 | 2.09k | } |
Unexecuted instantiation: lexical_parse_float::parse::parse_mantissa_sign::<_> lexical_parse_float::parse::parse_mantissa_sign::<0xa0000000000000000000000000c> Line | Count | Source | 173 | 2.97k | pub fn parse_mantissa_sign<const FORMAT: u128>(byte: &mut Bytes<'_, FORMAT>) -> Result<bool> { | 174 | 2.97k | let format = NumberFormat::<{ FORMAT }> {}; | 175 | 2.97k | parse_sign!( | 176 | | byte, | 177 | 31 | true, | 178 | 0 | format.no_positive_mantissa_sign(), | 179 | 2.92k | format.required_mantissa_sign(), | 180 | | InvalidPositiveSign, | 181 | | MissingSign | 182 | | ) | 183 | 2.97k | } |
|
184 | | |
185 | | /// Parse the sign from the leading digits. |
186 | | #[cfg_attr(not(feature = "compact"), inline(always))] |
187 | 2.30k | pub fn parse_exponent_sign<const FORMAT: u128>(byte: &mut Bytes<'_, FORMAT>) -> Result<bool> { |
188 | 2.30k | let format = NumberFormat::<{ FORMAT }> {}; |
189 | 2.30k | parse_sign!( |
190 | | byte, |
191 | 1.10k | true, |
192 | 0 | format.no_positive_exponent_sign(), |
193 | 1.19k | format.required_exponent_sign(), |
194 | | InvalidPositiveExponentSign, |
195 | | MissingExponentSign |
196 | | ) |
197 | 2.30k | } lexical_parse_float::parse::parse_exponent_sign::<0xa0000000000000000000000000c> Line | Count | Source | 187 | 848 | pub fn parse_exponent_sign<const FORMAT: u128>(byte: &mut Bytes<'_, FORMAT>) -> Result<bool> { | 188 | 848 | let format = NumberFormat::<{ FORMAT }> {}; | 189 | 848 | parse_sign!( | 190 | | byte, | 191 | 521 | true, | 192 | 0 | format.no_positive_exponent_sign(), | 193 | 326 | format.required_exponent_sign(), | 194 | | InvalidPositiveExponentSign, | 195 | | MissingExponentSign | 196 | | ) | 197 | 848 | } |
Unexecuted instantiation: lexical_parse_float::parse::parse_exponent_sign::<_> lexical_parse_float::parse::parse_exponent_sign::<0xa0000000000000000000000000c> Line | Count | Source | 187 | 1.45k | pub fn parse_exponent_sign<const FORMAT: u128>(byte: &mut Bytes<'_, FORMAT>) -> Result<bool> { | 188 | 1.45k | let format = NumberFormat::<{ FORMAT }> {}; | 189 | 1.45k | parse_sign!( | 190 | | byte, | 191 | 579 | true, | 192 | 0 | format.no_positive_exponent_sign(), | 193 | 872 | format.required_exponent_sign(), | 194 | | InvalidPositiveExponentSign, | 195 | | MissingExponentSign | 196 | | ) | 197 | 1.45k | } |
|
198 | | |
199 | | /// Utility to extract the result and handle any errors from parsing a `Number`. |
200 | | /// |
201 | | /// - `format` - The numerical format as a packed integer |
202 | | /// - `byte` - The `DigitsIter` iterator |
203 | | /// - `is_negative` - If the final value is negative |
204 | | /// - `parse_normal` - The function to parse non-special numbers with |
205 | | /// - `parse_special` - The function to parse special numbers with |
206 | | macro_rules! parse_number { |
207 | | ( |
208 | | $format:ident, |
209 | | $byte:ident, |
210 | | $is_negative:ident, |
211 | | $options:ident, |
212 | | $parse_normal:ident, |
213 | | $parse_special:ident |
214 | | ) => {{ |
215 | | match $parse_normal::<$format>($byte.clone(), $is_negative, $options) { |
216 | | Ok(n) => n, |
217 | | Err(e) => { |
218 | | if let Some(value) = |
219 | | $parse_special::<_, $format>($byte.clone(), $is_negative, $options) |
220 | | { |
221 | | return Ok(value); |
222 | | } else { |
223 | | return Err(e); |
224 | | } |
225 | | }, |
226 | | } |
227 | | }}; |
228 | | } |
229 | | |
230 | | /// Convert extended float to native. |
231 | | /// |
232 | | /// - `type` - The native floating point type. |
233 | | /// - `fp` - The extended floating-point representation. |
234 | | macro_rules! to_native { |
235 | | ($type:ident, $fp:ident, $is_negative:ident) => {{ |
236 | | let mut float = extended_to_float::<$type>($fp); |
237 | | if $is_negative { |
238 | | float = -float; |
239 | | } |
240 | | float |
241 | | }}; |
242 | | } |
243 | | |
244 | | /// Parse a float from bytes using a complete parser. |
245 | | #[inline(always)] |
246 | | #[allow(clippy::missing_inline_in_public_items)] // reason = "only public for testing" |
247 | 5.06k | pub fn parse_complete<F: LemireFloat, const FORMAT: u128>( |
248 | 5.06k | bytes: &[u8], |
249 | 5.06k | options: &Options, |
250 | 5.06k | ) -> Result<F> { |
251 | 5.06k | let mut byte = bytes.bytes::<{ FORMAT }>(); |
252 | 5.06k | let is_negative = parse_mantissa_sign(&mut byte)?; |
253 | 5.06k | if byte.integer_iter().is_consumed() { |
254 | 4 | if NumberFormat::<FORMAT>::REQUIRED_INTEGER_DIGITS |
255 | 4 | || NumberFormat::<FORMAT>::REQUIRED_MANTISSA_DIGITS |
256 | | { |
257 | 4 | return Err(Error::Empty(byte.cursor())); |
258 | | } else { |
259 | 0 | return Ok(F::ZERO); |
260 | | } |
261 | 5.06k | } |
262 | | |
263 | | // Parse our a small representation of our number. |
264 | 4.80k | let num: Number<'_> = |
265 | 5.06k | parse_number!(FORMAT, byte, is_negative, options, parse_complete_number, parse_special); |
266 | | // Try the fast-path algorithm. |
267 | 4.80k | if let Some(value) = num.try_fast_path::<_, FORMAT>() { |
268 | 352 | return Ok(value); |
269 | 4.45k | } |
270 | | // Now try the moderate path algorithm. |
271 | 4.45k | let mut fp = moderate_path::<F, FORMAT>(&num, options.lossy()); |
272 | | |
273 | | // Unable to correctly round the float using the fast or moderate algorithms. |
274 | | // Fallback to a slower, but always correct algorithm. If we have |
275 | | // lossy, we can't be here. |
276 | 4.45k | if fp.exp < 0 { |
277 | 2.87k | debug_assert!(!options.lossy(), "lossy algorithms never use slow algorithms"); |
278 | | // Undo the invalid extended float biasing. |
279 | 2.87k | fp.exp -= shared::INVALID_FP; |
280 | 2.87k | fp = slow_path::<F, FORMAT>(num, fp); |
281 | 1.58k | } |
282 | | |
283 | | // Convert to native float and return result. |
284 | 4.45k | Ok(to_native!(F, fp, is_negative)) |
285 | 5.06k | } lexical_parse_float::parse::parse_complete::<f32, 0xa0000000000000000000000000c> Line | Count | Source | 247 | 2.09k | pub fn parse_complete<F: LemireFloat, const FORMAT: u128>( | 248 | 2.09k | bytes: &[u8], | 249 | 2.09k | options: &Options, | 250 | 2.09k | ) -> Result<F> { | 251 | 2.09k | let mut byte = bytes.bytes::<{ FORMAT }>(); | 252 | 2.09k | let is_negative = parse_mantissa_sign(&mut byte)?; | 253 | 2.09k | if byte.integer_iter().is_consumed() { | 254 | 2 | if NumberFormat::<FORMAT>::REQUIRED_INTEGER_DIGITS | 255 | 2 | || NumberFormat::<FORMAT>::REQUIRED_MANTISSA_DIGITS | 256 | | { | 257 | 2 | return Err(Error::Empty(byte.cursor())); | 258 | | } else { | 259 | 0 | return Ok(F::ZERO); | 260 | | } | 261 | 2.09k | } | 262 | | | 263 | | // Parse our a small representation of our number. | 264 | 1.96k | let num: Number<'_> = | 265 | 2.09k | parse_number!(FORMAT, byte, is_negative, options, parse_complete_number, parse_special); | 266 | | // Try the fast-path algorithm. | 267 | 1.96k | if let Some(value) = num.try_fast_path::<_, FORMAT>() { | 268 | 120 | return Ok(value); | 269 | 1.84k | } | 270 | | // Now try the moderate path algorithm. | 271 | 1.84k | let mut fp = moderate_path::<F, FORMAT>(&num, options.lossy()); | 272 | | | 273 | | // Unable to correctly round the float using the fast or moderate algorithms. | 274 | | // Fallback to a slower, but always correct algorithm. If we have | 275 | | // lossy, we can't be here. | 276 | 1.84k | if fp.exp < 0 { | 277 | 1.13k | debug_assert!(!options.lossy(), "lossy algorithms never use slow algorithms"); | 278 | | // Undo the invalid extended float biasing. | 279 | 1.13k | fp.exp -= shared::INVALID_FP; | 280 | 1.13k | fp = slow_path::<F, FORMAT>(num, fp); | 281 | 714 | } | 282 | | | 283 | | // Convert to native float and return result. | 284 | 1.84k | Ok(to_native!(F, fp, is_negative)) | 285 | 2.09k | } |
Unexecuted instantiation: lexical_parse_float::parse::parse_complete::<_, _> lexical_parse_float::parse::parse_complete::<f64, 0xa0000000000000000000000000c> Line | Count | Source | 247 | 2.97k | pub fn parse_complete<F: LemireFloat, const FORMAT: u128>( | 248 | 2.97k | bytes: &[u8], | 249 | 2.97k | options: &Options, | 250 | 2.97k | ) -> Result<F> { | 251 | 2.97k | let mut byte = bytes.bytes::<{ FORMAT }>(); | 252 | 2.97k | let is_negative = parse_mantissa_sign(&mut byte)?; | 253 | 2.97k | if byte.integer_iter().is_consumed() { | 254 | 2 | if NumberFormat::<FORMAT>::REQUIRED_INTEGER_DIGITS | 255 | 2 | || NumberFormat::<FORMAT>::REQUIRED_MANTISSA_DIGITS | 256 | | { | 257 | 2 | return Err(Error::Empty(byte.cursor())); | 258 | | } else { | 259 | 0 | return Ok(F::ZERO); | 260 | | } | 261 | 2.96k | } | 262 | | | 263 | | // Parse our a small representation of our number. | 264 | 2.84k | let num: Number<'_> = | 265 | 2.96k | parse_number!(FORMAT, byte, is_negative, options, parse_complete_number, parse_special); | 266 | | // Try the fast-path algorithm. | 267 | 2.84k | if let Some(value) = num.try_fast_path::<_, FORMAT>() { | 268 | 232 | return Ok(value); | 269 | 2.61k | } | 270 | | // Now try the moderate path algorithm. | 271 | 2.61k | let mut fp = moderate_path::<F, FORMAT>(&num, options.lossy()); | 272 | | | 273 | | // Unable to correctly round the float using the fast or moderate algorithms. | 274 | | // Fallback to a slower, but always correct algorithm. If we have | 275 | | // lossy, we can't be here. | 276 | 2.61k | if fp.exp < 0 { | 277 | 1.73k | debug_assert!(!options.lossy(), "lossy algorithms never use slow algorithms"); | 278 | | // Undo the invalid extended float biasing. | 279 | 1.73k | fp.exp -= shared::INVALID_FP; | 280 | 1.73k | fp = slow_path::<F, FORMAT>(num, fp); | 281 | 872 | } | 282 | | | 283 | | // Convert to native float and return result. | 284 | 2.61k | Ok(to_native!(F, fp, is_negative)) | 285 | 2.97k | } |
|
286 | | |
287 | | /// Parse a float using only the fast path as a complete parser. |
288 | | #[inline(always)] |
289 | | #[allow(clippy::missing_inline_in_public_items)] // reason = "only public for testing" |
290 | 0 | pub fn fast_path_complete<F: LemireFloat, const FORMAT: u128>( |
291 | 0 | bytes: &[u8], |
292 | 0 | options: &Options, |
293 | 0 | ) -> Result<F> { |
294 | 0 | let mut byte = bytes.bytes::<{ FORMAT }>(); |
295 | 0 | let is_negative = parse_mantissa_sign(&mut byte)?; |
296 | 0 | if byte.integer_iter().is_consumed() { |
297 | 0 | if NumberFormat::<FORMAT>::REQUIRED_INTEGER_DIGITS |
298 | 0 | || NumberFormat::<FORMAT>::REQUIRED_MANTISSA_DIGITS |
299 | | { |
300 | 0 | return Err(Error::Empty(byte.cursor())); |
301 | | } else { |
302 | 0 | return Ok(F::ZERO); |
303 | | } |
304 | 0 | } |
305 | | |
306 | | // Parse our a small representation of our number. |
307 | 0 | let num = |
308 | 0 | parse_number!(FORMAT, byte, is_negative, options, parse_complete_number, parse_special); |
309 | 0 | Ok(num.force_fast_path::<_, FORMAT>()) |
310 | 0 | } |
311 | | |
312 | | /// Parse a float from bytes using a partial parser. |
313 | | #[inline(always)] |
314 | | #[allow(clippy::missing_inline_in_public_items)] // reason = "only public for testing" |
315 | 0 | pub fn parse_partial<F: LemireFloat, const FORMAT: u128>( |
316 | 0 | bytes: &[u8], |
317 | 0 | options: &Options, |
318 | 0 | ) -> Result<(F, usize)> { |
319 | 0 | let mut byte = bytes.bytes::<{ FORMAT }>(); |
320 | 0 | let is_negative = parse_mantissa_sign(&mut byte)?; |
321 | 0 | if byte.integer_iter().is_consumed() { |
322 | 0 | if NumberFormat::<FORMAT>::REQUIRED_INTEGER_DIGITS |
323 | 0 | || NumberFormat::<FORMAT>::REQUIRED_MANTISSA_DIGITS |
324 | | { |
325 | 0 | return Err(Error::Empty(byte.cursor())); |
326 | | } else { |
327 | 0 | return Ok((F::ZERO, byte.cursor())); |
328 | | } |
329 | 0 | } |
330 | | |
331 | | // Parse our a small representation of our number. |
332 | 0 | let (num, count) = parse_number!( |
333 | | FORMAT, |
334 | | byte, |
335 | | is_negative, |
336 | | options, |
337 | | parse_partial_number, |
338 | | parse_partial_special |
339 | | ); |
340 | | // Try the fast-path algorithm. |
341 | 0 | if let Some(value) = num.try_fast_path::<_, FORMAT>() { |
342 | 0 | return Ok((value, count)); |
343 | 0 | } |
344 | | // Now try the moderate path algorithm. |
345 | 0 | let mut fp = moderate_path::<F, FORMAT>(&num, options.lossy()); |
346 | | |
347 | | // Unable to correctly round the float using the fast or moderate algorithms. |
348 | | // Fallback to a slower, but always correct algorithm. If we have |
349 | | // lossy, we can't be here. |
350 | 0 | if fp.exp < 0 { |
351 | 0 | debug_assert!(!options.lossy(), "lossy algorithms never use slow algorithms"); |
352 | | // Undo the invalid extended float biasing. |
353 | 0 | fp.exp -= shared::INVALID_FP; |
354 | 0 | fp = slow_path::<F, FORMAT>(num, fp); |
355 | 0 | } |
356 | | |
357 | | // Convert to native float and return result. |
358 | 0 | Ok((to_native!(F, fp, is_negative), count)) |
359 | 0 | } |
360 | | |
361 | | /// Parse a float using only the fast path as a partial parser. |
362 | | #[inline(always)] |
363 | | #[allow(clippy::missing_inline_in_public_items)] // reason = "only public for testing" |
364 | 0 | pub fn fast_path_partial<F: LemireFloat, const FORMAT: u128>( |
365 | 0 | bytes: &[u8], |
366 | 0 | options: &Options, |
367 | 0 | ) -> Result<(F, usize)> { |
368 | 0 | let mut byte = bytes.bytes::<{ FORMAT }>(); |
369 | 0 | let is_negative = parse_mantissa_sign(&mut byte)?; |
370 | 0 | if byte.integer_iter().is_consumed() { |
371 | 0 | if NumberFormat::<FORMAT>::REQUIRED_INTEGER_DIGITS |
372 | 0 | || NumberFormat::<FORMAT>::REQUIRED_MANTISSA_DIGITS |
373 | | { |
374 | 0 | return Err(Error::Empty(byte.cursor())); |
375 | | } else { |
376 | 0 | return Ok((F::ZERO, byte.cursor())); |
377 | | } |
378 | 0 | } |
379 | | |
380 | | // Parse our a small representation of our number. |
381 | 0 | let (num, count) = parse_number!( |
382 | | FORMAT, |
383 | | byte, |
384 | | is_negative, |
385 | | options, |
386 | | parse_partial_number, |
387 | | parse_partial_special |
388 | | ); |
389 | 0 | Ok((num.force_fast_path::<_, FORMAT>(), count)) |
390 | 0 | } |
391 | | |
392 | | // PATHS |
393 | | // ----- |
394 | | |
395 | | /// Wrapper for different moderate-path algorithms. |
396 | | /// A return exponent of `-1` indicates an invalid value. |
397 | | #[must_use] |
398 | | #[inline(always)] |
399 | 4.45k | pub fn moderate_path<F: LemireFloat, const FORMAT: u128>( |
400 | 4.45k | num: &Number, |
401 | 4.45k | lossy: bool, |
402 | 4.45k | ) -> ExtendedFloat80 { |
403 | | #[cfg(feature = "compact")] |
404 | | { |
405 | | #[cfg(feature = "power-of-two")] |
406 | | { |
407 | | let format = NumberFormat::<{ FORMAT }> {}; |
408 | | if is_power_two!(format.mantissa_radix()) { |
409 | | // Implement the power-of-two backends. |
410 | | binary::<F, FORMAT>(num, lossy) |
411 | | } else { |
412 | | bellerophon::<F, FORMAT>(num, lossy) |
413 | | } |
414 | | } |
415 | | |
416 | | #[cfg(not(feature = "power-of-two"))] |
417 | | { |
418 | | bellerophon::<F, FORMAT>(num, lossy) |
419 | | } |
420 | | } |
421 | | |
422 | | #[cfg(not(feature = "compact"))] |
423 | | { |
424 | | #[cfg(feature = "radix")] |
425 | | { |
426 | | let format = NumberFormat::<{ FORMAT }> {}; |
427 | | let radix = format.mantissa_radix(); |
428 | | if radix == 10 { |
429 | | lemire::<F>(num, lossy) |
430 | | } else if is_power_two!(radix) { |
431 | | // Implement the power-of-two backends. |
432 | | binary::<F, FORMAT>(num, lossy) |
433 | | } else { |
434 | | bellerophon::<F, FORMAT>(num, lossy) |
435 | | } |
436 | | } |
437 | | |
438 | | #[cfg(all(feature = "power-of-two", not(feature = "radix")))] |
439 | | { |
440 | | let format = NumberFormat::<{ FORMAT }> {}; |
441 | | let radix = format.mantissa_radix(); |
442 | | debug_assert!(matches!(radix, 2 | 4 | 8 | 10 | 16 | 32)); |
443 | | if radix == 10 { |
444 | | lemire::<F>(num, lossy) |
445 | | } else { |
446 | | // Implement the power-of-two backends. |
447 | | binary::<F, FORMAT>(num, lossy) |
448 | | } |
449 | | } |
450 | | |
451 | | #[cfg(not(feature = "power-of-two"))] |
452 | | { |
453 | 4.45k | lemire::<F>(num, lossy) |
454 | | } |
455 | | } |
456 | 4.45k | } lexical_parse_float::parse::moderate_path::<f32, 0xa0000000000000000000000000c> Line | Count | Source | 399 | 1.84k | pub fn moderate_path<F: LemireFloat, const FORMAT: u128>( | 400 | 1.84k | num: &Number, | 401 | 1.84k | lossy: bool, | 402 | 1.84k | ) -> ExtendedFloat80 { | 403 | | #[cfg(feature = "compact")] | 404 | | { | 405 | | #[cfg(feature = "power-of-two")] | 406 | | { | 407 | | let format = NumberFormat::<{ FORMAT }> {}; | 408 | | if is_power_two!(format.mantissa_radix()) { | 409 | | // Implement the power-of-two backends. | 410 | | binary::<F, FORMAT>(num, lossy) | 411 | | } else { | 412 | | bellerophon::<F, FORMAT>(num, lossy) | 413 | | } | 414 | | } | 415 | | | 416 | | #[cfg(not(feature = "power-of-two"))] | 417 | | { | 418 | | bellerophon::<F, FORMAT>(num, lossy) | 419 | | } | 420 | | } | 421 | | | 422 | | #[cfg(not(feature = "compact"))] | 423 | | { | 424 | | #[cfg(feature = "radix")] | 425 | | { | 426 | | let format = NumberFormat::<{ FORMAT }> {}; | 427 | | let radix = format.mantissa_radix(); | 428 | | if radix == 10 { | 429 | | lemire::<F>(num, lossy) | 430 | | } else if is_power_two!(radix) { | 431 | | // Implement the power-of-two backends. | 432 | | binary::<F, FORMAT>(num, lossy) | 433 | | } else { | 434 | | bellerophon::<F, FORMAT>(num, lossy) | 435 | | } | 436 | | } | 437 | | | 438 | | #[cfg(all(feature = "power-of-two", not(feature = "radix")))] | 439 | | { | 440 | | let format = NumberFormat::<{ FORMAT }> {}; | 441 | | let radix = format.mantissa_radix(); | 442 | | debug_assert!(matches!(radix, 2 | 4 | 8 | 10 | 16 | 32)); | 443 | | if radix == 10 { | 444 | | lemire::<F>(num, lossy) | 445 | | } else { | 446 | | // Implement the power-of-two backends. | 447 | | binary::<F, FORMAT>(num, lossy) | 448 | | } | 449 | | } | 450 | | | 451 | | #[cfg(not(feature = "power-of-two"))] | 452 | | { | 453 | 1.84k | lemire::<F>(num, lossy) | 454 | | } | 455 | | } | 456 | 1.84k | } |
Unexecuted instantiation: lexical_parse_float::parse::moderate_path::<_, _> lexical_parse_float::parse::moderate_path::<f64, 0xa0000000000000000000000000c> Line | Count | Source | 399 | 2.61k | pub fn moderate_path<F: LemireFloat, const FORMAT: u128>( | 400 | 2.61k | num: &Number, | 401 | 2.61k | lossy: bool, | 402 | 2.61k | ) -> ExtendedFloat80 { | 403 | | #[cfg(feature = "compact")] | 404 | | { | 405 | | #[cfg(feature = "power-of-two")] | 406 | | { | 407 | | let format = NumberFormat::<{ FORMAT }> {}; | 408 | | if is_power_two!(format.mantissa_radix()) { | 409 | | // Implement the power-of-two backends. | 410 | | binary::<F, FORMAT>(num, lossy) | 411 | | } else { | 412 | | bellerophon::<F, FORMAT>(num, lossy) | 413 | | } | 414 | | } | 415 | | | 416 | | #[cfg(not(feature = "power-of-two"))] | 417 | | { | 418 | | bellerophon::<F, FORMAT>(num, lossy) | 419 | | } | 420 | | } | 421 | | | 422 | | #[cfg(not(feature = "compact"))] | 423 | | { | 424 | | #[cfg(feature = "radix")] | 425 | | { | 426 | | let format = NumberFormat::<{ FORMAT }> {}; | 427 | | let radix = format.mantissa_radix(); | 428 | | if radix == 10 { | 429 | | lemire::<F>(num, lossy) | 430 | | } else if is_power_two!(radix) { | 431 | | // Implement the power-of-two backends. | 432 | | binary::<F, FORMAT>(num, lossy) | 433 | | } else { | 434 | | bellerophon::<F, FORMAT>(num, lossy) | 435 | | } | 436 | | } | 437 | | | 438 | | #[cfg(all(feature = "power-of-two", not(feature = "radix")))] | 439 | | { | 440 | | let format = NumberFormat::<{ FORMAT }> {}; | 441 | | let radix = format.mantissa_radix(); | 442 | | debug_assert!(matches!(radix, 2 | 4 | 8 | 10 | 16 | 32)); | 443 | | if radix == 10 { | 444 | | lemire::<F>(num, lossy) | 445 | | } else { | 446 | | // Implement the power-of-two backends. | 447 | | binary::<F, FORMAT>(num, lossy) | 448 | | } | 449 | | } | 450 | | | 451 | | #[cfg(not(feature = "power-of-two"))] | 452 | | { | 453 | 2.61k | lemire::<F>(num, lossy) | 454 | | } | 455 | | } | 456 | 2.61k | } |
|
457 | | |
458 | | /// Invoke the slow path. |
459 | | /// At this point, the float string has already been validated. |
460 | | #[must_use] |
461 | | #[inline(always)] |
462 | 2.87k | pub fn slow_path<F: LemireFloat, const FORMAT: u128>( |
463 | 2.87k | num: Number, |
464 | 2.87k | fp: ExtendedFloat80, |
465 | 2.87k | ) -> ExtendedFloat80 { |
466 | | #[cfg(not(feature = "power-of-two"))] |
467 | | { |
468 | 2.87k | slow_radix::<F, FORMAT>(num, fp) |
469 | | } |
470 | | |
471 | | #[cfg(feature = "power-of-two")] |
472 | | { |
473 | | let format = NumberFormat::<{ FORMAT }> {}; |
474 | | if is_power_two!(format.mantissa_radix()) { |
475 | | slow_binary::<F, FORMAT>(num) |
476 | | } else { |
477 | | slow_radix::<F, FORMAT>(num, fp) |
478 | | } |
479 | | } |
480 | 2.87k | } lexical_parse_float::parse::slow_path::<f32, 0xa0000000000000000000000000c> Line | Count | Source | 462 | 1.13k | pub fn slow_path<F: LemireFloat, const FORMAT: u128>( | 463 | 1.13k | num: Number, | 464 | 1.13k | fp: ExtendedFloat80, | 465 | 1.13k | ) -> ExtendedFloat80 { | 466 | | #[cfg(not(feature = "power-of-two"))] | 467 | | { | 468 | 1.13k | slow_radix::<F, FORMAT>(num, fp) | 469 | | } | 470 | | | 471 | | #[cfg(feature = "power-of-two")] | 472 | | { | 473 | | let format = NumberFormat::<{ FORMAT }> {}; | 474 | | if is_power_two!(format.mantissa_radix()) { | 475 | | slow_binary::<F, FORMAT>(num) | 476 | | } else { | 477 | | slow_radix::<F, FORMAT>(num, fp) | 478 | | } | 479 | | } | 480 | 1.13k | } |
Unexecuted instantiation: lexical_parse_float::parse::slow_path::<_, _> lexical_parse_float::parse::slow_path::<f64, 0xa0000000000000000000000000c> Line | Count | Source | 462 | 1.73k | pub fn slow_path<F: LemireFloat, const FORMAT: u128>( | 463 | 1.73k | num: Number, | 464 | 1.73k | fp: ExtendedFloat80, | 465 | 1.73k | ) -> ExtendedFloat80 { | 466 | | #[cfg(not(feature = "power-of-two"))] | 467 | | { | 468 | 1.73k | slow_radix::<F, FORMAT>(num, fp) | 469 | | } | 470 | | | 471 | | #[cfg(feature = "power-of-two")] | 472 | | { | 473 | | let format = NumberFormat::<{ FORMAT }> {}; | 474 | | if is_power_two!(format.mantissa_radix()) { | 475 | | slow_binary::<F, FORMAT>(num) | 476 | | } else { | 477 | | slow_radix::<F, FORMAT>(num, fp) | 478 | | } | 479 | | } | 480 | 1.73k | } |
|
481 | | |
482 | | // NUMBER |
483 | | // ------ |
484 | | |
485 | | /// Parse a partial, non-special floating point number. |
486 | | /// |
487 | | /// This creates a representation of the float as the |
488 | | /// significant digits and the decimal exponent. |
489 | | #[cfg_attr(not(feature = "compact"), inline(always))] |
490 | | #[allow(unused_mut)] // reason = "used when format is enabled" |
491 | | #[allow(clippy::unwrap_used)] // reason = "developer error if we incorrectly assume an overflow" |
492 | | #[allow(clippy::collapsible_if)] // reason = "more readable uncollapsed" |
493 | | #[allow(clippy::cast_possible_wrap)] // reason = "no hardware supports buffers >= i64::MAX" |
494 | | #[allow(clippy::too_many_lines)] // reason = "function is one logical entity" |
495 | 5.06k | pub fn parse_number<'a, const FORMAT: u128, const IS_PARTIAL: bool>( |
496 | 5.06k | mut byte: Bytes<'a, FORMAT>, |
497 | 5.06k | is_negative: bool, |
498 | 5.06k | options: &Options, |
499 | 5.06k | ) -> Result<(Number<'a>, usize)> { |
500 | | // NOTE: |
501 | | // There are no satisfactory optimizations to reduce the number |
502 | | // of multiplications for very long input strings, but this will |
503 | | // be a small fraction of the performance penalty anyway. |
504 | | // |
505 | | // We've tried: |
506 | | // - checking for explicit overflow, via `overflowing_mul`. |
507 | | // - counting the max number of steps. |
508 | | // - subslicing the string, and only processing the first `step` |
509 | | // digits. |
510 | | // - pre-computing the maximum power, and only adding until then. |
511 | | // |
512 | | // All of these lead to substantial performance penalty. |
513 | | // If we pre-parse the string, then only process it then, we |
514 | | // get a performance penalty of ~2.5x (20ns to 50ns) for common |
515 | | // floats, an unacceptable cost, while only improving performance |
516 | | // for rare floats 5-25% (9.3µs to 7.5µs for denormal with 6400 |
517 | | // digits, and 7.8µs to 7.4µs for large floats with 6400 digits). |
518 | | // |
519 | | // The performance cost is **almost** entirely in this function, |
520 | | // but additional branching **does** not improve performance, |
521 | | // and pre-tokenization is a recipe for failure. For halfway |
522 | | // cases with smaller numbers of digits, the majority of the |
523 | | // performance cost is in the big integer arithmetic (`pow` and |
524 | | // `parse_mantissa`), which suggests few optimizations can or should |
525 | | // be made. |
526 | | |
527 | | // Config options |
528 | 5.06k | let format = NumberFormat::<{ FORMAT }> {}; |
529 | 5.06k | let decimal_point = options.decimal_point(); |
530 | 5.06k | let exponent_character = options.exponent(); |
531 | 5.06k | debug_assert!(format.is_valid(), "should have already checked for an invalid number format"); |
532 | 5.06k | debug_assert!(!byte.is_buffer_empty(), "should have previously checked for empty input"); |
533 | 5.06k | let bits_per_digit = shared::log2(format.mantissa_radix()) as i64; |
534 | 5.06k | let bits_per_base = shared::log2(format.exponent_base()) as i64; |
535 | | |
536 | | // INTEGER |
537 | | |
538 | | // Check to see if we have a valid base prefix. |
539 | | #[allow(unused_variables)] |
540 | 5.06k | let mut is_prefix = false; |
541 | | #[cfg(feature = "format")] |
542 | | { |
543 | | let base_prefix = format.base_prefix(); |
544 | | let mut iter = byte.integer_iter(); |
545 | | if base_prefix != 0 && iter.read_if_value_cased(b'0').is_some() { |
546 | | // Check to see if the next character is the base prefix. |
547 | | // We must have a format like `0x`, `0d`, `0o`. |
548 | | // NOTE: The check for empty integer digits happens below so |
549 | | // we don't need a redundant check here. |
550 | | is_prefix = true; |
551 | | if iter.read_if_value(base_prefix, format.case_sensitive_base_prefix()).is_some() |
552 | | && iter.is_buffer_empty() |
553 | | && format.required_integer_digits() |
554 | | { |
555 | | return Err(Error::EmptyInteger(iter.cursor())); |
556 | | } |
557 | | } |
558 | | } |
559 | | |
560 | | // Parse our integral digits. |
561 | 5.06k | let mut mantissa = 0_u64; |
562 | 5.06k | let start = byte.clone(); |
563 | | #[cfg(not(feature = "compact"))] |
564 | 5.06k | parse_8digits::<_, FORMAT>(byte.integer_iter(), &mut mantissa); |
565 | 13.9k | parse_digits(byte.integer_iter(), format.mantissa_radix(), |digit| { |
566 | 13.9k | mantissa = mantissa.wrapping_mul(format.radix() as u64).wrapping_add(digit as u64); |
567 | 13.9k | }); lexical_parse_float::parse::parse_number::<0xa0000000000000000000000000c, false>::{closure#0} Line | Count | Source | 565 | 6.09k | parse_digits(byte.integer_iter(), format.mantissa_radix(), |digit| { | 566 | 6.09k | mantissa = mantissa.wrapping_mul(format.radix() as u64).wrapping_add(digit as u64); | 567 | 6.09k | }); |
Unexecuted instantiation: lexical_parse_float::parse::parse_number::<_, _>::{closure#0} lexical_parse_float::parse::parse_number::<0xa0000000000000000000000000c, false>::{closure#0} Line | Count | Source | 565 | 7.85k | parse_digits(byte.integer_iter(), format.mantissa_radix(), |digit| { | 566 | 7.85k | mantissa = mantissa.wrapping_mul(format.radix() as u64).wrapping_add(digit as u64); | 567 | 7.85k | }); |
|
568 | 5.06k | let mut n_digits = byte.current_count() - start.current_count(); |
569 | | #[cfg(feature = "format")] |
570 | | if format.required_integer_digits() && n_digits == 0 { |
571 | | return Err(Error::EmptyInteger(byte.cursor())); |
572 | | } |
573 | | |
574 | | // Store the integer digits for slow-path algorithms. |
575 | | // NOTE: We can't use the number of digits to extract the slice for |
576 | | // non-contiguous iterators, but we also need to the number of digits |
577 | | // for our value calculation. We store both, and let the compiler know |
578 | | // to optimize it out when not needed. |
579 | 5.06k | let b_digits = if cfg!(feature = "format") && !byte.integer_iter().is_contiguous() { |
580 | 0 | byte.cursor() - start.cursor() |
581 | | } else { |
582 | 5.06k | n_digits |
583 | | }; |
584 | 5.06k | debug_assert!( |
585 | 0 | b_digits <= start.as_slice().len(), |
586 | 0 | "number of digits parsed must <= buffer length" |
587 | | ); |
588 | | // SAFETY: safe, since `n_digits <= start.as_slice().len()`. |
589 | | // This is since `byte.len() >= start.len()` but has to have |
590 | | // the same end bounds (that is, `start = byte.clone()`), so |
591 | | // `0 <= byte.current_count() <= start.current_count() <= start.lent()` |
592 | | // so, this will always return only the integer digits. |
593 | | // |
594 | | // NOTE: Removing this code leads to ~10% reduction in parsing |
595 | | // that triggers the Eisell-Lemire algorithm or the digit comp |
596 | | // algorithms, so don't remove the unsafe indexing. |
597 | 5.06k | let integer_digits = unsafe { start.as_slice().get_unchecked(..b_digits) }; |
598 | | |
599 | | // Check if integer leading zeros are disabled. |
600 | | #[cfg(feature = "format")] |
601 | | if !is_prefix && format.no_float_leading_zeros() { |
602 | | if integer_digits.len() > 1 && integer_digits.first() == Some(&b'0') { |
603 | | return Err(Error::InvalidLeadingZeros(start.cursor())); |
604 | | } |
605 | | } |
606 | | |
607 | | // FRACTION |
608 | | |
609 | | // Handle decimal point and digits afterwards. |
610 | 5.06k | let mut n_after_dot = 0; |
611 | 5.06k | let mut exponent = 0_i64; |
612 | | let mut implicit_exponent: i64; |
613 | 5.06k | let int_end = n_digits as i64; |
614 | 5.06k | let mut fraction_digits = None; |
615 | 5.06k | let has_decimal = byte.first_is_cased(decimal_point); |
616 | 5.06k | if has_decimal { |
617 | | // SAFETY: byte cannot be empty due to `first_is` |
618 | 2.06k | unsafe { byte.step_unchecked() }; |
619 | 2.06k | let before = byte.clone(); |
620 | | #[cfg(not(feature = "compact"))] |
621 | 2.06k | parse_8digits::<_, FORMAT>(byte.fraction_iter(), &mut mantissa); |
622 | 5.82k | parse_digits(byte.fraction_iter(), format.mantissa_radix(), |digit| { |
623 | 5.82k | mantissa = mantissa.wrapping_mul(format.radix() as u64).wrapping_add(digit as u64); |
624 | 5.82k | }); lexical_parse_float::parse::parse_number::<0xa0000000000000000000000000c, false>::{closure#1} Line | Count | Source | 622 | 2.65k | parse_digits(byte.fraction_iter(), format.mantissa_radix(), |digit| { | 623 | 2.65k | mantissa = mantissa.wrapping_mul(format.radix() as u64).wrapping_add(digit as u64); | 624 | 2.65k | }); |
Unexecuted instantiation: lexical_parse_float::parse::parse_number::<_, _>::{closure#1} lexical_parse_float::parse::parse_number::<0xa0000000000000000000000000c, false>::{closure#1} Line | Count | Source | 622 | 3.17k | parse_digits(byte.fraction_iter(), format.mantissa_radix(), |digit| { | 623 | 3.17k | mantissa = mantissa.wrapping_mul(format.radix() as u64).wrapping_add(digit as u64); | 624 | 3.17k | }); |
|
625 | 2.06k | n_after_dot = byte.current_count() - before.current_count(); |
626 | | // NOTE: We can't use the number of digits to extract the slice for |
627 | | // non-contiguous iterators, but we also need to the number of digits |
628 | | // for our value calculation. We store both, and let the compiler know |
629 | | // to optimize it out when not needed. |
630 | 2.06k | let b_after_dot = if cfg!(feature = "format") && !byte.fraction_iter().is_contiguous() { |
631 | 0 | byte.cursor() - before.cursor() |
632 | | } else { |
633 | 2.06k | n_after_dot |
634 | | }; |
635 | | |
636 | | // Store the fraction digits for slow-path algorithms. |
637 | 2.06k | debug_assert!( |
638 | 0 | b_after_dot <= before.as_slice().len(), |
639 | 0 | "digits after dot must be smaller than buffer" |
640 | | ); |
641 | | // SAFETY: safe, since `idx_after_dot <= before.as_slice().len()`. |
642 | 2.06k | fraction_digits = Some(unsafe { before.as_slice().get_unchecked(..b_after_dot) }); |
643 | | |
644 | | // Calculate the implicit exponent: the number of digits after the dot. |
645 | 2.06k | implicit_exponent = -(n_after_dot as i64); |
646 | 2.06k | if format.mantissa_radix() == format.exponent_base() { |
647 | 2.06k | exponent = implicit_exponent; |
648 | 2.06k | } else { |
649 | 0 | debug_assert!(bits_per_digit % bits_per_base == 0, "exponent must be a power of base"); |
650 | 0 | exponent = implicit_exponent * bits_per_digit / bits_per_base; |
651 | | }; |
652 | | #[cfg(feature = "format")] |
653 | | if format.required_fraction_digits() && n_after_dot == 0 { |
654 | | return Err(Error::EmptyFraction(byte.cursor())); |
655 | | } |
656 | 2.99k | } |
657 | | |
658 | | // NOTE: Check if we have our exponent **BEFORE** checking if the |
659 | | // mantissa is empty, so we can ensure |
660 | 5.06k | let has_exponent = byte |
661 | 5.06k | .first_is(exponent_character, format.case_sensitive_exponent() && cfg!(feature = "format")); |
662 | | |
663 | | // check to see if we have any invalid leading zeros |
664 | 5.06k | n_digits += n_after_dot; |
665 | 5.06k | if format.required_mantissa_digits() |
666 | 5.06k | && (n_digits == 0 || (cfg!(feature = "format") && byte.current_count() == 0)) |
667 | | { |
668 | 58 | let any_digits = start.clone().integer_iter().peek().is_some(); |
669 | | // NOTE: This is because numbers like `_12.34` have significant digits, |
670 | | // they just don't have a valid digit (#97). |
671 | 58 | if has_decimal || has_exponent || !any_digits || IS_PARTIAL { |
672 | 21 | return Err(Error::EmptyMantissa(byte.cursor())); |
673 | | } else { |
674 | 37 | return Err(Error::InvalidDigit(start.cursor())); |
675 | | } |
676 | 5.00k | } |
677 | | |
678 | | // EXPONENT |
679 | | |
680 | | // Handle scientific notation. |
681 | 5.00k | let mut explicit_exponent = 0_i64; |
682 | 5.00k | if has_exponent { |
683 | | // NOTE: See above for the safety invariant above `required_mantissa_digits`. |
684 | | // This is separated for correctness concerns, and therefore the two cannot |
685 | | // be on the same line. |
686 | | // SAFETY: byte cannot be empty due to `first_is` from `has_exponent`.` |
687 | 2.30k | unsafe { byte.step_unchecked() }; |
688 | | |
689 | | // Check float format syntax checks. |
690 | | #[cfg(feature = "format")] |
691 | | { |
692 | | // NOTE: We've overstepped for the safety invariant before. |
693 | | if format.no_exponent_notation() { |
694 | | return Err(Error::InvalidExponent(byte.cursor() - 1)); |
695 | | } |
696 | | // Check if we have no fraction but we required exponent notation. |
697 | | if format.no_exponent_without_fraction() && fraction_digits.is_none() { |
698 | | return Err(Error::ExponentWithoutFraction(byte.cursor() - 1)); |
699 | | } |
700 | | } |
701 | | |
702 | 2.30k | let is_negative_exponent = parse_exponent_sign(&mut byte)?; |
703 | 2.30k | let before = byte.current_count(); |
704 | 3.27M | parse_digits(byte.exponent_iter(), format.exponent_radix(), |digit| { |
705 | 3.27M | if explicit_exponent < 0x10000000 { |
706 | 30.6k | explicit_exponent *= format.exponent_radix() as i64; |
707 | 30.6k | explicit_exponent += digit as i64; |
708 | 3.24M | } |
709 | 3.27M | }); lexical_parse_float::parse::parse_number::<0xa0000000000000000000000000c, false>::{closure#2} Line | Count | Source | 704 | 2.18M | parse_digits(byte.exponent_iter(), format.exponent_radix(), |digit| { | 705 | 2.18M | if explicit_exponent < 0x10000000 { | 706 | 26.0k | explicit_exponent *= format.exponent_radix() as i64; | 707 | 26.0k | explicit_exponent += digit as i64; | 708 | 2.15M | } | 709 | 2.18M | }); |
Unexecuted instantiation: lexical_parse_float::parse::parse_number::<_, _>::{closure#2} lexical_parse_float::parse::parse_number::<0xa0000000000000000000000000c, false>::{closure#2} Line | Count | Source | 704 | 1.09M | parse_digits(byte.exponent_iter(), format.exponent_radix(), |digit| { | 705 | 1.09M | if explicit_exponent < 0x10000000 { | 706 | 4.55k | explicit_exponent *= format.exponent_radix() as i64; | 707 | 4.55k | explicit_exponent += digit as i64; | 708 | 1.09M | } | 709 | 1.09M | }); |
|
710 | 2.30k | if format.required_exponent_digits() && byte.current_count() - before == 0 { |
711 | 19 | return Err(Error::EmptyExponent(byte.cursor())); |
712 | 2.28k | } |
713 | | // Handle our sign, and get the explicit part of the exponent. |
714 | 2.28k | explicit_exponent = if is_negative_exponent { |
715 | 1.09k | -explicit_exponent |
716 | | } else { |
717 | 1.18k | explicit_exponent |
718 | | }; |
719 | 2.28k | exponent += explicit_exponent; |
720 | 2.70k | } else if cfg!(feature = "format") && format.required_exponent_notation() { |
721 | 0 | return Err(Error::MissingExponent(byte.cursor())); |
722 | 2.70k | } |
723 | | |
724 | | // Check to see if we have a valid base suffix. |
725 | | // We've already trimmed any leading digit separators here, so we can be safe |
726 | | // that the first character **is not** a digit separator. |
727 | | #[allow(unused_variables)] |
728 | 4.98k | let base_suffix = format.base_suffix(); |
729 | | #[cfg(feature = "format")] |
730 | | if base_suffix != 0 { |
731 | | if byte.first_is(base_suffix, format.case_sensitive_base_suffix()) { |
732 | | // SAFETY: safe since `byte.len() >= 1`. |
733 | | unsafe { byte.step_unchecked() }; |
734 | | } |
735 | | } |
736 | | |
737 | | // CHECK OVERFLOW |
738 | | |
739 | | // Get the number of parsed digits (total), and redo if we had overflow. |
740 | 4.98k | let end = byte.cursor(); |
741 | 4.98k | let mut step = u64_step(format.mantissa_radix()); |
742 | 4.98k | let mut many_digits = false; |
743 | | #[cfg(feature = "format")] |
744 | | if !format.required_mantissa_digits() && n_digits == 0 { |
745 | | exponent = 0; |
746 | | } |
747 | 4.98k | if n_digits <= step { |
748 | 1.62k | return Ok(( |
749 | 1.62k | Number { |
750 | 1.62k | exponent, |
751 | 1.62k | mantissa, |
752 | 1.62k | is_negative, |
753 | 1.62k | many_digits: false, |
754 | 1.62k | integer: integer_digits, |
755 | 1.62k | fraction: fraction_digits, |
756 | 1.62k | }, |
757 | 1.62k | end, |
758 | 1.62k | )); |
759 | 3.35k | } |
760 | | |
761 | | // Check for leading zeros, and to see if we had a false overflow. |
762 | 3.35k | n_digits -= step; |
763 | 3.35k | let mut zeros = start.clone(); |
764 | 3.35k | let mut zeros_integer = zeros.integer_iter(); |
765 | 3.35k | n_digits = n_digits.saturating_sub(zeros_integer.skip_zeros()); |
766 | 3.35k | if zeros.first_is_cased(decimal_point) { |
767 | 520 | // SAFETY: safe since zeros cannot be empty due to `first_is` |
768 | 520 | unsafe { zeros.step_unchecked() }; |
769 | 2.83k | } |
770 | 3.35k | let mut zeros_fraction = zeros.fraction_iter(); |
771 | 3.35k | n_digits = n_digits.saturating_sub(zeros_fraction.skip_zeros()); |
772 | | |
773 | | // OVERFLOW |
774 | | |
775 | | // Now, check if we explicitly overflowed. |
776 | 3.35k | if n_digits > 0 { |
777 | | // Have more than 19 significant digits, so we overflowed. |
778 | 3.20k | many_digits = true; |
779 | 3.20k | mantissa = 0; |
780 | 3.20k | let mut integer = integer_digits.bytes::<{ FORMAT }>(); |
781 | | // Skip leading zeros, so we can use the step properly. |
782 | 3.20k | let mut integer_iter = integer.integer_iter(); |
783 | 3.20k | integer_iter.skip_zeros(); |
784 | 3.20k | parse_u64_digits::<_, FORMAT>(integer_iter, &mut mantissa, &mut step); |
785 | | // NOTE: With the format feature enabled and non-contiguous iterators, we can |
786 | | // have null fraction digits even if step was not 0. We want to make the |
787 | | // none check as late in there as possible: any of them should |
788 | | // short-circuit and should be determined at compile time. So, the |
789 | | // conditions are either: |
790 | | // 1. Step == 0 |
791 | | // 2. `cfg!(feature = "format") && !byte.is_contiguous() && |
792 | | // fraction_digits.is_none()` |
793 | 3.20k | implicit_exponent = if step == 0 |
794 | 1.22k | || (cfg!(feature = "format") && !byte.is_contiguous() && fraction_digits.is_none()) |
795 | | { |
796 | | // Filled our mantissa with just the integer. |
797 | 1.97k | int_end - integer.current_count() as i64 |
798 | | } else { |
799 | | // We know this can't be a None since we had more than 19 |
800 | | // digits previously, so we overflowed a 64-bit integer, |
801 | | // but parsing only the integral digits produced less |
802 | | // than 19 digits. That means we must have a decimal |
803 | | // point, and at least 1 fractional digit. |
804 | 1.22k | let mut fraction = fraction_digits.unwrap().bytes::<{ FORMAT }>(); |
805 | 1.22k | let mut fraction_iter = fraction.fraction_iter(); |
806 | | // Skip leading zeros, so we can use the step properly. |
807 | 1.22k | if mantissa == 0 { |
808 | 457 | fraction_iter.skip_zeros(); |
809 | 771 | } |
810 | 1.22k | parse_u64_digits::<_, FORMAT>(fraction_iter, &mut mantissa, &mut step); |
811 | 1.22k | -(fraction.current_count() as i64) |
812 | | }; |
813 | 3.20k | if format.mantissa_radix() == format.exponent_base() { |
814 | 3.20k | exponent = implicit_exponent; |
815 | 3.20k | } else { |
816 | 0 | debug_assert!(bits_per_digit % bits_per_base == 0, "exponent must be a power of base"); |
817 | 0 | exponent = implicit_exponent * bits_per_digit / bits_per_base; |
818 | | }; |
819 | | // Add back the explicit exponent. |
820 | 3.20k | exponent += explicit_exponent; |
821 | 157 | } |
822 | | |
823 | 3.35k | Ok(( |
824 | 3.35k | Number { |
825 | 3.35k | exponent, |
826 | 3.35k | mantissa, |
827 | 3.35k | is_negative, |
828 | 3.35k | many_digits, |
829 | 3.35k | integer: integer_digits, |
830 | 3.35k | fraction: fraction_digits, |
831 | 3.35k | }, |
832 | 3.35k | end, |
833 | 3.35k | )) |
834 | 5.06k | } lexical_parse_float::parse::parse_number::<0xa0000000000000000000000000c, false> Line | Count | Source | 495 | 2.09k | pub fn parse_number<'a, const FORMAT: u128, const IS_PARTIAL: bool>( | 496 | 2.09k | mut byte: Bytes<'a, FORMAT>, | 497 | 2.09k | is_negative: bool, | 498 | 2.09k | options: &Options, | 499 | 2.09k | ) -> Result<(Number<'a>, usize)> { | 500 | | // NOTE: | 501 | | // There are no satisfactory optimizations to reduce the number | 502 | | // of multiplications for very long input strings, but this will | 503 | | // be a small fraction of the performance penalty anyway. | 504 | | // | 505 | | // We've tried: | 506 | | // - checking for explicit overflow, via `overflowing_mul`. | 507 | | // - counting the max number of steps. | 508 | | // - subslicing the string, and only processing the first `step` | 509 | | // digits. | 510 | | // - pre-computing the maximum power, and only adding until then. | 511 | | // | 512 | | // All of these lead to substantial performance penalty. | 513 | | // If we pre-parse the string, then only process it then, we | 514 | | // get a performance penalty of ~2.5x (20ns to 50ns) for common | 515 | | // floats, an unacceptable cost, while only improving performance | 516 | | // for rare floats 5-25% (9.3µs to 7.5µs for denormal with 6400 | 517 | | // digits, and 7.8µs to 7.4µs for large floats with 6400 digits). | 518 | | // | 519 | | // The performance cost is **almost** entirely in this function, | 520 | | // but additional branching **does** not improve performance, | 521 | | // and pre-tokenization is a recipe for failure. For halfway | 522 | | // cases with smaller numbers of digits, the majority of the | 523 | | // performance cost is in the big integer arithmetic (`pow` and | 524 | | // `parse_mantissa`), which suggests few optimizations can or should | 525 | | // be made. | 526 | | | 527 | | // Config options | 528 | 2.09k | let format = NumberFormat::<{ FORMAT }> {}; | 529 | 2.09k | let decimal_point = options.decimal_point(); | 530 | 2.09k | let exponent_character = options.exponent(); | 531 | 2.09k | debug_assert!(format.is_valid(), "should have already checked for an invalid number format"); | 532 | 2.09k | debug_assert!(!byte.is_buffer_empty(), "should have previously checked for empty input"); | 533 | 2.09k | let bits_per_digit = shared::log2(format.mantissa_radix()) as i64; | 534 | 2.09k | let bits_per_base = shared::log2(format.exponent_base()) as i64; | 535 | | | 536 | | // INTEGER | 537 | | | 538 | | // Check to see if we have a valid base prefix. | 539 | | #[allow(unused_variables)] | 540 | 2.09k | let mut is_prefix = false; | 541 | | #[cfg(feature = "format")] | 542 | | { | 543 | | let base_prefix = format.base_prefix(); | 544 | | let mut iter = byte.integer_iter(); | 545 | | if base_prefix != 0 && iter.read_if_value_cased(b'0').is_some() { | 546 | | // Check to see if the next character is the base prefix. | 547 | | // We must have a format like `0x`, `0d`, `0o`. | 548 | | // NOTE: The check for empty integer digits happens below so | 549 | | // we don't need a redundant check here. | 550 | | is_prefix = true; | 551 | | if iter.read_if_value(base_prefix, format.case_sensitive_base_prefix()).is_some() | 552 | | && iter.is_buffer_empty() | 553 | | && format.required_integer_digits() | 554 | | { | 555 | | return Err(Error::EmptyInteger(iter.cursor())); | 556 | | } | 557 | | } | 558 | | } | 559 | | | 560 | | // Parse our integral digits. | 561 | 2.09k | let mut mantissa = 0_u64; | 562 | 2.09k | let start = byte.clone(); | 563 | | #[cfg(not(feature = "compact"))] | 564 | 2.09k | parse_8digits::<_, FORMAT>(byte.integer_iter(), &mut mantissa); | 565 | 2.09k | parse_digits(byte.integer_iter(), format.mantissa_radix(), |digit| { | 566 | | mantissa = mantissa.wrapping_mul(format.radix() as u64).wrapping_add(digit as u64); | 567 | | }); | 568 | 2.09k | let mut n_digits = byte.current_count() - start.current_count(); | 569 | | #[cfg(feature = "format")] | 570 | | if format.required_integer_digits() && n_digits == 0 { | 571 | | return Err(Error::EmptyInteger(byte.cursor())); | 572 | | } | 573 | | | 574 | | // Store the integer digits for slow-path algorithms. | 575 | | // NOTE: We can't use the number of digits to extract the slice for | 576 | | // non-contiguous iterators, but we also need to the number of digits | 577 | | // for our value calculation. We store both, and let the compiler know | 578 | | // to optimize it out when not needed. | 579 | 2.09k | let b_digits = if cfg!(feature = "format") && !byte.integer_iter().is_contiguous() { | 580 | 0 | byte.cursor() - start.cursor() | 581 | | } else { | 582 | 2.09k | n_digits | 583 | | }; | 584 | 2.09k | debug_assert!( | 585 | 0 | b_digits <= start.as_slice().len(), | 586 | 0 | "number of digits parsed must <= buffer length" | 587 | | ); | 588 | | // SAFETY: safe, since `n_digits <= start.as_slice().len()`. | 589 | | // This is since `byte.len() >= start.len()` but has to have | 590 | | // the same end bounds (that is, `start = byte.clone()`), so | 591 | | // `0 <= byte.current_count() <= start.current_count() <= start.lent()` | 592 | | // so, this will always return only the integer digits. | 593 | | // | 594 | | // NOTE: Removing this code leads to ~10% reduction in parsing | 595 | | // that triggers the Eisell-Lemire algorithm or the digit comp | 596 | | // algorithms, so don't remove the unsafe indexing. | 597 | 2.09k | let integer_digits = unsafe { start.as_slice().get_unchecked(..b_digits) }; | 598 | | | 599 | | // Check if integer leading zeros are disabled. | 600 | | #[cfg(feature = "format")] | 601 | | if !is_prefix && format.no_float_leading_zeros() { | 602 | | if integer_digits.len() > 1 && integer_digits.first() == Some(&b'0') { | 603 | | return Err(Error::InvalidLeadingZeros(start.cursor())); | 604 | | } | 605 | | } | 606 | | | 607 | | // FRACTION | 608 | | | 609 | | // Handle decimal point and digits afterwards. | 610 | 2.09k | let mut n_after_dot = 0; | 611 | 2.09k | let mut exponent = 0_i64; | 612 | | let mut implicit_exponent: i64; | 613 | 2.09k | let int_end = n_digits as i64; | 614 | 2.09k | let mut fraction_digits = None; | 615 | 2.09k | let has_decimal = byte.first_is_cased(decimal_point); | 616 | 2.09k | if has_decimal { | 617 | | // SAFETY: byte cannot be empty due to `first_is` | 618 | 968 | unsafe { byte.step_unchecked() }; | 619 | 968 | let before = byte.clone(); | 620 | | #[cfg(not(feature = "compact"))] | 621 | 968 | parse_8digits::<_, FORMAT>(byte.fraction_iter(), &mut mantissa); | 622 | 968 | parse_digits(byte.fraction_iter(), format.mantissa_radix(), |digit| { | 623 | | mantissa = mantissa.wrapping_mul(format.radix() as u64).wrapping_add(digit as u64); | 624 | | }); | 625 | 968 | n_after_dot = byte.current_count() - before.current_count(); | 626 | | // NOTE: We can't use the number of digits to extract the slice for | 627 | | // non-contiguous iterators, but we also need to the number of digits | 628 | | // for our value calculation. We store both, and let the compiler know | 629 | | // to optimize it out when not needed. | 630 | 968 | let b_after_dot = if cfg!(feature = "format") && !byte.fraction_iter().is_contiguous() { | 631 | 0 | byte.cursor() - before.cursor() | 632 | | } else { | 633 | 968 | n_after_dot | 634 | | }; | 635 | | | 636 | | // Store the fraction digits for slow-path algorithms. | 637 | 968 | debug_assert!( | 638 | 0 | b_after_dot <= before.as_slice().len(), | 639 | 0 | "digits after dot must be smaller than buffer" | 640 | | ); | 641 | | // SAFETY: safe, since `idx_after_dot <= before.as_slice().len()`. | 642 | 968 | fraction_digits = Some(unsafe { before.as_slice().get_unchecked(..b_after_dot) }); | 643 | | | 644 | | // Calculate the implicit exponent: the number of digits after the dot. | 645 | 968 | implicit_exponent = -(n_after_dot as i64); | 646 | 968 | if format.mantissa_radix() == format.exponent_base() { | 647 | 968 | exponent = implicit_exponent; | 648 | 968 | } else { | 649 | 0 | debug_assert!(bits_per_digit % bits_per_base == 0, "exponent must be a power of base"); | 650 | 0 | exponent = implicit_exponent * bits_per_digit / bits_per_base; | 651 | | }; | 652 | | #[cfg(feature = "format")] | 653 | | if format.required_fraction_digits() && n_after_dot == 0 { | 654 | | return Err(Error::EmptyFraction(byte.cursor())); | 655 | | } | 656 | 1.12k | } | 657 | | | 658 | | // NOTE: Check if we have our exponent **BEFORE** checking if the | 659 | | // mantissa is empty, so we can ensure | 660 | 2.09k | let has_exponent = byte | 661 | 2.09k | .first_is(exponent_character, format.case_sensitive_exponent() && cfg!(feature = "format")); | 662 | | | 663 | | // check to see if we have any invalid leading zeros | 664 | 2.09k | n_digits += n_after_dot; | 665 | 2.09k | if format.required_mantissa_digits() | 666 | 2.09k | && (n_digits == 0 || (cfg!(feature = "format") && byte.current_count() == 0)) | 667 | | { | 668 | 28 | let any_digits = start.clone().integer_iter().peek().is_some(); | 669 | | // NOTE: This is because numbers like `_12.34` have significant digits, | 670 | | // they just don't have a valid digit (#97). | 671 | 28 | if has_decimal || has_exponent || !any_digits || IS_PARTIAL { | 672 | 12 | return Err(Error::EmptyMantissa(byte.cursor())); | 673 | | } else { | 674 | 16 | return Err(Error::InvalidDigit(start.cursor())); | 675 | | } | 676 | 2.06k | } | 677 | | | 678 | | // EXPONENT | 679 | | | 680 | | // Handle scientific notation. | 681 | 2.06k | let mut explicit_exponent = 0_i64; | 682 | 2.06k | if has_exponent { | 683 | | // NOTE: See above for the safety invariant above `required_mantissa_digits`. | 684 | | // This is separated for correctness concerns, and therefore the two cannot | 685 | | // be on the same line. | 686 | | // SAFETY: byte cannot be empty due to `first_is` from `has_exponent`.` | 687 | 848 | unsafe { byte.step_unchecked() }; | 688 | | | 689 | | // Check float format syntax checks. | 690 | | #[cfg(feature = "format")] | 691 | | { | 692 | | // NOTE: We've overstepped for the safety invariant before. | 693 | | if format.no_exponent_notation() { | 694 | | return Err(Error::InvalidExponent(byte.cursor() - 1)); | 695 | | } | 696 | | // Check if we have no fraction but we required exponent notation. | 697 | | if format.no_exponent_without_fraction() && fraction_digits.is_none() { | 698 | | return Err(Error::ExponentWithoutFraction(byte.cursor() - 1)); | 699 | | } | 700 | | } | 701 | | | 702 | 848 | let is_negative_exponent = parse_exponent_sign(&mut byte)?; | 703 | 848 | let before = byte.current_count(); | 704 | 848 | parse_digits(byte.exponent_iter(), format.exponent_radix(), |digit| { | 705 | | if explicit_exponent < 0x10000000 { | 706 | | explicit_exponent *= format.exponent_radix() as i64; | 707 | | explicit_exponent += digit as i64; | 708 | | } | 709 | | }); | 710 | 848 | if format.required_exponent_digits() && byte.current_count() - before == 0 { | 711 | 9 | return Err(Error::EmptyExponent(byte.cursor())); | 712 | 839 | } | 713 | | // Handle our sign, and get the explicit part of the exponent. | 714 | 839 | explicit_exponent = if is_negative_exponent { | 715 | 520 | -explicit_exponent | 716 | | } else { | 717 | 319 | explicit_exponent | 718 | | }; | 719 | 839 | exponent += explicit_exponent; | 720 | 1.21k | } else if cfg!(feature = "format") && format.required_exponent_notation() { | 721 | 0 | return Err(Error::MissingExponent(byte.cursor())); | 722 | 1.21k | } | 723 | | | 724 | | // Check to see if we have a valid base suffix. | 725 | | // We've already trimmed any leading digit separators here, so we can be safe | 726 | | // that the first character **is not** a digit separator. | 727 | | #[allow(unused_variables)] | 728 | 2.05k | let base_suffix = format.base_suffix(); | 729 | | #[cfg(feature = "format")] | 730 | | if base_suffix != 0 { | 731 | | if byte.first_is(base_suffix, format.case_sensitive_base_suffix()) { | 732 | | // SAFETY: safe since `byte.len() >= 1`. | 733 | | unsafe { byte.step_unchecked() }; | 734 | | } | 735 | | } | 736 | | | 737 | | // CHECK OVERFLOW | 738 | | | 739 | | // Get the number of parsed digits (total), and redo if we had overflow. | 740 | 2.05k | let end = byte.cursor(); | 741 | 2.05k | let mut step = u64_step(format.mantissa_radix()); | 742 | 2.05k | let mut many_digits = false; | 743 | | #[cfg(feature = "format")] | 744 | | if !format.required_mantissa_digits() && n_digits == 0 { | 745 | | exponent = 0; | 746 | | } | 747 | 2.05k | if n_digits <= step { | 748 | 666 | return Ok(( | 749 | 666 | Number { | 750 | 666 | exponent, | 751 | 666 | mantissa, | 752 | 666 | is_negative, | 753 | 666 | many_digits: false, | 754 | 666 | integer: integer_digits, | 755 | 666 | fraction: fraction_digits, | 756 | 666 | }, | 757 | 666 | end, | 758 | 666 | )); | 759 | 1.39k | } | 760 | | | 761 | | // Check for leading zeros, and to see if we had a false overflow. | 762 | 1.39k | n_digits -= step; | 763 | 1.39k | let mut zeros = start.clone(); | 764 | 1.39k | let mut zeros_integer = zeros.integer_iter(); | 765 | 1.39k | n_digits = n_digits.saturating_sub(zeros_integer.skip_zeros()); | 766 | 1.39k | if zeros.first_is_cased(decimal_point) { | 767 | 213 | // SAFETY: safe since zeros cannot be empty due to `first_is` | 768 | 213 | unsafe { zeros.step_unchecked() }; | 769 | 1.17k | } | 770 | 1.39k | let mut zeros_fraction = zeros.fraction_iter(); | 771 | 1.39k | n_digits = n_digits.saturating_sub(zeros_fraction.skip_zeros()); | 772 | | | 773 | | // OVERFLOW | 774 | | | 775 | | // Now, check if we explicitly overflowed. | 776 | 1.39k | if n_digits > 0 { | 777 | | // Have more than 19 significant digits, so we overflowed. | 778 | 1.31k | many_digits = true; | 779 | 1.31k | mantissa = 0; | 780 | 1.31k | let mut integer = integer_digits.bytes::<{ FORMAT }>(); | 781 | | // Skip leading zeros, so we can use the step properly. | 782 | 1.31k | let mut integer_iter = integer.integer_iter(); | 783 | 1.31k | integer_iter.skip_zeros(); | 784 | 1.31k | parse_u64_digits::<_, FORMAT>(integer_iter, &mut mantissa, &mut step); | 785 | | // NOTE: With the format feature enabled and non-contiguous iterators, we can | 786 | | // have null fraction digits even if step was not 0. We want to make the | 787 | | // none check as late in there as possible: any of them should | 788 | | // short-circuit and should be determined at compile time. So, the | 789 | | // conditions are either: | 790 | | // 1. Step == 0 | 791 | | // 2. `cfg!(feature = "format") && !byte.is_contiguous() && | 792 | | // fraction_digits.is_none()` | 793 | 1.31k | implicit_exponent = if step == 0 | 794 | 624 | || (cfg!(feature = "format") && !byte.is_contiguous() && fraction_digits.is_none()) | 795 | | { | 796 | | // Filled our mantissa with just the integer. | 797 | 688 | int_end - integer.current_count() as i64 | 798 | | } else { | 799 | | // We know this can't be a None since we had more than 19 | 800 | | // digits previously, so we overflowed a 64-bit integer, | 801 | | // but parsing only the integral digits produced less | 802 | | // than 19 digits. That means we must have a decimal | 803 | | // point, and at least 1 fractional digit. | 804 | 624 | let mut fraction = fraction_digits.unwrap().bytes::<{ FORMAT }>(); | 805 | 624 | let mut fraction_iter = fraction.fraction_iter(); | 806 | | // Skip leading zeros, so we can use the step properly. | 807 | 624 | if mantissa == 0 { | 808 | 182 | fraction_iter.skip_zeros(); | 809 | 442 | } | 810 | 624 | parse_u64_digits::<_, FORMAT>(fraction_iter, &mut mantissa, &mut step); | 811 | 624 | -(fraction.current_count() as i64) | 812 | | }; | 813 | 1.31k | if format.mantissa_radix() == format.exponent_base() { | 814 | 1.31k | exponent = implicit_exponent; | 815 | 1.31k | } else { | 816 | 0 | debug_assert!(bits_per_digit % bits_per_base == 0, "exponent must be a power of base"); | 817 | 0 | exponent = implicit_exponent * bits_per_digit / bits_per_base; | 818 | | }; | 819 | | // Add back the explicit exponent. | 820 | 1.31k | exponent += explicit_exponent; | 821 | 78 | } | 822 | | | 823 | 1.39k | Ok(( | 824 | 1.39k | Number { | 825 | 1.39k | exponent, | 826 | 1.39k | mantissa, | 827 | 1.39k | is_negative, | 828 | 1.39k | many_digits, | 829 | 1.39k | integer: integer_digits, | 830 | 1.39k | fraction: fraction_digits, | 831 | 1.39k | }, | 832 | 1.39k | end, | 833 | 1.39k | )) | 834 | 2.09k | } |
Unexecuted instantiation: lexical_parse_float::parse::parse_number::<_, _> lexical_parse_float::parse::parse_number::<0xa0000000000000000000000000c, false> Line | Count | Source | 495 | 2.96k | pub fn parse_number<'a, const FORMAT: u128, const IS_PARTIAL: bool>( | 496 | 2.96k | mut byte: Bytes<'a, FORMAT>, | 497 | 2.96k | is_negative: bool, | 498 | 2.96k | options: &Options, | 499 | 2.96k | ) -> Result<(Number<'a>, usize)> { | 500 | | // NOTE: | 501 | | // There are no satisfactory optimizations to reduce the number | 502 | | // of multiplications for very long input strings, but this will | 503 | | // be a small fraction of the performance penalty anyway. | 504 | | // | 505 | | // We've tried: | 506 | | // - checking for explicit overflow, via `overflowing_mul`. | 507 | | // - counting the max number of steps. | 508 | | // - subslicing the string, and only processing the first `step` | 509 | | // digits. | 510 | | // - pre-computing the maximum power, and only adding until then. | 511 | | // | 512 | | // All of these lead to substantial performance penalty. | 513 | | // If we pre-parse the string, then only process it then, we | 514 | | // get a performance penalty of ~2.5x (20ns to 50ns) for common | 515 | | // floats, an unacceptable cost, while only improving performance | 516 | | // for rare floats 5-25% (9.3µs to 7.5µs for denormal with 6400 | 517 | | // digits, and 7.8µs to 7.4µs for large floats with 6400 digits). | 518 | | // | 519 | | // The performance cost is **almost** entirely in this function, | 520 | | // but additional branching **does** not improve performance, | 521 | | // and pre-tokenization is a recipe for failure. For halfway | 522 | | // cases with smaller numbers of digits, the majority of the | 523 | | // performance cost is in the big integer arithmetic (`pow` and | 524 | | // `parse_mantissa`), which suggests few optimizations can or should | 525 | | // be made. | 526 | | | 527 | | // Config options | 528 | 2.96k | let format = NumberFormat::<{ FORMAT }> {}; | 529 | 2.96k | let decimal_point = options.decimal_point(); | 530 | 2.96k | let exponent_character = options.exponent(); | 531 | 2.96k | debug_assert!(format.is_valid(), "should have already checked for an invalid number format"); | 532 | 2.96k | debug_assert!(!byte.is_buffer_empty(), "should have previously checked for empty input"); | 533 | 2.96k | let bits_per_digit = shared::log2(format.mantissa_radix()) as i64; | 534 | 2.96k | let bits_per_base = shared::log2(format.exponent_base()) as i64; | 535 | | | 536 | | // INTEGER | 537 | | | 538 | | // Check to see if we have a valid base prefix. | 539 | | #[allow(unused_variables)] | 540 | 2.96k | let mut is_prefix = false; | 541 | | #[cfg(feature = "format")] | 542 | | { | 543 | | let base_prefix = format.base_prefix(); | 544 | | let mut iter = byte.integer_iter(); | 545 | | if base_prefix != 0 && iter.read_if_value_cased(b'0').is_some() { | 546 | | // Check to see if the next character is the base prefix. | 547 | | // We must have a format like `0x`, `0d`, `0o`. | 548 | | // NOTE: The check for empty integer digits happens below so | 549 | | // we don't need a redundant check here. | 550 | | is_prefix = true; | 551 | | if iter.read_if_value(base_prefix, format.case_sensitive_base_prefix()).is_some() | 552 | | && iter.is_buffer_empty() | 553 | | && format.required_integer_digits() | 554 | | { | 555 | | return Err(Error::EmptyInteger(iter.cursor())); | 556 | | } | 557 | | } | 558 | | } | 559 | | | 560 | | // Parse our integral digits. | 561 | 2.96k | let mut mantissa = 0_u64; | 562 | 2.96k | let start = byte.clone(); | 563 | | #[cfg(not(feature = "compact"))] | 564 | 2.96k | parse_8digits::<_, FORMAT>(byte.integer_iter(), &mut mantissa); | 565 | 2.96k | parse_digits(byte.integer_iter(), format.mantissa_radix(), |digit| { | 566 | | mantissa = mantissa.wrapping_mul(format.radix() as u64).wrapping_add(digit as u64); | 567 | | }); | 568 | 2.96k | let mut n_digits = byte.current_count() - start.current_count(); | 569 | | #[cfg(feature = "format")] | 570 | | if format.required_integer_digits() && n_digits == 0 { | 571 | | return Err(Error::EmptyInteger(byte.cursor())); | 572 | | } | 573 | | | 574 | | // Store the integer digits for slow-path algorithms. | 575 | | // NOTE: We can't use the number of digits to extract the slice for | 576 | | // non-contiguous iterators, but we also need to the number of digits | 577 | | // for our value calculation. We store both, and let the compiler know | 578 | | // to optimize it out when not needed. | 579 | 2.96k | let b_digits = if cfg!(feature = "format") && !byte.integer_iter().is_contiguous() { | 580 | 0 | byte.cursor() - start.cursor() | 581 | | } else { | 582 | 2.96k | n_digits | 583 | | }; | 584 | 2.96k | debug_assert!( | 585 | 0 | b_digits <= start.as_slice().len(), | 586 | 0 | "number of digits parsed must <= buffer length" | 587 | | ); | 588 | | // SAFETY: safe, since `n_digits <= start.as_slice().len()`. | 589 | | // This is since `byte.len() >= start.len()` but has to have | 590 | | // the same end bounds (that is, `start = byte.clone()`), so | 591 | | // `0 <= byte.current_count() <= start.current_count() <= start.lent()` | 592 | | // so, this will always return only the integer digits. | 593 | | // | 594 | | // NOTE: Removing this code leads to ~10% reduction in parsing | 595 | | // that triggers the Eisell-Lemire algorithm or the digit comp | 596 | | // algorithms, so don't remove the unsafe indexing. | 597 | 2.96k | let integer_digits = unsafe { start.as_slice().get_unchecked(..b_digits) }; | 598 | | | 599 | | // Check if integer leading zeros are disabled. | 600 | | #[cfg(feature = "format")] | 601 | | if !is_prefix && format.no_float_leading_zeros() { | 602 | | if integer_digits.len() > 1 && integer_digits.first() == Some(&b'0') { | 603 | | return Err(Error::InvalidLeadingZeros(start.cursor())); | 604 | | } | 605 | | } | 606 | | | 607 | | // FRACTION | 608 | | | 609 | | // Handle decimal point and digits afterwards. | 610 | 2.96k | let mut n_after_dot = 0; | 611 | 2.96k | let mut exponent = 0_i64; | 612 | | let mut implicit_exponent: i64; | 613 | 2.96k | let int_end = n_digits as i64; | 614 | 2.96k | let mut fraction_digits = None; | 615 | 2.96k | let has_decimal = byte.first_is_cased(decimal_point); | 616 | 2.96k | if has_decimal { | 617 | | // SAFETY: byte cannot be empty due to `first_is` | 618 | 1.10k | unsafe { byte.step_unchecked() }; | 619 | 1.10k | let before = byte.clone(); | 620 | | #[cfg(not(feature = "compact"))] | 621 | 1.10k | parse_8digits::<_, FORMAT>(byte.fraction_iter(), &mut mantissa); | 622 | 1.10k | parse_digits(byte.fraction_iter(), format.mantissa_radix(), |digit| { | 623 | | mantissa = mantissa.wrapping_mul(format.radix() as u64).wrapping_add(digit as u64); | 624 | | }); | 625 | 1.10k | n_after_dot = byte.current_count() - before.current_count(); | 626 | | // NOTE: We can't use the number of digits to extract the slice for | 627 | | // non-contiguous iterators, but we also need to the number of digits | 628 | | // for our value calculation. We store both, and let the compiler know | 629 | | // to optimize it out when not needed. | 630 | 1.10k | let b_after_dot = if cfg!(feature = "format") && !byte.fraction_iter().is_contiguous() { | 631 | 0 | byte.cursor() - before.cursor() | 632 | | } else { | 633 | 1.10k | n_after_dot | 634 | | }; | 635 | | | 636 | | // Store the fraction digits for slow-path algorithms. | 637 | 1.10k | debug_assert!( | 638 | 0 | b_after_dot <= before.as_slice().len(), | 639 | 0 | "digits after dot must be smaller than buffer" | 640 | | ); | 641 | | // SAFETY: safe, since `idx_after_dot <= before.as_slice().len()`. | 642 | 1.10k | fraction_digits = Some(unsafe { before.as_slice().get_unchecked(..b_after_dot) }); | 643 | | | 644 | | // Calculate the implicit exponent: the number of digits after the dot. | 645 | 1.10k | implicit_exponent = -(n_after_dot as i64); | 646 | 1.10k | if format.mantissa_radix() == format.exponent_base() { | 647 | 1.10k | exponent = implicit_exponent; | 648 | 1.10k | } else { | 649 | 0 | debug_assert!(bits_per_digit % bits_per_base == 0, "exponent must be a power of base"); | 650 | 0 | exponent = implicit_exponent * bits_per_digit / bits_per_base; | 651 | | }; | 652 | | #[cfg(feature = "format")] | 653 | | if format.required_fraction_digits() && n_after_dot == 0 { | 654 | | return Err(Error::EmptyFraction(byte.cursor())); | 655 | | } | 656 | 1.86k | } | 657 | | | 658 | | // NOTE: Check if we have our exponent **BEFORE** checking if the | 659 | | // mantissa is empty, so we can ensure | 660 | 2.96k | let has_exponent = byte | 661 | 2.96k | .first_is(exponent_character, format.case_sensitive_exponent() && cfg!(feature = "format")); | 662 | | | 663 | | // check to see if we have any invalid leading zeros | 664 | 2.96k | n_digits += n_after_dot; | 665 | 2.96k | if format.required_mantissa_digits() | 666 | 2.96k | && (n_digits == 0 || (cfg!(feature = "format") && byte.current_count() == 0)) | 667 | | { | 668 | 30 | let any_digits = start.clone().integer_iter().peek().is_some(); | 669 | | // NOTE: This is because numbers like `_12.34` have significant digits, | 670 | | // they just don't have a valid digit (#97). | 671 | 30 | if has_decimal || has_exponent || !any_digits || IS_PARTIAL { | 672 | 9 | return Err(Error::EmptyMantissa(byte.cursor())); | 673 | | } else { | 674 | 21 | return Err(Error::InvalidDigit(start.cursor())); | 675 | | } | 676 | 2.93k | } | 677 | | | 678 | | // EXPONENT | 679 | | | 680 | | // Handle scientific notation. | 681 | 2.93k | let mut explicit_exponent = 0_i64; | 682 | 2.93k | if has_exponent { | 683 | | // NOTE: See above for the safety invariant above `required_mantissa_digits`. | 684 | | // This is separated for correctness concerns, and therefore the two cannot | 685 | | // be on the same line. | 686 | | // SAFETY: byte cannot be empty due to `first_is` from `has_exponent`.` | 687 | 1.45k | unsafe { byte.step_unchecked() }; | 688 | | | 689 | | // Check float format syntax checks. | 690 | | #[cfg(feature = "format")] | 691 | | { | 692 | | // NOTE: We've overstepped for the safety invariant before. | 693 | | if format.no_exponent_notation() { | 694 | | return Err(Error::InvalidExponent(byte.cursor() - 1)); | 695 | | } | 696 | | // Check if we have no fraction but we required exponent notation. | 697 | | if format.no_exponent_without_fraction() && fraction_digits.is_none() { | 698 | | return Err(Error::ExponentWithoutFraction(byte.cursor() - 1)); | 699 | | } | 700 | | } | 701 | | | 702 | 1.45k | let is_negative_exponent = parse_exponent_sign(&mut byte)?; | 703 | 1.45k | let before = byte.current_count(); | 704 | 1.45k | parse_digits(byte.exponent_iter(), format.exponent_radix(), |digit| { | 705 | | if explicit_exponent < 0x10000000 { | 706 | | explicit_exponent *= format.exponent_radix() as i64; | 707 | | explicit_exponent += digit as i64; | 708 | | } | 709 | | }); | 710 | 1.45k | if format.required_exponent_digits() && byte.current_count() - before == 0 { | 711 | 10 | return Err(Error::EmptyExponent(byte.cursor())); | 712 | 1.44k | } | 713 | | // Handle our sign, and get the explicit part of the exponent. | 714 | 1.44k | explicit_exponent = if is_negative_exponent { | 715 | 578 | -explicit_exponent | 716 | | } else { | 717 | 864 | explicit_exponent | 718 | | }; | 719 | 1.44k | exponent += explicit_exponent; | 720 | 1.48k | } else if cfg!(feature = "format") && format.required_exponent_notation() { | 721 | 0 | return Err(Error::MissingExponent(byte.cursor())); | 722 | 1.48k | } | 723 | | | 724 | | // Check to see if we have a valid base suffix. | 725 | | // We've already trimmed any leading digit separators here, so we can be safe | 726 | | // that the first character **is not** a digit separator. | 727 | | #[allow(unused_variables)] | 728 | 2.92k | let base_suffix = format.base_suffix(); | 729 | | #[cfg(feature = "format")] | 730 | | if base_suffix != 0 { | 731 | | if byte.first_is(base_suffix, format.case_sensitive_base_suffix()) { | 732 | | // SAFETY: safe since `byte.len() >= 1`. | 733 | | unsafe { byte.step_unchecked() }; | 734 | | } | 735 | | } | 736 | | | 737 | | // CHECK OVERFLOW | 738 | | | 739 | | // Get the number of parsed digits (total), and redo if we had overflow. | 740 | 2.92k | let end = byte.cursor(); | 741 | 2.92k | let mut step = u64_step(format.mantissa_radix()); | 742 | 2.92k | let mut many_digits = false; | 743 | | #[cfg(feature = "format")] | 744 | | if !format.required_mantissa_digits() && n_digits == 0 { | 745 | | exponent = 0; | 746 | | } | 747 | 2.92k | if n_digits <= step { | 748 | 961 | return Ok(( | 749 | 961 | Number { | 750 | 961 | exponent, | 751 | 961 | mantissa, | 752 | 961 | is_negative, | 753 | 961 | many_digits: false, | 754 | 961 | integer: integer_digits, | 755 | 961 | fraction: fraction_digits, | 756 | 961 | }, | 757 | 961 | end, | 758 | 961 | )); | 759 | 1.96k | } | 760 | | | 761 | | // Check for leading zeros, and to see if we had a false overflow. | 762 | 1.96k | n_digits -= step; | 763 | 1.96k | let mut zeros = start.clone(); | 764 | 1.96k | let mut zeros_integer = zeros.integer_iter(); | 765 | 1.96k | n_digits = n_digits.saturating_sub(zeros_integer.skip_zeros()); | 766 | 1.96k | if zeros.first_is_cased(decimal_point) { | 767 | 307 | // SAFETY: safe since zeros cannot be empty due to `first_is` | 768 | 307 | unsafe { zeros.step_unchecked() }; | 769 | 1.66k | } | 770 | 1.96k | let mut zeros_fraction = zeros.fraction_iter(); | 771 | 1.96k | n_digits = n_digits.saturating_sub(zeros_fraction.skip_zeros()); | 772 | | | 773 | | // OVERFLOW | 774 | | | 775 | | // Now, check if we explicitly overflowed. | 776 | 1.96k | if n_digits > 0 { | 777 | | // Have more than 19 significant digits, so we overflowed. | 778 | 1.88k | many_digits = true; | 779 | 1.88k | mantissa = 0; | 780 | 1.88k | let mut integer = integer_digits.bytes::<{ FORMAT }>(); | 781 | | // Skip leading zeros, so we can use the step properly. | 782 | 1.88k | let mut integer_iter = integer.integer_iter(); | 783 | 1.88k | integer_iter.skip_zeros(); | 784 | 1.88k | parse_u64_digits::<_, FORMAT>(integer_iter, &mut mantissa, &mut step); | 785 | | // NOTE: With the format feature enabled and non-contiguous iterators, we can | 786 | | // have null fraction digits even if step was not 0. We want to make the | 787 | | // none check as late in there as possible: any of them should | 788 | | // short-circuit and should be determined at compile time. So, the | 789 | | // conditions are either: | 790 | | // 1. Step == 0 | 791 | | // 2. `cfg!(feature = "format") && !byte.is_contiguous() && | 792 | | // fraction_digits.is_none()` | 793 | 1.88k | implicit_exponent = if step == 0 | 794 | 604 | || (cfg!(feature = "format") && !byte.is_contiguous() && fraction_digits.is_none()) | 795 | | { | 796 | | // Filled our mantissa with just the integer. | 797 | 1.28k | int_end - integer.current_count() as i64 | 798 | | } else { | 799 | | // We know this can't be a None since we had more than 19 | 800 | | // digits previously, so we overflowed a 64-bit integer, | 801 | | // but parsing only the integral digits produced less | 802 | | // than 19 digits. That means we must have a decimal | 803 | | // point, and at least 1 fractional digit. | 804 | 604 | let mut fraction = fraction_digits.unwrap().bytes::<{ FORMAT }>(); | 805 | 604 | let mut fraction_iter = fraction.fraction_iter(); | 806 | | // Skip leading zeros, so we can use the step properly. | 807 | 604 | if mantissa == 0 { | 808 | 275 | fraction_iter.skip_zeros(); | 809 | 329 | } | 810 | 604 | parse_u64_digits::<_, FORMAT>(fraction_iter, &mut mantissa, &mut step); | 811 | 604 | -(fraction.current_count() as i64) | 812 | | }; | 813 | 1.88k | if format.mantissa_radix() == format.exponent_base() { | 814 | 1.88k | exponent = implicit_exponent; | 815 | 1.88k | } else { | 816 | 0 | debug_assert!(bits_per_digit % bits_per_base == 0, "exponent must be a power of base"); | 817 | 0 | exponent = implicit_exponent * bits_per_digit / bits_per_base; | 818 | | }; | 819 | | // Add back the explicit exponent. | 820 | 1.88k | exponent += explicit_exponent; | 821 | 79 | } | 822 | | | 823 | 1.96k | Ok(( | 824 | 1.96k | Number { | 825 | 1.96k | exponent, | 826 | 1.96k | mantissa, | 827 | 1.96k | is_negative, | 828 | 1.96k | many_digits, | 829 | 1.96k | integer: integer_digits, | 830 | 1.96k | fraction: fraction_digits, | 831 | 1.96k | }, | 832 | 1.96k | end, | 833 | 1.96k | )) | 834 | 2.96k | } |
|
835 | | |
836 | | #[inline(always)] |
837 | 0 | pub fn parse_partial_number<'a, const FORMAT: u128>( |
838 | 0 | byte: Bytes<'a, FORMAT>, |
839 | 0 | is_negative: bool, |
840 | 0 | options: &Options, |
841 | 0 | ) -> Result<(Number<'a>, usize)> { |
842 | 0 | parse_number::<FORMAT, true>(byte, is_negative, options) |
843 | 0 | } |
844 | | |
845 | | /// Try to parse a non-special floating point number. |
846 | | #[inline(always)] |
847 | 5.06k | pub fn parse_complete_number<'a, const FORMAT: u128>( |
848 | 5.06k | byte: Bytes<'a, FORMAT>, |
849 | 5.06k | is_negative: bool, |
850 | 5.06k | options: &Options, |
851 | 5.06k | ) -> Result<Number<'a>> { |
852 | | // Then have a const `IsPartial` as well |
853 | 5.06k | let length = byte.buffer_length(); |
854 | 5.06k | let (float, count) = parse_number::<FORMAT, false>(byte, is_negative, options)?; |
855 | 4.98k | if count == length { |
856 | 4.80k | Ok(float) |
857 | | } else { |
858 | 176 | Err(Error::InvalidDigit(count)) |
859 | | } |
860 | 5.06k | } lexical_parse_float::parse::parse_complete_number::<0xa0000000000000000000000000c> Line | Count | Source | 847 | 2.09k | pub fn parse_complete_number<'a, const FORMAT: u128>( | 848 | 2.09k | byte: Bytes<'a, FORMAT>, | 849 | 2.09k | is_negative: bool, | 850 | 2.09k | options: &Options, | 851 | 2.09k | ) -> Result<Number<'a>> { | 852 | | // Then have a const `IsPartial` as well | 853 | 2.09k | let length = byte.buffer_length(); | 854 | 2.09k | let (float, count) = parse_number::<FORMAT, false>(byte, is_negative, options)?; | 855 | 2.05k | if count == length { | 856 | 1.96k | Ok(float) | 857 | | } else { | 858 | 90 | Err(Error::InvalidDigit(count)) | 859 | | } | 860 | 2.09k | } |
Unexecuted instantiation: lexical_parse_float::parse::parse_complete_number::<_> lexical_parse_float::parse::parse_complete_number::<0xa0000000000000000000000000c> Line | Count | Source | 847 | 2.96k | pub fn parse_complete_number<'a, const FORMAT: u128>( | 848 | 2.96k | byte: Bytes<'a, FORMAT>, | 849 | 2.96k | is_negative: bool, | 850 | 2.96k | options: &Options, | 851 | 2.96k | ) -> Result<Number<'a>> { | 852 | | // Then have a const `IsPartial` as well | 853 | 2.96k | let length = byte.buffer_length(); | 854 | 2.96k | let (float, count) = parse_number::<FORMAT, false>(byte, is_negative, options)?; | 855 | 2.92k | if count == length { | 856 | 2.84k | Ok(float) | 857 | | } else { | 858 | 86 | Err(Error::InvalidDigit(count)) | 859 | | } | 860 | 2.96k | } |
|
861 | | |
862 | | // DIGITS |
863 | | // ------ |
864 | | |
865 | | /// Iteratively parse and consume digits from bytes. |
866 | | #[inline(always)] |
867 | 9.42k | pub fn parse_digits<'a, Iter, Cb>(mut iter: Iter, radix: u32, mut cb: Cb) |
868 | 9.42k | where |
869 | 9.42k | Iter: DigitsIter<'a>, |
870 | 9.42k | Cb: FnMut(u32), |
871 | | { |
872 | 3.30M | while let Some(&c) = iter.peek() { |
873 | 3.30M | match char_to_digit_const(c, radix) { |
874 | 3.29M | Some(v) => cb(v), |
875 | 4.61k | None => break, |
876 | | } |
877 | | // SAFETY: iter cannot be empty due to `iter.peek()`. |
878 | | // NOTE: Because of the match statement, this would optimize poorly with |
879 | | // `read_if`. |
880 | 3.29M | unsafe { iter.step_unchecked() }; |
881 | 3.29M | iter.increment_count(); |
882 | | } |
883 | 9.42k | } lexical_parse_float::parse::parse_digits::<lexical_util::noskip::DigitsIterator<0xa0000000000000000000000000c>, lexical_parse_float::parse::parse_number<0xa0000000000000000000000000c, false>::{closure#0}> Line | Count | Source | 867 | 2.09k | pub fn parse_digits<'a, Iter, Cb>(mut iter: Iter, radix: u32, mut cb: Cb) | 868 | 2.09k | where | 869 | 2.09k | Iter: DigitsIter<'a>, | 870 | 2.09k | Cb: FnMut(u32), | 871 | | { | 872 | 8.18k | while let Some(&c) = iter.peek() { | 873 | 7.84k | match char_to_digit_const(c, radix) { | 874 | 6.09k | Some(v) => cb(v), | 875 | 1.75k | None => break, | 876 | | } | 877 | | // SAFETY: iter cannot be empty due to `iter.peek()`. | 878 | | // NOTE: Because of the match statement, this would optimize poorly with | 879 | | // `read_if`. | 880 | 6.09k | unsafe { iter.step_unchecked() }; | 881 | 6.09k | iter.increment_count(); | 882 | | } | 883 | 2.09k | } |
lexical_parse_float::parse::parse_digits::<lexical_util::noskip::DigitsIterator<0xa0000000000000000000000000c>, lexical_parse_float::parse::parse_number<0xa0000000000000000000000000c, false>::{closure#2}> Line | Count | Source | 867 | 848 | pub fn parse_digits<'a, Iter, Cb>(mut iter: Iter, radix: u32, mut cb: Cb) | 868 | 848 | where | 869 | 848 | Iter: DigitsIter<'a>, | 870 | 848 | Cb: FnMut(u32), | 871 | | { | 872 | 2.18M | while let Some(&c) = iter.peek() { | 873 | 2.18M | match char_to_digit_const(c, radix) { | 874 | 2.18M | Some(v) => cb(v), | 875 | 15 | None => break, | 876 | | } | 877 | | // SAFETY: iter cannot be empty due to `iter.peek()`. | 878 | | // NOTE: Because of the match statement, this would optimize poorly with | 879 | | // `read_if`. | 880 | 2.18M | unsafe { iter.step_unchecked() }; | 881 | 2.18M | iter.increment_count(); | 882 | | } | 883 | 848 | } |
lexical_parse_float::parse::parse_digits::<lexical_util::noskip::DigitsIterator<0xa0000000000000000000000000c>, lexical_parse_float::parse::parse_number<0xa0000000000000000000000000c, false>::{closure#1}> Line | Count | Source | 867 | 968 | pub fn parse_digits<'a, Iter, Cb>(mut iter: Iter, radix: u32, mut cb: Cb) | 868 | 968 | where | 869 | 968 | Iter: DigitsIter<'a>, | 870 | 968 | Cb: FnMut(u32), | 871 | | { | 872 | 3.62k | while let Some(&c) = iter.peek() { | 873 | 2.82k | match char_to_digit_const(c, radix) { | 874 | 2.65k | Some(v) => cb(v), | 875 | 173 | None => break, | 876 | | } | 877 | | // SAFETY: iter cannot be empty due to `iter.peek()`. | 878 | | // NOTE: Because of the match statement, this would optimize poorly with | 879 | | // `read_if`. | 880 | 2.65k | unsafe { iter.step_unchecked() }; | 881 | 2.65k | iter.increment_count(); | 882 | | } | 883 | 968 | } |
Unexecuted instantiation: lexical_parse_float::parse::parse_digits::<_, _> lexical_parse_float::parse::parse_digits::<lexical_util::noskip::DigitsIterator<0xa0000000000000000000000000c>, lexical_parse_float::parse::parse_number<0xa0000000000000000000000000c, false>::{closure#0}> Line | Count | Source | 867 | 2.96k | pub fn parse_digits<'a, Iter, Cb>(mut iter: Iter, radix: u32, mut cb: Cb) | 868 | 2.96k | where | 869 | 2.96k | Iter: DigitsIter<'a>, | 870 | 2.96k | Cb: FnMut(u32), | 871 | | { | 872 | 10.8k | while let Some(&c) = iter.peek() { | 873 | 10.2k | match char_to_digit_const(c, radix) { | 874 | 7.85k | Some(v) => cb(v), | 875 | 2.38k | None => break, | 876 | | } | 877 | | // SAFETY: iter cannot be empty due to `iter.peek()`. | 878 | | // NOTE: Because of the match statement, this would optimize poorly with | 879 | | // `read_if`. | 880 | 7.85k | unsafe { iter.step_unchecked() }; | 881 | 7.85k | iter.increment_count(); | 882 | | } | 883 | 2.96k | } |
lexical_parse_float::parse::parse_digits::<lexical_util::noskip::DigitsIterator<0xa0000000000000000000000000c>, lexical_parse_float::parse::parse_number<0xa0000000000000000000000000c, false>::{closure#2}> Line | Count | Source | 867 | 1.45k | pub fn parse_digits<'a, Iter, Cb>(mut iter: Iter, radix: u32, mut cb: Cb) | 868 | 1.45k | where | 869 | 1.45k | Iter: DigitsIter<'a>, | 870 | 1.45k | Cb: FnMut(u32), | 871 | | { | 872 | 1.09M | while let Some(&c) = iter.peek() { | 873 | 1.09M | match char_to_digit_const(c, radix) { | 874 | 1.09M | Some(v) => cb(v), | 875 | 15 | None => break, | 876 | | } | 877 | | // SAFETY: iter cannot be empty due to `iter.peek()`. | 878 | | // NOTE: Because of the match statement, this would optimize poorly with | 879 | | // `read_if`. | 880 | 1.09M | unsafe { iter.step_unchecked() }; | 881 | 1.09M | iter.increment_count(); | 882 | | } | 883 | 1.45k | } |
lexical_parse_float::parse::parse_digits::<lexical_util::noskip::DigitsIterator<0xa0000000000000000000000000c>, lexical_parse_float::parse::parse_number<0xa0000000000000000000000000c, false>::{closure#1}> Line | Count | Source | 867 | 1.10k | pub fn parse_digits<'a, Iter, Cb>(mut iter: Iter, radix: u32, mut cb: Cb) | 868 | 1.10k | where | 869 | 1.10k | Iter: DigitsIter<'a>, | 870 | 1.10k | Cb: FnMut(u32), | 871 | | { | 872 | 4.27k | while let Some(&c) = iter.peek() { | 873 | 3.44k | match char_to_digit_const(c, radix) { | 874 | 3.17k | Some(v) => cb(v), | 875 | 272 | None => break, | 876 | | } | 877 | | // SAFETY: iter cannot be empty due to `iter.peek()`. | 878 | | // NOTE: Because of the match statement, this would optimize poorly with | 879 | | // `read_if`. | 880 | 3.17k | unsafe { iter.step_unchecked() }; | 881 | 3.17k | iter.increment_count(); | 882 | | } | 883 | 1.10k | } |
|
884 | | |
885 | | /// Iteratively parse and consume digits in intervals of 8. |
886 | | /// |
887 | | /// # Preconditions |
888 | | /// |
889 | | /// The iterator must be of the significant digits, not the exponent. |
890 | | #[inline(always)] |
891 | | #[cfg(not(feature = "compact"))] |
892 | 7.12k | pub fn parse_8digits<'a, Iter, const FORMAT: u128>(mut iter: Iter, mantissa: &mut u64) |
893 | 7.12k | where |
894 | 7.12k | Iter: DigitsIter<'a>, |
895 | | { |
896 | 7.12k | let format = NumberFormat::<{ FORMAT }> {}; |
897 | 7.12k | let radix: u64 = format.radix() as u64; |
898 | 7.12k | if can_try_parse_multidigit!(iter, radix) { |
899 | 7.12k | debug_assert!(radix < 16, "radices over 16 will overflow with radix^8"); |
900 | 7.12k | let radix8 = format.radix8() as u64; |
901 | | // Can do up to 2 iterations without overflowing, however, for large |
902 | | // inputs, this is much faster than any other alternative. |
903 | 8.84M | while let Some(v) = algorithm::try_parse_8digits::<u64, _, FORMAT>(&mut iter) { |
904 | 8.83M | *mantissa = mantissa.wrapping_mul(radix8).wrapping_add(v); |
905 | 8.83M | } |
906 | 0 | } |
907 | 7.12k | } lexical_parse_float::parse::parse_8digits::<lexical_util::noskip::DigitsIterator<0xa0000000000000000000000000c>, 0xa0000000000000000000000000c> Line | Count | Source | 892 | 3.06k | pub fn parse_8digits<'a, Iter, const FORMAT: u128>(mut iter: Iter, mantissa: &mut u64) | 893 | 3.06k | where | 894 | 3.06k | Iter: DigitsIter<'a>, | 895 | | { | 896 | 3.06k | let format = NumberFormat::<{ FORMAT }> {}; | 897 | 3.06k | let radix: u64 = format.radix() as u64; | 898 | 3.06k | if can_try_parse_multidigit!(iter, radix) { | 899 | 3.06k | debug_assert!(radix < 16, "radices over 16 will overflow with radix^8"); | 900 | 3.06k | let radix8 = format.radix8() as u64; | 901 | | // Can do up to 2 iterations without overflowing, however, for large | 902 | | // inputs, this is much faster than any other alternative. | 903 | 4.29M | while let Some(v) = algorithm::try_parse_8digits::<u64, _, FORMAT>(&mut iter) { | 904 | 4.29M | *mantissa = mantissa.wrapping_mul(radix8).wrapping_add(v); | 905 | 4.29M | } | 906 | 0 | } | 907 | 3.06k | } |
Unexecuted instantiation: lexical_parse_float::parse::parse_8digits::<_, _> lexical_parse_float::parse::parse_8digits::<lexical_util::noskip::DigitsIterator<0xa0000000000000000000000000c>, 0xa0000000000000000000000000c> Line | Count | Source | 892 | 4.06k | pub fn parse_8digits<'a, Iter, const FORMAT: u128>(mut iter: Iter, mantissa: &mut u64) | 893 | 4.06k | where | 894 | 4.06k | Iter: DigitsIter<'a>, | 895 | | { | 896 | 4.06k | let format = NumberFormat::<{ FORMAT }> {}; | 897 | 4.06k | let radix: u64 = format.radix() as u64; | 898 | 4.06k | if can_try_parse_multidigit!(iter, radix) { | 899 | 4.06k | debug_assert!(radix < 16, "radices over 16 will overflow with radix^8"); | 900 | 4.06k | let radix8 = format.radix8() as u64; | 901 | | // Can do up to 2 iterations without overflowing, however, for large | 902 | | // inputs, this is much faster than any other alternative. | 903 | 4.55M | while let Some(v) = algorithm::try_parse_8digits::<u64, _, FORMAT>(&mut iter) { | 904 | 4.54M | *mantissa = mantissa.wrapping_mul(radix8).wrapping_add(v); | 905 | 4.54M | } | 906 | 0 | } | 907 | 4.06k | } |
|
908 | | |
909 | | /// Iteratively parse and consume digits without overflowing. |
910 | | /// |
911 | | /// # Preconditions |
912 | | /// |
913 | | /// There must be at least `step` digits left in iterator. The iterator almost |
914 | | /// must be of the significant digits, not the exponent. |
915 | | #[cfg_attr(not(feature = "compact"), inline(always))] |
916 | 4.42k | pub fn parse_u64_digits<'a, Iter, const FORMAT: u128>( |
917 | 4.42k | mut iter: Iter, |
918 | 4.42k | mantissa: &mut u64, |
919 | 4.42k | step: &mut usize, |
920 | 4.42k | ) where |
921 | 4.42k | Iter: DigitsIter<'a>, |
922 | | { |
923 | 4.42k | let format = NumberFormat::<{ FORMAT }> {}; |
924 | 4.42k | let radix = format.radix() as u64; |
925 | | |
926 | | // Try to parse 8 digits at a time, if we can. |
927 | | #[cfg(not(feature = "compact"))] |
928 | 4.42k | if can_try_parse_multidigit!(iter, radix) { |
929 | 4.42k | debug_assert!(radix < 16, "radices over 16 will overflow with radix^8"); |
930 | 4.42k | let radix8 = format.radix8() as u64; |
931 | 10.4k | while *step > 8 { |
932 | 6.98k | if let Some(v) = algorithm::try_parse_8digits::<u64, _, FORMAT>(&mut iter) { |
933 | 5.97k | *mantissa = mantissa.wrapping_mul(radix8).wrapping_add(v); |
934 | 5.97k | *step -= 8; |
935 | 5.97k | } else { |
936 | 1.01k | break; |
937 | | } |
938 | | } |
939 | 0 | } |
940 | | |
941 | | // Parse single digits at a time. |
942 | 17.4k | while let Some(&c) = iter.peek() { |
943 | 16.1k | if *step > 0 { |
944 | 13.0k | let digit = char_to_valid_digit_const(c, radix as u32); |
945 | 13.0k | *mantissa = *mantissa * radix + digit as u64; |
946 | 13.0k | *step -= 1; |
947 | 13.0k | // SAFETY: safe, since `iter` cannot be empty due to `iter.peek()`. |
948 | 13.0k | unsafe { iter.step_unchecked() }; |
949 | 13.0k | iter.increment_count(); |
950 | 13.0k | } else { |
951 | 3.14k | break; |
952 | | } |
953 | | } |
954 | 4.42k | } lexical_parse_float::parse::parse_u64_digits::<lexical_util::noskip::DigitsIterator<0xa0000000000000000000000000c>, 0xa0000000000000000000000000c> Line | Count | Source | 916 | 1.93k | pub fn parse_u64_digits<'a, Iter, const FORMAT: u128>( | 917 | 1.93k | mut iter: Iter, | 918 | 1.93k | mantissa: &mut u64, | 919 | 1.93k | step: &mut usize, | 920 | 1.93k | ) where | 921 | 1.93k | Iter: DigitsIter<'a>, | 922 | | { | 923 | 1.93k | let format = NumberFormat::<{ FORMAT }> {}; | 924 | 1.93k | let radix = format.radix() as u64; | 925 | | | 926 | | // Try to parse 8 digits at a time, if we can. | 927 | | #[cfg(not(feature = "compact"))] | 928 | 1.93k | if can_try_parse_multidigit!(iter, radix) { | 929 | 1.93k | debug_assert!(radix < 16, "radices over 16 will overflow with radix^8"); | 930 | 1.93k | let radix8 = format.radix8() as u64; | 931 | 4.23k | while *step > 8 { | 932 | 2.87k | if let Some(v) = algorithm::try_parse_8digits::<u64, _, FORMAT>(&mut iter) { | 933 | 2.29k | *mantissa = mantissa.wrapping_mul(radix8).wrapping_add(v); | 934 | 2.29k | *step -= 8; | 935 | 2.29k | } else { | 936 | 581 | break; | 937 | | } | 938 | | } | 939 | 0 | } | 940 | | | 941 | | // Parse single digits at a time. | 942 | 8.50k | while let Some(&c) = iter.peek() { | 943 | 7.86k | if *step > 0 { | 944 | 6.56k | let digit = char_to_valid_digit_const(c, radix as u32); | 945 | 6.56k | *mantissa = *mantissa * radix + digit as u64; | 946 | 6.56k | *step -= 1; | 947 | 6.56k | // SAFETY: safe, since `iter` cannot be empty due to `iter.peek()`. | 948 | 6.56k | unsafe { iter.step_unchecked() }; | 949 | 6.56k | iter.increment_count(); | 950 | 6.56k | } else { | 951 | 1.29k | break; | 952 | | } | 953 | | } | 954 | 1.93k | } |
Unexecuted instantiation: lexical_parse_float::parse::parse_u64_digits::<_, _> lexical_parse_float::parse::parse_u64_digits::<lexical_util::noskip::DigitsIterator<0xa0000000000000000000000000c>, 0xa0000000000000000000000000c> Line | Count | Source | 916 | 2.49k | pub fn parse_u64_digits<'a, Iter, const FORMAT: u128>( | 917 | 2.49k | mut iter: Iter, | 918 | 2.49k | mantissa: &mut u64, | 919 | 2.49k | step: &mut usize, | 920 | 2.49k | ) where | 921 | 2.49k | Iter: DigitsIter<'a>, | 922 | | { | 923 | 2.49k | let format = NumberFormat::<{ FORMAT }> {}; | 924 | 2.49k | let radix = format.radix() as u64; | 925 | | | 926 | | // Try to parse 8 digits at a time, if we can. | 927 | | #[cfg(not(feature = "compact"))] | 928 | 2.49k | if can_try_parse_multidigit!(iter, radix) { | 929 | 2.49k | debug_assert!(radix < 16, "radices over 16 will overflow with radix^8"); | 930 | 2.49k | let radix8 = format.radix8() as u64; | 931 | 6.17k | while *step > 8 { | 932 | 4.11k | if let Some(v) = algorithm::try_parse_8digits::<u64, _, FORMAT>(&mut iter) { | 933 | 3.67k | *mantissa = mantissa.wrapping_mul(radix8).wrapping_add(v); | 934 | 3.67k | *step -= 8; | 935 | 3.67k | } else { | 936 | 432 | break; | 937 | | } | 938 | | } | 939 | 0 | } | 940 | | | 941 | | // Parse single digits at a time. | 942 | 8.93k | while let Some(&c) = iter.peek() { | 943 | 8.28k | if *step > 0 { | 944 | 6.44k | let digit = char_to_valid_digit_const(c, radix as u32); | 945 | 6.44k | *mantissa = *mantissa * radix + digit as u64; | 946 | 6.44k | *step -= 1; | 947 | 6.44k | // SAFETY: safe, since `iter` cannot be empty due to `iter.peek()`. | 948 | 6.44k | unsafe { iter.step_unchecked() }; | 949 | 6.44k | iter.increment_count(); | 950 | 6.44k | } else { | 951 | 1.84k | break; | 952 | | } | 953 | | } | 954 | 2.49k | } |
|
955 | | |
956 | | // SPECIAL |
957 | | // ------- |
958 | | |
959 | | /// Determine if the input data matches the special string. |
960 | | /// If there's no match, returns 0. Otherwise, returns the byte's cursor. |
961 | | #[must_use] |
962 | | #[inline(always)] |
963 | 547 | pub fn is_special_eq<const FORMAT: u128>(mut byte: Bytes<FORMAT>, string: &'static [u8]) -> usize { |
964 | 547 | let format = NumberFormat::<{ FORMAT }> {}; |
965 | 547 | if cfg!(feature = "format") && format.case_sensitive_special() { |
966 | 0 | if shared::starts_with(byte.special_iter(), string.iter()) { |
967 | | // Trim the iterator afterwards. |
968 | 0 | byte.special_iter().peek(); |
969 | 0 | return byte.cursor(); |
970 | 0 | } |
971 | 547 | } else if shared::starts_with_uncased(byte.special_iter(), string.iter()) { |
972 | | // Trim the iterator afterwards. |
973 | 0 | byte.special_iter().peek(); |
974 | 0 | return byte.cursor(); |
975 | 547 | } |
976 | 547 | 0 |
977 | 547 | } lexical_parse_float::parse::is_special_eq::<0xa0000000000000000000000000c> Line | Count | Source | 963 | 282 | pub fn is_special_eq<const FORMAT: u128>(mut byte: Bytes<FORMAT>, string: &'static [u8]) -> usize { | 964 | 282 | let format = NumberFormat::<{ FORMAT }> {}; | 965 | 282 | if cfg!(feature = "format") && format.case_sensitive_special() { | 966 | 0 | if shared::starts_with(byte.special_iter(), string.iter()) { | 967 | | // Trim the iterator afterwards. | 968 | 0 | byte.special_iter().peek(); | 969 | 0 | return byte.cursor(); | 970 | 0 | } | 971 | 282 | } else if shared::starts_with_uncased(byte.special_iter(), string.iter()) { | 972 | | // Trim the iterator afterwards. | 973 | 0 | byte.special_iter().peek(); | 974 | 0 | return byte.cursor(); | 975 | 282 | } | 976 | 282 | 0 | 977 | 282 | } |
Unexecuted instantiation: lexical_parse_float::parse::is_special_eq::<_> lexical_parse_float::parse::is_special_eq::<0xa0000000000000000000000000c> Line | Count | Source | 963 | 265 | pub fn is_special_eq<const FORMAT: u128>(mut byte: Bytes<FORMAT>, string: &'static [u8]) -> usize { | 964 | 265 | let format = NumberFormat::<{ FORMAT }> {}; | 965 | 265 | if cfg!(feature = "format") && format.case_sensitive_special() { | 966 | 0 | if shared::starts_with(byte.special_iter(), string.iter()) { | 967 | | // Trim the iterator afterwards. | 968 | 0 | byte.special_iter().peek(); | 969 | 0 | return byte.cursor(); | 970 | 0 | } | 971 | 265 | } else if shared::starts_with_uncased(byte.special_iter(), string.iter()) { | 972 | | // Trim the iterator afterwards. | 973 | 0 | byte.special_iter().peek(); | 974 | 0 | return byte.cursor(); | 975 | 265 | } | 976 | 265 | 0 | 977 | 265 | } |
|
978 | | |
979 | | /// Parse a positive representation of a special, non-finite float. |
980 | | #[must_use] |
981 | | #[cfg_attr(not(feature = "compact"), inline(always))] |
982 | 253 | pub fn parse_positive_special<F, const FORMAT: u128>( |
983 | 253 | byte: Bytes<FORMAT>, |
984 | 253 | options: &Options, |
985 | 253 | ) -> Option<(F, usize)> |
986 | 253 | where |
987 | 253 | F: LemireFloat, |
988 | | { |
989 | 253 | let format = NumberFormat::<{ FORMAT }> {}; |
990 | 253 | if cfg!(feature = "format") && format.no_special() { |
991 | 0 | return None; |
992 | 253 | } |
993 | | |
994 | 253 | let cursor = byte.cursor(); |
995 | 253 | let length = byte.buffer_length() - cursor; |
996 | 253 | if let Some(nan_string) = options.nan_string() { |
997 | 253 | if length >= nan_string.len() { |
998 | 189 | let count = is_special_eq::<FORMAT>(byte.clone(), nan_string); |
999 | 189 | if count != 0 { |
1000 | 0 | return Some((F::NAN, count)); |
1001 | 189 | } |
1002 | 64 | } |
1003 | 0 | } |
1004 | 253 | if let Some(infinity_string) = options.infinity_string() { |
1005 | 253 | if length >= infinity_string.len() { |
1006 | 169 | let count = is_special_eq::<FORMAT>(byte.clone(), infinity_string); |
1007 | 169 | if count != 0 { |
1008 | 0 | return Some((F::INFINITY, count)); |
1009 | 169 | } |
1010 | 84 | } |
1011 | 0 | } |
1012 | 253 | if let Some(inf_string) = options.inf_string() { |
1013 | 253 | if length >= inf_string.len() { |
1014 | 189 | let count = is_special_eq::<FORMAT>(byte.clone(), inf_string); |
1015 | 189 | if count != 0 { |
1016 | 0 | return Some((F::INFINITY, count)); |
1017 | 189 | } |
1018 | 64 | } |
1019 | 0 | } |
1020 | | |
1021 | 253 | None |
1022 | 253 | } lexical_parse_float::parse::parse_positive_special::<f32, 0xa0000000000000000000000000c> Line | Count | Source | 982 | 127 | pub fn parse_positive_special<F, const FORMAT: u128>( | 983 | 127 | byte: Bytes<FORMAT>, | 984 | 127 | options: &Options, | 985 | 127 | ) -> Option<(F, usize)> | 986 | 127 | where | 987 | 127 | F: LemireFloat, | 988 | | { | 989 | 127 | let format = NumberFormat::<{ FORMAT }> {}; | 990 | 127 | if cfg!(feature = "format") && format.no_special() { | 991 | 0 | return None; | 992 | 127 | } | 993 | | | 994 | 127 | let cursor = byte.cursor(); | 995 | 127 | let length = byte.buffer_length() - cursor; | 996 | 127 | if let Some(nan_string) = options.nan_string() { | 997 | 127 | if length >= nan_string.len() { | 998 | 97 | let count = is_special_eq::<FORMAT>(byte.clone(), nan_string); | 999 | 97 | if count != 0 { | 1000 | 0 | return Some((F::NAN, count)); | 1001 | 97 | } | 1002 | 30 | } | 1003 | 0 | } | 1004 | 127 | if let Some(infinity_string) = options.infinity_string() { | 1005 | 127 | if length >= infinity_string.len() { | 1006 | 88 | let count = is_special_eq::<FORMAT>(byte.clone(), infinity_string); | 1007 | 88 | if count != 0 { | 1008 | 0 | return Some((F::INFINITY, count)); | 1009 | 88 | } | 1010 | 39 | } | 1011 | 0 | } | 1012 | 127 | if let Some(inf_string) = options.inf_string() { | 1013 | 127 | if length >= inf_string.len() { | 1014 | 97 | let count = is_special_eq::<FORMAT>(byte.clone(), inf_string); | 1015 | 97 | if count != 0 { | 1016 | 0 | return Some((F::INFINITY, count)); | 1017 | 97 | } | 1018 | 30 | } | 1019 | 0 | } | 1020 | | | 1021 | 127 | None | 1022 | 127 | } |
Unexecuted instantiation: lexical_parse_float::parse::parse_positive_special::<_, _> lexical_parse_float::parse::parse_positive_special::<f64, 0xa0000000000000000000000000c> Line | Count | Source | 982 | 126 | pub fn parse_positive_special<F, const FORMAT: u128>( | 983 | 126 | byte: Bytes<FORMAT>, | 984 | 126 | options: &Options, | 985 | 126 | ) -> Option<(F, usize)> | 986 | 126 | where | 987 | 126 | F: LemireFloat, | 988 | | { | 989 | 126 | let format = NumberFormat::<{ FORMAT }> {}; | 990 | 126 | if cfg!(feature = "format") && format.no_special() { | 991 | 0 | return None; | 992 | 126 | } | 993 | | | 994 | 126 | let cursor = byte.cursor(); | 995 | 126 | let length = byte.buffer_length() - cursor; | 996 | 126 | if let Some(nan_string) = options.nan_string() { | 997 | 126 | if length >= nan_string.len() { | 998 | 92 | let count = is_special_eq::<FORMAT>(byte.clone(), nan_string); | 999 | 92 | if count != 0 { | 1000 | 0 | return Some((F::NAN, count)); | 1001 | 92 | } | 1002 | 34 | } | 1003 | 0 | } | 1004 | 126 | if let Some(infinity_string) = options.infinity_string() { | 1005 | 126 | if length >= infinity_string.len() { | 1006 | 81 | let count = is_special_eq::<FORMAT>(byte.clone(), infinity_string); | 1007 | 81 | if count != 0 { | 1008 | 0 | return Some((F::INFINITY, count)); | 1009 | 81 | } | 1010 | 45 | } | 1011 | 0 | } | 1012 | 126 | if let Some(inf_string) = options.inf_string() { | 1013 | 126 | if length >= inf_string.len() { | 1014 | 92 | let count = is_special_eq::<FORMAT>(byte.clone(), inf_string); | 1015 | 92 | if count != 0 { | 1016 | 0 | return Some((F::INFINITY, count)); | 1017 | 92 | } | 1018 | 34 | } | 1019 | 0 | } | 1020 | | | 1021 | 126 | None | 1022 | 126 | } |
|
1023 | | |
1024 | | /// Parse a partial representation of a special, non-finite float. |
1025 | | #[must_use] |
1026 | | #[inline(always)] |
1027 | 253 | pub fn parse_partial_special<F, const FORMAT: u128>( |
1028 | 253 | byte: Bytes<FORMAT>, |
1029 | 253 | is_negative: bool, |
1030 | 253 | options: &Options, |
1031 | 253 | ) -> Option<(F, usize)> |
1032 | 253 | where |
1033 | 253 | F: LemireFloat, |
1034 | | { |
1035 | 253 | let (mut float, count) = parse_positive_special::<F, FORMAT>(byte, options)?; |
1036 | 0 | if is_negative { |
1037 | 0 | float = -float; |
1038 | 0 | } |
1039 | 0 | Some((float, count)) |
1040 | 253 | } lexical_parse_float::parse::parse_partial_special::<f32, 0xa0000000000000000000000000c> Line | Count | Source | 1027 | 127 | pub fn parse_partial_special<F, const FORMAT: u128>( | 1028 | 127 | byte: Bytes<FORMAT>, | 1029 | 127 | is_negative: bool, | 1030 | 127 | options: &Options, | 1031 | 127 | ) -> Option<(F, usize)> | 1032 | 127 | where | 1033 | 127 | F: LemireFloat, | 1034 | | { | 1035 | 127 | let (mut float, count) = parse_positive_special::<F, FORMAT>(byte, options)?; | 1036 | 0 | if is_negative { | 1037 | 0 | float = -float; | 1038 | 0 | } | 1039 | 0 | Some((float, count)) | 1040 | 127 | } |
Unexecuted instantiation: lexical_parse_float::parse::parse_partial_special::<_, _> lexical_parse_float::parse::parse_partial_special::<f64, 0xa0000000000000000000000000c> Line | Count | Source | 1027 | 126 | pub fn parse_partial_special<F, const FORMAT: u128>( | 1028 | 126 | byte: Bytes<FORMAT>, | 1029 | 126 | is_negative: bool, | 1030 | 126 | options: &Options, | 1031 | 126 | ) -> Option<(F, usize)> | 1032 | 126 | where | 1033 | 126 | F: LemireFloat, | 1034 | | { | 1035 | 126 | let (mut float, count) = parse_positive_special::<F, FORMAT>(byte, options)?; | 1036 | 0 | if is_negative { | 1037 | 0 | float = -float; | 1038 | 0 | } | 1039 | 0 | Some((float, count)) | 1040 | 126 | } |
|
1041 | | |
1042 | | /// Try to parse a special, non-finite float. |
1043 | | #[must_use] |
1044 | | #[inline(always)] |
1045 | 253 | pub fn parse_special<F, const FORMAT: u128>( |
1046 | 253 | byte: Bytes<FORMAT>, |
1047 | 253 | is_negative: bool, |
1048 | 253 | options: &Options, |
1049 | 253 | ) -> Option<F> |
1050 | 253 | where |
1051 | 253 | F: LemireFloat, |
1052 | | { |
1053 | 253 | let length = byte.buffer_length(); |
1054 | 253 | if let Some((float, count)) = parse_partial_special::<F, FORMAT>(byte, is_negative, options) { |
1055 | 0 | if count == length { |
1056 | 0 | return Some(float); |
1057 | 0 | } |
1058 | 253 | } |
1059 | 253 | None |
1060 | 253 | } lexical_parse_float::parse::parse_special::<f32, 0xa0000000000000000000000000c> Line | Count | Source | 1045 | 127 | pub fn parse_special<F, const FORMAT: u128>( | 1046 | 127 | byte: Bytes<FORMAT>, | 1047 | 127 | is_negative: bool, | 1048 | 127 | options: &Options, | 1049 | 127 | ) -> Option<F> | 1050 | 127 | where | 1051 | 127 | F: LemireFloat, | 1052 | | { | 1053 | 127 | let length = byte.buffer_length(); | 1054 | 127 | if let Some((float, count)) = parse_partial_special::<F, FORMAT>(byte, is_negative, options) { | 1055 | 0 | if count == length { | 1056 | 0 | return Some(float); | 1057 | 0 | } | 1058 | 127 | } | 1059 | 127 | None | 1060 | 127 | } |
Unexecuted instantiation: lexical_parse_float::parse::parse_special::<_, _> lexical_parse_float::parse::parse_special::<f64, 0xa0000000000000000000000000c> Line | Count | Source | 1045 | 126 | pub fn parse_special<F, const FORMAT: u128>( | 1046 | 126 | byte: Bytes<FORMAT>, | 1047 | 126 | is_negative: bool, | 1048 | 126 | options: &Options, | 1049 | 126 | ) -> Option<F> | 1050 | 126 | where | 1051 | 126 | F: LemireFloat, | 1052 | | { | 1053 | 126 | let length = byte.buffer_length(); | 1054 | 126 | if let Some((float, count)) = parse_partial_special::<F, FORMAT>(byte, is_negative, options) { | 1055 | 0 | if count == length { | 1056 | 0 | return Some(float); | 1057 | 0 | } | 1058 | 126 | } | 1059 | 126 | None | 1060 | 126 | } |
|