From f7328b4da7cd8b787b52101a740b06d190c537aa Mon Sep 17 00:00:00 2001 From: Patrick Norton Date: Thu, 22 Jul 2021 19:22:58 -0400 Subject: [PATCH 1/5] Added iter_u*_digits_be() methods --- src/biguint.rs | 39 +++++++ src/biguint/iter_be.rs | 257 +++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 + 3 files changed, 298 insertions(+) create mode 100644 src/biguint/iter_be.rs diff --git a/src/biguint.rs b/src/biguint.rs index 271a8837..e30582f4 100644 --- a/src/biguint.rs +++ b/src/biguint.rs @@ -30,9 +30,11 @@ mod arbitrary; #[cfg(feature = "serde")] mod serde; +mod iter_be; pub(crate) use self::convert::to_str_radix_reversed; pub use self::iter::{U32Digits, U64Digits}; +pub use self::iter_be::{U32DigitsBe, U64DigitsBe}; /// A big unsigned integer type. pub struct BigUint { @@ -774,6 +776,43 @@ impl BigUint { U64Digits::new(self.data.as_slice()) } + /// Returns an iterator of `u32` digits representation of the `BigUint` ordered least + /// significant digit first. + /// + /// # Examples + /// + /// ``` + /// use num_bigint::BigUint; + /// + /// assert_eq!(BigUint::from(1125u32).iter_u32_digits_be().collect::>(), vec![1125]); + /// assert_eq!(BigUint::from(4294967295u32).iter_u32_digits_be().collect::>(), vec![4294967295]); + /// assert_eq!(BigUint::from(4294967296u64).iter_u32_digits_be().collect::>(), vec![0, 1]); + /// assert_eq!(BigUint::from(112500000000u64).iter_u32_digits_be().collect::>(), vec![26, 830850304]); + /// ``` + #[inline] + pub fn iter_u32_digits_be(&self) -> U32DigitsBe<'_> { + U32DigitsBe::new(self.data.as_slice()) + } + + /// Returns an iterator of `u64` digits representation of the `BigUint` ordered least + /// significant digit first. + /// + /// # Examples + /// + /// ``` + /// use num_bigint::BigUint; + /// + /// assert_eq!(BigUint::from(1125u32).iter_u64_digits_be().collect::>(), vec![1125]); + /// assert_eq!(BigUint::from(4294967295u32).iter_u64_digits_be().collect::>(), vec![4294967295]); + /// assert_eq!(BigUint::from(4294967296u64).iter_u64_digits_be().collect::>(), vec![4294967296]); + /// assert_eq!(BigUint::from(112500000000u64).iter_u64_digits_be().collect::>(), vec![112500000000]); + /// assert_eq!(BigUint::from(1u128 << 64).iter_u64_digits_be().collect::>(), vec![1, 0]); + /// ``` + #[inline] + pub fn iter_u64_digits_be(&self) -> U64DigitsBe<'_> { + U64DigitsBe::new(self.data.as_slice()) + } + /// Returns the integer formatted as a string in the given radix. /// `radix` must be in the range `2...36`. /// diff --git a/src/biguint/iter_be.rs b/src/biguint/iter_be.rs new file mode 100644 index 00000000..948b6dc1 --- /dev/null +++ b/src/biguint/iter_be.rs @@ -0,0 +1,257 @@ +use core::iter::FusedIterator; + +#[cfg(not(u64_digit))] +use super::u32_chunk_to_u64; + +/// An iterator of `u32` digits representation of a `BigUint` or `BigInt`, +/// ordered most significant digit first. +pub struct U32DigitsBe<'a> { + #[cfg(u64_digit)] + data: &'a [u64], + #[cfg(u64_digit)] + next_is_hi: bool, + + #[cfg(not(u64_digit))] + it: core::slice::Iter<'a, u32>, +} + +#[cfg(u64_digit)] +impl<'a> U32DigitsBe<'a> { + #[inline] + pub(super) fn new(data: &'a [u64]) -> Self { + let last_hi_is_zero = data + .last() + .map(|&last| { + let last_hi = (last >> 32) as u32; + last_hi == 0 + }) + .unwrap_or(false); + U32DigitsBe { + data, + next_is_hi: !last_hi_is_zero, + } + } +} + +#[cfg(u64_digit)] +impl Iterator for U32DigitsBe<'_> { + type Item = u32; + #[inline] + fn next(&mut self) -> Option { + match self.data.split_last() { + Some((&first, data)) => { + let next_is_hi = self.next_is_hi; + self.next_is_hi = !next_is_hi; + if next_is_hi { + Some((first >> 32) as u32) + } else { + self.data = data; + Some(first as u32) + } + } + None => None, + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let len = self.len(); + (len, Some(len)) + } + + #[inline] + fn last(self) -> Option { + self.data.first().map(|&last| last as u32) + } + + #[inline] + fn count(self) -> usize { + self.len() + } +} + +#[cfg(u64_digit)] +impl ExactSizeIterator for U32DigitsBe<'_> { + #[inline] + fn len(&self) -> usize { + self.data.len() * 2 - usize::from(!self.next_is_hi) + } +} + +#[cfg(not(u64_digit))] +impl<'a> U32DigitsBe<'a> { + #[inline] + pub(super) fn new(data: &'a [u32]) -> Self { + Self { it: data.iter() } + } +} + +#[cfg(not(u64_digit))] +impl Iterator for U32DigitsBe<'_> { + type Item = u32; + #[inline] + fn next(&mut self) -> Option { + self.it.next_back().cloned() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + self.it.nth_back(n).cloned() + } + + #[inline] + fn last(mut self) -> Option { + self.it.next().cloned() + } + + #[inline] + fn count(self) -> usize { + self.it.count() + } +} + +#[cfg(not(u64_digit))] +impl ExactSizeIterator for U32DigitsBe<'_> { + #[inline] + fn len(&self) -> usize { + self.it.len() + } +} + +impl FusedIterator for U32DigitsBe<'_> {} + +/// An iterator of `u64` digits representation of a `BigUint` or `BigInt`, +/// ordered most significant digit first. +pub struct U64DigitsBe<'a> { + #[cfg(not(u64_digit))] + it: core::slice::Chunks<'a, u32>, + + #[cfg(u64_digit)] + it: core::slice::Iter<'a, u64>, +} + +#[cfg(not(u64_digit))] +impl<'a> U64DigitsBe<'a> { + #[inline] + pub(super) fn new(data: &'a [u32]) -> Self { + U64DigitsBe { it: data.chunks(2) } + } +} + +#[cfg(not(u64_digit))] +impl Iterator for U64DigitsBe<'_> { + type Item = u64; + #[inline] + fn next(&mut self) -> Option { + self.it.next_back().map(u32_chunk_to_u64) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let len = self.len(); + (len, Some(len)) + } + + #[inline] + fn last(mut self) -> Option { + self.it.next().map(u32_chunk_to_u64) + } + + #[inline] + fn count(self) -> usize { + self.len() + } +} + +#[cfg(u64_digit)] +impl<'a> U64DigitsBe<'a> { + #[inline] + pub(super) fn new(data: &'a [u64]) -> Self { + Self { it: data.iter() } + } +} + +#[cfg(u64_digit)] +impl Iterator for U64DigitsBe<'_> { + type Item = u64; + #[inline] + fn next(&mut self) -> Option { + self.it.next_back().cloned() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + self.it.nth_back(n).cloned() + } + + #[inline] + fn last(mut self) -> Option { + self.it.next().cloned() + } + + #[inline] + fn count(self) -> usize { + self.it.count() + } +} + +impl ExactSizeIterator for U64DigitsBe<'_> { + #[inline] + fn len(&self) -> usize { + self.it.len() + } +} + +impl FusedIterator for U64DigitsBe<'_> {} + +#[test] +fn test_iter_u32_digits() { + let n = super::BigUint::from(5u8); + let mut it = n.iter_u32_digits_be(); + assert_eq!(it.len(), 1); + assert_eq!(it.next(), Some(5)); + assert_eq!(it.len(), 0); + assert_eq!(it.next(), None); + assert_eq!(it.len(), 0); + assert_eq!(it.next(), None); + + let n = super::BigUint::from(112500000000u64); + let mut it = n.iter_u32_digits_be(); + assert_eq!(it.len(), 2); + assert_eq!(it.next(), Some(26)); + assert_eq!(it.len(), 1); + assert_eq!(it.next(), Some(830850304)); + assert_eq!(it.len(), 0); + assert_eq!(it.next(), None); +} + +#[test] +fn test_iter_u64_digits() { + let n = super::BigUint::from(5u8); + let mut it = n.iter_u64_digits_be(); + assert_eq!(it.len(), 1); + assert_eq!(it.next(), Some(5)); + assert_eq!(it.len(), 0); + assert_eq!(it.next(), None); + assert_eq!(it.len(), 0); + assert_eq!(it.next(), None); + + let n = super::BigUint::from(18_446_744_073_709_551_616u128); + let mut it = n.iter_u64_digits_be(); + assert_eq!(it.len(), 2); + assert_eq!(it.next(), Some(1)); + assert_eq!(it.len(), 1); + assert_eq!(it.next(), Some(0)); + assert_eq!(it.len(), 0); + assert_eq!(it.next(), None); +} diff --git a/src/lib.rs b/src/lib.rs index b88c5df2..b1758130 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -231,6 +231,8 @@ pub use crate::biguint::BigUint; pub use crate::biguint::ToBigUint; pub use crate::biguint::U32Digits; pub use crate::biguint::U64Digits; +pub use crate::biguint::U32DigitsBe; +pub use crate::biguint::U64DigitsBe; pub use crate::bigint::BigInt; pub use crate::bigint::Sign; From aef8dcb6a3783ac694a754d5a87eca7cdc2fc132 Mon Sep 17 00:00:00 2001 From: Patrick Norton Date: Thu, 22 Jul 2021 19:34:37 -0400 Subject: [PATCH 2/5] Added iter_u*_digits_be() methods to BigInt --- src/bigint.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/bigint.rs b/src/bigint.rs index 891eeb46..14c59d9e 100644 --- a/src/bigint.rs +++ b/src/bigint.rs @@ -303,6 +303,7 @@ enum CheckedUnsignedAbs { Negative(T), } use self::CheckedUnsignedAbs::{Negative, Positive}; +use crate::{U32DigitsBe, U64DigitsBe}; macro_rules! impl_unsigned_abs { ($Signed:ty, $Unsigned:ty) => { @@ -825,6 +826,45 @@ impl BigInt { self.data.iter_u64_digits() } + /// Returns an iterator of `u32` digits representation of the `BigInt` ordered most + /// significant digit first. + /// + /// # Examples + /// + /// ``` + /// use num_bigint::BigInt; + /// + /// assert_eq!(BigInt::from(-1125).iter_u32_digits().collect::>(), vec![1125]); + /// assert_eq!(BigInt::from(4294967295u32).iter_u32_digits().collect::>(), vec![4294967295]); + /// assert_eq!(BigInt::from(4294967296u64).iter_u32_digits().collect::>(), vec![1, 0]); + /// assert_eq!(BigInt::from(-112500000000i64).iter_u32_digits().collect::>(), vec![26, 830850304]); + /// assert_eq!(BigInt::from(112500000000i64).iter_u32_digits().collect::>(), vec![26, 830850304]); + /// ``` + #[inline] + pub fn iter_u32_digits_be(&self) -> U32DigitsBe<'_> { + self.data.iter_u32_digits_be() + } + + /// Returns an iterator of `u64` digits representation of the `BigInt` ordered most + /// significant digit first. + /// + /// # Examples + /// + /// ``` + /// use num_bigint::BigInt; + /// + /// assert_eq!(BigInt::from(-1125).iter_u64_digits().collect::>(), vec![1125u64]); + /// assert_eq!(BigInt::from(4294967295u32).iter_u64_digits().collect::>(), vec![4294967295u64]); + /// assert_eq!(BigInt::from(4294967296u64).iter_u64_digits().collect::>(), vec![4294967296u64]); + /// assert_eq!(BigInt::from(-112500000000i64).iter_u64_digits().collect::>(), vec![112500000000u64]); + /// assert_eq!(BigInt::from(112500000000i64).iter_u64_digits().collect::>(), vec![112500000000u64]); + /// assert_eq!(BigInt::from(1u128 << 64).iter_u64_digits().collect::>(), vec![1, 0]); + /// ``` + #[inline] + pub fn iter_u64_digits_be(&self) -> U64DigitsBe<'_> { + self.data.iter_u64_digits_be() + } + /// Returns the two's-complement byte representation of the `BigInt` in big-endian byte order. /// /// # Examples From 37dd0fa25c729d41d398b0eef9475a42f6e2573c Mon Sep 17 00:00:00 2001 From: Patrick Norton Date: Tue, 27 Jul 2021 20:40:47 -0400 Subject: [PATCH 3/5] Implemented DoubleEndedIterator for iter_*_digits --- src/biguint/iter.rs | 87 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/src/biguint/iter.rs b/src/biguint/iter.rs index 5b9ceff5..1e673e45 100644 --- a/src/biguint/iter.rs +++ b/src/biguint/iter.rs @@ -84,6 +84,30 @@ impl Iterator for U32Digits<'_> { } } +#[cfg(u64_digit)] +impl DoubleEndedIterator for U32Digits<'_> { + fn next_back(&mut self) -> Option { + match self.data.split_last() { + Some((&last, data)) => { + let last_is_lo = self.last_hi_is_zero; + self.last_hi_is_zero = !last_is_lo; + if last_is_lo { + self.data = data; + if data.is_empty() && !self.next_is_lo { + self.next_is_lo = true; + None + } else { + Some(last as u32) + } + } else { + Some((last >> 32) as u32) + } + } + None => None, + } + } +} + #[cfg(u64_digit)] impl ExactSizeIterator for U32Digits<'_> { #[inline] @@ -129,6 +153,13 @@ impl Iterator for U32Digits<'_> { } } +#[cfg(not(u64_digit))] +impl DoubleEndedIterator for U32Digits<'_> { + fn next_back(&mut self) -> Option { + self.it.next_back().copied() + } +} + #[cfg(not(u64_digit))] impl ExactSizeIterator for U32Digits<'_> { #[inline] @@ -182,6 +213,13 @@ impl Iterator for U64Digits<'_> { } } +#[cfg(not(u64_digit))] +impl DoubleEndedIterator for U64Digits<'_> { + fn next_back(&mut self) -> Option { + self.it.next_back().map(u32_chunk_to_u64) + } +} + #[cfg(u64_digit)] impl<'a> U64Digits<'a> { #[inline] @@ -219,6 +257,13 @@ impl Iterator for U64Digits<'_> { } } +#[cfg(u64_digit)] +impl DoubleEndedIterator for U64Digits<'_> { + fn next_back(&mut self) -> Option { + self.it.next_back().cloned() + } +} + impl ExactSizeIterator for U64Digits<'_> { #[inline] fn len(&self) -> usize { @@ -269,3 +314,45 @@ fn test_iter_u64_digits() { assert_eq!(it.len(), 0); assert_eq!(it.next(), None); } + +#[test] +fn test_iter_u32_digits_be() { + let n = super::BigUint::from(5u8); + let mut it = n.iter_u32_digits(); + assert_eq!(it.len(), 1); + assert_eq!(it.next(), Some(5)); + assert_eq!(it.len(), 0); + assert_eq!(it.next(), None); + assert_eq!(it.len(), 0); + assert_eq!(it.next(), None); + + let n = super::BigUint::from(112500000000u64); + let mut it = n.iter_u32_digits(); + assert_eq!(it.len(), 2); + assert_eq!(it.next(), Some(830850304)); + assert_eq!(it.len(), 1); + assert_eq!(it.next(), Some(26)); + assert_eq!(it.len(), 0); + assert_eq!(it.next(), None); +} + +#[test] +fn test_iter_u64_digits_be() { + let n = super::BigUint::from(5u8); + let mut it = n.iter_u64_digits(); + assert_eq!(it.len(), 1); + assert_eq!(it.next_back(), Some(5)); + assert_eq!(it.len(), 0); + assert_eq!(it.next(), None); + assert_eq!(it.len(), 0); + assert_eq!(it.next(), None); + + let n = super::BigUint::from(18_446_744_073_709_551_616u128); + let mut it = n.iter_u64_digits(); + assert_eq!(it.len(), 2); + assert_eq!(it.next_back(), Some(1)); + assert_eq!(it.len(), 1); + assert_eq!(it.next_back(), Some(0)); + assert_eq!(it.len(), 0); + assert_eq!(it.next(), None); +} From 1597792173da1365744c1d24d0c6844e6e7d5b20 Mon Sep 17 00:00:00 2001 From: Patrick Norton Date: Wed, 28 Jul 2021 08:58:03 -0400 Subject: [PATCH 4/5] Removed iter_*_digits_be() methods --- src/bigint.rs | 40 ------- src/biguint.rs | 39 ------- src/biguint/iter_be.rs | 257 ----------------------------------------- src/lib.rs | 2 - 4 files changed, 338 deletions(-) delete mode 100644 src/biguint/iter_be.rs diff --git a/src/bigint.rs b/src/bigint.rs index 14c59d9e..891eeb46 100644 --- a/src/bigint.rs +++ b/src/bigint.rs @@ -303,7 +303,6 @@ enum CheckedUnsignedAbs { Negative(T), } use self::CheckedUnsignedAbs::{Negative, Positive}; -use crate::{U32DigitsBe, U64DigitsBe}; macro_rules! impl_unsigned_abs { ($Signed:ty, $Unsigned:ty) => { @@ -826,45 +825,6 @@ impl BigInt { self.data.iter_u64_digits() } - /// Returns an iterator of `u32` digits representation of the `BigInt` ordered most - /// significant digit first. - /// - /// # Examples - /// - /// ``` - /// use num_bigint::BigInt; - /// - /// assert_eq!(BigInt::from(-1125).iter_u32_digits().collect::>(), vec![1125]); - /// assert_eq!(BigInt::from(4294967295u32).iter_u32_digits().collect::>(), vec![4294967295]); - /// assert_eq!(BigInt::from(4294967296u64).iter_u32_digits().collect::>(), vec![1, 0]); - /// assert_eq!(BigInt::from(-112500000000i64).iter_u32_digits().collect::>(), vec![26, 830850304]); - /// assert_eq!(BigInt::from(112500000000i64).iter_u32_digits().collect::>(), vec![26, 830850304]); - /// ``` - #[inline] - pub fn iter_u32_digits_be(&self) -> U32DigitsBe<'_> { - self.data.iter_u32_digits_be() - } - - /// Returns an iterator of `u64` digits representation of the `BigInt` ordered most - /// significant digit first. - /// - /// # Examples - /// - /// ``` - /// use num_bigint::BigInt; - /// - /// assert_eq!(BigInt::from(-1125).iter_u64_digits().collect::>(), vec![1125u64]); - /// assert_eq!(BigInt::from(4294967295u32).iter_u64_digits().collect::>(), vec![4294967295u64]); - /// assert_eq!(BigInt::from(4294967296u64).iter_u64_digits().collect::>(), vec![4294967296u64]); - /// assert_eq!(BigInt::from(-112500000000i64).iter_u64_digits().collect::>(), vec![112500000000u64]); - /// assert_eq!(BigInt::from(112500000000i64).iter_u64_digits().collect::>(), vec![112500000000u64]); - /// assert_eq!(BigInt::from(1u128 << 64).iter_u64_digits().collect::>(), vec![1, 0]); - /// ``` - #[inline] - pub fn iter_u64_digits_be(&self) -> U64DigitsBe<'_> { - self.data.iter_u64_digits_be() - } - /// Returns the two's-complement byte representation of the `BigInt` in big-endian byte order. /// /// # Examples diff --git a/src/biguint.rs b/src/biguint.rs index e30582f4..271a8837 100644 --- a/src/biguint.rs +++ b/src/biguint.rs @@ -30,11 +30,9 @@ mod arbitrary; #[cfg(feature = "serde")] mod serde; -mod iter_be; pub(crate) use self::convert::to_str_radix_reversed; pub use self::iter::{U32Digits, U64Digits}; -pub use self::iter_be::{U32DigitsBe, U64DigitsBe}; /// A big unsigned integer type. pub struct BigUint { @@ -776,43 +774,6 @@ impl BigUint { U64Digits::new(self.data.as_slice()) } - /// Returns an iterator of `u32` digits representation of the `BigUint` ordered least - /// significant digit first. - /// - /// # Examples - /// - /// ``` - /// use num_bigint::BigUint; - /// - /// assert_eq!(BigUint::from(1125u32).iter_u32_digits_be().collect::>(), vec![1125]); - /// assert_eq!(BigUint::from(4294967295u32).iter_u32_digits_be().collect::>(), vec![4294967295]); - /// assert_eq!(BigUint::from(4294967296u64).iter_u32_digits_be().collect::>(), vec![0, 1]); - /// assert_eq!(BigUint::from(112500000000u64).iter_u32_digits_be().collect::>(), vec![26, 830850304]); - /// ``` - #[inline] - pub fn iter_u32_digits_be(&self) -> U32DigitsBe<'_> { - U32DigitsBe::new(self.data.as_slice()) - } - - /// Returns an iterator of `u64` digits representation of the `BigUint` ordered least - /// significant digit first. - /// - /// # Examples - /// - /// ``` - /// use num_bigint::BigUint; - /// - /// assert_eq!(BigUint::from(1125u32).iter_u64_digits_be().collect::>(), vec![1125]); - /// assert_eq!(BigUint::from(4294967295u32).iter_u64_digits_be().collect::>(), vec![4294967295]); - /// assert_eq!(BigUint::from(4294967296u64).iter_u64_digits_be().collect::>(), vec![4294967296]); - /// assert_eq!(BigUint::from(112500000000u64).iter_u64_digits_be().collect::>(), vec![112500000000]); - /// assert_eq!(BigUint::from(1u128 << 64).iter_u64_digits_be().collect::>(), vec![1, 0]); - /// ``` - #[inline] - pub fn iter_u64_digits_be(&self) -> U64DigitsBe<'_> { - U64DigitsBe::new(self.data.as_slice()) - } - /// Returns the integer formatted as a string in the given radix. /// `radix` must be in the range `2...36`. /// diff --git a/src/biguint/iter_be.rs b/src/biguint/iter_be.rs deleted file mode 100644 index 948b6dc1..00000000 --- a/src/biguint/iter_be.rs +++ /dev/null @@ -1,257 +0,0 @@ -use core::iter::FusedIterator; - -#[cfg(not(u64_digit))] -use super::u32_chunk_to_u64; - -/// An iterator of `u32` digits representation of a `BigUint` or `BigInt`, -/// ordered most significant digit first. -pub struct U32DigitsBe<'a> { - #[cfg(u64_digit)] - data: &'a [u64], - #[cfg(u64_digit)] - next_is_hi: bool, - - #[cfg(not(u64_digit))] - it: core::slice::Iter<'a, u32>, -} - -#[cfg(u64_digit)] -impl<'a> U32DigitsBe<'a> { - #[inline] - pub(super) fn new(data: &'a [u64]) -> Self { - let last_hi_is_zero = data - .last() - .map(|&last| { - let last_hi = (last >> 32) as u32; - last_hi == 0 - }) - .unwrap_or(false); - U32DigitsBe { - data, - next_is_hi: !last_hi_is_zero, - } - } -} - -#[cfg(u64_digit)] -impl Iterator for U32DigitsBe<'_> { - type Item = u32; - #[inline] - fn next(&mut self) -> Option { - match self.data.split_last() { - Some((&first, data)) => { - let next_is_hi = self.next_is_hi; - self.next_is_hi = !next_is_hi; - if next_is_hi { - Some((first >> 32) as u32) - } else { - self.data = data; - Some(first as u32) - } - } - None => None, - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let len = self.len(); - (len, Some(len)) - } - - #[inline] - fn last(self) -> Option { - self.data.first().map(|&last| last as u32) - } - - #[inline] - fn count(self) -> usize { - self.len() - } -} - -#[cfg(u64_digit)] -impl ExactSizeIterator for U32DigitsBe<'_> { - #[inline] - fn len(&self) -> usize { - self.data.len() * 2 - usize::from(!self.next_is_hi) - } -} - -#[cfg(not(u64_digit))] -impl<'a> U32DigitsBe<'a> { - #[inline] - pub(super) fn new(data: &'a [u32]) -> Self { - Self { it: data.iter() } - } -} - -#[cfg(not(u64_digit))] -impl Iterator for U32DigitsBe<'_> { - type Item = u32; - #[inline] - fn next(&mut self) -> Option { - self.it.next_back().cloned() - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.it.size_hint() - } - - #[inline] - fn nth(&mut self, n: usize) -> Option { - self.it.nth_back(n).cloned() - } - - #[inline] - fn last(mut self) -> Option { - self.it.next().cloned() - } - - #[inline] - fn count(self) -> usize { - self.it.count() - } -} - -#[cfg(not(u64_digit))] -impl ExactSizeIterator for U32DigitsBe<'_> { - #[inline] - fn len(&self) -> usize { - self.it.len() - } -} - -impl FusedIterator for U32DigitsBe<'_> {} - -/// An iterator of `u64` digits representation of a `BigUint` or `BigInt`, -/// ordered most significant digit first. -pub struct U64DigitsBe<'a> { - #[cfg(not(u64_digit))] - it: core::slice::Chunks<'a, u32>, - - #[cfg(u64_digit)] - it: core::slice::Iter<'a, u64>, -} - -#[cfg(not(u64_digit))] -impl<'a> U64DigitsBe<'a> { - #[inline] - pub(super) fn new(data: &'a [u32]) -> Self { - U64DigitsBe { it: data.chunks(2) } - } -} - -#[cfg(not(u64_digit))] -impl Iterator for U64DigitsBe<'_> { - type Item = u64; - #[inline] - fn next(&mut self) -> Option { - self.it.next_back().map(u32_chunk_to_u64) - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let len = self.len(); - (len, Some(len)) - } - - #[inline] - fn last(mut self) -> Option { - self.it.next().map(u32_chunk_to_u64) - } - - #[inline] - fn count(self) -> usize { - self.len() - } -} - -#[cfg(u64_digit)] -impl<'a> U64DigitsBe<'a> { - #[inline] - pub(super) fn new(data: &'a [u64]) -> Self { - Self { it: data.iter() } - } -} - -#[cfg(u64_digit)] -impl Iterator for U64DigitsBe<'_> { - type Item = u64; - #[inline] - fn next(&mut self) -> Option { - self.it.next_back().cloned() - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.it.size_hint() - } - - #[inline] - fn nth(&mut self, n: usize) -> Option { - self.it.nth_back(n).cloned() - } - - #[inline] - fn last(mut self) -> Option { - self.it.next().cloned() - } - - #[inline] - fn count(self) -> usize { - self.it.count() - } -} - -impl ExactSizeIterator for U64DigitsBe<'_> { - #[inline] - fn len(&self) -> usize { - self.it.len() - } -} - -impl FusedIterator for U64DigitsBe<'_> {} - -#[test] -fn test_iter_u32_digits() { - let n = super::BigUint::from(5u8); - let mut it = n.iter_u32_digits_be(); - assert_eq!(it.len(), 1); - assert_eq!(it.next(), Some(5)); - assert_eq!(it.len(), 0); - assert_eq!(it.next(), None); - assert_eq!(it.len(), 0); - assert_eq!(it.next(), None); - - let n = super::BigUint::from(112500000000u64); - let mut it = n.iter_u32_digits_be(); - assert_eq!(it.len(), 2); - assert_eq!(it.next(), Some(26)); - assert_eq!(it.len(), 1); - assert_eq!(it.next(), Some(830850304)); - assert_eq!(it.len(), 0); - assert_eq!(it.next(), None); -} - -#[test] -fn test_iter_u64_digits() { - let n = super::BigUint::from(5u8); - let mut it = n.iter_u64_digits_be(); - assert_eq!(it.len(), 1); - assert_eq!(it.next(), Some(5)); - assert_eq!(it.len(), 0); - assert_eq!(it.next(), None); - assert_eq!(it.len(), 0); - assert_eq!(it.next(), None); - - let n = super::BigUint::from(18_446_744_073_709_551_616u128); - let mut it = n.iter_u64_digits_be(); - assert_eq!(it.len(), 2); - assert_eq!(it.next(), Some(1)); - assert_eq!(it.len(), 1); - assert_eq!(it.next(), Some(0)); - assert_eq!(it.len(), 0); - assert_eq!(it.next(), None); -} diff --git a/src/lib.rs b/src/lib.rs index b1758130..b88c5df2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -231,8 +231,6 @@ pub use crate::biguint::BigUint; pub use crate::biguint::ToBigUint; pub use crate::biguint::U32Digits; pub use crate::biguint::U64Digits; -pub use crate::biguint::U32DigitsBe; -pub use crate::biguint::U64DigitsBe; pub use crate::bigint::BigInt; pub use crate::bigint::Sign; From 25e96286981aa705afbc1fc35c40309379c9b29f Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 27 Aug 2021 16:32:30 -0700 Subject: [PATCH 5/5] Downgrade arbitrary for Rust < 1.51 --- ci/test_full.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ci/test_full.sh b/ci/test_full.sh index d84feae8..5f3d2b29 100755 --- a/ci/test_full.sh +++ b/ci/test_full.sh @@ -37,6 +37,9 @@ if [ -n "${NO_STD_FEATURES[*]}" ]; then echo " no_std supported features: ${NO_STD_FEATURES[*]}" fi +# arbitrary 1.0.1 added const-generic arrays, which requires Rust 1.51 +check_version 1.51.0 || cargo update -p arbitrary --precise 1.0.0 + set -x # test the default with std