diff options
| author | bors <bors@rust-lang.org> | 2014-02-08 05:01:30 -0800 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-02-08 05:01:30 -0800 |
| commit | 5acc998ed9b76d9c00849e007101f9c33b17c6c4 (patch) | |
| tree | 1f1a5ad2080acda5446285f9da7077938cddd9df /src/libstd/path | |
| parent | 548b8cec199c28c102fd98d6dd2833d3a171e7d0 (diff) | |
| parent | 1d17c2129ec696d81e6c6caee8b1740dd9509090 (diff) | |
| download | rust-5acc998ed9b76d9c00849e007101f9c33b17c6c4.tar.gz rust-5acc998ed9b76d9c00849e007101f9c33b17c6c4.zip | |
auto merge of #12098 : kballard/rust/from_utf8_lossy_tweak, r=huonw
MaybeOwned allows from_utf8_lossy to avoid allocation if there are no invalid bytes in the input. Before: ``` test str::bench::from_utf8_lossy_100_ascii ... bench: 183 ns/iter (+/- 5) test str::bench::from_utf8_lossy_100_invalid ... bench: 341 ns/iter (+/- 15) test str::bench::from_utf8_lossy_100_multibyte ... bench: 227 ns/iter (+/- 13) test str::bench::from_utf8_lossy_invalid ... bench: 102 ns/iter (+/- 4) test str::bench::is_utf8_100_ascii ... bench: 2 ns/iter (+/- 0) test str::bench::is_utf8_100_multibyte ... bench: 2 ns/iter (+/- 0) ``` Now: ``` test str::bench::from_utf8_lossy_100_ascii ... bench: 96 ns/iter (+/- 4) test str::bench::from_utf8_lossy_100_invalid ... bench: 318 ns/iter (+/- 10) test str::bench::from_utf8_lossy_100_multibyte ... bench: 105 ns/iter (+/- 2) test str::bench::from_utf8_lossy_invalid ... bench: 105 ns/iter (+/- 2) test str::bench::is_utf8_100_ascii ... bench: 2 ns/iter (+/- 0) test str::bench::is_utf8_100_multibyte ... bench: 2 ns/iter (+/- 0) ```
Diffstat (limited to 'src/libstd/path')
| -rw-r--r-- | src/libstd/path/mod.rs | 49 | ||||
| -rw-r--r-- | src/libstd/path/posix.rs | 16 | ||||
| -rw-r--r-- | src/libstd/path/windows.rs | 16 |
3 files changed, 37 insertions, 44 deletions
diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index 18f28994cba..ed0ce201750 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -70,7 +70,7 @@ use fmt; use iter::Iterator; use option::{Option, None, Some}; use str; -use str::{OwnedStr, Str, StrSlice}; +use str::{MaybeOwned, OwnedStr, Str, StrSlice, from_utf8_lossy}; use to_str::ToStr; use vec; use vec::{CloneableVector, OwnedCloneableVector, OwnedVector, Vector}; @@ -495,7 +495,7 @@ pub struct Display<'a, P> { impl<'a, P: GenericPath> fmt::Show for Display<'a, P> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.with_str(|s| f.pad(s)) + self.as_maybe_owned().as_slice().fmt(f) } } @@ -505,33 +505,25 @@ impl<'a, P: GenericPath> ToStr for Display<'a, P> { /// If the path is not UTF-8, invalid sequences with be replaced with the /// unicode replacement char. This involves allocation. fn to_str(&self) -> ~str { - if self.filename { - match self.path.filename() { - None => ~"", - Some(v) => str::from_utf8_lossy(v) - } - } else { - str::from_utf8_lossy(self.path.as_vec()) - } + self.as_maybe_owned().into_owned() } } impl<'a, P: GenericPath> Display<'a, P> { - /// Provides the path as a string to a closure + /// Returns the path as a possibly-owned string. /// /// If the path is not UTF-8, invalid sequences will be replaced with the /// unicode replacement char. This involves allocation. #[inline] - pub fn with_str<T>(&self, f: |&str| -> T) -> T { - let opt = if self.filename { self.path.filename_str() } - else { self.path.as_str() }; - match opt { - Some(s) => f(s), - None => { - let s = self.to_str(); - f(s.as_slice()) + pub fn as_maybe_owned(&self) -> MaybeOwned<'a> { + from_utf8_lossy(if self.filename { + match self.path.filename() { + None => &[], + Some(v) => v } - } + } else { + self.path.as_vec() + }) } } @@ -591,6 +583,23 @@ impl BytesContainer for CString { } } +impl<'a> BytesContainer for str::MaybeOwned<'a> { + #[inline] + fn container_as_bytes<'b>(&'b self) -> &'b [u8] { + self.as_slice().as_bytes() + } + #[inline] + fn container_into_owned_bytes(self) -> ~[u8] { + self.into_owned().into_bytes() + } + #[inline] + fn container_as_str<'b>(&'b self) -> Option<&'b str> { + Some(self.as_slice()) + } + #[inline] + fn is_str(_: Option<str::MaybeOwned>) -> bool { true } +} + #[inline(always)] fn contains_nul(v: &[u8]) -> bool { v.iter().any(|&x| x == 0) diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index 6970ebfb15d..f8e9d0ae344 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -564,24 +564,16 @@ mod tests { macro_rules! t( ($path:expr, $exp:expr) => ( { - let mut called = false; let path = Path::new($path); - path.display().with_str(|s| { - assert_eq!(s, $exp); - called = true; - }); - assert!(called); + let mo = path.display().as_maybe_owned(); + assert_eq!(mo.as_slice(), $exp); } ); ($path:expr, $exp:expr, filename) => ( { - let mut called = false; let path = Path::new($path); - path.filename_display().with_str(|s| { - assert_eq!(s, $exp); - called = true; - }); - assert!(called); + let mo = path.filename_display().as_maybe_owned(); + assert_eq!(mo.as_slice(), $exp); } ) ) diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 90154adb7fe..972b7d178a1 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -1278,20 +1278,12 @@ mod tests { let path = Path::new(b!("\\")); assert_eq!(path.filename_display().to_str(), ~""); - let mut called = false; let path = Path::new("foo"); - path.display().with_str(|s| { - assert_eq!(s, "foo"); - called = true; - }); - assert!(called); - called = false; + let mo = path.display().as_maybe_owned(); + assert_eq!(mo.as_slice(), "foo"); let path = Path::new(b!("\\")); - path.filename_display().with_str(|s| { - assert_eq!(s, ""); - called = true; - }); - assert!(called); + let mo = path.filename_display().as_maybe_owned(); + assert_eq!(mo.as_slice(), ""); } #[test] |
