diff --git a/.github/workflows/Comprehensive.yml b/.github/workflows/Comprehensive.yml index 762cc824..c30284b1 100644 --- a/.github/workflows/Comprehensive.yml +++ b/.github/workflows/Comprehensive.yml @@ -10,12 +10,11 @@ jobs: strategy: fail-fast: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install latest nightly - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@stable with: toolchain: nightly - override: true components: rustfmt, clippy - run: ci/comprehensive.sh - run: ALL_FEATURES=1 ci/comprehensive.sh diff --git a/.github/workflows/Cross.yml b/.github/workflows/Cross.yml index 60c423f0..a62b813f 100644 --- a/.github/workflows/Cross.yml +++ b/.github/workflows/Cross.yml @@ -38,12 +38,11 @@ jobs: - x86_64-pc-windows-gnu steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable with: toolchain: stable target: ${{matrix.target}} - override: true - uses: actions-rs/cargo@v1 with: use-cross: true @@ -77,12 +76,11 @@ jobs: - x86_64-unknown-netbsd steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable with: toolchain: stable target: ${{matrix.target}} - override: true - uses: actions-rs/cargo@v1 with: use-cross: true diff --git a/.github/workflows/Features.yml b/.github/workflows/Features.yml index 9de95bb3..17ea1422 100644 --- a/.github/workflows/Features.yml +++ b/.github/workflows/Features.yml @@ -10,12 +10,11 @@ jobs: strategy: fail-fast: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install latest nightly - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@stable with: toolchain: nightly - override: true components: rustfmt, clippy - run: ci/test.sh - run: NIGHTLY=1 NO_STD=1 ci/test.sh diff --git a/.github/workflows/OSX.yml b/.github/workflows/OSX.yml index 4c1f91b7..446d02fd 100644 --- a/.github/workflows/OSX.yml +++ b/.github/workflows/OSX.yml @@ -15,12 +15,11 @@ jobs: - x86_64-apple-darwin steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable with: toolchain: stable target: ${{matrix.target}} - override: true - uses: actions-rs/cargo@v1 with: use-cross: true diff --git a/.github/workflows/Simple.yml b/.github/workflows/Simple.yml index 136b65ce..94e4d753 100644 --- a/.github/workflows/Simple.yml +++ b/.github/workflows/Simple.yml @@ -4,18 +4,35 @@ on: [push, pull_request, workflow_dispatch] jobs: + build: + name: Rust ${{matrix.rust}} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rust: [1.63.0] + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - uses: dtolnay/rust-toolchain@stable + with: + toolchain: ${{matrix.rust}} + - run: cargo check + - run: cargo build + test: name: Rust ${{matrix.rust}} runs-on: ubuntu-latest strategy: fail-fast: false matrix: - rust: [1.51.0, stable, beta, nightly] + rust: [1.65.0, stable, beta, nightly] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: recursive - - uses: dtolnay/rust-toolchain@master + - uses: dtolnay/rust-toolchain@stable with: toolchain: ${{matrix.rust}} - run: cargo check @@ -28,7 +45,7 @@ jobs: strategy: fail-fast: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install latest nightly uses: actions-rs/toolchain@v1 with: diff --git a/.github/workflows/Valgrind.yml b/.github/workflows/Valgrind.yml index 9d269603..3730b38b 100644 --- a/.github/workflows/Valgrind.yml +++ b/.github/workflows/Valgrind.yml @@ -10,12 +10,11 @@ jobs: strategy: fail-fast: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install latest nightly - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@stable with: toolchain: nightly - override: true - run: sudo apt-get update - run: sudo apt-get install valgrind - run: cargo +nightly install cargo-valgrind diff --git a/ci/check.sh b/ci/check.sh index b1fc9d38..b97a6ba8 100755 --- a/ci/check.sh +++ b/ci/check.sh @@ -4,7 +4,7 @@ set -ex # Change to our project home. -script_dir=`dirname "${BASH_SOURCE[0]}"` +script_dir=$(dirname "${BASH_SOURCE[0]}") cd "$script_dir"/.. scripts/check.sh diff --git a/ci/comprehensive.sh b/ci/comprehensive.sh index c20339a6..b223b567 100755 --- a/ci/comprehensive.sh +++ b/ci/comprehensive.sh @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC2086,SC2236 # Run a small subset of our comprehensive test suite. set -ex @@ -7,8 +8,8 @@ set -ex cargo --version # Change to our project home. -script_dir=`dirname "${BASH_SOURCE[0]}"` -script_home=`realpath "$script_dir"` +script_dir=$(dirname "${BASH_SOURCE[0]}") +script_home=$(realpath "$script_dir") cd "$script_home"/.. FEATURES= diff --git a/ci/test.sh b/ci/test.sh index 15836a44..d7251143 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -1,10 +1,11 @@ #!/bin/bash +# shellcheck disable=SC2086,SC2236 # Run main test suite. set -ex # Change to our project home. -script_dir=`dirname "${BASH_SOURCE[0]}"` +script_dir=$(dirname "${BASH_SOURCE[0]}") cd "$script_dir"/.. # Print our cargo version, for debugging. diff --git a/lexical-asm/src/lib.rs b/lexical-asm/src/lib.rs index e7504ae9..77d244d9 100644 --- a/lexical-asm/src/lib.rs +++ b/lexical-asm/src/lib.rs @@ -83,6 +83,7 @@ pub struct ParseIntError { pub kind: IntErrorKind, } +#[allow(dead_code)] trait FromStrRadixHelper: PartialOrd + Copy { fn min_value() -> Self; fn max_value() -> Self; diff --git a/lexical-benchmark/algorithm/Cargo.toml b/lexical-benchmark/algorithm/Cargo.toml index 893db6f0..a7ae7f76 100644 --- a/lexical-benchmark/algorithm/Cargo.toml +++ b/lexical-benchmark/algorithm/Cargo.toml @@ -16,13 +16,17 @@ default-features = false features = [] [dev-dependencies] -criterion = { version = "0.3", features = ["html_reports"] } -fastrand = "1.4" +criterion = { version = "0.5.0", features = ["html_reports"] } +fastrand = "2.1.0" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" [features] -default = ["std", "integers"] +default = ["std", "integers", "floats", "json"] std = ["lexical-util/std", "lexical-parse-float/std"] integers = [] +floats = [] +json = [] [[bench]] name = "bigint" diff --git a/lexical-benchmark/algorithm/bigint.rs b/lexical-benchmark/algorithm/bigint.rs index 0506eff0..975b01d7 100644 --- a/lexical-benchmark/algorithm/bigint.rs +++ b/lexical-benchmark/algorithm/bigint.rs @@ -187,7 +187,7 @@ fn karatsuba_mul_algo(big: &mut bigint::Bigint, y: &[bigint::Limb]) { // GENERATOR #[inline(always)] -fn new_limb(rng: &Rng) -> bigint::Limb { +fn new_limb(rng: &mut Rng) -> bigint::Limb { if bigint::LIMB_BITS == 32 { rng.u32(..) as bigint::Limb } else { @@ -200,10 +200,10 @@ macro_rules! generator { $group.bench_function($name, |bench| { let mut big = bigint::Bigint::new(); let seed = fastrand::u64(..); - let rng = Rng::with_seed(seed); + let mut rng = Rng::with_seed(seed); bench.iter(|| { unsafe { big.data.set_len(0) }; - big.data.try_push(new_limb(&rng)).unwrap(); + big.data.try_push(new_limb(&mut rng)).unwrap(); // Don't go any higher than 300. $cb(&mut big, rng.u32(1..300)); black_box(&big); @@ -220,18 +220,18 @@ macro_rules! generator { $group.bench_function($name, |bench| { let mut big = bigint::Bigint::new(); let seed = fastrand::u64(..); - let rng = Rng::with_seed(seed); + let mut rng = Rng::with_seed(seed); bench.iter(|| { unsafe { big.data.set_len(0) }; // Don't go higher than 20, since we a minimum of 60 limbs. let count = rng.usize(1..20); for _ in 0..count { - big.data.try_push(new_limb(&rng)).unwrap(); + big.data.try_push(new_limb(&mut rng)).unwrap(); } let count = rng.usize(1..20); let mut vec: Vec = Vec::new(); for _ in 0..count { - vec.push(new_limb(&rng)); + vec.push(new_limb(&mut rng)); } // Don't go any higher than 300. diff --git a/lexical-benchmark/algorithm/division.rs b/lexical-benchmark/algorithm/division.rs index a58412a6..23769f8d 100644 --- a/lexical-benchmark/algorithm/division.rs +++ b/lexical-benchmark/algorithm/division.rs @@ -35,7 +35,7 @@ fn fast_div(v: u32) -> (u32, u32) { let max_precision = 14; let additional_precision = 5; - let left_end = (((1 << (max_precision + additional_precision)) + divisor - 1) / divisor) as u32; + let left_end = ((1 << (max_precision + additional_precision)) + divisor - 1) / divisor; let quotient = (v.wrapping_mul(left_end)) >> (max_precision + additional_precision); let remainder = v - divisor * quotient; diff --git a/lexical-benchmark/input.rs b/lexical-benchmark/input.rs index b43fc403..2936f439 100644 --- a/lexical-benchmark/input.rs +++ b/lexical-benchmark/input.rs @@ -395,16 +395,12 @@ macro_rules! to_lexical_generator { macro_rules! dtoa_generator { ($group:ident, $name:expr, $iter:expr) => {{ - use lexical_util::constants::BUFFER_SIZE; - let mut buffer = vec![b'0'; BUFFER_SIZE]; + let mut buffer = dtoa::Buffer::new(); $group.bench_function($name, |bench| { bench.iter(|| { $iter.for_each(|x| { - dtoa::write(&mut buffer, *x).unwrap(); + dtoa::format(&mut buffer, *x).unwrap(); black_box(&buffer); - unsafe { - buffer.set_len(0); - } // Way faster than Vec::clear(). }) }) }); @@ -502,7 +498,8 @@ macro_rules! parse_integer_generator { macro_rules! write_float_generator { ($group:ident, $type:expr, $iter:expr, $fmt:ident) => {{ to_lexical_generator!($group, concat!("write_", $type, "_lexical"), $iter); - dtoa_generator!($group, concat!("write_", $type, "_dtoa"), $iter); + // FIXME: Restore dtoa format later + //dtoa_generator!($group, concat!("write_", $type, "_dtoa"), $iter); ryu_generator!($group, concat!("write_", $type, "_ryu"), $iter, $fmt); fmt_generator!($group, concat!("write_", $type, "_fmt"), $iter); }}; diff --git a/lexical-benchmark/parse-float/Cargo.toml b/lexical-benchmark/parse-float/Cargo.toml index e63844f4..04348a25 100644 --- a/lexical-benchmark/parse-float/Cargo.toml +++ b/lexical-benchmark/parse-float/Cargo.toml @@ -16,8 +16,8 @@ default-features = false features = [] [dev-dependencies] -criterion = { version = "0.3", features = ["html_reports"] } -fastrand = "1.4" +criterion = { version = "0.5", features = ["html_reports"] } +fastrand = "2.1.0" lazy_static = "1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" @@ -30,7 +30,9 @@ power-of-two = ["lexical-util/power-of-two", "lexical-parse-float/power-of-two"] format = ["lexical-util/format", "lexical-parse-float/format"] compact = ["lexical-util/compact", "lexical-parse-float/compact"] asm = [] -floats = [] +nightly = ["lexical-parse-float/nightly"] +integers = ["lexical-util/integers"] +floats = ["lexical-util/floats"] json = [] [[bench]] diff --git a/lexical-benchmark/parse-float/black_box.rs b/lexical-benchmark/parse-float/black_box.rs index 70189536..19cbcf83 100644 --- a/lexical-benchmark/parse-float/black_box.rs +++ b/lexical-benchmark/parse-float/black_box.rs @@ -15,6 +15,7 @@ pub fn black_box(mut dummy: f64) -> f64 { // Optimized black box using the nicer assembly syntax. #[cfg(not(feature = "asm"))] +#[allow(forgetting_copy_types)] pub fn black_box(dummy: f64) -> f64 { unsafe { let x = core::ptr::read_volatile(&dummy); diff --git a/lexical-benchmark/parse-integer/Cargo.toml b/lexical-benchmark/parse-integer/Cargo.toml index 0e4b34ac..e8681ec9 100644 --- a/lexical-benchmark/parse-integer/Cargo.toml +++ b/lexical-benchmark/parse-integer/Cargo.toml @@ -16,8 +16,8 @@ default-features = false features = [] [dev-dependencies] -criterion = { version = "0.3", features = ["html_reports"] } -fastrand = "1.4" +criterion = { version = "0.5.0", features = ["html_reports"] } +fastrand = "2.1.0" lazy_static = "1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" @@ -30,6 +30,7 @@ power-of-two = ["lexical-util/power-of-two", "lexical-parse-integer/power-of-two format = ["lexical-util/format", "lexical-parse-integer/format"] compact = ["lexical-util/compact", "lexical-parse-integer/compact"] integers = [] +floats = [] json = [] [[bench]] diff --git a/lexical-benchmark/write-float/Cargo.toml b/lexical-benchmark/write-float/Cargo.toml index 33704bfb..5243835f 100644 --- a/lexical-benchmark/write-float/Cargo.toml +++ b/lexical-benchmark/write-float/Cargo.toml @@ -18,7 +18,7 @@ features = [] [dev-dependencies] criterion = { version = "0.5", features = ["html_reports"] } dtoa = "1.0.9" -fastrand = "2.1.1" +fastrand = "2.1.0" lazy_static = "1" ryu = "1.0" serde = { version = "1.0", features = ["derive"] } @@ -31,6 +31,7 @@ radix = ["lexical-util/radix", "lexical-write-float/radix"] power-of-two = ["lexical-util/power-of-two", "lexical-write-float/power-of-two"] format = ["lexical-util/format", "lexical-write-float/format"] compact = ["lexical-util/compact", "lexical-write-float/compact"] +integers = [] floats = [] json = [] diff --git a/lexical-benchmark/write-integer/Cargo.toml b/lexical-benchmark/write-integer/Cargo.toml index d17bade2..b9681dbb 100644 --- a/lexical-benchmark/write-integer/Cargo.toml +++ b/lexical-benchmark/write-integer/Cargo.toml @@ -16,9 +16,9 @@ default-features = false features = [] [dev-dependencies] -criterion = { version = "0.3", features = ["html_reports"] } +criterion = { version = "0.5.0", features = ["html_reports"] } itoa = { version = "0.4", features = ["i128"] } -fastrand = "1.4" +fastrand = "2.1.0" lazy_static = "1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" @@ -31,6 +31,7 @@ power-of-two = ["lexical-util/power-of-two", "lexical-write-integer/power-of-two format = ["lexical-util/format", "lexical-write-integer/format"] compact = ["lexical-util/compact", "lexical-write-integer/compact"] integers = [] +floats = [] json = [] [[bench]] diff --git a/lexical-parse-float/Cargo.toml b/lexical-parse-float/Cargo.toml index 84054be5..29d5c165 100644 --- a/lexical-parse-float/Cargo.toml +++ b/lexical-parse-float/Cargo.toml @@ -38,7 +38,7 @@ static_assertions = "1" # Issue: https://github.com/BurntSushi/quickcheck/issues/295 # Fix: https://github.com/BurntSushi/quickcheck/pull/296 quickcheck = { git = "https://github.com/neithernut/quickcheck/", branch = "i32min-shrink-bound" } -proptest = "1.5.0" +proptest = ">=1.5.0" [features] default = ["std"] diff --git a/lexical-parse-integer/Cargo.toml b/lexical-parse-integer/Cargo.toml index f6fe8391..bbfff0e3 100644 --- a/lexical-parse-integer/Cargo.toml +++ b/lexical-parse-integer/Cargo.toml @@ -32,7 +32,7 @@ features = ["parse-integers"] # Issue: https://github.com/BurntSushi/quickcheck/issues/295 # Fix: https://github.com/BurntSushi/quickcheck/pull/296 quickcheck = { git = "https://github.com/neithernut/quickcheck/", branch = "i32min-shrink-bound" } -proptest = "1.5.0" +proptest = ">=1.5.0" [features] default = ["std"] diff --git a/lexical-parse-integer/docs/Algorithm.md b/lexical-parse-integer/docs/Algorithm.md index 201d40c2..d8c83dc2 100644 --- a/lexical-parse-integer/docs/Algorithm.md +++ b/lexical-parse-integer/docs/Algorithm.md @@ -145,8 +145,8 @@ let min_value = 10u64.pow(max as u32 - 1); let max_value = i64::MAX as u64 + 1; let is_overflow = count > max || (count == max && ( - value < min_value - || value > max_value + value < min_value + || value > max_value || (!is_negative && value == max_value) )); ``` diff --git a/lexical-util/etc/div128.py b/lexical-util/etc/div128.py index d85a52ac..8ce3160f 100644 --- a/lexical-util/etc/div128.py +++ b/lexical-util/etc/div128.py @@ -18,6 +18,7 @@ u64_max = 2**64 - 1 u128_max = 2**128-1 + def is_valid(x): '''Determine if the power is valid.''' return ( @@ -25,6 +26,7 @@ def is_valid(x): and (u128_max / (x**2)) < x ) + def find_power(radix): '''Find the power of the divisor.''' @@ -33,6 +35,7 @@ def find_power(radix): start_power += 1 return start_power - 1 + def choose_multiplier(divisor, bits, is_signed=False): ''' Choose multiplier algorithm from: @@ -58,6 +61,7 @@ def choose_multiplier(divisor, bits, is_signed=False): return (m_high, sh_post, div_bits) + def fast_shift(divisor): ''' Check if we can do a fast shift for quick division as a smaller type. @@ -69,6 +73,7 @@ def fast_shift(divisor): n += 1 return n + def is_pow2(radix): '''Determine if the value is an exact power-of-two.''' return radix == 2**int(math.log2(radix)) @@ -86,6 +91,7 @@ def print_comment(): // in the function signatures of the functions they call. ''') + def print_pow2(radix): '''Print the function for a power-of-two radix.''' @@ -100,6 +106,7 @@ def print_pow2(radix): print('}') print('') + def print_fast(radix, divisor, fast_shr, factor, factor_shr): '''Print the function for the fastest division algorithm.''' @@ -110,6 +117,7 @@ def print_fast(radix, divisor, fast_shr, factor, factor_shr): print('}') print('') + def print_moderate(radix, divisor, factor, factor_shr): '''Print the function for the moderate division algorithm.''' @@ -119,6 +127,7 @@ def print_moderate(radix, divisor, factor, factor_shr): print('}') print('') + def print_slow(radix, divisor): '''Print the function for the slow division algorithm.''' @@ -129,6 +138,7 @@ def print_slow(radix, divisor): print('}') print('') + def divisor_constants(): '''Generate all the divisor constants for all radices.''' @@ -156,10 +166,11 @@ def divisor_constants(): # PYTHON LOGIC # This is the approach, in Python, for how to do this. + def u128_mulhi(x, y): '''Multiply 2 128-bit integers, and get the high 128 bits.''' - lo_mask = (1<<64) - 1 + lo_mask = (1 << 64) - 1 x_lo = x & lo_mask x_hi = x >> 64 y_lo = y & lo_mask @@ -174,17 +185,19 @@ def u128_mulhi(x, y): return x_hi * y_hi + high1 + high2 + def udiv128(n, divisor=10**19): '''Do an exact division using pre-computed values.''' factor, factor_shr, _ = choose_multiplier(divisor, 128) shr = fast_shift(divisor) - if n < (1<<(64 + shr)): + if n < (1 << (64 + shr)): quotient = (n >> shr) // (divisor >> shr) else: quotient = u128_mulhi(n, factor) >> factor_shr remainder = (n - quotient * divisor) return (quotient, remainder) + if __name__ == '__main__': divisor_constants() diff --git a/lexical-util/etc/step.py b/lexical-util/etc/step.py index 5ebd7fca..6c2cd328 100644 --- a/lexical-util/etc/step.py +++ b/lexical-util/etc/step.py @@ -16,10 +16,12 @@ UNSIGNED_MAX = [2**i for i in WIDTHS] SIGNED_MAX = [2**(i - 1) for i in WIDTHS] + def is_pow2(radix): '''Determine if the value is an exact power-of-two.''' return radix == 2**int(math.log2(radix)) + def find_power(max_value, radix): '''Find the power of the divisor.''' @@ -34,6 +36,7 @@ def find_power(max_value, radix): return (power, power + 1) return (power, power) + def print_comment(): '''Print the auto-generated comment''' @@ -47,6 +50,7 @@ def print_comment(): // recurse. Under normal circumstances, this will never be called. ''') + def print_power(radix): '''Print the minimum and maximum powers.''' @@ -59,7 +63,7 @@ def print_power(radix): for index in range(len(WIDTHS)): print(f' {WIDTHS[index]} if is_signed => {signed[index][1]},') print(f' {WIDTHS[index]} if !is_signed => {unsigned[index][1]},') - print(f' _ => 1,') + print(' _ => 1,') print(' }') print('}') print('') @@ -70,11 +74,12 @@ def print_power(radix): for index in range(len(WIDTHS)): print(f' {WIDTHS[index]} if is_signed => {signed[index][0]},') print(f' {WIDTHS[index]} if !is_signed => {unsigned[index][0]},') - print(f' _ => 1,') + print(' _ => 1,') print(' }') print('}') print('') + def main(): '''Generate all the step sizes for given radixes.''' @@ -82,5 +87,6 @@ def main(): for radix in range(2, 37): print_power(radix) + if __name__ == '__main__': main() diff --git a/lexical-util/src/div128.rs b/lexical-util/src/div128.rs index 50b0fa57..72e5cf77 100644 --- a/lexical-util/src/div128.rs +++ b/lexical-util/src/div128.rs @@ -47,6 +47,7 @@ use crate::assert::debug_assert_radix; use crate::mul::mulhi; /// Calculate a div/remainder algorithm optimized for power-of-two radixes. +/// /// This is trivial: the number of digits we process is `64 / log2(radix)`. /// Therefore, the `shr` is `log2(radix) * digits`, and the mask is just the /// lower `shr` bits of the digits. diff --git a/lexical-util/src/iterator.rs b/lexical-util/src/iterator.rs index 77e004e3..e9864f77 100644 --- a/lexical-util/src/iterator.rs +++ b/lexical-util/src/iterator.rs @@ -124,7 +124,6 @@ pub trait BytesIter<'a>: Iterator { /// This advances the internal state of the iterator. fn read_u32(&self) -> Option; - /// Try to read the next eight bytes as a u64 /// This advances the internal state of the iterator. fn read_u64(&self) -> Option; diff --git a/lexical-util/src/not_feature_format.rs b/lexical-util/src/not_feature_format.rs index 224f2cc5..181b825d 100644 --- a/lexical-util/src/not_feature_format.rs +++ b/lexical-util/src/not_feature_format.rs @@ -566,3 +566,9 @@ impl NumberFormat { NumberFormatBuilder::rebuild(FORMAT) } } + +impl Default for NumberFormat { + fn default() -> Self { + Self::new() + } +} diff --git a/lexical-util/tests/div128_tests.rs b/lexical-util/tests/div128_tests.rs index f64d9548..9d6c5bf8 100644 --- a/lexical-util/tests/div128_tests.rs +++ b/lexical-util/tests/div128_tests.rs @@ -8,7 +8,7 @@ use proptest::{prop_assert_eq, proptest}; proptest! { #[test] #[cfg_attr(miri, ignore)] - fn u128_divrem_proptest(i in u128::min_value()..u128::max_value()) { + fn u128_divrem_proptest(i in u128::MIN..u128::MAX) { let (hi, lo) = u128_divrem(i, 10); let step = u64_step(10); let d = 10u128.pow(step as u32); @@ -19,7 +19,7 @@ proptest! { #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn u128_divrem_radix_proptest(i in u128::min_value()..u128::max_value(), radix in 2u32..=36) { + fn u128_divrem_radix_proptest(i in u128::MIN..u128::MAX, radix in 2u32..=36) { // Simulate a const expr. let (hi, lo) = u128_divrem(i, radix); let step = u64_step(radix); diff --git a/lexical-util/tests/iterator_tests.rs b/lexical-util/tests/iterator_tests.rs index 45245652..813217f2 100644 --- a/lexical-util/tests/iterator_tests.rs +++ b/lexical-util/tests/iterator_tests.rs @@ -21,7 +21,7 @@ fn digits_iterator_test() { assert_eq!(iter.as_ptr(), digits.as_ptr()); assert_eq!(iter.is_consumed(), false); assert_eq!(iter.is_done(), false); - assert_eq!(u32::from_le(iter.read::().unwrap()), 0x34333231); + assert_eq!(u32::from_le(iter.read_u32().unwrap()), 0x34333231); assert_eq!(iter.length(), 5); assert_eq!(iter.cursor(), 0); assert_eq!(iter.current_count(), 0); @@ -39,7 +39,7 @@ fn digits_iterator_test() { let mut byte = digits.bytes::<{ STANDARD }>(); let mut iter = byte.integer_iter(); - assert_eq!(iter.read::(), None); + assert_eq!(iter.read_u64(), None); assert_eq!(iter.nth(4).unwrap(), &b'5'); assert_eq!(iter.as_slice(), &digits[digits.len()..]); assert_eq!(iter.as_ptr(), digits[digits.len()..].as_ptr()); diff --git a/lexical-write-float/Cargo.toml b/lexical-write-float/Cargo.toml index cc163854..0dcc76cc 100644 --- a/lexical-write-float/Cargo.toml +++ b/lexical-write-float/Cargo.toml @@ -39,7 +39,7 @@ approx = "0.5.0" # Issue: https://github.com/BurntSushi/quickcheck/issues/295 # Fix: https://github.com/BurntSushi/quickcheck/pull/296 quickcheck = { git = "https://github.com/neithernut/quickcheck/", branch = "i32min-shrink-bound" } -proptest = "1.5.0" +proptest = ">=1.5.0" fraction = "0.15.0" [features] diff --git a/lexical-write-float/etc/correctness/Cargo.toml b/lexical-write-float/etc/correctness/Cargo.toml index 6842560a..bbf9c08b 100644 --- a/lexical-write-float/etc/correctness/Cargo.toml +++ b/lexical-write-float/etc/correctness/Cargo.toml @@ -20,7 +20,7 @@ version = "4.5" features = ["derive"] [dependencies] -fastrand = "2.1" +fastrand = "2.1.0" [features] std = ["lexical-util/std", "lexical-write-float/std"] diff --git a/lexical-write-float/src/algorithm.rs b/lexical-write-float/src/algorithm.rs index f3a1fb41..687c75fc 100644 --- a/lexical-write-float/src/algorithm.rs +++ b/lexical-write-float/src/algorithm.rs @@ -793,10 +793,11 @@ pub unsafe fn write_digits_u32(bytes: &mut [u8], mantissa: u32) -> usize { unsafe { mantissa.write_mantissa::(bytes) } } -/// Write the significant digits, when the significant digits cannot fit in a -/// 32-bit integer. Returns the number of digits written. Note that this -/// might not be the same as the number of digits in the mantissa, since -/// trailing zeros will be removed. +/// Write the significant digits, when the significant digits cannot fit in a 32-bit integer. +/// +/// Returns the number of digits written. Note that this might not be the +/// same as the number of digits in the mantissa, since trailing zeros will +/// be removed. /// /// # Safety /// @@ -985,7 +986,7 @@ pub const fn divide_by_pow10_32(n: u32, exp: u32) -> u32 { if exp == 2 { ((n as u64 * 1374389535) >> 37) as u32 } else { - let divisor = pow32(exp as u32, 10); + let divisor = pow32(exp, 10); n / divisor } } @@ -999,7 +1000,7 @@ pub const fn divide_by_pow10_64(n: u64, exp: u32, n_max: u64) -> u64 { if exp == 3 && n_max <= 15534100272597517998 { umul128_upper64(n, 2361183241434822607) >> 7 } else { - let divisor = pow64(exp as u32, 10); + let divisor = pow64(exp, 10); n / divisor } } diff --git a/lexical-write-float/src/table_dragonbox.rs b/lexical-write-float/src/table_dragonbox.rs index 930bc32d..ae381111 100644 --- a/lexical-write-float/src/table_dragonbox.rs +++ b/lexical-write-float/src/table_dragonbox.rs @@ -20,6 +20,7 @@ pub const LARGEST_F64_POW5: i32 = 326; pub const N64_POWERS_OF_FIVE: usize = (LARGEST_F64_POW5 - SMALLEST_F64_POW5 + 1) as usize; /// Pre-computed powers-of-5 for the dragonbox algorithm for f32. +/// /// This is very similar to the high bits for `DRAGONBOX64_POWERS_OF_FIVE`, /// with rounding obviously for the bits. pub const DRAGONBOX32_POWERS_OF_FIVE: [u64; N32_POWERS_OF_FIVE] = [ @@ -104,6 +105,7 @@ pub const DRAGONBOX32_POWERS_OF_FIVE: [u64; N32_POWERS_OF_FIVE] = [ ]; /// Pre-computed powers-of-5 for the dragonbox algorithm for f64. +/// /// This is very similar to the Lemire table, however, a few slight /// differences exist: this goes from `5^-292` to `5^326`, a different /// range than Lemire which goes from `5^-342 to 5^308`. diff --git a/lexical-write-integer/Cargo.toml b/lexical-write-integer/Cargo.toml index b87de1a0..a4d9887e 100644 --- a/lexical-write-integer/Cargo.toml +++ b/lexical-write-integer/Cargo.toml @@ -32,7 +32,7 @@ features = ["write-integers"] # Issue: https://github.com/BurntSushi/quickcheck/issues/295 # Fix: https://github.com/BurntSushi/quickcheck/pull/296 quickcheck = { git = "https://github.com/neithernut/quickcheck/", branch = "i32min-shrink-bound" } -proptest = "1.5.0" +proptest = ">=1.5.0" [features] default = ["std"] diff --git a/lexical-write-integer/tests/api_tests.rs b/lexical-write-integer/tests/api_tests.rs index 4c938b5f..79a8c437 100644 --- a/lexical-write-integer/tests/api_tests.rs +++ b/lexical-write-integer/tests/api_tests.rs @@ -16,6 +16,7 @@ use quickcheck::quickcheck; use util::from_radix; trait Roundtrip: ToLexical + ToLexicalWithOptions + FromStr { + #[allow(dead_code)] fn from_str_radix(src: &str, radix: u32) -> Result; } @@ -1251,157 +1252,157 @@ quickcheck! { proptest! { #[test] #[cfg_attr(miri, ignore)] - fn u8_proptest(i in u8::min_value()..u8::max_value()) { + fn u8_proptest(i in u8::MIN..u8::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn i8_proptest(i in i8::min_value()..i8::max_value()) { + fn i8_proptest(i in i8::MIN..i8::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn u16_proptest(i in u16::min_value()..u16::max_value()) { + fn u16_proptest(i in u16::MIN..u16::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn i16_proptest(i in i16::min_value()..i16::max_value()) { + fn i16_proptest(i in i16::MIN..i16::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn u32_proptest(i in u32::min_value()..u32::max_value()) { + fn u32_proptest(i in u32::MIN..u32::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn i32_proptest(i in i32::min_value()..i32::max_value()) { + fn i32_proptest(i in i32::MIN..i32::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn u64_proptest(i in u64::min_value()..u64::max_value()) { + fn u64_proptest(i in u64::MIN..u64::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn i64_proptest(i in i64::min_value()..i64::max_value()) { + fn i64_proptest(i in i64::MIN..i64::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn u128_proptest(i in u128::min_value()..u128::max_value()) { + fn u128_proptest(i in u128::MIN..u128::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn i128_proptest(i in i128::min_value()..i128::max_value()) { + fn i128_proptest(i in i128::MIN..i128::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn usize_proptest(i in usize::min_value()..usize::max_value()) { + fn usize_proptest(i in usize::MIN..usize::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] - fn isize_proptest(i in isize::min_value()..isize::max_value()) { + fn isize_proptest(i in isize::MIN..isize::MAX) { prop_assert_eq!(i, roundtrip(i)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn u8_proptest_radix(i in u8::min_value()..u8::max_value(), radix in 2u32..=36) { + fn u8_proptest_radix(i in u8::MIN..u8::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn i8_proptest_radix(i in i8::min_value()..i8::max_value(), radix in 2u32..=36) { + fn i8_proptest_radix(i in i8::MIN..i8::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn u16_proptest_radix(i in u16::min_value()..u16::max_value(), radix in 2u32..=36) { + fn u16_proptest_radix(i in u16::MIN..u16::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn i16_proptest_radix(i in i16::min_value()..i16::max_value(), radix in 2u32..=36) { + fn i16_proptest_radix(i in i16::MIN..i16::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn u32_proptest_radix(i in u32::min_value()..u32::max_value(), radix in 2u32..=36) { + fn u32_proptest_radix(i in u32::MIN..u32::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn i32_proptest_radix(i in i32::min_value()..i32::max_value(), radix in 2u32..=36) { + fn i32_proptest_radix(i in i32::MIN..i32::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn u64_proptest_radix(i in u64::min_value()..u64::max_value(), radix in 2u32..=36) { + fn u64_proptest_radix(i in u64::MIN..u64::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn i64_proptest_radix(i in i64::min_value()..i64::max_value(), radix in 2u32..=36) { + fn i64_proptest_radix(i in i64::MIN..i64::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn u128_proptest_radix(i in u128::min_value()..u128::max_value(), radix in 2u32..=36) { + fn u128_proptest_radix(i in u128::MIN..u128::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn i128_proptest_radix(i in i128::min_value()..i128::max_value(), radix in 2u32..=36) { + fn i128_proptest_radix(i in i128::MIN..i128::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn usize_proptest_radix(i in usize::min_value()..usize::max_value(), radix in 2u32..=36) { + fn usize_proptest_radix(i in usize::MIN..usize::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } #[test] #[cfg_attr(miri, ignore)] #[cfg(feature = "radix")] - fn isize_proptest_radix(i in isize::min_value()..isize::max_value(), radix in 2u32..=36) { + fn isize_proptest_radix(i in isize::MIN..isize::MAX, radix in 2u32..=36) { prop_assert_eq!(i, roundtrip_radix(i, radix)); } } diff --git a/scripts/check.sh b/scripts/check.sh index 3b7da291..70fb5e7f 100755 --- a/scripts/check.sh +++ b/scripts/check.sh @@ -4,7 +4,7 @@ set -ex # Change to our project home. -script_dir=`dirname "${BASH_SOURCE[0]}"` +script_dir=$(dirname "${BASH_SOURCE[0]}") cd "$script_dir"/.. # Make sure we error on warnings, and don't format in-place. diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..c836869e --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[flake8] +max-line-length = 110