diff --git a/src/libcollections/hashmap.rs b/src/libcollections/hashmap.rs index bd0e2ebec6f..9d08bf17668 100644 --- a/src/libcollections/hashmap.rs +++ b/src/libcollections/hashmap.rs @@ -1595,6 +1595,7 @@ pub type SetAlgebraItems<'a, T, H> = mod test_map { use super::HashMap; use std::cmp::Equiv; + use std::hash::Hash; use std::iter::{Iterator,range_inclusive,range_step_inclusive}; use std::local_data; use std::vec; @@ -1607,6 +1608,12 @@ mod test_map { this == *other } } + impl Hash for KindaIntLike { + fn hash(&self, state: &mut S) { + let KindaIntLike(this) = *self; + this.hash(state) + } + } #[test] fn test_create_capacity_zero() { @@ -1848,11 +1855,12 @@ mod test_map { } #[test] + #[allow(experimental)] fn test_pop_equiv() { let mut m = HashMap::new(); m.insert(1, 2); - assert_eq!(m.pop_equiv(&KindaIntLike(1), Some(2))); - assert_eq!(m.pop_equiv(&KindaIntLike(1), None)); + assert_eq!(m.pop_equiv(&KindaIntLike(1)), Some(2)); + assert_eq!(m.pop_equiv(&KindaIntLike(1)), None); } #[test] diff --git a/src/libglob/lib.rs b/src/libglob/lib.rs index e7661b26b76..3cad5bf8175 100644 --- a/src/libglob/lib.rs +++ b/src/libglob/lib.rs @@ -462,8 +462,8 @@ impl Pattern { fn fill_todo(todo: &mut Vec<(Path, uint)>, patterns: &[Pattern], idx: uint, path: &Path, options: MatchOptions) { // convert a pattern that's just many Char(_) to a string - fn pattern_as_str(pattern: &Pattern) -> Option<~str> { - let mut s = ~""; + fn pattern_as_str(pattern: &Pattern) -> Option { + let mut s = StrBuf::new(); for token in pattern.tokens.iter() { match *token { Char(c) => s.push_char(c), @@ -493,8 +493,8 @@ fn fill_todo(todo: &mut Vec<(Path, uint)>, patterns: &[Pattern], idx: uint, path // continue. So instead of passing control back to the iterator, // we can just check for that one entry and potentially recurse // right away. - let special = "." == s || ".." == s; - let next_path = path.join(s); + let special = "." == s.as_slice() || ".." == s.as_slice(); + let next_path = path.join(s.as_slice()); if (special && path.is_dir()) || (!special && next_path.exists()) { add(todo, next_path); } diff --git a/src/libnative/io/process.rs b/src/libnative/io/process.rs index 8ef46239e61..e3bb938995b 100644 --- a/src/libnative/io/process.rs +++ b/src/libnative/io/process.rs @@ -402,7 +402,7 @@ fn make_command_line(prog: &str, args: &[~str]) -> ~str { cmd.push_char(' '); append_arg(&mut cmd, *arg); } - return cmd.to_owned_str(); + return cmd.into_owned(); fn append_arg(cmd: &mut StrBuf, arg: &str) { let quote = arg.chars().any(|c| c == ' ' || c == '\t'); diff --git a/src/libstd/hash/sip.rs b/src/libstd/hash/sip.rs index 69b35df50e4..4a523e3d09e 100644 --- a/src/libstd/hash/sip.rs +++ b/src/libstd/hash/sip.rs @@ -291,7 +291,7 @@ mod tests { use iter::Iterator; use num::ToStrRadix; use option::{Some, None}; - use str::{Str, OwnedStr}; + use str::Str; use strbuf::StrBuf; use slice::{Vector, ImmutableVector, OwnedVector}; use self::test::BenchHarness; diff --git a/src/libstd/strbuf.rs b/src/libstd/strbuf.rs index e9e50f0a07a..1fcc9c6465a 100644 --- a/src/libstd/strbuf.rs +++ b/src/libstd/strbuf.rs @@ -20,9 +20,11 @@ use iter::{Extendable, FromIterator, Iterator, range}; use option::{None, Option, Some}; use ptr::RawPtr; use slice::{OwnedVector, Vector}; +use str; use str::{OwnedStr, Str, StrSlice}; use vec::Vec; +/// A growable string stored as a UTF-8 encoded buffer. #[deriving(Clone, Eq, Ord, TotalEq, TotalOrd)] pub struct StrBuf { vec: Vec, @@ -69,6 +71,23 @@ impl StrBuf { } } + /// Tries to create a new string buffer from the given byte + /// vector, validating that the vector is UTF-8 encoded. + #[inline] + pub fn from_utf8(vec: Vec) -> Option { + if str::is_utf8(vec.as_slice()) { + Some(StrBuf { vec: vec }) + } else { + None + } + } + + /// Return the underlying byte buffer, encoded as UTF-8. + #[inline] + pub fn into_bytes(self) -> Vec { + self.vec + } + /// Pushes the given string onto this buffer; then, returns `self` so that it can be used /// again. #[inline] @@ -100,6 +119,7 @@ impl StrBuf { self.vec.push_all(string.as_bytes()) } + /// Push `ch` onto the given string `count` times. #[inline] pub fn grow(&mut self, count: uint, ch: char) { for _ in range(0, count) { @@ -352,4 +372,3 @@ mod tests { s.truncate(1); } } - diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index 18900abace6..5ea84feffde 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -32,53 +32,62 @@ struct CreatureInfo { color: color } -fn show_color(cc: color) -> ~str { +fn show_color(cc: color) -> &'static str { match cc { - Red => {~"red"} - Yellow => {~"yellow"} - Blue => {~"blue"} + Red => "red", + Yellow => "yellow", + Blue => "blue" } } -fn show_color_list(set: Vec) -> ~str { +fn show_color_list(set: Vec) -> StrBuf { let mut out = StrBuf::new(); for col in set.iter() { out.push_char(' '); out.push_str(show_color(*col)); } - return out.to_owned_str(); + out } -fn show_digit(nn: uint) -> ~str { +fn show_digit(nn: uint) -> &'static str { match nn { - 0 => {~"zero"} - 1 => {~"one"} - 2 => {~"two"} - 3 => {~"three"} - 4 => {~"four"} - 5 => {~"five"} - 6 => {~"six"} - 7 => {~"seven"} - 8 => {~"eight"} - 9 => {~"nine"} + 0 => {"zero"} + 1 => {"one"} + 2 => {"two"} + 3 => {"three"} + 4 => {"four"} + 5 => {"five"} + 6 => {"six"} + 7 => {"seven"} + 8 => {"eight"} + 9 => {"nine"} _ => {fail!("expected digits from 0 to 9...")} } } -fn show_number(nn: uint) -> ~str { - let mut out = ~""; +fn show_number(nn: uint) -> StrBuf { + let mut out = vec![]; let mut num = nn; let mut dig; - - if num == 0 { out = show_digit(0) }; + let mut len = 0; + if num == 0 { out.push(show_digit(0)) }; while num != 0 { dig = num % 10; num = num / 10; - out = show_digit(dig) + " " + out; + out.push(" "); + let s = show_digit(dig); + out.push(s); + len += 1 + s.len(); } + len += 1; + out.push(" "); - return ~" " + out; + let mut ret = StrBuf::with_capacity(len); + for s in out.iter().rev() { + ret.push_str(*s); + } + ret } fn transform(aa: color, bb: color) -> color { @@ -125,7 +134,7 @@ fn creature( option::None => { // log creatures met and evil clones of self let report = format!("{} {}", - creatures_met, show_number(evil_clones_met)); + creatures_met, show_number(evil_clones_met).as_slice()); to_rendezvous_log.send(report); break; } diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index ca88f107336..9dd76f5e475 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -15,17 +15,11 @@ extern crate collections; -use std::cmp::Ord; -use std::comm; use collections::HashMap; use std::mem::replace; use std::option; use std::os; -use std::io; -use std::str; use std::strbuf::StrBuf; -use std::task; -use std::vec; fn f64_cmp(x: f64, y: f64) -> Ordering { // arbitrarily decide that NaNs are larger than everything. @@ -66,16 +60,14 @@ fn sort_and_fmt(mm: &HashMap , uint>, total: uint) -> ~str { let mut buffer = StrBuf::new(); for &(ref k, v) in pairs_sorted.iter() { - unsafe { - buffer.push_str(format!("{} {:0.3f}\n", - k.as_slice() - .to_ascii() - .to_upper() - .into_str(), v)); - } + buffer.push_str(format!("{} {:0.3f}\n", + k.as_slice() + .to_ascii() + .to_upper() + .into_str(), v)); } - return buffer.to_owned_str(); + return buffer.into_owned(); } // given a map, search for the frequency of a pattern diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs index c9794d54829..a1daf45cea9 100644 --- a/src/test/bench/shootout-k-nucleotide.rs +++ b/src/test/bench/shootout-k-nucleotide.rs @@ -11,8 +11,6 @@ // ignore-android see #10393 #13206 // ignore-pretty -use std::ascii::OwnedStrAsciiExt; -use std::str; use std::strbuf::StrBuf; use std::slice; @@ -50,8 +48,7 @@ impl Code { string.bytes().fold(Code(0u64), |a, b| a.push_char(b)) } - // FIXME: Inefficient. - fn unpack(&self, frame: uint) -> ~str { + fn unpack(&self, frame: uint) -> StrBuf { let mut key = self.hash(); let mut result = Vec::new(); for _ in range(0, frame) { @@ -60,7 +57,7 @@ impl Code { } result.reverse(); - str::from_utf8_owned(result.move_iter().collect()).unwrap() + StrBuf::from_utf8(result).unwrap() } } @@ -239,7 +236,7 @@ fn print_frequencies(frequencies: &Table, frame: uint) { for &(count, key) in vector.iter().rev() { println!("{} {:.3f}", - key.unpack(frame), + key.unpack(frame).as_slice(), (count as f32 * 100.0) / (total_count as f32)); } println!(""); @@ -249,14 +246,17 @@ fn print_occurrences(frequencies: &mut Table, occurrence: &'static str) { frequencies.lookup(Code::pack(occurrence), PrintCallback(occurrence)) } -fn get_sequence(r: &mut R, key: &str) -> ~[u8] { - let mut res = StrBuf::new(); +fn get_sequence(r: &mut R, key: &str) -> Vec { + let mut res = Vec::new(); for l in r.lines().map(|l| l.ok().unwrap()) .skip_while(|l| key != l.slice_to(key.len())).skip(1) { - res.push_str(l.trim()); + res.push_all(l.trim().as_bytes()); } - res.to_owned_str().into_ascii_upper().into_bytes() + for b in res.mut_iter() { + *b = b.to_ascii().to_upper().to_byte(); + } + res } fn main() { @@ -268,17 +268,17 @@ fn main() { }; let mut frequencies = Table::new(); - generate_frequencies(&mut frequencies, input, 1); + generate_frequencies(&mut frequencies, input.as_slice(), 1); print_frequencies(&frequencies, 1); frequencies = Table::new(); - generate_frequencies(&mut frequencies, input, 2); + generate_frequencies(&mut frequencies, input.as_slice(), 2); print_frequencies(&frequencies, 2); for occurrence in OCCURRENCES.iter() { frequencies = Table::new(); generate_frequencies(&mut frequencies, - input, + input.as_slice(), occurrence.len()); print_occurrences(&mut frequencies, *occurrence); }