Coverage Report

Created: 2025-10-10 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}