diff options
| author | Kevin Ballard <kevin@sb.org> | 2014-02-07 16:36:59 -0800 |
|---|---|---|
| committer | Kevin Ballard <kevin@sb.org> | 2014-02-07 22:31:52 -0800 |
| commit | 086c0dd33febb752b036fba62dcfb8aa22a51642 (patch) | |
| tree | 2543a402c3d2ce04b4d7cd7e8c60da6c5fb40371 /src/libstd | |
| parent | 122c94d2f3909a06a5dd172b423b9b56a2f17039 (diff) | |
| download | rust-086c0dd33febb752b036fba62dcfb8aa22a51642.tar.gz rust-086c0dd33febb752b036fba62dcfb8aa22a51642.zip | |
Delete send_str, rewrite clients on top of MaybeOwned<'static>
Declare a `type SendStr = MaybeOwned<'static>` to ease readibility of types that needed the old SendStr behavior. Implement all the traits for MaybeOwned that SendStr used to implement.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/lib.rs | 1 | ||||
| -rw-r--r-- | src/libstd/prelude.rs | 3 | ||||
| -rw-r--r-- | src/libstd/rt/task.rs | 2 | ||||
| -rw-r--r-- | src/libstd/send_str.rs | 246 | ||||
| -rw-r--r-- | src/libstd/str.rs | 297 | ||||
| -rw-r--r-- | src/libstd/task.rs | 9 |
6 files changed, 240 insertions, 318 deletions
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 0398af9c1c1..7b574d68e78 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -117,7 +117,6 @@ pub mod vec_ng; pub mod str; pub mod ascii; -pub mod send_str; pub mod ptr; pub mod owned; diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index b08d792822b..f113b2f17eb 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -63,8 +63,7 @@ pub use num::{Primitive, Int, Float, ToStrRadix, ToPrimitive, FromPrimitive}; pub use path::{GenericPath, Path, PosixPath, WindowsPath}; pub use ptr::RawPtr; pub use io::{Buffer, Writer, Reader, Seek}; -pub use send_str::{SendStr, SendStrOwned, SendStrStatic, IntoSendStr}; -pub use str::{Str, StrVector, StrSlice, OwnedStr}; +pub use str::{Str, StrVector, StrSlice, OwnedStr, IntoMaybeOwned}; pub use to_bytes::IterBytes; pub use to_str::{ToStr, IntoStr}; pub use tuple::{CloneableTuple, ImmutableTuple}; diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index fbe82531f69..a7648dd2d19 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -30,7 +30,7 @@ use rt::local::Local; use rt::local_heap::LocalHeap; use rt::rtio::LocalIo; use rt::unwind::Unwinder; -use send_str::SendStr; +use str::SendStr; use sync::arc::UnsafeArc; use sync::atomics::{AtomicUint, SeqCst}; use task::{TaskResult, TaskOpts}; diff --git a/src/libstd/send_str.rs b/src/libstd/send_str.rs deleted file mode 100644 index b075b75b70a..00000000000 --- a/src/libstd/send_str.rs +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! The `SendStr` trait for optionally static strings - -use clone::{Clone, DeepClone}; -use cmp::{Eq, TotalEq, Ord, TotalOrd, Equiv}; -use cmp::Ordering; -use container::Container; -use default::Default; -use str::{Str, StrSlice}; -use to_str::ToStr; -use to_bytes::{IterBytes, Cb}; - -/// A SendStr is a string that can hold either a ~str or a &'static str. -/// This can be useful as an optimization when an allocation is sometimes -/// needed but the common case is statically known. -#[allow(missing_doc)] -pub enum SendStr { - SendStrOwned(~str), - SendStrStatic(&'static str) -} - -impl SendStr { - /// Returns `true` if this `SendStr` wraps an owned string - #[inline] - pub fn is_owned(&self) -> bool { - match *self { - SendStrOwned(_) => true, - SendStrStatic(_) => false - } - } - - /// Returns `true` if this `SendStr` wraps a static string - #[inline] - pub fn is_static(&self) -> bool { - match *self { - SendStrOwned(_) => false, - SendStrStatic(_) => true - } - } -} - -/// Trait for moving into an `SendStr` -pub trait IntoSendStr { - /// Moves self into an `SendStr` - fn into_send_str(self) -> SendStr; -} - -impl IntoSendStr for ~str { - #[inline] - fn into_send_str(self) -> SendStr { SendStrOwned(self) } -} - -impl IntoSendStr for &'static str { - #[inline] - fn into_send_str(self) -> SendStr { SendStrStatic(self) } -} - -impl IntoSendStr for SendStr { - #[inline] - fn into_send_str(self) -> SendStr { self } -} - -/* -Section: String trait impls. -`SendStr` should behave like a normal string, so we don't derive. -*/ - -impl ToStr for SendStr { - #[inline] - fn to_str(&self) -> ~str { self.as_slice().to_owned() } -} - -impl Eq for SendStr { - #[inline] - fn eq(&self, other: &SendStr) -> bool { - self.as_slice().equals(&other.as_slice()) - } -} - -impl TotalEq for SendStr { - #[inline] - fn equals(&self, other: &SendStr) -> bool { - self.as_slice().equals(&other.as_slice()) - } -} - -impl Ord for SendStr { - #[inline] - fn lt(&self, other: &SendStr) -> bool { - self.as_slice().lt(&other.as_slice()) - } -} - -impl TotalOrd for SendStr { - #[inline] - fn cmp(&self, other: &SendStr) -> Ordering { - self.as_slice().cmp(&other.as_slice()) - } -} - -impl<'a, S: Str> Equiv<S> for SendStr { - #[inline] - fn equiv(&self, other: &S) -> bool { - self.as_slice().equals(&other.as_slice()) - } -} - -impl Str for SendStr { - #[inline] - fn as_slice<'r>(&'r self) -> &'r str { - match *self { - SendStrOwned(ref s) => s.as_slice(), - // FIXME: Borrowchecker doesn't recognize lifetime as static unless prompted - // SendStrStatic(s) => s.as_slice() - SendStrStatic(s) => {let tmp: &'static str = s; tmp} - } - } - - #[inline] - fn into_owned(self) -> ~str { - match self { - SendStrOwned(s) => s, - SendStrStatic(s) => s.to_owned() - } - } -} - -impl Container for SendStr { - #[inline] - fn len(&self) -> uint { self.as_slice().len() } -} - -impl Clone for SendStr { - #[inline] - fn clone(&self) -> SendStr { - match *self { - SendStrOwned(ref s) => SendStrOwned(s.to_owned()), - SendStrStatic(s) => SendStrStatic(s) - } - } -} - -impl DeepClone for SendStr { - #[inline] - fn deep_clone(&self) -> SendStr { - match *self { - SendStrOwned(ref s) => SendStrOwned(s.to_owned()), - SendStrStatic(s) => SendStrStatic(s) - } - } -} - -impl Default for SendStr { - #[inline] - fn default() -> SendStr { SendStrStatic("") } -} - -impl IterBytes for SendStr { - #[inline] - fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { - match *self { - SendStrOwned(ref s) => s.iter_bytes(lsb0, f), - SendStrStatic(s) => s.iter_bytes(lsb0, f) - } - } -} - -#[cfg(test)] -mod tests { - use prelude::*; - use send_str::{SendStrOwned, SendStrStatic}; - - #[test] - fn test_send_str_traits() { - let s = SendStrStatic("abcde"); - assert_eq!(s.len(), 5); - assert_eq!(s.as_slice(), "abcde"); - assert_eq!(s.to_str(), ~"abcde"); - assert!(s.lt(&SendStrOwned(~"bcdef"))); - assert_eq!(SendStrStatic(""), Default::default()); - - let o = SendStrOwned(~"abcde"); - assert_eq!(o.len(), 5); - assert_eq!(o.as_slice(), "abcde"); - assert_eq!(o.to_str(), ~"abcde"); - assert!(o.lt(&SendStrStatic("bcdef"))); - assert_eq!(SendStrOwned(~""), Default::default()); - - assert_eq!(s.cmp(&o), Equal); - assert!(s.equals(&o)); - assert!(s.equiv(&o)); - - assert_eq!(o.cmp(&s), Equal); - assert!(o.equals(&s)); - assert!(o.equiv(&s)); - } - - #[test] - fn test_send_str_methods() { - let s = SendStrStatic("abcde"); - assert!(s.is_static()); - assert!(!s.is_owned()); - - let o = SendStrOwned(~"abcde"); - assert!(!o.is_static()); - assert!(o.is_owned()); - } - - #[test] - fn test_send_str_clone() { - assert_eq!(SendStrOwned(~"abcde"), SendStrStatic("abcde").clone()); - assert_eq!(SendStrOwned(~"abcde"), SendStrStatic("abcde").deep_clone()); - - assert_eq!(SendStrOwned(~"abcde"), SendStrOwned(~"abcde").clone()); - assert_eq!(SendStrOwned(~"abcde"), SendStrOwned(~"abcde").deep_clone()); - - assert_eq!(SendStrStatic("abcde"), SendStrStatic("abcde").clone()); - assert_eq!(SendStrStatic("abcde"), SendStrStatic("abcde").deep_clone()); - - assert_eq!(SendStrStatic("abcde"), SendStrOwned(~"abcde").clone()); - assert_eq!(SendStrStatic("abcde"), SendStrOwned(~"abcde").deep_clone()); - } - - #[test] - fn test_send_str_into_owned() { - assert_eq!(SendStrStatic("abcde").into_owned(), ~"abcde"); - assert_eq!(SendStrOwned(~"abcde").into_owned(), ~"abcde"); - } - - #[test] - fn test_into_send_str() { - assert_eq!("abcde".into_send_str(), SendStrStatic("abcde")); - assert_eq!((~"abcde").into_send_str(), SendStrStatic("abcde")); - assert_eq!("abcde".into_send_str(), SendStrOwned(~"abcde")); - assert_eq!((~"abcde").into_send_str(), SendStrOwned(~"abcde")); - } -} diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 204139c5d78..3225bb3a678 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -86,7 +86,9 @@ use cast::transmute; use char; use char::Char; use clone::{Clone, DeepClone}; +use cmp::{Eq, TotalEq, Ord, TotalOrd, Equiv, Ordering}; use container::{Container, Mutable}; +use fmt; use iter::{Iterator, FromIterator, Extendable, range}; use iter::{Filter, AdditiveIterator, Map}; use iter::{Rev, DoubleEndedIterator, ExactSize}; @@ -100,7 +102,7 @@ use from_str::FromStr; use vec; use vec::{OwnedVector, OwnedCloneableVector, ImmutableVector, MutableVector}; use default::Default; -use send_str::{SendStr, SendStrOwned}; +use to_bytes::{IterBytes, Cb}; use unstable::raw::Repr; /* @@ -915,53 +917,6 @@ macro_rules! utf8_acc_cont_byte( static TAG_CONT_U8: u8 = 128u8; -/// Enum that represents either a borrowed or an owned string. -#[deriving(Eq,Clone)] -pub enum MaybeOwned<'a> { - /// A borrowed string - Slice(&'a str), - /// An owned string - Owned(~str) -} - -impl<'a> Str for MaybeOwned<'a> { - #[inline] - fn as_slice<'b>(&'b self) -> &'b str { - match *self { - Slice(s) => s, - Owned(ref s) => s.as_slice() - } - } - - #[inline] - fn into_owned(self) -> ~str { - match self { - Slice(s) => s.to_owned(), - Owned(s) => s - } - } -} - -impl<'a> ToStr for MaybeOwned<'a> { - #[inline] - fn to_str(&self) -> ~str { - match *self { - Slice(s) => s.to_str(), - Owned(ref s) => s.clone() - } - } -} - -impl<'a> ::fmt::Show for MaybeOwned<'a> { - #[inline] - fn fmt(mo: &MaybeOwned, f: &mut ::fmt::Formatter) -> ::fmt::Result { - match *mo { - Slice(ref s) => ::fmt::Show::fmt(s, f), - Owned(ref s) => ::fmt::Show::fmt(&s.as_slice(), f) - } - } -} - /// Converts a vector of bytes to a new utf-8 string. /// Any invalid utf-8 sequences are replaced with U+FFFD REPLACEMENT CHARACTER. /// @@ -1083,6 +1038,172 @@ pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> MaybeOwned<'a> { Owned(res) } +/* +Section: MaybeOwned +*/ + +/// A MaybeOwned is a string that can hold either a ~str or a &str. +/// This can be useful as an optimization when an allocation is sometimes +/// needed but not always. +pub enum MaybeOwned<'a> { + /// A borrowed string + Slice(&'a str), + /// An owned string + Owned(~str) +} + +/// SendStr is a specialization of `MaybeOwned` to be sendable +pub type SendStr = MaybeOwned<'static>; + +impl<'a> MaybeOwned<'a> { + /// Returns `true` if this `MaybeOwned` wraps an owned string + #[inline] + pub fn is_owned(&self) -> bool { + match *self { + Slice(_) => false, + Owned(_) => true + } + } + + /// Returns `true` if this `MaybeOwned` wraps a borrowed string + #[inline] + pub fn is_slice(&self) -> bool { + match *self { + Slice(_) => true, + Owned(_) => false + } + } +} + +/// Trait for moving into a `MaybeOwned` +pub trait IntoMaybeOwned<'a> { + /// Moves self into a `MaybeOwned` + fn into_maybe_owned(self) -> MaybeOwned<'a>; +} + +impl<'a> IntoMaybeOwned<'a> for ~str { + #[inline] + fn into_maybe_owned(self) -> MaybeOwned<'a> { Owned(self) } +} + +impl<'a> IntoMaybeOwned<'a> for &'a str { + #[inline] + fn into_maybe_owned(self) -> MaybeOwned<'a> { Slice(self) } +} + +impl<'a> IntoMaybeOwned<'a> for MaybeOwned<'a> { + #[inline] + fn into_maybe_owned(self) -> MaybeOwned<'a> { self } +} + +impl<'a> ToStr for MaybeOwned<'a> { + #[inline] + fn to_str(&self) -> ~str { self.as_slice().to_owned() } +} + +impl<'a> Eq for MaybeOwned<'a> { + #[inline] + fn eq(&self, other: &MaybeOwned) -> bool { + self.as_slice().equals(&other.as_slice()) + } +} + +impl<'a> TotalEq for MaybeOwned<'a> { + #[inline] + fn equals(&self, other: &MaybeOwned) -> bool { + self.as_slice().equals(&other.as_slice()) + } +} + +impl<'a> Ord for MaybeOwned<'a> { + #[inline] + fn lt(&self, other: &MaybeOwned) -> bool { + self.as_slice().lt(&other.as_slice()) + } +} + +impl<'a> TotalOrd for MaybeOwned<'a> { + #[inline] + fn cmp(&self, other: &MaybeOwned) -> Ordering { + self.as_slice().cmp(&other.as_slice()) + } +} + +impl<'a, S: Str> Equiv<S> for MaybeOwned<'a> { + #[inline] + fn equiv(&self, other: &S) -> bool { + self.as_slice().equals(&other.as_slice()) + } +} + +impl<'a> Str for MaybeOwned<'a> { + #[inline] + fn as_slice<'b>(&'b self) -> &'b str { + match *self { + Slice(s) => s, + Owned(ref s) => s.as_slice() + } + } + + #[inline] + fn into_owned(self) -> ~str { + match self { + Slice(s) => s.to_owned(), + Owned(s) => s + } + } +} + +impl<'a> Container for MaybeOwned<'a> { + #[inline] + fn len(&self) -> uint { self.as_slice().len() } +} + +impl<'a> Clone for MaybeOwned<'a> { + #[inline] + fn clone(&self) -> MaybeOwned<'a> { + match *self { + Slice(s) => Slice(s), + Owned(ref s) => Owned(s.to_owned()) + } + } +} + +impl<'a> DeepClone for MaybeOwned<'a> { + #[inline] + fn deep_clone(&self) -> MaybeOwned<'a> { + match *self { + Slice(s) => Slice(s), + Owned(ref s) => Owned(s.to_owned()) + } + } +} + +impl<'a> Default for MaybeOwned<'a> { + #[inline] + fn default() -> MaybeOwned<'a> { Slice("") } +} + +impl<'a> IterBytes for MaybeOwned<'a> { + #[inline] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + match *self { + Slice(s) => s.iter_bytes(lsb0, f), + Owned(ref s) => s.iter_bytes(lsb0, f) + } + } +} + +impl<'a> fmt::Show for MaybeOwned<'a> { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Slice(ref s) => s.fmt(f), + Owned(ref s) => s.fmt(f) + } + } +} + /// Unsafe operations pub mod raw { use cast; @@ -1837,9 +1958,6 @@ pub trait StrSlice<'a> { /// Converts to a vector of `u16` encoded as UTF-16. fn to_utf16(&self) -> ~[u16]; - /// Copy a slice into a new `SendStr`. - fn to_send_str(&self) -> SendStr; - /// Check that `index`-th byte lies at the start and/or end of a /// UTF-8 code point sequence. /// @@ -2365,11 +2483,6 @@ impl<'a> StrSlice<'a> for &'a str { } #[inline] - fn to_send_str(&self) -> SendStr { - SendStrOwned(self.to_owned()) - } - - #[inline] fn is_char_boundary(&self, index: uint) -> bool { if index == self.len() { return true; } let b = self[index]; @@ -2808,7 +2921,6 @@ mod tests { use prelude::*; use ptr; use str::*; - use send_str::{SendStrOwned, SendStrStatic}; #[test] fn test_eq() { @@ -4039,16 +4151,75 @@ mod tests { } #[test] - fn test_to_send_str() { - assert_eq!("abcde".to_send_str(), SendStrStatic("abcde")); - assert_eq!("abcde".to_send_str(), SendStrOwned(~"abcde")); - } - - #[test] fn test_from_str() { let owned: Option<~str> = from_str(&"string"); assert_eq!(owned, Some(~"string")); } + + #[test] + fn test_maybe_owned_traits() { + let s = Slice("abcde"); + assert_eq!(s.len(), 5); + assert_eq!(s.as_slice(), "abcde"); + assert_eq!(s.to_str(), ~"abcde"); + assert!(s.lt(&Owned(~"bcdef"))); + assert_eq!(Slice(""), Default::default()); + + let o = Owned(~"abcde"); + assert_eq!(o.len(), 5); + assert_eq!(o.as_slice(), "abcde"); + assert_eq!(o.to_str(), ~"abcde"); + assert!(o.lt(&Slice("bcdef"))); + assert_eq!(Owned(~""), Default::default()); + + assert_eq!(s.cmp(&o), Equal); + assert!(s.equals(&o)); + assert!(s.equiv(&o)); + + assert_eq!(o.cmp(&s), Equal); + assert!(o.equals(&s)); + assert!(o.equiv(&s)); + } + + #[test] + fn test_maybe_owned_methods() { + let s = Slice("abcde"); + assert!(s.is_slice()); + assert!(!s.is_owned()); + + let o = Owned(~"abcde"); + assert!(!o.is_slice()); + assert!(o.is_owned()); + } + + #[test] + fn test_maybe_owned_clone() { + assert_eq!(Owned(~"abcde"), Slice("abcde").clone()); + assert_eq!(Owned(~"abcde"), Slice("abcde").deep_clone()); + + assert_eq!(Owned(~"abcde"), Owned(~"abcde").clone()); + assert_eq!(Owned(~"abcde"), Owned(~"abcde").deep_clone()); + + assert_eq!(Slice("abcde"), Slice("abcde").clone()); + assert_eq!(Slice("abcde"), Slice("abcde").deep_clone()); + + assert_eq!(Slice("abcde"), Owned(~"abcde").clone()); + assert_eq!(Slice("abcde"), Owned(~"abcde").deep_clone()); + } + + #[test] + fn test_maybe_owned_into_owned() { + assert_eq!(Slice("abcde").into_owned(), ~"abcde"); + assert_eq!(Owned(~"abcde").into_owned(), ~"abcde"); + } + + #[test] + fn test_into_maybe_owned() { + assert_eq!("abcde".into_maybe_owned(), Slice("abcde")); + assert_eq!((~"abcde").into_maybe_owned(), Slice("abcde")); + assert_eq!("abcde".into_maybe_owned(), Owned(~"abcde")); + assert_eq!((~"abcde").into_maybe_owned(), Owned(~"abcde")); + } } #[cfg(test)] diff --git a/src/libstd/task.rs b/src/libstd/task.rs index 078933be78f..921d0feaa8b 100644 --- a/src/libstd/task.rs +++ b/src/libstd/task.rs @@ -62,8 +62,7 @@ use option::{None, Some, Option}; use result::{Result, Ok, Err}; use rt::local::Local; use rt::task::Task; -use send_str::{SendStr, IntoSendStr}; -use str::Str; +use str::{Str, SendStr, IntoMaybeOwned}; #[cfg(test)] use any::{AnyOwnExt, AnyRefExt}; #[cfg(test)] use comm::SharedChan; @@ -190,8 +189,8 @@ impl TaskBuilder { /// Name the task-to-be. Currently the name is used for identification /// only in failure messages. - pub fn name<S: IntoSendStr>(&mut self, name: S) { - self.opts.name = Some(name.into_send_str()); + pub fn name<S: IntoMaybeOwned<'static>>(&mut self, name: S) { + self.opts.name = Some(name.into_maybe_owned()); } /** @@ -396,7 +395,7 @@ fn test_static_named_task() { #[test] fn test_send_named_task() { let mut t = task(); - t.name("ada lovelace".into_send_str()); + t.name("ada lovelace".into_maybe_owned()); t.spawn(proc() { with_task_name(|name| { assert!(name.unwrap() == "ada lovelace"); |
