diff --git a/src/libextra/base64.rs b/src/libextra/base64.rs index b8f3a267d2d..62d4a32b8e2 100644 --- a/src/libextra/base64.rs +++ b/src/libextra/base64.rs @@ -49,7 +49,7 @@ impl<'self> ToBase64 for &'self [u8] { fn to_base64(&self) -> ~str { let mut s = ~""; let len = self.len(); - str::reserve(&mut s, ((len + 3u) / 4u) * 3u); + s.reserve(((len + 3u) / 4u) * 3u); let mut i = 0u; @@ -59,10 +59,10 @@ fn to_base64(&self) -> ~str { (self[i + 2u] as uint); // This 24-bit number gets separated into four 6-bit numbers. - str::push_char(&mut s, CHARS[(n >> 18u) & 63u]); - str::push_char(&mut s, CHARS[(n >> 12u) & 63u]); - str::push_char(&mut s, CHARS[(n >> 6u) & 63u]); - str::push_char(&mut s, CHARS[n & 63u]); + s.push_char(CHARS[(n >> 18u) & 63u]); + s.push_char(CHARS[(n >> 12u) & 63u]); + s.push_char(CHARS[(n >> 6u) & 63u]); + s.push_char(CHARS[n & 63u]); i += 3u; } @@ -73,18 +73,18 @@ fn to_base64(&self) -> ~str { 0 => (), 1 => { let n = (self[i] as uint) << 16u; - str::push_char(&mut s, CHARS[(n >> 18u) & 63u]); - str::push_char(&mut s, CHARS[(n >> 12u) & 63u]); - str::push_char(&mut s, '='); - str::push_char(&mut s, '='); + s.push_char(CHARS[(n >> 18u) & 63u]); + s.push_char(CHARS[(n >> 12u) & 63u]); + s.push_char('='); + s.push_char('='); } 2 => { let n = (self[i] as uint) << 16u | (self[i + 1u] as uint) << 8u; - str::push_char(&mut s, CHARS[(n >> 18u) & 63u]); - str::push_char(&mut s, CHARS[(n >> 12u) & 63u]); - str::push_char(&mut s, CHARS[(n >> 6u) & 63u]); - str::push_char(&mut s, '='); + s.push_char(CHARS[(n >> 18u) & 63u]); + s.push_char(CHARS[(n >> 12u) & 63u]); + s.push_char(CHARS[(n >> 6u) & 63u]); + s.push_char('='); } _ => fail!("Algebra is broken, please alert the math police") } diff --git a/src/libextra/json.rs b/src/libextra/json.rs index 30a2b5f8627..1e9ec48aff3 100644 --- a/src/libextra/json.rs +++ b/src/libextra/json.rs @@ -79,7 +79,7 @@ fn escape_str(s: &str) -> ~str { fn spaces(n: uint) -> ~str { let mut ss = ~""; - for n.times { str::push_str(&mut ss, " "); } + for n.times { ss.push_str(" "); } return ss; } @@ -712,14 +712,14 @@ fn parse_str(&mut self) -> Result<~str, Error> { if (escape) { match self.ch { - '"' => str::push_char(&mut res, '"'), - '\\' => str::push_char(&mut res, '\\'), - '/' => str::push_char(&mut res, '/'), - 'b' => str::push_char(&mut res, '\x08'), - 'f' => str::push_char(&mut res, '\x0c'), - 'n' => str::push_char(&mut res, '\n'), - 'r' => str::push_char(&mut res, '\r'), - 't' => str::push_char(&mut res, '\t'), + '"' => res.push_char('"'), + '\\' => res.push_char('\\'), + '/' => res.push_char('/'), + 'b' => res.push_char('\x08'), + 'f' => res.push_char('\x0c'), + 'n' => res.push_char('\n'), + 'r' => res.push_char('\r'), + 't' => res.push_char('\t'), 'u' => { // Parse \u1234. let mut i = 0u; @@ -748,7 +748,7 @@ fn parse_str(&mut self) -> Result<~str, Error> { ~"invalid \\u escape (not four digits)"); } - str::push_char(&mut res, n as char); + res.push_char(n as char); } _ => return self.error(~"invalid escape") } @@ -760,7 +760,7 @@ fn parse_str(&mut self) -> Result<~str, Error> { self.bump(); return Ok(res); } - str::push_char(&mut res, self.ch); + res.push_char(self.ch); } } diff --git a/src/libextra/net_url.rs b/src/libextra/net_url.rs index 6fd6fa3acd9..30d55721efb 100644 --- a/src/libextra/net_url.rs +++ b/src/libextra/net_url.rs @@ -81,7 +81,7 @@ fn encode_inner(s: &str, full_url: bool) -> ~str { 'a' .. 'z' | '0' .. '9' | '-' | '.' | '_' | '~' => { - str::push_char(&mut out, ch); + out.push_char(ch); } _ => { if full_url { @@ -92,7 +92,7 @@ fn encode_inner(s: &str, full_url: bool) -> ~str { // sub-delims: '!' | '$' | '&' | '"' | '(' | ')' | '*' | '+' | ',' | ';' | '=' => { - str::push_char(&mut out, ch); + out.push_char(ch); } _ => out += fmt!("%%%X", ch as uint) @@ -148,18 +148,18 @@ fn decode_inner(s: &str, full_url: bool) -> ~str { // sub-delims: '!' | '$' | '&' | '"' | '(' | ')' | '*' | '+' | ',' | ';' | '=' => { - str::push_char(&mut out, '%'); - str::push_char(&mut out, bytes[0u] as char); - str::push_char(&mut out, bytes[1u] as char); + out.push_char('%'); + out.push_char(bytes[0u] as char); + out.push_char(bytes[1u] as char); } - ch => str::push_char(&mut out, ch) + ch => out.push_char(ch) } } else { - str::push_char(&mut out, ch); + out.push_char(ch); } } - ch => str::push_char(&mut out, ch) + ch => out.push_char(ch) } } @@ -191,9 +191,9 @@ fn encode_plus(s: &str) -> ~str { let ch = rdr.read_byte() as char; match ch { 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_' | '.' | '-' => { - str::push_char(&mut out, ch); + out.push_char(ch); } - ' ' => str::push_char(&mut out, '+'), + ' ' => out.push_char('+'), _ => out += fmt!("%%%X", ch as uint) } } @@ -216,7 +216,7 @@ pub fn encode_form_urlencoded(m: &HashMap<~str, ~[~str]>) -> ~str { if first { first = false; } else { - str::push_char(&mut out, '&'); + out.push_char('&'); first = false; } @@ -267,9 +267,9 @@ pub fn decode_form_urlencoded(s: &[u8]) -> HashMap<~str, ~[~str]> { }; if parsing_key { - str::push_char(&mut key, ch) + key.push_char(ch) } else { - str::push_char(&mut value, ch) + value.push_char(ch) } } } diff --git a/src/libextra/rope.rs b/src/libextra/rope.rs index 9ae8c47ae3c..de78e0a6eeb 100644 --- a/src/libextra/rope.rs +++ b/src/libextra/rope.rs @@ -1289,9 +1289,7 @@ fn rope_to_string(r: Rope) -> ~str { fn aux(str: &mut ~str, node: @node::Node) { match (*node) { node::Leaf(x) => { - str::push_str( - str, - x.content.slice(x.byte_offset, x.byte_offset + x.byte_len)); + str.push_str(x.content.slice(x.byte_offset, x.byte_offset + x.byte_len)); } node::Concat(ref x) => { aux(str, x.left); diff --git a/src/libextra/semver.rs b/src/libextra/semver.rs index 36ebd10ae17..dad08075238 100644 --- a/src/libextra/semver.rs +++ b/src/libextra/semver.rs @@ -149,7 +149,7 @@ fn take_nonempty_prefix(rdr: @io::Reader, let mut buf = ~""; let mut ch = ch; while pred(ch) { - str::push_char(&mut buf, ch); + buf.push_char(ch); ch = rdr.read_char(); } if buf.is_empty() { diff --git a/src/libextra/time.rs b/src/libextra/time.rs index f545b28c507..fea5cb560ac 100644 --- a/src/libextra/time.rs +++ b/src/libextra/time.rs @@ -851,7 +851,7 @@ fn parse_type(ch: char, tm: &Tm) -> ~str { while !rdr.eof() { match rdr.read_char() { '%' => buf += parse_type(rdr.read_char(), tm), - ch => str::push_char(&mut buf, ch) + ch => buf.push_char(ch) } } } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 32a2bf22f27..18946ee2d79 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -980,7 +980,7 @@ fn read_ty(&mut self, xcx: @ExtendedDecodeContext) -> ty::t { fn type_string(doc: ebml::Doc) -> ~str { let mut str = ~""; for uint::range(doc.start, doc.end) |i| { - str::push_char(&mut str, doc.data[i] as char); + str.push_char(doc.data[i] as char); } str } diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index fa3bae3f5ac..b0b9c9f7efb 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -694,9 +694,9 @@ pub fn append_loan_path_to_str_from_interior(&self, out: &mut ~str) { match *loan_path { LpExtend(_, _, LpDeref) => { - str::push_char(out, '('); + out.push_char('('); self.append_loan_path_to_str(loan_path, out); - str::push_char(out, ')'); + out.push_char(')'); } LpExtend(_, _, LpInterior(_)) | LpVar(_) => { @@ -712,7 +712,7 @@ pub fn append_loan_path_to_str(&self, LpVar(id) => { match self.tcx.items.find(&id) { Some(&ast_map::node_local(ref ident)) => { - str::push_str(out, *token::ident_to_str(ident)); + out.push_str(*token::ident_to_str(ident)); } r => { self.tcx.sess.bug( @@ -726,23 +726,23 @@ pub fn append_loan_path_to_str(&self, self.append_loan_path_to_str_from_interior(lp_base, out); match fname { mc::NamedField(ref fname) => { - str::push_char(out, '.'); - str::push_str(out, *token::ident_to_str(fname)); + out.push_char('.'); + out.push_str(*token::ident_to_str(fname)); } mc::PositionalField(idx) => { - str::push_char(out, '#'); // invent a notation here - str::push_str(out, idx.to_str()); + out.push_char('#'); // invent a notation here + out.push_str(idx.to_str()); } } } LpExtend(lp_base, _, LpInterior(mc::InteriorElement(_))) => { self.append_loan_path_to_str_from_interior(lp_base, out); - str::push_str(out, "[]"); + out.push_str("[]"); } LpExtend(lp_base, _, LpDeref) => { - str::push_char(out, '*'); + out.push_char('*'); self.append_loan_path_to_str(lp_base, out); } } diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index 1f9fff14ba2..e2d88e3c768 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -947,13 +947,13 @@ fn bits_to_str(words: &[uint]) -> ~str { for words.each |&word| { let mut v = word; for uint::range(0, uint::bytes) |_| { - str::push_char(&mut result, sep); - str::push_str(&mut result, fmt!("%02x", v & 0xFF)); + result.push_char(sep); + result.push_str(fmt!("%02x", v & 0xFF)); v >>= 8; sep = '-'; } } - str::push_char(&mut result, ']'); + result.push_char(']'); return result; } diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 7ae59e524a0..5455edc2586 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -139,121 +139,35 @@ pub fn from_byte(b: u8) -> ~str { unsafe { ::cast::transmute(~[b, 0u8]) } } -/// Appends a character at the end of a string -pub fn push_char(s: &mut ~str, ch: char) { - unsafe { - let code = ch as uint; - let nb = if code < max_one_b { 1u } - else if code < max_two_b { 2u } - else if code < max_three_b { 3u } - else if code < max_four_b { 4u } - else if code < max_five_b { 5u } - else { 6u }; - let len = s.len(); - let new_len = len + nb; - reserve_at_least(&mut *s, new_len); - let off = len; - do as_buf(*s) |buf, _len| { - let buf: *mut u8 = ::cast::transmute(buf); - match nb { - 1u => { - *ptr::mut_offset(buf, off) = code as u8; - } - 2u => { - *ptr::mut_offset(buf, off) = (code >> 6u & 31u | tag_two_b) as u8; - *ptr::mut_offset(buf, off + 1u) = (code & 63u | tag_cont) as u8; - } - 3u => { - *ptr::mut_offset(buf, off) = (code >> 12u & 15u | tag_three_b) as u8; - *ptr::mut_offset(buf, off + 1u) = (code >> 6u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 2u) = (code & 63u | tag_cont) as u8; - } - 4u => { - *ptr::mut_offset(buf, off) = (code >> 18u & 7u | tag_four_b) as u8; - *ptr::mut_offset(buf, off + 1u) = (code >> 12u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 2u) = (code >> 6u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 3u) = (code & 63u | tag_cont) as u8; - } - 5u => { - *ptr::mut_offset(buf, off) = (code >> 24u & 3u | tag_five_b) as u8; - *ptr::mut_offset(buf, off + 1u) = (code >> 18u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 2u) = (code >> 12u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 3u) = (code >> 6u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 4u) = (code & 63u | tag_cont) as u8; - } - 6u => { - *ptr::mut_offset(buf, off) = (code >> 30u & 1u | tag_six_b) as u8; - *ptr::mut_offset(buf, off + 1u) = (code >> 24u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 2u) = (code >> 18u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 3u) = (code >> 12u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 4u) = (code >> 6u & 63u | tag_cont) as u8; - *ptr::mut_offset(buf, off + 5u) = (code & 63u | tag_cont) as u8; - } - _ => {} - } - } - raw::set_len(s, new_len); - } -} - /// Convert a char to a string pub fn from_char(ch: char) -> ~str { let mut buf = ~""; - push_char(&mut buf, ch); + buf.push_char(ch); buf } /// Convert a vector of chars to a string pub fn from_chars(chs: &[char]) -> ~str { let mut buf = ~""; - reserve(&mut buf, chs.len()); + buf.reserve(chs.len()); for chs.each |ch| { - push_char(&mut buf, *ch); + buf.push_char(*ch) } buf } -/// Appends a string slice to the back of a string, without overallocating -#[inline(always)] -pub fn push_str_no_overallocate(lhs: &mut ~str, rhs: &str) { - unsafe { - let llen = lhs.len(); - let rlen = rhs.len(); - reserve(&mut *lhs, llen + rlen); - do as_buf(*lhs) |lbuf, _llen| { - do as_buf(rhs) |rbuf, _rlen| { - let dst = ptr::offset(lbuf, llen); - let dst = ::cast::transmute_mut_unsafe(dst); - ptr::copy_memory(dst, rbuf, rlen); - } - } - raw::set_len(lhs, llen + rlen); - } -} - -/// Appends a string slice to the back of a string -#[inline(always)] +/// A function version of the `.push_str`, required for `fmt!` during +/// the bootstrap. Use `lhs.push_str(rhs)` instead of this. +#[doc="hidden"] pub fn push_str(lhs: &mut ~str, rhs: &str) { - unsafe { - let llen = lhs.len(); - let rlen = rhs.len(); - reserve_at_least(&mut *lhs, llen + rlen); - do as_buf(*lhs) |lbuf, _llen| { - do as_buf(rhs) |rbuf, _rlen| { - let dst = ptr::offset(lbuf, llen); - let dst = ::cast::transmute_mut_unsafe(dst); - ptr::copy_memory(dst, rbuf, rlen); - } - } - raw::set_len(lhs, llen + rlen); - } + lhs.push_str(rhs) } /// Concatenate two strings together #[inline(always)] pub fn append(lhs: ~str, rhs: &str) -> ~str { let mut v = lhs; - push_str_no_overallocate(&mut v, rhs); + v.push_str_no_overallocate(rhs); v } @@ -286,7 +200,7 @@ pub fn concat(&self) -> ~str { } let mut s = ~""; - reserve(&mut s, len); + s.reserve(len); unsafe { do as_buf(s) |buf, _| { @@ -319,7 +233,7 @@ pub fn connect(&self, sep: &str) -> ~str { let mut s = ~""; let mut first = true; - reserve(&mut s, len); + s.reserve(len); unsafe { do as_buf(s) |buf, _| { @@ -358,7 +272,7 @@ pub fn concat(&self) -> ~str { } let mut s = ~""; - reserve(&mut s, len); + s.reserve(len); unsafe { do as_buf(s) |buf, _| { @@ -391,7 +305,7 @@ pub fn connect(&self, sep: &str) -> ~str { let mut s = ~""; let mut first = true; - reserve(&mut s, len); + s.reserve(len); unsafe { do as_buf(s) |buf, _| { @@ -425,7 +339,7 @@ pub fn repeat(ss: &str, nn: uint) -> ~str { let mut ret = ~""; // ignore the NULL terminator let len = len - 1; - reserve(&mut ret, nn * len); + ret.reserve(nn * len); unsafe { do as_buf(ret) |rbuf, _len| { @@ -1148,9 +1062,9 @@ fn equiv(&self, other: &~str) -> bool { eq_slice(*self, *other) } /// Apply a function to each character pub fn map(ss: &str, ff: &fn(char) -> char) -> ~str { let mut result = ~""; - reserve(&mut result, ss.len()); + result.reserve(ss.len()); for ss.iter().advance |cc| { - str::push_char(&mut result, ff(cc)); + result.push_char(ff(cc)); } result } @@ -1325,8 +1239,8 @@ pub fn utf16_chars(v: &[u16], f: &fn(char)) { */ pub fn from_utf16(v: &[u16]) -> ~str { let mut buf = ~""; - reserve(&mut buf, v.len()); - utf16_chars(v, |ch| push_char(&mut buf, ch)); + buf.reserve(v.len()); + utf16_chars(v, |ch| buf.push_char(ch)); buf } @@ -1336,7 +1250,7 @@ pub fn from_utf16(v: &[u16]) -> ~str { */ pub fn with_capacity(capacity: uint) -> ~str { let mut buf = ~""; - reserve(&mut buf, capacity); + buf.reserve(capacity); buf } @@ -1660,54 +1574,6 @@ pub fn subslice_offset(outer: &str, inner: &str) -> uint { } } -/** - * Reserves capacity for exactly `n` bytes in the given string, not including - * the null terminator. - * - * Assuming single-byte characters, the resulting string will be large - * enough to hold a string of length `n`. To account for the null terminator, - * the underlying buffer will have the size `n` + 1. - * - * If the capacity for `s` is already equal to or greater than the requested - * capacity, then no action is taken. - * - * # Arguments - * - * * s - A string - * * n - The number of bytes to reserve space for - */ -#[inline(always)] -pub fn reserve(s: &mut ~str, n: uint) { - unsafe { - let v: *mut ~[u8] = cast::transmute(s); - vec::reserve(&mut *v, n + 1); - } -} - -/** - * Reserves capacity for at least `n` bytes in the given string, not including - * the null terminator. - * - * Assuming single-byte characters, the resulting string will be large - * enough to hold a string of length `n`. To account for the null terminator, - * the underlying buffer will have the size `n` + 1. - * - * This function will over-allocate in order to amortize the allocation costs - * in scenarios where the caller may need to repeatedly reserve additional - * space. - * - * If the capacity for `s` is already equal to or greater than the requested - * capacity, then no action is taken. - * - * # Arguments - * - * * s - A string - * * n - The number of bytes to reserve space for - */ -#[inline(always)] -pub fn reserve_at_least(s: &mut ~str, n: uint) { - reserve(s, uint::next_power_of_two(n + 1u) - 1u) -} /** * Returns the number of single-byte characters the string can hold without @@ -1724,9 +1590,9 @@ pub fn capacity(s: &const ~str) -> uint { /// Escape each char in `s` with char::escape_default. pub fn escape_default(s: &str) -> ~str { let mut out: ~str = ~""; - reserve_at_least(&mut out, s.len()); + out.reserve_at_least(s.len()); for s.iter().advance |c| { - push_str(&mut out, char::escape_default(c)); + out.push_str(char::escape_default(c)); } out } @@ -1734,9 +1600,9 @@ pub fn escape_default(s: &str) -> ~str { /// Escape each char in `s` with char::escape_unicode. pub fn escape_unicode(s: &str) -> ~str { let mut out: ~str = ~""; - reserve_at_least(&mut out, s.len()); + out.reserve_at_least(s.len()); for s.iter().advance |c| { - push_str(&mut out, char::escape_unicode(c)); + out.push_str(char::escape_unicode(c)); } out } @@ -1747,7 +1613,7 @@ pub mod raw { use libc; use ptr; use str::raw; - use str::{as_buf, is_utf8, reserve_at_least}; + use str::{as_buf, is_utf8}; use vec; /// Create a Rust string from a null-terminated *u8 buffer @@ -1859,7 +1725,7 @@ pub unsafe fn slice_bytes(s: &str, begin: uint, end: uint) -> &str { /// Appends a byte to a string. (Not UTF-8 safe). pub unsafe fn push_byte(s: &mut ~str, b: u8) { let new_len = s.len() + 1; - reserve_at_least(&mut *s, new_len); + s.reserve_at_least(new_len); do as_buf(*s) |buf, len| { let buf: *mut u8 = ::cast::transmute(buf); *ptr::mut_offset(buf, len) = b; @@ -1870,7 +1736,7 @@ pub unsafe fn push_byte(s: &mut ~str, b: u8) { /// Appends a vector of bytes to a string. (Not UTF-8 safe). unsafe fn push_bytes(s: &mut ~str, bytes: &[u8]) { let new_len = s.len() + bytes.len(); - reserve_at_least(&mut *s, new_len); + s.reserve_at_least(new_len); for bytes.each |byte| { push_byte(&mut *s, *byte); } } @@ -2274,18 +2140,154 @@ fn find_str(&self, needle: &str) -> Option { #[allow(missing_doc)] pub trait OwnedStr { - fn push_str(&mut self, v: &str); + fn push_str_no_overallocate(&mut self, rhs: &str); + fn push_str(&mut self, rhs: &str); fn push_char(&mut self, c: char); + fn reserve(&mut self, n: uint); + fn reserve_at_least(&mut self, n: uint); } impl OwnedStr for ~str { - #[inline] - fn push_str(&mut self, v: &str) { - push_str(self, v); + /// Appends a string slice to the back of a string, without overallocating + #[inline(always)] + fn push_str_no_overallocate(&mut self, rhs: &str) { + unsafe { + let llen = self.len(); + let rlen = rhs.len(); + self.reserve(llen + rlen); + do as_buf(*self) |lbuf, _llen| { + do as_buf(rhs) |rbuf, _rlen| { + let dst = ptr::offset(lbuf, llen); + let dst = ::cast::transmute_mut_unsafe(dst); + ptr::copy_memory(dst, rbuf, rlen); + } + } + raw::set_len(self, llen + rlen); + } } + + /// Appends a string slice to the back of a string + #[inline] + fn push_str(&mut self, rhs: &str) { + unsafe { + let llen = self.len(); + let rlen = rhs.len(); + self.reserve_at_least(llen + rlen); + do as_buf(*self) |lbuf, _llen| { + do as_buf(rhs) |rbuf, _rlen| { + let dst = ptr::offset(lbuf, llen); + let dst = ::cast::transmute_mut_unsafe(dst); + ptr::copy_memory(dst, rbuf, rlen); + } + } + raw::set_len(self, llen + rlen); + } + } + /// Appends a character to the back of a string #[inline] fn push_char(&mut self, c: char) { - push_char(self, c); + unsafe { + let code = c as uint; + let nb = if code < max_one_b { 1u } + else if code < max_two_b { 2u } + else if code < max_three_b { 3u } + else if code < max_four_b { 4u } + else if code < max_five_b { 5u } + else { 6u }; + let len = self.len(); + let new_len = len + nb; + self.reserve_at_least(new_len); + let off = len; + do as_buf(*self) |buf, _len| { + let buf: *mut u8 = ::cast::transmute(buf); + match nb { + 1u => { + *ptr::mut_offset(buf, off) = code as u8; + } + 2u => { + *ptr::mut_offset(buf, off) = (code >> 6u & 31u | tag_two_b) as u8; + *ptr::mut_offset(buf, off + 1u) = (code & 63u | tag_cont) as u8; + } + 3u => { + *ptr::mut_offset(buf, off) = (code >> 12u & 15u | tag_three_b) as u8; + *ptr::mut_offset(buf, off + 1u) = (code >> 6u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 2u) = (code & 63u | tag_cont) as u8; + } + 4u => { + *ptr::mut_offset(buf, off) = (code >> 18u & 7u | tag_four_b) as u8; + *ptr::mut_offset(buf, off + 1u) = (code >> 12u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 2u) = (code >> 6u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 3u) = (code & 63u | tag_cont) as u8; + } + 5u => { + *ptr::mut_offset(buf, off) = (code >> 24u & 3u | tag_five_b) as u8; + *ptr::mut_offset(buf, off + 1u) = (code >> 18u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 2u) = (code >> 12u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 3u) = (code >> 6u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 4u) = (code & 63u | tag_cont) as u8; + } + 6u => { + *ptr::mut_offset(buf, off) = (code >> 30u & 1u | tag_six_b) as u8; + *ptr::mut_offset(buf, off + 1u) = (code >> 24u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 2u) = (code >> 18u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 3u) = (code >> 12u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 4u) = (code >> 6u & 63u | tag_cont) as u8; + *ptr::mut_offset(buf, off + 5u) = (code & 63u | tag_cont) as u8; + } + _ => {} + } + } + raw::set_len(self, new_len); + } + } + + /** + * Reserves capacity for exactly `n` bytes in the given string, not including + * the null terminator. + * + * Assuming single-byte characters, the resulting string will be large + * enough to hold a string of length `n`. To account for the null terminator, + * the underlying buffer will have the size `n` + 1. + * + * If the capacity for `s` is already equal to or greater than the requested + * capacity, then no action is taken. + * + * # Arguments + * + * * s - A string + * * n - The number of bytes to reserve space for + */ + #[inline(always)] + pub fn reserve(&mut self, n: uint) { + unsafe { + let v: *mut ~[u8] = cast::transmute(self); + vec::reserve(&mut *v, n + 1); + } + } + + /** + * Reserves capacity for at least `n` bytes in the given string, not including + * the null terminator. + * + * Assuming single-byte characters, the resulting string will be large + * enough to hold a string of length `n`. To account for the null terminator, + * the underlying buffer will have the size `n` + 1. + * + * This function will over-allocate in order to amortize the allocation costs + * in scenarios where the caller may need to repeatedly reserve additional + * space. + * + * If the capacity for `s` is already equal to or greater than the requested + * capacity, then no action is taken. + * + * # Arguments + * + * * s - A string + * * n - The number of bytes to reserve space for + */ + #[inline(always)] + fn reserve_at_least(&mut self, n: uint) { + self.reserve(uint::next_power_of_two(n + 1u) - 1u) } } @@ -2582,13 +2584,13 @@ fn test_unsafe_slice() { fn a_million_letter_a() -> ~str { let mut i = 0; let mut rs = ~""; - while i < 100000 { push_str(&mut rs, "aaaaaaaaaa"); i += 1; } + while i < 100000 { rs.push_str("aaaaaaaaaa"); i += 1; } rs } fn half_a_million_letter_a() -> ~str { let mut i = 0; let mut rs = ~""; - while i < 100000 { push_str(&mut rs, "aaaaa"); i += 1; } + while i < 100000 { rs.push_str("aaaaa"); i += 1; } rs } let letters = a_million_letter_a(); diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs index cd3e0cf303e..e75cf2c01c6 100644 --- a/src/libstd/unstable/lang.rs +++ b/src/libstd/unstable/lang.rs @@ -136,10 +136,10 @@ unsafe fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) { let mut sep = " at "; for borrow_list.rev_iter().advance |entry| { if entry.box == box { - str::push_str(&mut msg, sep); + msg.push_str(sep); let filename = str::raw::from_c_str(entry.file); - str::push_str(&mut msg, filename); - str::push_str(&mut msg, fmt!(":%u", entry.line as uint)); + msg.push_str(filename); + msg.push_str(fmt!(":%u", entry.line as uint)); sep = " and at "; } } diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs index 6d0c499f2c8..b2ec3684b70 100644 --- a/src/libsyntax/ext/fmt.rs +++ b/src/libsyntax/ext/fmt.rs @@ -276,6 +276,9 @@ fn log_conv(c: &Conv) { stms.push(cx.stmt_let(fmt_sp, npieces > 1, ident, cx.expr_str_uniq(fmt_sp, s))); } else { + // we call the push_str function because the + // bootstrap doesnt't seem to work if we call the + // method. let args = ~[cx.expr_mut_addr_of(fmt_sp, buf()), cx.expr_str(fmt_sp, s)]; let call = cx.expr_call_global(fmt_sp, ~[core_ident, diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index a715ede7664..89fd5c3762a 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -125,7 +125,7 @@ fn block_trim(lines: ~[~str], chars: ~str, max: Option) -> ~[~str] { fn read_to_eol(rdr: @mut StringReader) -> ~str { let mut val = ~""; while rdr.curr != '\n' && !is_eof(rdr) { - str::push_char(&mut val, rdr.curr); + val.push_char(rdr.curr); bump(rdr); } if rdr.curr == '\n' { bump(rdr); } @@ -237,7 +237,7 @@ fn read_block_comment(rdr: @mut StringReader, // doc-comments are not really comments, they are attributes if rdr.curr == '*' || rdr.curr == '!' { while !(rdr.curr == '*' && nextch(rdr) == '/') && !is_eof(rdr) { - str::push_char(&mut curr_line, rdr.curr); + curr_line.push_char(rdr.curr); bump(rdr); } if !is_eof(rdr) { @@ -261,7 +261,7 @@ fn read_block_comment(rdr: @mut StringReader, curr_line = ~""; bump(rdr); } else { - str::push_char(&mut curr_line, rdr.curr); + curr_line.push_char(rdr.curr); if rdr.curr == '/' && nextch(rdr) == '*' { bump(rdr); bump(rdr); diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index 2dc8008f8ec..809a222352f 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -358,11 +358,11 @@ fn scan_exponent(rdr: @mut StringReader) -> Option<~str> { let mut c = rdr.curr; let mut rslt = ~""; if c == 'e' || c == 'E' { - str::push_char(&mut rslt, c); + rslt.push_char(c); bump(rdr); c = rdr.curr; if c == '-' || c == '+' { - str::push_char(&mut rslt, c); + rslt.push_char(c); bump(rdr); } let exponent = scan_digits(rdr, 10u); @@ -379,7 +379,7 @@ fn scan_digits(rdr: @mut StringReader, radix: uint) -> ~str { if c == '_' { bump(rdr); loop; } match char::to_digit(c, radix) { Some(_) => { - str::push_char(&mut rslt, c); + rslt.push_char(c); bump(rdr); } _ => return rslt @@ -721,31 +721,28 @@ fn binop(rdr: @mut StringReader, op: token::binop) -> token::Token { let escaped = rdr.curr; bump(rdr); match escaped { - 'n' => str::push_char(&mut accum_str, '\n'), - 'r' => str::push_char(&mut accum_str, '\r'), - 't' => str::push_char(&mut accum_str, '\t'), - '\\' => str::push_char(&mut accum_str, '\\'), - '\'' => str::push_char(&mut accum_str, '\''), - '"' => str::push_char(&mut accum_str, '"'), + 'n' => accum_str.push_char('\n'), + 'r' => accum_str.push_char('\r'), + 't' => accum_str.push_char('\t'), + '\\' => accum_str.push_char('\\'), + '\'' => accum_str.push_char('\''), + '"' => accum_str.push_char('"'), '\n' => consume_whitespace(rdr), 'x' => { - str::push_char(&mut accum_str, - scan_numeric_escape(rdr, 2u)); + accum_str.push_char(scan_numeric_escape(rdr, 2u)); } 'u' => { - str::push_char(&mut accum_str, - scan_numeric_escape(rdr, 4u)); + accum_str.push_char(scan_numeric_escape(rdr, 4u)); } 'U' => { - str::push_char(&mut accum_str, - scan_numeric_escape(rdr, 8u)); + accum_str.push_char(scan_numeric_escape(rdr, 8u)); } c2 => { rdr.fatal(fmt!("unknown string escape: %d", c2 as int)); } } } - _ => str::push_char(&mut accum_str, ch) + _ => accum_str.push_char(ch) } } bump(rdr); diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs index c497a30ec5f..5c77e698bec 100644 --- a/src/test/bench/shootout-fasta.rs +++ b/src/test/bench/shootout-fasta.rs @@ -79,7 +79,7 @@ fn make_random_fasta(wr: @io::Writer, }; let mut op: ~str = ~""; for uint::range(0u, n as uint) |_i| { - str::push_char(&mut op, select_random(myrandom_next(rng, 100u32), + op.push_char(select_random(myrandom_next(rng, 100u32), copy genelist)); if op.len() >= LINE_LENGTH() { wr.write_line(op); diff --git a/src/test/run-pass/issue-4241.rs b/src/test/run-pass/issue-4241.rs index 4aa604160d9..972b9c7a525 100644 --- a/src/test/run-pass/issue-4241.rs +++ b/src/test/run-pass/issue-4241.rs @@ -95,10 +95,10 @@ enum Result { priv fn cmd_to_str(cmd: ~[~str]) -> ~str { let mut res = ~"*"; - str::push_str(&mut res, cmd.len().to_str()); - str::push_str(&mut res, "\r\n"); + res.push_str(cmd.len().to_str()); + res.push_str("\r\n"); for cmd.each |s| { - str::push_str(&mut res, str::concat(~[~"$", s.len().to_str(), ~"\r\n", + res.push_str(str::concat(~[~"$", s.len().to_str(), ~"\r\n", copy *s, ~"\r\n"])); } res diff --git a/src/test/run-pass/move-out-of-field.rs b/src/test/run-pass/move-out-of-field.rs index b6485348a51..a3c2872803a 100644 --- a/src/test/run-pass/move-out-of-field.rs +++ b/src/test/run-pass/move-out-of-field.rs @@ -6,7 +6,7 @@ struct StringBuffer { impl StringBuffer { pub fn append(&mut self, v: &str) { - str::push_str(&mut self.s, v); + self.s.push_str(v); } } diff --git a/src/test/run-pass/utf8_chars.rs b/src/test/run-pass/utf8_chars.rs index 011fb4435c3..94990d649d8 100644 --- a/src/test/run-pass/utf8_chars.rs +++ b/src/test/run-pass/utf8_chars.rs @@ -33,7 +33,7 @@ pub fn main() { let mut stack = ~"a×c€"; assert_eq!(str::pop_char(&mut stack), '€'); assert_eq!(str::pop_char(&mut stack), 'c'); - str::push_char(&mut stack, 'u'); + stack.push_char('u'); assert!(stack == ~"a×u"); assert_eq!(str::shift_char(&mut stack), 'a'); assert_eq!(str::shift_char(&mut stack), '×');