Add an unstable constructor for creating `Rc<str>` from `str`
This commit is contained in:
parent
a29c49f5cc
commit
ef3a6a8ee6
|
@ -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<T: ?Sized> {
|
||||
strong: Cell<usize>,
|
||||
|
@ -365,6 +366,30 @@ impl<T> Rc<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl Rc<str> {
|
||||
/// Constructs a new `Rc<str>` 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<str> {
|
||||
unsafe {
|
||||
// Allocate enough space for `RcBox<str>`.
|
||||
let aligned_len = (value.len() + size_of::<usize>() - 1) / size_of::<usize>();
|
||||
let vec = RawVec::<usize>::with_capacity(2 + aligned_len);
|
||||
let ptr = vec.ptr();
|
||||
forget(vec);
|
||||
// Initialize fields of `RcBox<str>`.
|
||||
*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<T: ?Sized> Rc<T> {
|
||||
/// Creates a new [`Weak`][weak] pointer to this value.
|
||||
///
|
||||
|
|
Loading…
Reference in New Issue