diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 1aa47f066b69f..a2022a2eeb23c 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -19,8 +19,10 @@ use memchr; use ops; use os::raw::c_char; use ptr; +use rc::Rc; use slice; use str::{self, Utf8Error}; +use sync::Arc; use sys; /// A type representing an owned, C-compatible, nul-terminated string with no nul bytes in the @@ -704,6 +706,42 @@ impl From for Box { } } +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl From for Arc { + #[inline] + fn from(s: CString) -> Arc { + let arc: Arc<[u8]> = Arc::from(s.into_inner()); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const CStr) } + } +} + +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl<'a> From<&'a CStr> for Arc { + #[inline] + fn from(s: &CStr) -> Arc { + let arc: Arc<[u8]> = Arc::from(s.to_bytes_with_nul()); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const CStr) } + } +} + +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl From for Rc { + #[inline] + fn from(s: CString) -> Rc { + let rc: Rc<[u8]> = Rc::from(s.into_inner()); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const CStr) } + } +} + +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl<'a> From<&'a CStr> for Rc { + #[inline] + fn from(s: &CStr) -> Rc { + let rc: Rc<[u8]> = Rc::from(s.to_bytes_with_nul()); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const CStr) } + } +} + #[stable(feature = "default_box_extra", since = "1.17.0")] impl Default for Box { fn default() -> Box { @@ -1201,6 +1239,8 @@ mod tests { use borrow::Cow::{Borrowed, Owned}; use hash::{Hash, Hasher}; use collections::hash_map::DefaultHasher; + use rc::Rc; + use sync::Arc; #[test] fn c_to_rust() { @@ -1337,4 +1377,21 @@ mod tests { let boxed = >::default(); assert_eq!(boxed.to_bytes_with_nul(), &[0]); } + + #[test] + fn into_rc() { + let orig: &[u8] = b"Hello, world!\0"; + let cstr = CStr::from_bytes_with_nul(orig).unwrap(); + let rc: Rc = Rc::from(cstr); + let arc: Arc = Arc::from(cstr); + + assert_eq!(&*rc, cstr); + assert_eq!(&*arc, cstr); + + let rc2: Rc = Rc::from(cstr.to_owned()); + let arc2: Arc = Arc::from(cstr.to_owned()); + + assert_eq!(&*rc2, cstr); + assert_eq!(&*arc2, cstr); + } } diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 8c34660f821b7..cb902461f39fd 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -13,6 +13,8 @@ use fmt; use ops; use cmp; use hash::{Hash, Hasher}; +use rc::Rc; +use sync::Arc; use sys::os_str::{Buf, Slice}; use sys_common::{AsInner, IntoInner, FromInner}; @@ -592,6 +594,42 @@ impl From for Box { } } +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl From for Arc { + #[inline] + fn from(s: OsString) -> Arc { + let arc = s.inner.into_arc(); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) } + } +} + +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl<'a> From<&'a OsStr> for Arc { + #[inline] + fn from(s: &OsStr) -> Arc { + let arc = s.inner.into_arc(); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) } + } +} + +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl From for Rc { + #[inline] + fn from(s: OsString) -> Rc { + let rc = s.inner.into_rc(); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) } + } +} + +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl<'a> From<&'a OsStr> for Rc { + #[inline] + fn from(s: &OsStr) -> Rc { + let rc = s.inner.into_rc(); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) } + } +} + #[stable(feature = "box_default_extra", since = "1.17.0")] impl Default for Box { fn default() -> Box { @@ -793,6 +831,9 @@ mod tests { use super::*; use sys_common::{AsInner, IntoInner}; + use rc::Rc; + use sync::Arc; + #[test] fn test_os_string_with_capacity() { let os_string = OsString::with_capacity(0); @@ -935,4 +976,21 @@ mod tests { assert_eq!(os_str, os_string); assert!(os_string.capacity() >= 123); } + + #[test] + fn into_rc() { + let orig = "Hello, world!"; + let os_str = OsStr::new(orig); + let rc: Rc = Rc::from(os_str); + let arc: Arc = Arc::from(os_str); + + assert_eq!(&*rc, os_str); + assert_eq!(&*arc, os_str); + + let rc2: Rc = Rc::from(os_str.to_owned()); + let arc2: Arc = Arc::from(os_str.to_owned()); + + assert_eq!(&*rc2, os_str); + assert_eq!(&*arc2, os_str); + } } diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 4e35cf840de96..eb125a4737a1c 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -86,6 +86,8 @@ use hash::{Hash, Hasher}; use io; use iter::{self, FusedIterator}; use ops::{self, Deref}; +use rc::Rc; +use sync::Arc; use ffi::{OsStr, OsString}; @@ -1452,6 +1454,42 @@ impl<'a> From for Cow<'a, Path> { } } +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl From for Arc { + #[inline] + fn from(s: PathBuf) -> Arc { + let arc: Arc = Arc::from(s.into_os_string()); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Path) } + } +} + +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl<'a> From<&'a Path> for Arc { + #[inline] + fn from(s: &Path) -> Arc { + let arc: Arc = Arc::from(s.as_os_str()); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Path) } + } +} + +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl From for Rc { + #[inline] + fn from(s: PathBuf) -> Rc { + let rc: Rc = Rc::from(s.into_os_string()); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Path) } + } +} + +#[stable(feature = "shared_from_slice2", since = "1.23.0")] +impl<'a> From<&'a Path> for Rc { + #[inline] + fn from(s: &Path) -> Rc { + let rc: Rc = Rc::from(s.as_os_str()); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Path) } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl ToOwned for Path { type Owned = PathBuf; @@ -2568,6 +2606,9 @@ impl Error for StripPrefixError { mod tests { use super::*; + use rc::Rc; + use sync::Arc; + macro_rules! t( ($path:expr, iter: $iter:expr) => ( { @@ -3970,4 +4011,21 @@ mod tests { assert_eq!(format!("a{:#<5}b", Path::new("").display()), "a#####b"); assert_eq!(format!("a{:#<5}b", Path::new("a").display()), "aa####b"); } + + #[test] + fn into_rc() { + let orig = "hello/world"; + let path = Path::new(orig); + let rc: Rc = Rc::from(path); + let arc: Arc = Arc::from(path); + + assert_eq!(&*rc, path); + assert_eq!(&*arc, path); + + let rc2: Rc = Rc::from(path.to_owned()); + let arc2: Arc = Arc::from(path.to_owned()); + + assert_eq!(&*rc2, path); + assert_eq!(&*arc2, path); + } } diff --git a/src/libstd/sys/redox/os_str.rs b/src/libstd/sys/redox/os_str.rs index c54286353a92f..5c40d42fa0a44 100644 --- a/src/libstd/sys/redox/os_str.rs +++ b/src/libstd/sys/redox/os_str.rs @@ -15,6 +15,8 @@ use borrow::Cow; use fmt; use str; use mem; +use rc::Rc; +use sync::Arc; use sys_common::{AsInner, IntoInner}; use std_unicode::lossy::Utf8Lossy; @@ -123,6 +125,16 @@ impl Buf { let inner: Box<[u8]> = unsafe { mem::transmute(boxed) }; Buf { inner: inner.into_vec() } } + + #[inline] + pub fn into_arc(&self) -> Arc { + self.as_slice().into_arc() + } + + #[inline] + pub fn into_rc(&self) -> Rc { + self.as_slice().into_rc() + } } impl Slice { @@ -156,4 +168,16 @@ impl Slice { let boxed: Box<[u8]> = Default::default(); unsafe { mem::transmute(boxed) } } + + #[inline] + pub fn into_arc(&self) -> Arc { + let arc: Arc<[u8]> = Arc::from(&self.inner); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) } + } + + #[inline] + pub fn into_rc(&self) -> Rc { + let rc: Rc<[u8]> = Rc::from(&self.inner); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) } + } } diff --git a/src/libstd/sys/unix/os_str.rs b/src/libstd/sys/unix/os_str.rs index 777db17e3e164..a27e76a0e3bcc 100644 --- a/src/libstd/sys/unix/os_str.rs +++ b/src/libstd/sys/unix/os_str.rs @@ -15,6 +15,8 @@ use borrow::Cow; use fmt; use str; use mem; +use rc::Rc; +use sync::Arc; use sys_common::{AsInner, IntoInner}; use std_unicode::lossy::Utf8Lossy; @@ -123,6 +125,16 @@ impl Buf { let inner: Box<[u8]> = unsafe { mem::transmute(boxed) }; Buf { inner: inner.into_vec() } } + + #[inline] + pub fn into_arc(&self) -> Arc { + self.as_slice().into_arc() + } + + #[inline] + pub fn into_rc(&self) -> Rc { + self.as_slice().into_rc() + } } impl Slice { @@ -156,4 +168,16 @@ impl Slice { let boxed: Box<[u8]> = Default::default(); unsafe { mem::transmute(boxed) } } + + #[inline] + pub fn into_arc(&self) -> Arc { + let arc: Arc<[u8]> = Arc::from(&self.inner); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) } + } + + #[inline] + pub fn into_rc(&self) -> Rc { + let rc: Rc<[u8]> = Rc::from(&self.inner); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) } + } } diff --git a/src/libstd/sys/wasm/os_str.rs b/src/libstd/sys/wasm/os_str.rs index c5908a7a8dc22..0e64b5bc6b8fb 100644 --- a/src/libstd/sys/wasm/os_str.rs +++ b/src/libstd/sys/wasm/os_str.rs @@ -15,6 +15,8 @@ use borrow::Cow; use fmt; use str; use mem; +use rc::Rc; +use sync::Arc; use sys_common::{AsInner, IntoInner}; use std_unicode::lossy::Utf8Lossy; @@ -123,6 +125,16 @@ impl Buf { let inner: Box<[u8]> = unsafe { mem::transmute(boxed) }; Buf { inner: inner.into_vec() } } + + #[inline] + pub fn into_arc(&self) -> Arc { + self.as_slice().into_arc() + } + + #[inline] + pub fn into_rc(&self) -> Rc { + self.as_slice().into_rc() + } } impl Slice { @@ -156,4 +168,16 @@ impl Slice { let boxed: Box<[u8]> = Default::default(); unsafe { mem::transmute(boxed) } } + + #[inline] + pub fn into_arc(&self) -> Arc { + let arc: Arc<[u8]> = Arc::from(&self.inner); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) } + } + + #[inline] + pub fn into_rc(&self) -> Rc { + let rc: Rc<[u8]> = Rc::from(&self.inner); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) } + } } diff --git a/src/libstd/sys/windows/os_str.rs b/src/libstd/sys/windows/os_str.rs index 3eb4582718b51..b8d2f7bc53ce7 100644 --- a/src/libstd/sys/windows/os_str.rs +++ b/src/libstd/sys/windows/os_str.rs @@ -15,6 +15,8 @@ use borrow::Cow; use fmt; use sys_common::wtf8::{Wtf8, Wtf8Buf}; use mem; +use rc::Rc; +use sync::Arc; use sys_common::{AsInner, IntoInner}; #[derive(Clone, Hash)] @@ -115,6 +117,16 @@ impl Buf { let inner: Box = unsafe { mem::transmute(boxed) }; Buf { inner: Wtf8Buf::from_box(inner) } } + + #[inline] + pub fn into_arc(&self) -> Arc { + self.as_slice().into_arc() + } + + #[inline] + pub fn into_rc(&self) -> Rc { + self.as_slice().into_rc() + } } impl Slice { @@ -144,4 +156,16 @@ impl Slice { pub fn empty_box() -> Box { unsafe { mem::transmute(Wtf8::empty_box()) } } + + #[inline] + pub fn into_arc(&self) -> Arc { + let arc = self.inner.into_arc(); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) } + } + + #[inline] + pub fn into_rc(&self) -> Rc { + let rc = self.inner.into_rc(); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) } + } } diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs index b89a73cd28a09..e212b5006f2d1 100644 --- a/src/libstd/sys_common/wtf8.rs +++ b/src/libstd/sys_common/wtf8.rs @@ -35,8 +35,10 @@ use hash::{Hash, Hasher}; use iter::FromIterator; use mem; use ops; +use rc::Rc; use slice; use str; +use sync::Arc; use sys_common::AsInner; const UTF8_REPLACEMENT_CHARACTER: &'static str = "\u{FFFD}"; @@ -641,6 +643,18 @@ impl Wtf8 { let boxed: Box<[u8]> = Default::default(); unsafe { mem::transmute(boxed) } } + + #[inline] + pub fn into_arc(&self) -> Arc { + let arc: Arc<[u8]> = Arc::from(&self.bytes); + unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Wtf8) } + } + + #[inline] + pub fn into_rc(&self) -> Rc { + let rc: Rc<[u8]> = Rc::from(&self.bytes); + unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Wtf8) } + } }