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 | 95 ++++++++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/src/bigint.rs b/src/bigint.rs index 02bffaa..088672c 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,7 +703,39 @@ 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) + 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 = 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 FromStrRadix::from_str_radix(s.slice(start, end), radix) { + Some(d) => { + let d: Option = FromPrimitive::from_uint(d); + match d { + Some(d) => { + // FIXME(#5992): assignment operator overloads + // n += d * power; + n = n + d * power; + } + None => { return None; } + } + } + None => { return None; } + } + if end <= unit_len { + return Some(n); + } + end -= unit_len; + // FIXME(#5992): assignment operator overloads + // power *= base_num; + power = power * base_num; + } } } @@ -728,42 +760,9 @@ impl BigUint { } /// Creates and initializes a `BigUint`. + #[inline] 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(); - 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) - }) { - Some(d) => { - let d: Option = FromPrimitive::from_uint(d); - match d { - Some(d) => { - // FIXME(#5992): assignment operator overloads - // n += d * power; - n = n + d * power; - } - None => { return None; } - } - } - None => { return None; } - } - if end <= unit_len { - return Some(n); - } - end -= unit_len; - // FIXME(#5992): assignment operator overloads - // power *= base_num; - power = power * base_num; - } + str::from_utf8(buf).and_then(|s| FromStrRadix::from_str_radix(s, radix)) } #[inline] @@ -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 088672c..5c887ed 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 f12279b..53d1e81 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 8995ec0..ac08038 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 1ffac74..370dba9 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};