auto merge of #5479 : Kimundi/rust/str-dealloc, r=z0w0
This makes the `trim` and `substr` functions return a slice instead of an `~str`, and removes the unnecessary `Trimmable` trait (`StrSlice` already contains the same functionality). Also moves the `ToStr` implementations for the three str types into the str module in anticipation of further untangling.
This commit is contained in:
commit
5f2d4102c5
@ -198,7 +198,7 @@ pub use path::WindowsPath;
|
||||
pub use path::PosixPath;
|
||||
|
||||
pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
|
||||
pub use str::{StrSlice, Trimmable};
|
||||
pub use str::{StrSlice};
|
||||
pub use container::{Container, Mutable};
|
||||
pub use vec::{CopyableVector, ImmutableVector};
|
||||
pub use vec::{ImmutableEqVector, ImmutableCopyableVector};
|
||||
|
@ -36,7 +36,7 @@
|
||||
pub use path::PosixPath;
|
||||
pub use path::WindowsPath;
|
||||
pub use ptr::Ptr;
|
||||
pub use str::{StrSlice, Trimmable, OwnedStr};
|
||||
pub use str::{StrSlice, OwnedStr};
|
||||
pub use to_bytes::IterBytes;
|
||||
pub use to_str::ToStr;
|
||||
pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
|
||||
|
@ -29,6 +29,7 @@
|
||||
use u8;
|
||||
use uint;
|
||||
use vec;
|
||||
use to_str::ToStr;
|
||||
|
||||
#[cfg(notest)] use cmp::{Eq, Ord};
|
||||
|
||||
@ -53,6 +54,19 @@
|
||||
unsafe { raw::slice_bytes_unique(s, 0, len(s)) }
|
||||
}
|
||||
|
||||
impl ToStr for ~str {
|
||||
#[inline(always)]
|
||||
pure fn to_str(&self) -> ~str { copy *self }
|
||||
}
|
||||
impl ToStr for &'self str {
|
||||
#[inline(always)]
|
||||
pure fn to_str(&self) -> ~str { ::str::from_slice(*self) }
|
||||
}
|
||||
impl ToStr for @str {
|
||||
#[inline(always)]
|
||||
pure fn to_str(&self) -> ~str { ::str::from_slice(*self) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a byte to a UTF-8 string
|
||||
*
|
||||
@ -299,12 +313,12 @@ pub fn unshift_char(s: &mut ~str, ch: char) {
|
||||
* * chars_to_trim - A vector of chars
|
||||
*
|
||||
*/
|
||||
pub pure fn trim_left_chars(s: &str, chars_to_trim: &[char]) -> ~str {
|
||||
if chars_to_trim.is_empty() { return from_slice(s); }
|
||||
pub pure fn trim_left_chars(s: &'a str, chars_to_trim: &[char]) -> &'a str {
|
||||
if chars_to_trim.is_empty() { return s; }
|
||||
|
||||
match find(s, |c| !chars_to_trim.contains(&c)) {
|
||||
None => ~"",
|
||||
Some(first) => unsafe { raw::slice_bytes_unique(s, first, s.len()) }
|
||||
None => "",
|
||||
Some(first) => unsafe { raw::slice_bytes(s, first, s.len()) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,14 +331,14 @@ pub fn unshift_char(s: &mut ~str, ch: char) {
|
||||
* * chars_to_trim - A vector of chars
|
||||
*
|
||||
*/
|
||||
pub pure fn trim_right_chars(s: &str, chars_to_trim: &[char]) -> ~str {
|
||||
if chars_to_trim.is_empty() { return str::from_slice(s); }
|
||||
pub pure fn trim_right_chars(s: &'a str, chars_to_trim: &[char]) -> &'a str {
|
||||
if chars_to_trim.is_empty() { return s; }
|
||||
|
||||
match rfind(s, |c| !chars_to_trim.contains(&c)) {
|
||||
None => ~"",
|
||||
None => "",
|
||||
Some(last) => {
|
||||
let next = char_range_at(s, last).next;
|
||||
unsafe { raw::slice_bytes_unique(s, 0u, next) }
|
||||
unsafe { raw::slice_bytes(s, 0u, next) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -338,31 +352,31 @@ pub fn unshift_char(s: &mut ~str, ch: char) {
|
||||
* * chars_to_trim - A vector of chars
|
||||
*
|
||||
*/
|
||||
pub pure fn trim_chars(s: &str, chars_to_trim: &[char]) -> ~str {
|
||||
pub pure fn trim_chars(s: &'a str, chars_to_trim: &[char]) -> &'a str {
|
||||
trim_left_chars(trim_right_chars(s, chars_to_trim), chars_to_trim)
|
||||
}
|
||||
|
||||
/// Returns a string with leading whitespace removed
|
||||
pub pure fn trim_left(s: &str) -> ~str {
|
||||
pub pure fn trim_left(s: &'a str) -> &'a str {
|
||||
match find(s, |c| !char::is_whitespace(c)) {
|
||||
None => ~"",
|
||||
Some(first) => unsafe { raw::slice_bytes_unique(s, first, len(s)) }
|
||||
None => "",
|
||||
Some(first) => unsafe { raw::slice_bytes(s, first, len(s)) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a string with trailing whitespace removed
|
||||
pub pure fn trim_right(s: &str) -> ~str {
|
||||
pub pure fn trim_right(s: &'a str) -> &'a str {
|
||||
match rfind(s, |c| !char::is_whitespace(c)) {
|
||||
None => ~"",
|
||||
None => "",
|
||||
Some(last) => {
|
||||
let next = char_range_at(s, last).next;
|
||||
unsafe { raw::slice_bytes_unique(s, 0u, next) }
|
||||
unsafe { raw::slice_bytes(s, 0u, next) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a string with leading and trailing whitespace removed
|
||||
pub pure fn trim(s: &str) -> ~str { trim_left(trim_right(s)) }
|
||||
pub pure fn trim(s: &'a str) -> &'a str { trim_left(trim_right(s)) }
|
||||
|
||||
/*
|
||||
Section: Transforming strings
|
||||
@ -407,8 +421,8 @@ pub fn unshift_char(s: &mut ~str, ch: char) {
|
||||
* Returns a string containing `n` characters starting at byte offset
|
||||
* `begin`.
|
||||
*/
|
||||
pub pure fn substr(s: &str, begin: uint, n: uint) -> ~str {
|
||||
slice(s, begin, begin + count_bytes(s, begin, n)).to_owned()
|
||||
pub pure fn substr(s: &'a str, begin: uint, n: uint) -> &'a str {
|
||||
slice(s, begin, begin + count_bytes(s, begin, n))
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2221,25 +2235,6 @@ fn test_from_buf_len() {
|
||||
|
||||
}
|
||||
|
||||
pub trait Trimmable {
|
||||
pure fn trim(&self) -> Self;
|
||||
pure fn trim_left(&self) -> Self;
|
||||
pure fn trim_right(&self) -> Self;
|
||||
}
|
||||
|
||||
/// Extension methods for strings
|
||||
impl Trimmable for ~str {
|
||||
/// Returns a string with leading and trailing whitespace removed
|
||||
#[inline]
|
||||
pure fn trim(&self) -> ~str { trim(*self) }
|
||||
/// Returns a string with leading whitespace removed
|
||||
#[inline]
|
||||
pure fn trim_left(&self) -> ~str { trim_left(*self) }
|
||||
/// Returns a string with trailing whitespace removed
|
||||
#[inline]
|
||||
pure fn trim_right(&self) -> ~str { trim_right(*self) }
|
||||
}
|
||||
|
||||
#[cfg(notest)]
|
||||
pub mod traits {
|
||||
use ops::Add;
|
||||
@ -2280,14 +2275,17 @@ pub trait StrSlice {
|
||||
pure fn split_char(&self, sep: char) -> ~[~str];
|
||||
pure fn split_str(&self, sep: &'a str) -> ~[~str];
|
||||
pure fn starts_with(&self, needle: &'a str) -> bool;
|
||||
pure fn substr(&self, begin: uint, n: uint) -> ~str;
|
||||
pure fn substr(&self, begin: uint, n: uint) -> &'self str;
|
||||
pure fn to_lower(&self) -> ~str;
|
||||
pure fn to_upper(&self) -> ~str;
|
||||
pure fn escape_default(&self) -> ~str;
|
||||
pure fn escape_unicode(&self) -> ~str;
|
||||
pure fn trim(&self) -> ~str;
|
||||
pure fn trim_left(&self) -> ~str;
|
||||
pure fn trim_right(&self) -> ~str;
|
||||
pure fn trim(&self) -> &'self str;
|
||||
pure fn trim_left(&self) -> &'self str;
|
||||
pure fn trim_right(&self) -> &'self str;
|
||||
pure fn trim_chars(&self, chars_to_trim: &[char]) -> &'self str;
|
||||
pure fn trim_left_chars(&self, chars_to_trim: &[char]) -> &'self str;
|
||||
pure fn trim_right_chars(&self, chars_to_trim: &[char]) -> &'self str;
|
||||
pure fn to_owned(&self) -> ~str;
|
||||
pure fn to_managed(&self) -> @str;
|
||||
pure fn char_at(&self, i: uint) -> char;
|
||||
@ -2421,7 +2419,7 @@ impl StrSlice for &'self str {
|
||||
* `begin`.
|
||||
*/
|
||||
#[inline]
|
||||
pure fn substr(&self, begin: uint, n: uint) -> ~str {
|
||||
pure fn substr(&self, begin: uint, n: uint) -> &'self str {
|
||||
substr(*self, begin, n)
|
||||
}
|
||||
/// Convert a string to lowercase
|
||||
@ -2439,13 +2437,27 @@ impl StrSlice for &'self str {
|
||||
|
||||
/// Returns a string with leading and trailing whitespace removed
|
||||
#[inline]
|
||||
pure fn trim(&self) -> ~str { trim(*self) }
|
||||
pure fn trim(&self) -> &'self str { trim(*self) }
|
||||
/// Returns a string with leading whitespace removed
|
||||
#[inline]
|
||||
pure fn trim_left(&self) -> ~str { trim_left(*self) }
|
||||
pure fn trim_left(&self) -> &'self str { trim_left(*self) }
|
||||
/// Returns a string with trailing whitespace removed
|
||||
#[inline]
|
||||
pure fn trim_right(&self) -> ~str { trim_right(*self) }
|
||||
pure fn trim_right(&self) -> &'self str { trim_right(*self) }
|
||||
|
||||
#[inline]
|
||||
pure fn trim_chars(&self, chars_to_trim: &[char]) -> &'self str {
|
||||
trim_chars(*self, chars_to_trim)
|
||||
}
|
||||
#[inline]
|
||||
pure fn trim_left_chars(&self, chars_to_trim: &[char]) -> &'self str {
|
||||
trim_left_chars(*self, chars_to_trim)
|
||||
}
|
||||
#[inline]
|
||||
pure fn trim_right_chars(&self, chars_to_trim: &[char]) -> &'self str {
|
||||
trim_right_chars(*self, chars_to_trim)
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
pure fn to_owned(&self) -> ~str { from_slice(*self) }
|
||||
@ -2805,11 +2817,11 @@ fn test_find_str_between() {
|
||||
#[test]
|
||||
fn test_substr() {
|
||||
fn t(a: &str, b: &str, start: int) {
|
||||
fail_unless!(substr(a, start as uint, len(b)) == b.to_str());
|
||||
fail_unless!(substr(a, start as uint, len(b)) == b);
|
||||
}
|
||||
t(~"hello", ~"llo", 2);
|
||||
t(~"hello", ~"el", 1);
|
||||
fail_unless!(~"ะเทศไท" == substr(~"ประเทศไทย中华Việt Nam", 6u, 6u));
|
||||
t("hello", "llo", 2);
|
||||
t("hello", "el", 1);
|
||||
fail_unless!("ะเทศไท" == substr("ประเทศไทย中华Việt Nam", 6u, 6u));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -3042,62 +3054,62 @@ fn test_slice_fail() {
|
||||
|
||||
#[test]
|
||||
fn test_trim_left_chars() {
|
||||
fail_unless!(trim_left_chars(~" *** foo *** ", ~[]) ==
|
||||
~" *** foo *** ");
|
||||
fail_unless!(trim_left_chars(~" *** foo *** ", ~['*', ' ']) ==
|
||||
~"foo *** ");
|
||||
fail_unless!(trim_left_chars(~" *** *** ", ~['*', ' ']) == ~"");
|
||||
fail_unless!(trim_left_chars(~"foo *** ", ~['*', ' ']) ==
|
||||
~"foo *** ");
|
||||
fail_unless!(trim_left_chars(" *** foo *** ", ~[]) ==
|
||||
" *** foo *** ");
|
||||
fail_unless!(trim_left_chars(" *** foo *** ", ~['*', ' ']) ==
|
||||
"foo *** ");
|
||||
fail_unless!(trim_left_chars(" *** *** ", ~['*', ' ']) == "");
|
||||
fail_unless!(trim_left_chars("foo *** ", ~['*', ' ']) ==
|
||||
"foo *** ");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trim_right_chars() {
|
||||
fail_unless!(trim_right_chars(~" *** foo *** ", ~[]) ==
|
||||
~" *** foo *** ");
|
||||
fail_unless!(trim_right_chars(~" *** foo *** ", ~['*', ' ']) ==
|
||||
~" *** foo");
|
||||
fail_unless!(trim_right_chars(~" *** *** ", ~['*', ' ']) == ~"");
|
||||
fail_unless!(trim_right_chars(~" *** foo", ~['*', ' ']) ==
|
||||
~" *** foo");
|
||||
fail_unless!(trim_right_chars(" *** foo *** ", ~[]) ==
|
||||
" *** foo *** ");
|
||||
fail_unless!(trim_right_chars(" *** foo *** ", ~['*', ' ']) ==
|
||||
" *** foo");
|
||||
fail_unless!(trim_right_chars(" *** *** ", ~['*', ' ']) == "");
|
||||
fail_unless!(trim_right_chars(" *** foo", ~['*', ' ']) ==
|
||||
" *** foo");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trim_chars() {
|
||||
fail_unless!(trim_chars(~" *** foo *** ", ~[]) == ~" *** foo *** ");
|
||||
fail_unless!(trim_chars(~" *** foo *** ", ~['*', ' ']) == ~"foo");
|
||||
fail_unless!(trim_chars(~" *** *** ", ~['*', ' ']) == ~"");
|
||||
fail_unless!(trim_chars(~"foo", ~['*', ' ']) == ~"foo");
|
||||
fail_unless!(trim_chars(" *** foo *** ", ~[]) == " *** foo *** ");
|
||||
fail_unless!(trim_chars(" *** foo *** ", ~['*', ' ']) == "foo");
|
||||
fail_unless!(trim_chars(" *** *** ", ~['*', ' ']) == "");
|
||||
fail_unless!(trim_chars("foo", ~['*', ' ']) == "foo");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trim_left() {
|
||||
fail_unless!((trim_left(~"") == ~""));
|
||||
fail_unless!((trim_left(~"a") == ~"a"));
|
||||
fail_unless!((trim_left(~" ") == ~""));
|
||||
fail_unless!((trim_left(~" blah") == ~"blah"));
|
||||
fail_unless!((trim_left(~" \u3000 wut") == ~"wut"));
|
||||
fail_unless!((trim_left(~"hey ") == ~"hey "));
|
||||
fail_unless!((trim_left("") == ""));
|
||||
fail_unless!((trim_left("a") == "a"));
|
||||
fail_unless!((trim_left(" ") == ""));
|
||||
fail_unless!((trim_left(" blah") == "blah"));
|
||||
fail_unless!((trim_left(" \u3000 wut") == "wut"));
|
||||
fail_unless!((trim_left("hey ") == "hey "));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trim_right() {
|
||||
fail_unless!((trim_right(~"") == ~""));
|
||||
fail_unless!((trim_right(~"a") == ~"a"));
|
||||
fail_unless!((trim_right(~" ") == ~""));
|
||||
fail_unless!((trim_right(~"blah ") == ~"blah"));
|
||||
fail_unless!((trim_right(~"wut \u3000 ") == ~"wut"));
|
||||
fail_unless!((trim_right(~" hey") == ~" hey"));
|
||||
fail_unless!((trim_right("") == ""));
|
||||
fail_unless!((trim_right("a") == "a"));
|
||||
fail_unless!((trim_right(" ") == ""));
|
||||
fail_unless!((trim_right("blah ") == "blah"));
|
||||
fail_unless!((trim_right("wut \u3000 ") == "wut"));
|
||||
fail_unless!((trim_right(" hey") == " hey"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trim() {
|
||||
fail_unless!((trim(~"") == ~""));
|
||||
fail_unless!((trim(~"a") == ~"a"));
|
||||
fail_unless!((trim(~" ") == ~""));
|
||||
fail_unless!((trim(~" blah ") == ~"blah"));
|
||||
fail_unless!((trim(~"\nwut \u3000 ") == ~"wut"));
|
||||
fail_unless!((trim(~" hey dude ") == ~"hey dude"));
|
||||
fail_unless!((trim("") == ""));
|
||||
fail_unless!((trim("a") == "a"));
|
||||
fail_unless!((trim(" ") == ""));
|
||||
fail_unless!((trim(" blah ") == "blah"));
|
||||
fail_unless!((trim("\nwut \u3000 ") == "wut"));
|
||||
fail_unless!((trim(" hey dude ") == "hey dude"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -28,18 +28,6 @@ impl ToStr for () {
|
||||
#[inline(always)]
|
||||
pure fn to_str(&self) -> ~str { ~"()" }
|
||||
}
|
||||
impl ToStr for ~str {
|
||||
#[inline(always)]
|
||||
pure fn to_str(&self) -> ~str { copy *self }
|
||||
}
|
||||
impl ToStr for &'self str {
|
||||
#[inline(always)]
|
||||
pure fn to_str(&self) -> ~str { ::str::from_slice(*self) }
|
||||
}
|
||||
impl ToStr for @str {
|
||||
#[inline(always)]
|
||||
pure fn to_str(&self) -> ~str { ::str::from_slice(*self) }
|
||||
}
|
||||
|
||||
// FIXME #4898: impl for one-tuples
|
||||
|
||||
|
@ -537,7 +537,7 @@ pub struct Conv {
|
||||
let mut unpadded = match cv.precision {
|
||||
CountImplied => s.to_owned(),
|
||||
CountIs(max) => if (max as uint) < str::char_len(s) {
|
||||
str::substr(s, 0, max as uint)
|
||||
str::substr(s, 0, max as uint).to_owned()
|
||||
} else {
|
||||
s.to_owned()
|
||||
}
|
||||
|
@ -1849,6 +1849,7 @@ fn trans_assign_op(bcx: block,
|
||||
return result_datum.copy_to_datum(bcx, DROP_EXISTING, dst_datum);
|
||||
}
|
||||
|
||||
// NOTE: Mode neccessary here?
|
||||
fn shorten(+x: ~str) -> ~str {
|
||||
if x.len() > 60 { x.substr(0, 60) } else { x }
|
||||
if x.len() > 60 { x.substr(0, 60).to_owned() } else { x }
|
||||
}
|
||||
|
@ -311,7 +311,7 @@ pub fn mk_doc(source: ~str) -> doc::Doc {
|
||||
let doc = (attr_pass::mk_pass().f)(srv.clone(), doc);
|
||||
let doc = (desc_to_brief_pass::mk_pass().f)(srv.clone(), doc);
|
||||
let doc = (sectionalize_pass::mk_pass().f)(srv.clone(), doc);
|
||||
(mk_pass(~"", |s| str::trim(s) ).f)(srv.clone(), doc)
|
||||
(mk_pass(~"", |s| str::trim(s).to_owned() ).f)(srv.clone(), doc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
use core::str;
|
||||
|
||||
pub fn mk_pass() -> Pass {
|
||||
text_pass::mk_pass(~"trim", |s| str::trim(s) )
|
||||
text_pass::mk_pass(~"trim", |s| s.trim().to_owned() )
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -78,7 +78,7 @@ fn unindent(s: &str) -> ~str {
|
||||
};
|
||||
|
||||
if !lines.is_empty() {
|
||||
let unindented = ~[lines.head().trim()]
|
||||
let unindented = ~[lines.head().trim().to_owned()]
|
||||
+ do lines.tail().map |line| {
|
||||
if str::is_whitespace(*line) {
|
||||
copy *line
|
||||
|
@ -283,7 +283,7 @@ fn run_cmd(repl: &mut Repl, _in: @io::Reader, _out: @io::Writer,
|
||||
for args.each |arg| {
|
||||
let (crate, filename) =
|
||||
if arg.ends_with(".rs") || arg.ends_with(".rc") {
|
||||
(arg.substr(0, arg.len() - 3), *arg)
|
||||
(arg.substr(0, arg.len() - 3).to_owned(), *arg)
|
||||
} else {
|
||||
(*arg, arg + ~".rs")
|
||||
};
|
||||
|
@ -458,10 +458,11 @@ pub impl BigUint {
|
||||
|
||||
pure fn fill_concat(v: &[BigDigit], radix: uint, l: uint) -> ~str {
|
||||
if v.is_empty() { return ~"0" }
|
||||
str::trim_left_chars(str::concat(vec::reversed(v).map(|n| {
|
||||
let s = str::concat(vec::reversed(v).map(|n| {
|
||||
let s = uint::to_str_radix(*n as uint, radix);
|
||||
str::from_chars(vec::from_elem(l - s.len(), '0')) + s
|
||||
})), ['0'])
|
||||
}));
|
||||
str::trim_left_chars(s, ['0']).to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,7 +228,7 @@ pub fn parse(s: &str) -> Option<Version> {
|
||||
do bad_parse::cond.trap(|_| { debug!("bad"); bad = true }).in {
|
||||
do io::with_str_reader(s) |rdr| {
|
||||
let v = parse_reader(rdr);
|
||||
if bad || v.to_str() != s {
|
||||
if bad || v.to_str() != s.to_owned() {
|
||||
None
|
||||
} else {
|
||||
Some(v)
|
||||
|
@ -109,7 +109,10 @@ fn block_trim(lines: ~[~str], chars: ~str, max: Option<uint>) -> ~[~str] {
|
||||
}
|
||||
|
||||
if comment.starts_with(~"//") {
|
||||
return comment.slice(3u, comment.len()).trim();
|
||||
// FIXME #5475:
|
||||
// return comment.slice(3u, comment.len()).trim().to_owned();
|
||||
let r = comment.slice(3u, comment.len()); return r.trim().to_owned();
|
||||
|
||||
}
|
||||
|
||||
if comment.starts_with(~"/*") {
|
||||
|
@ -67,7 +67,8 @@ pub fn equal(&self, other: &Sudoku) -> bool {
|
||||
|
||||
let mut g = vec::from_fn(10u, { |_i| ~[0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8] });
|
||||
while !reader.eof() {
|
||||
let comps = str::split_char(str::trim(reader.read_line()), ',');
|
||||
let line = reader.read_line();
|
||||
let comps = str::split_char(line.trim(), ',');
|
||||
if vec::len(comps) == 3u {
|
||||
let row = uint::from_str(comps[0]).get() as u8;
|
||||
let col = uint::from_str(comps[1]).get() as u8;
|
||||
|
Loading…
Reference in New Issue
Block a user