lexical_parse_float/
lib.rs

1//! Fast lexical string-to-float conversion routines.
2//!
3//! This contains high-performance methods to parse floats from bytes.
4//! Using [`from_lexical`] is analogous to [`parse`][`core-parse`],
5//! while enabling parsing from bytes as well as [`str`].
6//!
7//!
8//! [`from_lexical`]: FromLexical::from_lexical
9//! [`core-parse`]: core::str::FromStr
10//!
11//! # Getting Started
12//!
13//! To parse a number from bytes, use [`from_lexical`]:
14//!
15//! ```rust
16//! # #[no_std]
17//! # use core::str;
18//! use lexical_parse_float::{Error, FromLexical};
19//!
20//! let value = f64::from_lexical("1234.5".as_bytes());
21//! assert_eq!(value, Ok(1234.5));
22//!
23//! let value = f64::from_lexical("1.2345e325".as_bytes());
24//! assert_eq!(value, Ok(f64::INFINITY));
25//!
26//! let value = f64::from_lexical("1234.5 }, {\"Key\", \"Value\"}}".as_bytes());
27//! assert_eq!(value, Err(Error::InvalidDigit(6)));
28//! ```
29//!
30//! If wishing to incrementally parse a string from bytes, that is, parse as
31//! many characters until an invalid digit is found, you can use the partial
32//! parsers. This is useful in parsing data where the type is known, such as
33//! JSON, but where the end of the number is not yet known.
34//!
35//! ```rust
36//! # #[no_std]
37//! # use core::str;
38//! use lexical_parse_float::{Error, FromLexical};
39//!
40//! let value = f64::from_lexical_partial("1234.5 }, {\"Key\", \"Value\"}}".as_bytes());
41//! assert_eq!(value, Ok((1234.5, 6)));
42//!
43//! let value = f64::from_lexical_partial("1.2345e325".as_bytes());
44//! assert_eq!(value, Ok((f64::INFINITY, 10)));
45//! ```
46//!
47//! # Options/Formatting API
48//!
49//! Each float parser contains extensive formatting control through
50//! [`mod@options`] and [`mod@format`], including digit [`separator`]
51//! support (that is, floats such as `1_2__3.4_5`), if integral,
52//! fractional, or any significant digits are required, if to disable
53//! parsing non-finite values, if `+` signs are invalid or required,
54//! and much more. For more comprehensive examples, see the
55//! [`format`](#format) and [Comprehensive Configuration] sections
56//! below.
57//!
58//! [`separator`]: NumberFormat::digit_separator
59//! [Comprehensive Configuration]: #comprehensive-configuration
60//!
61//! ```rust
62//! # #[cfg(feature = "radix")] {
63//! # use core::str;
64//! use lexical_parse_float::{Error, FromLexicalWithOptions, NumberFormatBuilder, Options};
65//!
66//! const FORMAT: u128 = NumberFormatBuilder::new()
67//!     // require a `+` or `-` sign before the number
68//!     .required_mantissa_sign(true)
69//!     // require a `+` or `-` sign before the exponent digits
70//!     .required_exponent_sign(true)
71//!     // build the format, panicking if the format is invalid
72//!     .build_strict();
73//! const OPTIONS: Options = Options::new();
74//!
75//! let value = "+1.234e+300";
76//! let result = f64::from_lexical_with_options::<FORMAT>(value.as_bytes(), &OPTIONS);
77//! assert_eq!(result, Ok(1.234e+300));
78//!
79//! let value = "1.234e+300";
80//! let result = f64::from_lexical_with_options::<FORMAT>(value.as_bytes(), &OPTIONS);
81//! assert_eq!(result, Err(Error::MissingSign(0)));
82//! # }
83//! ```
84//!
85//! # Features
86//!
87//! * `format` - Add support for parsing custom integer formats.
88//! * `power-of-two` - Add support for parsing power-of-two integer strings.
89//! * `radix` - Add support for strings of any radix.
90//! * `compact` - Reduce code size at the cost of performance.
91//! * `f16` - Enable support for half-precision [`f16`][`ieee-f16`] and
92//!   [`bf16`][`brain-float`] floats.
93//! * `std` (Default) - Disable to allow use in a [`no_std`] environment.
94//!
95//! [`no_std`]: https://docs.rust-embedded.org/book/intro/no-std.html
96//! [`ieee-f16`]: https://en.wikipedia.org/wiki/Half-precision_floating-point_format
97//! [`brain-float`]: https://en.wikipedia.org/wiki/Bfloat16_floating-point_format
98//!
99//! A complete description of supported features includes:
100//!
101//! #### format
102//!
103//! Add support custom float parsing specifications. This should be used in
104//! conjunction with [`Options`] for extensible float parsing.
105//!
106//! ##### JSON
107//!
108//! For example, in JSON, the following floats are valid or invalid:
109//!
110//! ```text
111//! -1          // valid
112//! +1          // invalid
113//! 1           // valid
114//! 1.          // invalid
115//! .1          // invalid
116//! 0.1         // valid
117//! nan         // invalid
118//! inf         // invalid
119//! Infinity    // invalid
120//! ```
121//!
122//! All of the finite numbers are valid in Rust, and Rust provides constants
123//! for non-finite floats. In order to parse standard-conforming JSON floats
124//! using lexical, you may use the following approach:
125//!
126//! ```rust
127//! # #[cfg(feature = "format")] {
128//! use lexical_parse_float::{format, options, Error, FromLexicalWithOptions, Result};
129//!
130//! fn parse_json_float(bytes: &[u8]) -> Result<f64> {
131//!     f64::from_lexical_with_options::<{ format::JSON }>(bytes, &options::JSON)
132//! }
133//!
134//! assert_eq!(parse_json_float(b"-1"), Ok(-1.0));
135//! assert_eq!(parse_json_float(b"+1"), Err(Error::InvalidPositiveSign(0)));
136//! assert_eq!(parse_json_float(b"1"), Ok(1.0));
137//! assert_eq!(parse_json_float(b"1."), Err(Error::EmptyFraction(2)));
138//! assert_eq!(parse_json_float(b"0.1"), Ok(0.1));
139//! assert_eq!(parse_json_float(b"nan"), Err(Error::EmptyInteger(0)));
140//! assert_eq!(parse_json_float(b"inf"), Err(Error::EmptyInteger(0)));
141//! assert_eq!(parse_json_float(b"Infinity"), Err(Error::EmptyInteger(0)));
142//! # }
143//! ```
144//!
145//! ##### Custom Format
146//!
147//! An example building and using a custom format, with many of the available
148//! options is:
149//!
150//! ```rust
151//! # #[cfg(feature = "format")] {
152//! # use core::{num, str};
153//! use lexical_parse_float::{Error, NumberFormatBuilder, Options, FromLexicalWithOptions};
154//!
155//! const FORMAT: u128 = NumberFormatBuilder::new()
156//!     // enable the use of digit separators with `_`
157//!     .digit_separator(num::NonZeroU8::new(b'_'))
158//!     // require digits before and after the decimal point,
159//!     // if the decimal point is present.
160//!     .required_integer_digits(true)
161//!     .required_fraction_digits(true)
162//!     // do not allow a leading `+` sign, so `+123` is invalid
163//!     .no_positive_mantissa_sign(true)
164//!     // do not allow `0` before an integer, so `01.1` is invalid.
165//!     // however, `0.1` is valid.
166//!     .no_integer_leading_zeros(true)
167//!     // allow digit separators anywhere, including consecutive ones
168//!     .leading_digit_separator(true)
169//!     .trailing_digit_separator(true)
170//!     .internal_digit_separator(true)
171//!     .consecutive_digit_separator(true)
172//!     // make it so the exponent character, `e`, is case-sensitive
173//!     // that is, `E` is not considered a valid exponent character
174//!     .case_sensitive_exponent(true)
175//!     .build_strict();
176//! const OPTIONS: Options = Options::builder()
177//!     // change the string representation of NaN from `NaN` to `nan`
178//!     .nan_string(Some(b"nan"))
179//!     // disable a short infinity: long infinity is still allowed
180//!     .inf_string(None)
181//!     .build_strict();
182//!
183//! let value = f64::from_lexical_with_options::<FORMAT>(b"1_2.3_4", &OPTIONS);
184//! assert_eq!(value, Ok(12.34));
185//!
186//! let value = f64::from_lexical_with_options::<FORMAT>(b"-inf", &OPTIONS);
187//! assert_eq!(value, Err(Error::EmptyInteger(1)));
188//!
189//! let value = f64::from_lexical_with_options::<FORMAT>(b"Infinity", &OPTIONS);
190//! assert_eq!(value, Ok(f64::INFINITY));
191//!
192//! let value = f64::from_lexical_with_options::<FORMAT>(b"nan", &OPTIONS);
193//! assert_eq!(value.map(|x| x.is_nan()), Ok(true));
194//!
195//! let value = f64::from_lexical_with_options::<FORMAT>(b"+1_2.3_4", &OPTIONS);
196//! assert_eq!(value, Err(Error::InvalidPositiveSign(0)));
197//!
198//! let value = f64::from_lexical_with_options::<FORMAT>(b"0.3_4", &OPTIONS);
199//! assert_eq!(value, Ok(0.34));
200//!
201//! let value = f64::from_lexical_with_options::<FORMAT>(b"12", &OPTIONS);
202//! assert_eq!(value, Ok(12.0));
203//!
204//! let value = f64::from_lexical_with_options::<FORMAT>(b"12.", &OPTIONS);
205//! assert_eq!(value, Err(Error::EmptyFraction(3)));
206//!
207//! let value = f64::from_lexical_with_options::<FORMAT>(b"1.234e5", &OPTIONS);
208//! assert_eq!(value, Ok(1.234e5));
209//!
210//! let value = f64::from_lexical_with_options::<FORMAT>(b"1.234E5", &OPTIONS);
211//! assert_eq!(value, Err(Error::InvalidDigit(5)));
212//! # }
213//! ```
214//!
215//! Enabling the [`format`](crate#format) API significantly increases compile
216//! times, however, it enables a large amount of customization in how floats are
217//! written.
218//!
219//! #### power-of-two
220//!
221//! Enable parsing numbers with radixes that are powers of two, that is, `2`,
222//! `4`, `8`, `16`, and `32`.
223//!
224//! ```rust
225//! # #[cfg(feature = "power-of-two")] {
226//! use lexical_parse_float::{NumberFormatBuilder, Options, FromLexicalWithOptions};
227//!
228//! const BINARY: u128 = NumberFormatBuilder::binary();
229//! const OPTIONS: Options = Options::new();
230//! let value = "1.0011101111100111011011001000101101000011100101011";
231//! let result = f64::from_lexical_with_options::<BINARY>(value.as_bytes(), &OPTIONS);
232//! assert_eq!(result, Ok(1.234f64));
233//! # }
234//! ```
235//!
236//! #### radix
237//!
238//! Enable parsing numbers using all radixes from `2` to `36`. This requires
239//! more static storage than [`power-of-two`][crate#power-of-two], and increases
240//! compile times, but can be quite useful for esoteric programming languages
241//! which use duodecimal floats, for example.
242//!
243//! ```rust
244//! # #[cfg(feature = "radix")] {
245//! use lexical_parse_float::{NumberFormatBuilder, Options, FromLexicalWithOptions};
246//!
247//! const FORMAT: u128 = NumberFormatBuilder::from_radix(12);
248//! const OPTIONS: Options = Options::new();
249//! let value = "1.29842830A44BAA2";
250//! let result = f64::from_lexical_with_options::<FORMAT>(value.as_bytes(), &OPTIONS);
251//! assert_eq!(result, Ok(1.234f64));
252//! # }
253//! ```
254//!
255//! #### compact
256//!
257//! Reduce the generated code size at the cost of performance. This minimizes
258//! the number of static tables, inlining, and generics used, drastically
259//! reducing the size of the generated binaries. However, this resulting
260//! performance of the generated code is much lower.
261//!
262//! #### f16
263//!
264//! This enables the use of the half-precision floats [`f16`][`ieee-f16`] and
265//! [`bf16`][`brain-float`]. However, since these have limited hardware support
266//! and are primarily used for vectorized operations, they are parsed as if
267//! they were an [`f32`]. Due to the low precision of 16-bit floats, the results
268//! may appear to have significant rounding error.
269//!
270//! ```rust
271//! # #[cfg(feature = "f16")] {
272//! # use core::str;
273//! use lexical_parse_float::{f16, FromLexical};
274//!
275//! let value = "1.234375";
276//! let result = f16::from_lexical(value.as_bytes());
277//! assert_eq!(result, Ok(f16::from_f64_const(1.234f64)));
278//! # }
279//! ```
280//!
281//! #### std
282//!
283//! Enable use of the standard library. Currently, the standard library
284//! is not used, and may be disabled without any change in functionality
285//! on stable.
286//!
287//! # Comprehensive Configuration
288//!
289//! `lexical-parse-float` provides two main levels of configuration:
290//! - The [`NumberFormatBuilder`], creating a packed struct with custom
291//!   formatting options.
292//! - The [`Options`] API.
293//!
294//! ## Number Format
295//!
296//! The number format class provides numerous flags to specify number writing.
297//! When the [`power-of-two`](#power-of-two) feature is enabled, additional
298//! flags are added:
299//! - The radix for the significant digits (default `10`).
300//! - The radix for the exponent base (default `10`).
301//! - The radix for the exponent digits (default `10`).
302//!
303//! When the [`format`](#format) feature is enabled, numerous other syntax and
304//! digit separator flags are enabled, including:
305//! - A digit separator character, to group digits for increased legibility.
306//! - Whether leading, trailing, internal, and consecutive digit separators are
307//!   allowed.
308//! - Toggling required float components, such as digits before the decimal
309//!   point.
310//! - Toggling whether special floats are allowed or are case-sensitive.
311//!
312//! Many pre-defined constants therefore exist to simplify common use-cases,
313//! including:
314//! - [`JSON`], [`XML`], [`TOML`], [`YAML`], [`SQLite`], and many more.
315//! - [`Rust`], [`Python`], [`C#`], [`FORTRAN`], [`COBOL`] literals and strings,
316//!   and many more.
317//!
318//! For a list of all supported fields, see [Parse
319//! Float Fields][NumberFormatBuilder#parse-float-fields].
320//!
321//! <!-- Spacer for rustfmt -->
322#![cfg_attr(
323    feature = "format",
324    doc = "
325[`JSON`]: format::JSON
326[`XML`]: format::XML
327[`TOML`]: format::TOML
328[`YAML`]: format::YAML
329[`SQLite`]: format::SQLITE
330[`Rust`]: format::RUST_LITERAL
331[`Python`]: format::PYTHON_LITERAL
332[`C#`]: format::CSHARP_LITERAL
333[`FORTRAN`]: format::FORTRAN_LITERAL
334[`COBOL`]: format::COBOL_LITERAL
335"
336)]
337#![cfg_attr(
338    not(feature = "format"),
339    doc = "
340[`JSON`]: https://docs.rs/lexical-parse-float/latest/lexical_parse_float/format/constant.JSON.html
341[`XML`]: https://docs.rs/lexical-parse-float/latest/lexical_parse_float/format/constant.XML.html
342[`TOML`]: https://docs.rs/lexical-parse-float/latest/lexical_parse_float/format/constant.TOML.html
343[`YAML`]: https://docs.rs/lexical-parse-float/latest/lexical_parse_float/format/constant.YAML.html
344[`SQLite`]: https://docs.rs/lexical-parse-float/latest/lexical_parse_float/format/constant.SQLITE.html
345[`Rust`]: https://docs.rs/lexical-parse-float/latest/lexical_parse_float/format/constant.RUST_LITERAL.html
346[`Python`]: https://docs.rs/lexical-parse-float/latest/lexical_parse_float/format/constant.PYTHON_LITERAL.html
347[`C#`]: https://docs.rs/lexical-parse-float/latest/lexical_parse_float/format/constant.CSHARP_LITERAL.html
348[`FORTRAN`]: https://docs.rs/lexical-parse-float/latest/lexical_parse_float/format/constant.FORTRAN_LITERAL.html
349[`COBOL`]: https://docs.rs/lexical-parse-float/latest/lexical_parse_float/format/constant.COBOL_LITERAL.html
350"
351)]
352//!
353//! ## Options API
354//!
355//! The Options API provides high-level options to specify number parsing
356//! or writing, options not intrinsically tied to a number format.
357//! For example, the Options API provides:
358//! - The [`exponent`][OptionsBuilder::exponent] character (defaults to `b'e'`
359//!   or `b'^'`, depending on the radix).
360//! - The [`decimal point`][OptionsBuilder::decimal_point] character (defaults
361//!   to `b'.'`).
362//! - Custom [`NaN`][f64::NAN] and [`Infinity`][f64::INFINITY] string
363//!   [`representations`][Options::nan_string].
364//!
365//!
366//! In addition, pre-defined constants for each category of options may
367//! be found in their respective modules, for example, [`JSON`][`JSON-OPTS`].
368//!
369//! [`JSON-OPTS`]: options::JSON
370//!
371//! ## Examples
372//!
373//! An example of creating your own options to parse European-style
374//! numbers (which use commas as decimal points, and periods as digit
375//! separators) is as follows:
376//!
377//! ```
378//! # #[cfg(feature = "format")] {
379//! # use core::num;
380//! use lexical_parse_float::{format, FromLexicalWithOptions, NumberFormatBuilder, Options};
381//!
382//! // This creates a format to parse a European-style float number.
383//! // The decimal point is a comma, and the digit separators (optional)
384//! // are periods.
385//! const EUROPEAN: u128 = NumberFormatBuilder::new()
386//!     .digit_separator(num::NonZeroU8::new(b'.'))
387//!     .build_strict();
388//! const COMMA_OPTIONS: Options = Options::builder()
389//!     .decimal_point(b',')
390//!     .build_strict();
391//! assert_eq!(
392//!     f32::from_lexical_with_options::<EUROPEAN>(b"300,10", &COMMA_OPTIONS),
393//!     Ok(300.10)
394//! );
395//!
396//! // Another example, using a pre-defined constant for JSON.
397//! const JSON: u128 = format::JSON;
398//! const JSON_OPTIONS: Options = Options::new();
399//! assert_eq!(
400//!     f32::from_lexical_with_options::<JSON>(b"0e1", &JSON_OPTIONS),
401//!     Ok(0.0)
402//! );
403//! assert_eq!(
404//!     f32::from_lexical_with_options::<JSON>(b"1E+2", &JSON_OPTIONS),
405//!     Ok(100.0)
406//! );
407//! # }
408//! ```
409//!
410//! # Higher-Level APIs
411//!
412//! If you would like an API that supports multiple numeric conversions rather
413//! than just writing integers, use [`lexical`] or [`lexical-core`] instead.
414//!
415//! [`lexical`]: https://crates.io/crates/lexical
416//! [`lexical-core`]: https://crates.io/crates/lexical-core
417//!
418//! # Version Support
419//!
420//! The minimum, standard, required version is [`1.63.0`][`rust-1.63.0`], for
421//! const generic support. Older versions of lexical support older Rust
422//! versions.
423//!
424//! # Algorithm
425//!
426//! The default implementations are highly optimized both for simple
427//! strings, as well as input with large numbers of digits. In order to
428//! keep performance optimal for simple strings, we avoid overly branching
429//! to minimize the number of branches (and therefore optimization checks).
430//! Most of the branches in the code are resolved at compile-time, and
431//! the resulting ASM as well as comprehensive benchmarks are monitored
432//! to ensure there are no regressions.
433//!
434//! For simple floats, we use an optimized digit parser with multiple-digit
435//! optimizations (parsing 8 digits in 3 multiplication instructions),
436//! and then use machine floats to create an exact representation with
437//! high throughput. In more complex cases, we use the Eisel-Lemire
438//! algorithm, described in "Number Parsing at a Gigabyte per Second",
439//! available online [here](https://arxiv.org/abs/2101.11408). The
440//! Eisel-Lemire algorithm creates an extended representation using a
441//! 128-bit (or a fallback 192-bit representation) of the significant
442//! digits of the float, scaled to the proper exponent using pre-computed
443//! powers-of-5.
444//!
445//! If the Eisel-Lemire algorithm is unable to unambiguously round the float,
446//! we fallback to using optimized, big-integer algorithms, which are
447//! described in [Algorithm Approach](#algorithm-approach) below.
448//!
449//! ## Machine Float-Only Algorithm
450//!
451//! We also support an algorithm that uses only machine floats for the
452//! fast-path algorithm, however, this may be slower for floats with large
453//! exponents since it uses an iterative algorithm. A code sample
454//! using this is:
455//!
456//! ```rust
457//! use lexical_parse_float::Options;
458//! use lexical_parse_float::format::STANDARD;
459//! use lexical_parse_float::parse::ParseFloat;
460//!
461//! const OPTIONS: Options = Options::new();
462//! let result = f64::fast_path_complete::<{ STANDARD }>(b"1.34000", &OPTIONS);
463//! assert_eq!(result, Ok(1.34000));
464//! ```
465//!
466//! # Design
467//!
468//! - [Algorithm Approach](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-parse-float/docs/Algorithm.md)
469//! - [Benchmarks](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-parse-float/docs/Benchmarks.md)
470//! - [Comprehensive Benchmarks](https://github.com/Alexhuszagh/lexical-benchmarks)
471//! - [Big Integer Implementation](https://github.com/Alexhuszagh/rust-lexical/blob/main/lexical-parse-float/docs/BigInteger.md)
472//!
473//! # Safety Guarantees
474//!
475//! <div class="warning info-warning">
476//! <style>
477//! .info-warning::before {
478//!   color: #87CEFAb0 !important;
479//! }
480//! .info-warning {
481//!   border-left: 2px solid #87CEFAb0 !important;
482//! }
483//! </style>
484//!
485//! This module uses some unsafe code to achieve accept acceptable performance.
486//! The safety guarantees and logic are described below.
487//!
488//! </div>
489//!
490//! The primary use of unsafe code is in the big integer implementation, which
491//! for performance reasons requires unchecked indexing at certain points, where
492//! rust cannot elide the index check. The use of unsafe code can be found in
493//! the calculation of the [hi] bits, however, every invocation requires the
494//! buffer to be of sufficient [length][longbits]. The other major source is the
495//! implementation of methods such as [push_unchecked], however, the safety
496//! invariants for each caller to create a safe API are documented and has
497//! similar safety guarantees to a regular vector. All other invocations of
498//! unsafe code are indexing a buffer where the index is proven to be within
499//! bounds within a few lines of code of the unsafe index.
500//!
501//! [hi]: <https://github.com/Alexhuszagh/rust-lexical/blob/15d4c8c92d70b1fb9bd6d33f582ffe27e0e74f99/lexical-parse-float/src/bigint.rs#L266>
502//! [longbits]: <https://github.com/Alexhuszagh/rust-lexical/blob/15d4c8c92d70b1fb9bd6d33f582ffe27e0e74f99/lexical-parse-float/src/bigint.rs#L550-L557>
503//! [push_unchecked]: <https://github.com/Alexhuszagh/rust-lexical/blob/15d4c8c92d70b1fb9bd6d33f582ffe27e0e74f99/lexical-parse-float/src/bigint.rs#L377-L386>
504//! [`rust-1.63.0`]: https://blog.rust-lang.org/2022/08/11/Rust-1.63.0.html
505
506// FIXME: Implement clippy/allow reasons once we drop support for 1.80.0 and below
507// Clippy reasons were stabilized in 1.81.0.
508
509// We want to have the same safety guarantees as Rust core,
510// so we allow unused unsafe to clearly document safety guarantees.
511#![allow(unused_unsafe)]
512#![cfg_attr(feature = "lint", warn(unsafe_op_in_unsafe_fn))]
513#![cfg_attr(not(feature = "std"), no_std)]
514#![cfg_attr(docsrs, feature(doc_cfg))]
515#![cfg_attr(docsrs, feature(doc_auto_cfg))]
516#![deny(
517    clippy::doc_markdown,
518    clippy::unnecessary_safety_comment,
519    clippy::semicolon_if_nothing_returned,
520    clippy::unwrap_used,
521    clippy::as_underscore
522)]
523#![allow(
524    // used when concepts are logically separate
525    clippy::match_same_arms,
526    // loss of precision is intentional
527    clippy::integer_division,
528    // mathematical names use 1-character identifiers
529    clippy::min_ident_chars,
530    // these are not cryptographically secure contexts
531    clippy::integer_division_remainder_used,
532    // this can be intentional
533    clippy::module_name_repetitions,
534    // this is intentional: already passing a pointer and need performance
535    clippy::needless_pass_by_value,
536    // we use this for inline formatting for unsafe blocks
537    clippy::semicolon_inside_block,
538)]
539
540#[macro_use]
541pub mod shared;
542
543pub mod bellerophon;
544pub mod bigint;
545pub mod binary;
546pub mod float;
547pub mod fpu;
548pub mod lemire;
549pub mod libm;
550pub mod limits;
551pub mod mask;
552pub mod number;
553pub mod options;
554pub mod parse;
555pub mod slow;
556pub mod table;
557
558mod api;
559mod table_bellerophon_decimal;
560mod table_bellerophon_radix;
561mod table_binary;
562mod table_decimal;
563mod table_large;
564mod table_lemire;
565mod table_radix;
566mod table_small;
567
568#[macro_use(parse_sign)]
569extern crate lexical_parse_integer;
570
571// Re-exports
572#[cfg(feature = "f16")]
573pub use lexical_util::bf16::bf16;
574pub use lexical_util::error::Error;
575#[cfg(feature = "f16")]
576pub use lexical_util::f16::f16;
577pub use lexical_util::format::{self, NumberFormat, NumberFormatBuilder};
578pub use lexical_util::options::ParseOptions;
579pub use lexical_util::result::Result;
580
581pub use self::api::{FromLexical, FromLexicalWithOptions};
582#[doc(inline)]
583pub use self::options::{Options, OptionsBuilder};