Struct spinoso_array::RawParts

source ·
pub struct RawParts<T> {
    pub ptr: *mut T,
    pub length: usize,
    pub capacity: usize,
}
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§

source§

impl<T> RawParts<T>

source

pub fn from_vec(vec: Vec<T, Global>) -> 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]);
source

pub unsafe fn into_vec(this: RawParts<T>) -> Vec<T, Global>

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 via String/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 what ptr was allocated with. (T having a less strict alignment is not sufficient, the alignment really needs to be equal to satisfy the dealloc requirement that memory must be allocated and deallocated with the same layout.)
  • length needs to be less than or equal to capacity.
  • 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§

source§

impl<T> Debug for RawParts<T>

source§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<T> From<Vec<T, Global>> for RawParts<T>

source§

fn from(vec: Vec<T, Global>) -> RawParts<T>

Decompose a Vec<T> into its raw components.

source§

impl<T> Hash for RawParts<T>

source§

fn hash<H>(&self, state: &mut H)where
H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where
H: Hasher,
Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<T> PartialEq<RawParts<T>> for RawParts<T>

source§

fn eq(&self, other: &RawParts<T>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

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§

source§

impl<T> Any for Twhere
T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere
T: ?Sized,

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere
T: ?Sized,

const: unstable · source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere
U: From<T>,

const: unstable · source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere
U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere
U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
const: unstable · source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.