Skip to content

Commit b95a8c6

Browse files
committed
std::ascii: Provide a copyless [Ascii] -> str method.
This renames to_str_ascii to as_str_ascii and makes it non-copying, which is possible now that strings no longer have a hidden extra byte/null terminator. Fixes #6120.
1 parent 7fc6893 commit b95a8c6

File tree

5 files changed

+24
-33
lines changed

5 files changed

+24
-33
lines changed

src/compiletest/errors.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,8 @@ fn parse_expected(line_num: uint, line: ~str) -> ~[ExpectedError] {
5252
let start_kind = idx;
5353
while idx < len && line[idx] != (' ' as u8) { idx += 1u; }
5454

55-
// FIXME: #4318 Instead of to_ascii and to_str_ascii, could use
56-
// to_ascii_consume and to_str_consume to not do a unnecessary copy.
5755
let kind = line.slice(start_kind, idx);
58-
let kind = kind.to_ascii().to_lower().to_str_ascii();
56+
let kind = kind.to_ascii().to_lower().into_str();
5957

6058
// Extract msg:
6159
while idx < len && line[idx] == (' ' as u8) { idx += 1u; }

src/libextra/sort.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -887,12 +887,8 @@ mod tests {
887887
// tjc: funny that we have to use parens
888888
fn ile(x: &(&'static str), y: &(&'static str)) -> bool
889889
{
890-
// FIXME: #4318 Instead of to_ascii and to_str_ascii, could use
891-
// to_ascii_move and to_str_move to not do a unnecessary clone.
892-
// (Actually, could just remove the to_str_* call, but needs an deriving(Ord) on
893-
// Ascii)
894-
let x = x.to_ascii().to_lower().to_str_ascii();
895-
let y = y.to_ascii().to_lower().to_str_ascii();
890+
let x = x.to_ascii().to_lower().into_str();
891+
let y = y.to_ascii().to_lower().into_str();
896892
x <= y
897893
}
898894

src/librustc/driver/driver.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -669,10 +669,8 @@ pub fn build_session_options(binary: @str,
669669
for level in lint_levels.iter() {
670670
let level_name = lint::level_to_str(*level);
671671

672-
// FIXME: #4318 Instead of to_ascii and to_str_ascii, could use
673-
// to_ascii_move and to_str_move to not do a unnecessary copy.
674672
let level_short = level_name.slice_chars(0, 1);
675-
let level_short = level_short.to_ascii().to_upper().to_str_ascii();
673+
let level_short = level_short.to_ascii().to_upper().into_str();
676674
let flags = vec::append(matches.opt_strs(level_short),
677675
matches.opt_strs(level_name));
678676
for lint_name in flags.iter() {

src/libstd/ascii.rs

+18-15
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use str::OwnedStr;
1717
use container::Container;
1818
use cast;
1919
use iter::Iterator;
20-
use vec::{CopyableVector, ImmutableVector, MutableVector};
20+
use vec::{ImmutableVector, MutableVector};
2121
use to_bytes::IterBytes;
2222
use option::{Some, None};
2323

@@ -154,10 +154,10 @@ impl AsciiCast<Ascii> for char {
154154

155155
/// Trait for copyless casting to an ascii vector.
156156
pub trait OwnedAsciiCast {
157-
/// Take ownership and cast to an ascii vector without trailing zero element.
157+
/// Take ownership and cast to an ascii vector.
158158
fn into_ascii(self) -> ~[Ascii];
159159

160-
/// Take ownership and cast to an ascii vector without trailing zero element.
160+
/// Take ownership and cast to an ascii vector.
161161
/// Does not perform validation checks.
162162
unsafe fn into_ascii_nocheck(self) -> ~[Ascii];
163163
}
@@ -188,26 +188,26 @@ impl OwnedAsciiCast for ~str {
188188
}
189189
}
190190

191-
/// Trait for converting an ascii type to a string. Needed to convert `&[Ascii]` to `~str`
191+
/// Trait for converting an ascii type to a string. Needed to convert
192+
/// `&[Ascii]` to `&str`.
192193
pub trait AsciiStr {
193194
/// Convert to a string.
194-
fn to_str_ascii(&self) -> ~str;
195+
fn as_str_ascii<'a>(&'a self) -> &'a str;
195196

196197
/// Convert to vector representing a lower cased ascii string.
197198
fn to_lower(&self) -> ~[Ascii];
198199

199200
/// Convert to vector representing a upper cased ascii string.
200201
fn to_upper(&self) -> ~[Ascii];
201202

202-
/// Compares two Ascii strings ignoring case
203+
/// Compares two Ascii strings ignoring case.
203204
fn eq_ignore_case(self, other: &[Ascii]) -> bool;
204205
}
205206

206207
impl<'self> AsciiStr for &'self [Ascii] {
207208
#[inline]
208-
fn to_str_ascii(&self) -> ~str {
209-
let cpy = self.to_owned();
210-
unsafe { cast::transmute(cpy) }
209+
fn as_str_ascii<'a>(&'a self) -> &'a str {
210+
unsafe { cast::transmute(*self) }
211211
}
212212

213213
#[inline]
@@ -443,12 +443,12 @@ mod tests {
443443
let v = ~[40u8, 32u8, 59u8]; assert_eq!(v.to_ascii(), v2ascii!([40, 32, 59]));
444444
let v = ~"( ;"; assert_eq!(v.to_ascii(), v2ascii!([40, 32, 59]));
445445
446-
assert_eq!("abCDef&?#".to_ascii().to_lower().to_str_ascii(), ~"abcdef&?#");
447-
assert_eq!("abCDef&?#".to_ascii().to_upper().to_str_ascii(), ~"ABCDEF&?#");
446+
assert_eq!("abCDef&?#".to_ascii().to_lower().into_str(), ~"abcdef&?#");
447+
assert_eq!("abCDef&?#".to_ascii().to_upper().into_str(), ~"ABCDEF&?#");
448448
449-
assert_eq!("".to_ascii().to_lower().to_str_ascii(), ~"");
450-
assert_eq!("YMCA".to_ascii().to_lower().to_str_ascii(), ~"ymca");
451-
assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().to_str_ascii(), ~"ABCDEFXYZ:.;");
449+
assert_eq!("".to_ascii().to_lower().into_str(), ~"");
450+
assert_eq!("YMCA".to_ascii().to_lower().into_str(), ~"ymca");
451+
assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().into_str(), ~"ABCDEFXYZ:.;");
452452
453453
assert!("aBcDeF&?#".to_ascii().eq_ignore_case("AbCdEf&?#".to_ascii()));
454454
@@ -465,7 +465,10 @@ mod tests {
465465
}
466466
467467
#[test]
468-
fn test_ascii_to_str() { assert_eq!(v2ascii!([40, 32, 59]).to_str_ascii(), ~"( ;"); }
468+
fn test_ascii_as_str() {
469+
let v = v2ascii!([40, 32, 59]);
470+
assert_eq!(v.as_str_ascii(), "( ;");
471+
}
469472
470473
#[test]
471474
fn test_ascii_into_str() {

src/test/bench/shootout-k-nucleotide-pipes.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,8 @@ fn sort_and_fmt(mm: &HashMap<~[u8], uint>, total: uint) -> ~str {
7272
let (k,v) = (*kv).clone();
7373
unsafe {
7474
let b = str::raw::from_utf8(k);
75-
// FIXME: #4318 Instead of to_ascii and to_str_ascii, could use
76-
// to_ascii_move and to_str_move to not do a unnecessary copy.
7775
buffer.push_str(format!("{} {:0.3f}\n",
78-
b.to_ascii().to_upper().to_str_ascii(), v));
76+
b.into_ascii().to_upper().into_str(), v));
7977
}
8078
}
8179

@@ -84,9 +82,7 @@ fn sort_and_fmt(mm: &HashMap<~[u8], uint>, total: uint) -> ~str {
8482

8583
// given a map, search for the frequency of a pattern
8684
fn find(mm: &HashMap<~[u8], uint>, key: ~str) -> uint {
87-
// FIXME: #4318 Instead of to_ascii and to_str_ascii, could use
88-
// to_ascii_move and to_str_move to not do a unnecessary copy.
89-
let key = key.to_ascii().to_lower().to_str_ascii();
85+
let key = key.into_ascii().to_lower().into_str();
9086
match mm.find_equiv(&key.as_bytes()) {
9187
option::None => { return 0u; }
9288
option::Some(&num) => { return num; }

0 commit comments

Comments
 (0)