From 26e72bf92bb0f9cf4d10a5edb07dbbd5c09f0e24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20L=C3=B6bel?= Date: Sun, 27 Jan 2013 03:20:15 +0100 Subject: [PATCH] Converted libcore/int-template.rs to the new string functions. - Moved ToStr implementation of integers to int-template.rs. - Marked the `str()` function as deprecated. - Forwarded all conversion functions to `core::num::to_str_common()` and `core::num::from_str_common()`. - Fixed most places in the codebase where `to_str()` is being used. - Added int-template to_str and from_str overflow tests. --- src/libcore/num/int-template.rs | 180 +++++++++++++++++------- src/libcore/to_str.rs | 20 --- src/librustc/driver/driver.rs | 8 +- src/librustc/metadata/encoder.rs | 2 +- src/librustc/middle/trans/base.rs | 2 +- src/test/run-pass/reflect-visit-data.rs | 2 +- 6 files changed, 134 insertions(+), 80 deletions(-) diff --git a/src/libcore/num/int-template.rs b/src/libcore/num/int-template.rs index 7f3a15621ac..27e3b0d04ea 100644 --- a/src/libcore/num/int-template.rs +++ b/src/libcore/num/int-template.rs @@ -17,7 +17,9 @@ use T = self::inst::T; use char; use cmp::{Eq, Ord}; use cmp; +use to_str::ToStr; use from_str::FromStr; +use num::{ToStrRadix, FromStrRadix}; use num; use num::Num::from_int; use prelude::*; @@ -212,70 +214,87 @@ impl T: num::Round { pure fn fract(&self) -> T { 0 } } -/** - * Parse a buffer of bytes - * - * # Arguments - * - * * buf - A byte buffer - * * radix - The base of the number - */ -pub pure fn parse_bytes(buf: &[u8], radix: uint) -> Option { - if vec::len(buf) == 0u { return None; } - let mut i = vec::len(buf) - 1u; - let mut start = 0u; - let mut power = 1 as T; +// String conversion functions and impl str -> num - if buf[0] == ('-' as u8) { - power = -1 as T; - start = 1u; - } - let mut n = 0 as T; - loop { - match char::to_digit(buf[i] as char, radix) { - Some(d) => n += (d as T) * power, - None => return None - } - power *= radix as T; - if i <= start { return Some(n); } - i -= 1u; - }; +/// Parse a string as a number in base 10. +#[inline(always)] +pub pure fn from_str(s: &str) -> Option { + num::from_str_common(s, 10u, true, false, false, + num::ExpNone, false) } -/// Parse a string to an int +/// Parse a string as a number in the given base. #[inline(always)] -pub pure fn from_str(s: &str) -> Option -{ - parse_bytes(str::to_bytes(s), 10u) +pub pure fn from_str_radix(s: &str, radix: uint) -> Option { + num::from_str_common(s, radix, true, false, false, + num::ExpNone, false) +} + +/// Parse a byte slice as a number in the given base. +#[inline(always)] +pub pure fn parse_bytes(buf: &[u8], radix: uint) -> Option { + num::from_str_bytes_common(buf, radix, true, false, false, + num::ExpNone, false) } impl T : FromStr { #[inline(always)] - static pure fn from_str(s: &str) -> Option { from_str(s) } -} - -/// Convert to a string in a given base -#[inline(always)] -pub pure fn to_str(n: T, radix: uint) -> ~str { - do to_str_bytes(n, radix) |slice| { - do vec::as_imm_buf(slice) |p, len| { - unsafe { str::raw::from_buf_len(p, len) } - } + static pure fn from_str(s: &str) -> Option { + from_str(s) } } +impl T : FromStrRadix { + #[inline(always)] + static pure fn from_str_radix(&self, s: &str, radix: uint) -> Option { + from_str_radix(s, radix) + } +} + +// String conversion functions and impl num -> str + +/// Convert to a string as a byte slice in a given base. #[inline(always)] pub pure fn to_str_bytes(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U { - if n < 0 as T { - uint::to_str_bytes(true, -n as uint, radix, f) - } else { - uint::to_str_bytes(false, n as uint, radix, f) + let (buf, _) = num::to_str_bytes_common(&n, radix, false, false, + num::SignNeg, num::DigAll); + f(buf) +} + +/// Convert to a string in base 10. +#[inline(always)] +pub pure fn to_str(num: T) -> ~str { + let (buf, _) = num::to_str_common(&num, 10u, false, false, + num::SignNeg, num::DigAll); + buf +} + +/// Convert to a string in a given base. +#[inline(always)] +pub pure fn to_str_radix(num: T, radix: uint) -> ~str { + let (buf, _) = num::to_str_common(&num, radix, false, false, + num::SignNeg, num::DigAll); + buf +} + +/// Convert to a string. +/// *Deprecated*, use to_str() instead. +#[inline(always)] +pub pure fn str(i: T) -> ~str { to_str(i) } + +impl T : ToStr { + #[inline(always)] + pure fn to_str() -> ~str { + to_str(self) } } -/// Convert to a string -#[inline(always)] -pub pure fn str(i: T) -> ~str { return to_str(i, 10u); } +impl T : ToStrRadix { + #[inline(always)] + pure fn to_str_radix(&self, radix: uint) -> ~str { + to_str_radix(*self, radix) + } +} #[test] fn test_from_str() { @@ -322,11 +341,66 @@ fn test_parse_bytes() { #[test] fn test_to_str() { - assert (to_str(0 as T, 10u) == ~"0"); - assert (to_str(1 as T, 10u) == ~"1"); - assert (to_str(-1 as T, 10u) == ~"-1"); - assert (to_str(127 as T, 16u) == ~"7f"); - assert (to_str(100 as T, 10u) == ~"100"); + assert (to_str_radix(0 as T, 10u) == ~"0"); + assert (to_str_radix(1 as T, 10u) == ~"1"); + assert (to_str_radix(-1 as T, 10u) == ~"-1"); + assert (to_str_radix(127 as T, 16u) == ~"7f"); + assert (to_str_radix(100 as T, 10u) == ~"100"); + +} + +#[test] +fn test_int_to_str_overflow() { + let mut i8_val: i8 = 127_i8; + assert (i8::to_str(i8_val) == ~"127"); + + i8_val += 1 as i8; + assert (i8::to_str(i8_val) == ~"-128"); + + let mut i16_val: i16 = 32_767_i16; + assert (i16::to_str(i16_val) == ~"32767"); + + i16_val += 1 as i16; + assert (i16::to_str(i16_val) == ~"-32768"); + + let mut i32_val: i32 = 2_147_483_647_i32; + assert (i32::to_str(i32_val) == ~"2147483647"); + + i32_val += 1 as i32; + assert (i32::to_str(i32_val) == ~"-2147483648"); + + let mut i64_val: i64 = 9_223_372_036_854_775_807_i64; + assert (i64::to_str(i64_val) == ~"9223372036854775807"); + + i64_val += 1 as i64; + assert (i64::to_str(i64_val) == ~"-9223372036854775808"); +} + +#[test] +fn test_int_from_str_overflow() { + let mut i8_val: i8 = 127_i8; + assert (i8::from_str(~"127") == Some(i8_val)); + + i8_val += 1 as i8; + assert (i8::from_str(~"-128") == Some(i8_val)); + + let mut i16_val: i16 = 32_767_i16; + assert (i16::from_str(~"32767") == Some(i16_val)); + + i16_val += 1 as i16; + assert (i16::from_str(~"-32768") == Some(i16_val)); + + let mut i32_val: i32 = 2_147_483_647_i32; + assert (i32::from_str(~"2147483647") == Some(i32_val)); + + i32_val += 1 as i32; + assert (i32::from_str(~"-2147483648") == Some(i32_val)); + + let mut i64_val: i64 = 9_223_372_036_854_775_807_i64; + assert (i64::from_str(~"9223372036854775807") == Some(i64_val)); + + i64_val += 1 as i64; + assert (i64::from_str(~"-9223372036854775808") == Some(i64_val)); } #[test] diff --git a/src/libcore/to_str.rs b/src/libcore/to_str.rs index b1fb1fdd483..054512811be 100644 --- a/src/libcore/to_str.rs +++ b/src/libcore/to_str.rs @@ -24,26 +24,6 @@ use vec; pub trait ToStr { pub pure fn to_str() -> ~str; } -impl int: ToStr { - #[inline(always)] - pure fn to_str() -> ~str { ::int::str(self) } -} -impl i8: ToStr { - #[inline(always)] - pure fn to_str() -> ~str { ::i8::str(self) } -} -impl i16: ToStr { - #[inline(always)] - pure fn to_str() -> ~str { ::i16::str(self) } -} -impl i32: ToStr { - #[inline(always)] - pure fn to_str() -> ~str { ::i32::str(self) } -} -impl i64: ToStr { - #[inline(always)] - pure fn to_str() -> ~str { ::i64::str(self) } -} impl uint: ToStr { #[inline(always)] pure fn to_str() -> ~str { ::uint::str(self) } diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 7f7c0114988..3dd49f661ee 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -382,21 +382,21 @@ pub fn pretty_print_input(sess: Session, +cfg: ast::crate_cfg, input: input, match node { pprust::node_item(s, item) => { pp::space(s.s); - pprust::synth_comment(s, int::to_str(item.id, 10u)); + pprust::synth_comment(s, int::to_str(item.id)); } pprust::node_block(s, ref blk) => { pp::space(s.s); pprust::synth_comment( - s, ~"block " + int::to_str((*blk).node.id, 10u)); + s, ~"block " + int::to_str((*blk).node.id)); } pprust::node_expr(s, expr) => { pp::space(s.s); - pprust::synth_comment(s, int::to_str(expr.id, 10u)); + pprust::synth_comment(s, int::to_str(expr.id)); pprust::pclose(s); } pprust::node_pat(s, pat) => { pp::space(s.s); - pprust::synth_comment(s, ~"pat " + int::to_str(pat.id, 10u)); + pprust::synth_comment(s, ~"pat " + int::to_str(pat.id)); } } } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 33879237ffb..b8a1b942453 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -245,7 +245,7 @@ fn encode_discriminant(ecx: @encode_ctxt, ebml_w: writer::Encoder, fn encode_disr_val(_ecx: @encode_ctxt, ebml_w: writer::Encoder, disr_val: int) { ebml_w.start_tag(tag_disr_val); - ebml_w.writer.write(str::to_bytes(int::to_str(disr_val,10u))); + ebml_w.writer.write(str::to_bytes(int::to_str(disr_val))); ebml_w.end_tag(); } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index f394c98ab6f..5a8fe94a439 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -679,7 +679,7 @@ pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t, let variant_cx = sub_block(cx, ~"enum-iter-variant-" + - int::to_str(variant.disr_val, 10u)); + int::to_str(variant.disr_val)); AddCase(llswitch, C_int(ccx, variant.disr_val), variant_cx.llbb); let variant_cx = iter_variant(variant_cx, llunion_a_ptr, *variant, diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index 3ea8ef23ea9..96bddf7099b 100644 --- a/src/test/run-pass/reflect-visit-data.rs +++ b/src/test/run-pass/reflect-visit-data.rs @@ -517,7 +517,7 @@ impl my_visitor: TyVisitor { } fn visit_int(&self) -> bool { do self.get::() |i| { - self.vals += ~[int::to_str(i, 10u)]; + self.vals += ~[int::to_str(i)]; }; true }