From ef3a6a8ee6e0c38def279df77885fc8b995d9635 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 12 Oct 2016 20:54:41 +0300 Subject: Add an unstable constructor for creating `Rc` from `str` --- src/liballoc/rc.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'src/liballoc') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 699f777138d..18a345630d1 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -230,13 +230,14 @@ use core::hash::{Hash, Hasher}; use core::intrinsics::{abort, assume}; use core::marker; use core::marker::Unsize; -use core::mem::{self, align_of_val, forget, size_of_val, uninitialized}; +use core::mem::{self, align_of_val, forget, size_of, size_of_val, uninitialized}; use core::ops::Deref; use core::ops::CoerceUnsized; use core::ptr::{self, Shared}; use core::convert::From; use heap::deallocate; +use raw_vec::RawVec; struct RcBox { strong: Cell, @@ -365,6 +366,30 @@ impl Rc { } } +impl Rc { + /// Constructs a new `Rc` from a string slice. + #[doc(hidden)] + #[unstable(feature = "rustc_private", + reason = "for internal use in rustc", + issue = "0")] + pub fn __from_str(value: &str) -> Rc { + unsafe { + // Allocate enough space for `RcBox`. + let aligned_len = (value.len() + size_of::() - 1) / size_of::(); + let vec = RawVec::::with_capacity(2 + aligned_len); + let ptr = vec.ptr(); + forget(vec); + // Initialize fields of `RcBox`. + *ptr.offset(0) = 1; // strong: Cell::new(1) + *ptr.offset(1) = 1; // weak: Cell::new(1) + ptr::copy_nonoverlapping(value.as_ptr(), ptr.offset(2) as *mut u8, value.len()); + // Combine the allocation address and the string length into a fat pointer to `RcBox`. + let rcbox_ptr = mem::transmute([ptr as usize, value.len()]); + Rc { ptr: Shared::new(rcbox_ptr) } + } + } +} + impl Rc { /// Creates a new [`Weak`][weak] pointer to this value. /// -- cgit 1.4.1-3-g733a5