Struct packed_ptr::PackedPtr

source ·
pub struct PackedPtr<T, C: PtrCfg>(/* private fields */);
Expand description

A packed pointer that wraps a raw pointer to a specified type with additional data packed into the pointer itself.

A PackedPtr will always be the same size as a raw pointer, but can contain a configuration specific amount of data packed into the pointer itself.

§Safety

Creating a PackedPtr instance requires a raw pointer, which can be obtained from other safe or unsafe operations. It’s important to ensure the safety of the source of the raw pointer when using PackedPtr, as it does not provide additional checks or guarantees like Rust’s reference lifetimes do.

This struct does not enforce any guarantees about the validity or ownership of the pointed-to data. It is the responsibility of the user to ensure that the underlying data remains valid and accessible for the lifetime of this pointer.

With that being said, PackedPtr does provide some safety requirements:

  • The pointer must be aligned to the alignment of T.
  • The data must be less than 2^Self::BITS.

Implementations§

source§

impl<T, C: PtrCfg> PackedPtr<T, C>

source

pub fn bits() -> usize

The number of bits available for storing data in the pointer. Equivalent to C::bits::<T>().

source

pub fn new(ptr: *const T, data: usize, _cfg: C) -> Result<Self, PackedPtrError>

Create a new packed pointer.

Performs checks to ensure that the pointer is aligned and that the data will fit inside the free space available in the pointer.

The data will fit in the pointer if & only if data < 2^C::bits().

See PtrCfg for more information on how to configure the number of bits available for storing data.

§Arguments
  • ptr: Pointer to data to pack.
  • data: Data to pack into the pointer.

returns: Result<PackedPtr<T>, NewPackedPtrError>

§Errors
§Examples
use packed_ptr::PackedPtr;
use packed_ptr::config::AlignOnly;

let data = 0xdeadbeefu32;
let ptr = PackedPtr::new(&data, 1, AlignOnly).unwrap();
assert_eq!(data, unsafe { *ptr.ptr() });
assert_eq!(1, ptr.data());
source

pub unsafe fn new_unchecked(ptr: *const T, data: usize) -> Self

Create a new packed pointer without performing any checks.

If the pointer is not aligned the resulting packed pointer will be invalid. If the data is too large the data will be truncated to fit in the pointer.

§Arguments
  • ptr: Pointer to data to pack.
  • data: Data to pack into the pointer.

returns: PackedPtr<T>

§Safety

This function is unsafe because it does not perform any checks to ensure that the pointer is properly aligned or that the data will fit in the pointer.

Passing an unaligned pointer will cause the pointer to be truncated to the nearest aligned address.

Passing data that is too large will cause the data to be truncated to fit in the pointer.

Passing a pointer that is not compatible with the configuration will cause the pointer to be corrupted, leading to UB.

source

pub fn get(self) -> (*const T, usize)

Retrieves a pointer to the data stored in the structure along with the data.

§Returns

Returns a tuple containing a pointer to the data and the length of the data.

The *const T is a raw pointer to the data stored in the structure, while the usize represents the length of the data.

source

pub fn ptr(self) -> *const T

Returns a raw pointer to the underlying data.

This method calculates the address of the underlying data by masking out the most significant bit and the alignment bits. It then returns the resulting pointer.

§Examples
use packed_ptr::PackedPtr;
use packed_ptr::config::AlignOnly;

let data = 0xdeadbeefu32;
let ptr = PackedPtr::new(&data, 1, AlignOnly).unwrap();
assert_eq!(data, unsafe { *ptr.ptr() });
source

pub fn data(self) -> usize

Extracts the data from the packed pointer.

Data will be a value in the range 0..2^Self::bits().

§Returns

The extracted data as a usize value.

§Example
use packed_ptr::PackedPtr;
use packed_ptr::config::AlignOnly;

let value = 0x12345678;
let ptr = PackedPtr::new(&value, 1, AlignOnly).unwrap();
assert_eq!(1, ptr.data());

Trait Implementations§

source§

impl<T, C: PtrCfg> Clone for PackedPtr<T, C>

source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T, C: PtrCfg> Debug for PackedPtr<T, C>

source§

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

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

impl<T, C: PtrCfg> Hash for PackedPtr<T, C>

source§

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

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, C: PtrCfg> PartialEq for PackedPtr<T, C>

source§

fn eq(&self, other: &Self) -> 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, C: PtrCfg> Pointer for PackedPtr<T, C>

source§

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

Formats the value using the given formatter.
source§

impl<T, C: PtrCfg> Copy for PackedPtr<T, C>

source§

impl<T, C: PtrCfg> Eq for PackedPtr<T, C>

Auto Trait Implementations§

§

impl<T, C> RefUnwindSafe for PackedPtr<T, C>

§

impl<T, C> !Send for PackedPtr<T, C>

§

impl<T, C> !Sync for PackedPtr<T, C>

§

impl<T, C> Unpin for PackedPtr<T, C>
where C: Unpin,

§

impl<T, C> UnwindSafe for PackedPtr<T, C>

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

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

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 T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

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

Performs the conversion.
source§

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

§

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

The type returned in the event of a conversion error.
source§

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

Performs the conversion.