Expand description
A wrapper around the decomposed parts of a Vec<T>
.
This struct contains the Vec
’s internal pointer, length, and allocated
capacity.
RawParts
makes Vec::from_raw_parts
and Vec::into_raw_parts
easier
to use by giving names to the returned values. This prevents errors from
mixing up the two usize
values of length and capacity.
Examples
use raw_parts::RawParts;
let v: Vec<i32> = vec![-1, 0, 1];
let RawParts { ptr, length, capacity } = RawParts::from_vec(v);
let rebuilt = unsafe {
// We can now make changes to the components, such as
// transmuting the raw pointer to a compatible type.
let ptr = ptr as *mut u32;
let raw_parts = RawParts { ptr, length, capacity };
RawParts::into_vec(raw_parts)
};
assert_eq!(rebuilt, [4294967295, 0, 1]);
Fields
ptr: *mut T
A non-null pointer to a buffer of T
.
This pointer is the same as the value returned by Vec::as_mut_ptr
in
the source vector.
length: usize
The number of elements in the source vector, also referred to as its “length”.
This value is the same as the value returned by Vec::len
in the
source vector.
capacity: usize
The number of elements the source vector can hold without reallocating.
This value is the same as the value returned by Vec::capacity
in the
source vector.
Implementations
sourceimpl<T> RawParts<T>
impl<T> RawParts<T>
sourcepub fn from_vec(vec: Vec<T>) -> RawParts<T>
pub fn from_vec(vec: Vec<T>) -> RawParts<T>
Construct the raw components of a Vec<T>
by decomposing it.
Returns a struct containing the raw pointer to the underlying data, the length of the vector (in elements), and the allocated capacity of the data (in elements).
After calling this function, the caller is responsible for the memory
previously managed by the Vec
. The only way to do this is to convert
the raw pointer, length, and capacity back into a Vec
with the
Vec::from_raw_parts
function or the into_vec
function, allowing
the destructor to perform the cleanup.
Examples
use raw_parts::RawParts;
let v: Vec<i32> = vec![-1, 0, 1];
let RawParts { ptr, length, capacity } = RawParts::from_vec(v);
let rebuilt = unsafe {
// We can now make changes to the components, such as
// transmuting the raw pointer to a compatible type.
let ptr = ptr as *mut u32;
let raw_parts = RawParts { ptr, length, capacity };
RawParts::into_vec(raw_parts)
};
assert_eq!(rebuilt, [4294967295, 0, 1]);
sourcepub unsafe fn into_vec(this: Self) -> Vec<T>
pub unsafe fn into_vec(this: Self) -> Vec<T>
Creates a Vec<T>
directly from the raw components of another vector.
This function is declared as an associated function and must be called
as RawParts::into_vec(raw_parts)
.
Safety
This function has the same safety invariants as Vec::from_raw_parts
,
which are repeated in the following paragraphs.
This is highly unsafe, due to the number of invariants that aren’t checked:
ptr
needs to have been previously allocated viaString
/Vec<T>
(at least, it’s highly likely to be incorrect if it wasn’t).T
needs to have the same size and alignment as whatptr
was allocated with. (T
having a less strict alignment is not sufficient, the alignment really needs to be equal to satisfy thedealloc
requirement that memory must be allocated and deallocated with the same layout.)length
needs to be less than or equal tocapacity
.capacity
needs to be the capacity that the pointer was allocated with.
Violating these may cause problems like corrupting the allocator’s
internal data structures. For example it is not safe
to build a Vec<u8>
from a pointer to a C char
array with length size_t
.
It’s also not safe to build one from a Vec<u16>
and its length, because
the allocator cares about the alignment, and these two types have different
alignments. The buffer was allocated with alignment 2 (for u16
), but after
turning it into a Vec<u8>
it’ll be deallocated with alignment 1.
The ownership of ptr
is effectively transferred to the
Vec<T>
which may then deallocate, reallocate or change the
contents of memory pointed to by the pointer at will. Ensure
that nothing else uses the pointer after calling this
function.
Examples
use core::ptr;
use core::mem;
use raw_parts::RawParts;
let v = vec![1, 2, 3];
// Pull out the various important pieces of information about `v`
let RawParts { ptr, length, capacity } = RawParts::from_vec(v);
unsafe {
// Overwrite memory with 4, 5, 6
for i in 0..length as isize {
ptr::write(ptr.offset(i), 4 + i);
}
// Put everything back together into a Vec
let raw_parts = RawParts { ptr, length, capacity };
let rebuilt = RawParts::into_vec(raw_parts);
assert_eq!(rebuilt, [4, 5, 6]);
}
Trait Implementations
impl<T> Eq for RawParts<T>
Auto Trait Implementations
impl<T> RefUnwindSafe for RawParts<T> where
T: RefUnwindSafe,
impl<T> !Send for RawParts<T>
impl<T> !Sync for RawParts<T>
impl<T> Unpin for RawParts<T>
impl<T> UnwindSafe for RawParts<T> where
T: RefUnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more