From 436f95462784c3d7a9ac4302bc2b2e34478d8d7e Mon Sep 17 00:00:00 2001 From: gifnksm Date: Tue, 4 Nov 2014 23:20:37 +0900 Subject: [PATCH 1/3] bigint: Refactor the `parse_bytes` and `from_str_radix`. This follows the changes of "Separate string->integer implementation in strconv" (rust-lang/rust@138b76b). This allows `parse_bytes` to be removed without breaking `libnum` code. --- src/bigint.rs | 87 ++++++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/src/bigint.rs b/src/bigint.rs index 02bffaa66b..088672c148 100644 --- a/src/bigint.rs +++ b/src/bigint.rs @@ -67,7 +67,7 @@ use std::num::{ToPrimitive, FromPrimitive}; use std::num::{Zero, One, FromStrRadix}; use std::str; use std::string::String; -use std::{uint, i64, u64}; +use std::{i64, u64}; /// A `BigDigit` is a `BigUint`'s composing element. pub type BigDigit = u32; @@ -703,46 +703,18 @@ impl FromStrRadix for BigUint { /// Creates and initializes a `BigUint`. #[inline] fn from_str_radix(s: &str, radix: uint) -> Option { - BigUint::parse_bytes(s.as_bytes(), radix) - } -} - -impl BigUint { - /// Creates and initializes a `BigUint`. - /// - /// The digits are be in base 2^32. - #[inline] - pub fn new(mut digits: Vec) -> BigUint { - // omit trailing zeros - let new_len = digits.iter().rposition(|n| *n != 0).map_or(0, |p| p + 1); - digits.truncate(new_len); - BigUint { data: digits } - } - - /// Creates and initializes a `BigUint`. - /// - /// The digits are be in base 2^32. - #[inline] - pub fn from_slice(slice: &[BigDigit]) -> BigUint { - BigUint::new(slice.to_vec()) - } - - /// Creates and initializes a `BigUint`. - pub fn parse_bytes(buf: &[u8], radix: uint) -> Option { let (base, unit_len) = get_radix_base(radix); let base_num = match base.to_biguint() { Some(base_num) => base_num, None => { return None; } }; - let mut end = buf.len(); - let mut n: BigUint = Zero::zero(); - let mut power: BigUint = One::one(); + let mut end = s.len(); + let mut n: BigUint = Zero::zero(); + let mut power: BigUint = One::one(); loop { let start = cmp::max(end, unit_len) - unit_len; - match str::from_utf8(buf.slice(start, end)).and_then(|s| { - FromStrRadix::from_str_radix(s, radix) - }) { + match FromStrRadix::from_str_radix(s.slice(start, end), radix) { Some(d) => { let d: Option = FromPrimitive::from_uint(d); match d { @@ -765,6 +737,33 @@ impl BigUint { power = power * base_num; } } +} + +impl BigUint { + /// Creates and initializes a `BigUint`. + /// + /// The digits are be in base 2^32. + #[inline] + pub fn new(mut digits: Vec) -> BigUint { + // omit trailing zeros + let new_len = digits.iter().rposition(|n| *n != 0).map_or(0, |p| p + 1); + digits.truncate(new_len); + BigUint { data: digits } + } + + /// Creates and initializes a `BigUint`. + /// + /// The digits are be in base 2^32. + #[inline] + pub fn from_slice(slice: &[BigDigit]) -> BigUint { + BigUint::new(slice.to_vec()) + } + + /// Creates and initializes a `BigUint`. + #[inline] + pub fn parse_bytes(buf: &[u8], radix: uint) -> Option { + str::from_utf8(buf).and_then(|s| FromStrRadix::from_str_radix(s, radix)) + } #[inline] fn shl_unit(&self, n_unit: uint) -> BigUint { @@ -1280,7 +1279,15 @@ impl FromStrRadix for BigInt { /// Creates and initializes a BigInt. #[inline] fn from_str_radix(s: &str, radix: uint) -> Option { - BigInt::parse_bytes(s.as_bytes(), radix) + if s.is_empty() { return None; } + let mut sign = Plus; + let mut start = 0; + if s.starts_with("-") { + sign = Minus; + start = 1; + } + FromStrRadix::from_str_radix(s.slice_from(start), radix) + .map(|bu| BigInt::from_biguint(sign, bu)) } } @@ -1396,18 +1403,12 @@ impl BigInt { } /// Creates and initializes a `BigInt`. + #[inline] pub fn parse_bytes(buf: &[u8], radix: uint) -> Option { - if buf.is_empty() { return None; } - let mut sign = Plus; - let mut start = 0; - if buf[0] == b'-' { - sign = Minus; - start = 1; - } - return BigUint::parse_bytes(buf.slice(start, buf.len()), radix) - .map(|bu| BigInt::from_biguint(sign, bu)); + str::from_utf8(buf).and_then(|s| FromStrRadix::from_str_radix(s, radix)) } + /// Converts this `BigInt` into a `BigUint`, if it's not negative. #[inline] pub fn to_biguint(&self) -> Option { From 163646cd635648f53114568f8785d890d35e4a30 Mon Sep 17 00:00:00 2001 From: gifnksm Date: Tue, 4 Nov 2014 23:22:21 +0900 Subject: [PATCH 2/3] Use sliciing_syntax --- src/bigint.rs | 36 +++++++++++++++++------------------- src/lib.rs | 1 + src/rational.rs | 2 +- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/bigint.rs b/src/bigint.rs index 088672c148..5c887edbaf 100644 --- a/src/bigint.rs +++ b/src/bigint.rs @@ -294,8 +294,8 @@ impl Mul for BigUint { if self.is_zero() || other.is_zero() { return Zero::zero(); } let (s_len, o_len) = (self.data.len(), other.data.len()); - if s_len == 1 { return mul_digit(other, self.data.as_slice()[0]); } - if o_len == 1 { return mul_digit(self, other.data.as_slice()[0]); } + if s_len == 1 { return mul_digit(other, self.data[0]); } + if o_len == 1 { return mul_digit(self, other.data[0]); } // Using Karatsuba multiplication // (a1 * base + a0) * (b1 * base + b0) @@ -340,8 +340,8 @@ impl Mul for BigUint { #[inline] fn cut_at(a: &BigUint, n: uint) -> (BigUint, BigUint) { let mid = cmp::min(a.data.len(), n); - return (BigUint::from_slice(a.data.slice(mid, a.data.len())), - BigUint::from_slice(a.data.slice(0, mid))); + (BigUint::from_slice(a.data[mid ..]), + BigUint::from_slice(a.data[.. mid])) } #[inline] @@ -488,7 +488,7 @@ impl Integer for BigUint { return (Zero::zero(), Zero::zero(), (*a).clone()); } - let an = a.data.slice_from(a.data.len() - n); + let an = a.data[a.data.len() - n ..]; let bn = *b.data.last().unwrap(); let mut d = Vec::with_capacity(an.len()); let mut carry = 0; @@ -545,7 +545,7 @@ impl Integer for BigUint { #[inline] fn is_even(&self) -> bool { // Considering only the last digit. - match self.data.as_slice().head() { + match self.data.head() { Some(x) => x.is_even(), None => true } @@ -574,8 +574,8 @@ impl ToPrimitive for BigUint { fn to_u64(&self) -> Option { match self.data.len() { 0 => Some(0), - 1 => Some(self.data.as_slice()[0] as u64), - 2 => Some(BigDigit::to_doublebigdigit(self.data.as_slice()[1], self.data.as_slice()[0]) + 1 => Some(self.data[0] as u64), + 2 => Some(BigDigit::to_doublebigdigit(self.data[1], self.data[0]) as u64), _ => None } @@ -658,9 +658,9 @@ fn to_str_radix(me: &BigUint, radix: uint) -> String { assert!(1 < radix && radix <= 16, "The radix must be within (1, 16]"); let (base, max_len) = get_radix_base(radix); if base == BigDigit::base { - return fill_concat(me.data.as_slice(), radix, max_len) + return fill_concat(me.data[], radix, max_len) } - return fill_concat(convert_base(me, base).as_slice(), radix, max_len); + return fill_concat(convert_base(me, base)[], radix, max_len); fn convert_base(n: &BigUint, base: DoubleBigDigit) -> Vec { let divider = base.to_biguint().unwrap(); @@ -684,10 +684,10 @@ fn to_str_radix(me: &BigUint, radix: uint) -> String { let mut s = String::with_capacity(v.len() * l); for n in v.iter().rev() { let ss = fmt::radix(*n as uint, radix as u8).to_string(); - s.push_str("0".repeat(l - ss.len()).as_slice()); - s.push_str(ss.as_slice()); + s.push_str("0".repeat(l - ss.len())[]); + s.push_str(ss[]); } - s.as_slice().trim_left_chars('0').to_string() + s.trim_left_chars('0').to_string() } } @@ -714,7 +714,7 @@ impl FromStrRadix for BigUint { let mut power: BigUint = One::one(); loop { let start = cmp::max(end, unit_len) - unit_len; - match FromStrRadix::from_str_radix(s.slice(start, end), radix) { + match FromStrRadix::from_str_radix(s[start .. end], radix) { Some(d) => { let d: Option = FromPrimitive::from_uint(d); match d { @@ -770,7 +770,7 @@ impl BigUint { if n_unit == 0 || self.is_zero() { return (*self).clone(); } let mut v = Vec::from_elem(n_unit, ZERO_BIG_DIGIT); - v.push_all(self.data.as_slice()); + v.push_all(self.data[]); BigUint::new(v) } @@ -794,9 +794,7 @@ impl BigUint { fn shr_unit(&self, n_unit: uint) -> BigUint { if n_unit == 0 { return (*self).clone(); } if self.data.len() < n_unit { return Zero::zero(); } - return BigUint::from_slice( - self.data.slice(n_unit, self.data.len()) - ); + BigUint::from_slice(self.data[n_unit ..]) } #[inline] @@ -1286,7 +1284,7 @@ impl FromStrRadix for BigInt { sign = Minus; start = 1; } - FromStrRadix::from_str_radix(s.slice_from(start), radix) + FromStrRadix::from_str_radix(s[start ..], radix) .map(|bu| BigInt::from_biguint(sign, bu)) } } diff --git a/src/lib.rs b/src/lib.rs index f12279b20e..53d1e81f97 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,6 +44,7 @@ #![feature(macro_rules)] #![feature(default_type_params)] +#![feature(slicing_syntax)] #![crate_name = "num"] #![experimental] diff --git a/src/rational.rs b/src/rational.rs index 8995ec06bc..ac0803863e 100644 --- a/src/rational.rs +++ b/src/rational.rs @@ -668,7 +668,7 @@ mod test { #[test] fn test_to_from_str() { fn test(r: Rational, s: String) { - assert_eq!(FromStr::from_str(s.as_slice()), Some(r)); + assert_eq!(FromStr::from_str(s[]), Some(r)); assert_eq!(r.to_string(), s); } test(_1, "1".to_string()); From d3fd33a8781911170d14767540e93295c2059b73 Mon Sep 17 00:00:00 2001 From: gifnksm Date: Tue, 4 Nov 2014 23:24:20 +0900 Subject: [PATCH 3/3] Fix lint name warning --- src/complex.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/complex.rs b/src/complex.rs index 1ffac74a5f..370dba90fb 100644 --- a/src/complex.rs +++ b/src/complex.rs @@ -174,7 +174,7 @@ impl fmt::Show for Complex { #[cfg(test)] mod test { - #![allow(non_uppercase_statics)] + #![allow(non_upper_case_globals)] use super::{Complex64, Complex}; use std::num::{Zero, One, Float};