Struct Ptr

Source
pub struct Ptr<T: ?Sized> { /* private fields */ }
Expand description

A nullable raw pointer.

This type is intended as an improved version of *mut T, which provides clearer methods for common operations on raw pointers.

Unlike Rust’s raw pointers, this pointer type does not track mutability (which is not deeply useful book-keeping on raw pointers).

struct Foo {
  first: i32,
  second: u64,
}

let data = vec![Foo::default(); 100];
let ptr = Ptr::from(data.as_ptr());
assert!(!ptr.is_null() && ptr.is_aligned());

unsafe {
  ptr.at(42).write_at(gep::field!(Foo.first), -1);
  ptr.at(42).write_at(gep::field!(Foo.second), 42);
}

assert_eq!(data[42], Foo { first: -1, second: 42 });

§Unsized Types

Currently, T: !Sized is poorly supported (due to lack of good support on *mut T itself). In particular, Ptr<[T]> should be separated into a Ptr<T> and a usize, since there is no supported way to get the length out.

Implementations§

Source§

impl<T: ?Sized> Ptr<T>

Source

pub const fn new(ptr: *mut T) -> Self

Constructs a new Ptr from a raw pointer or reference.

Source

pub const fn new_from_ref(ptr: &T) -> Self

Constructs a new Ptr from a reference.

§Safety

This function is safe, but Ptrs created with it cannot be written through.

Source

pub const fn is_null(self) -> bool

Checks whether this pointer is null.

let x = 1997;
assert!(!Ptr::from(&x).is_null());
assert!(Ptr::<i32>::null().is_null());
Source

pub const fn to_raw(self) -> *mut T

Extracts the underlying raw pointer.

let x = 1997;
let p = Ptr::from(&x);
assert!(ptr::eq(p.to_raw(), &x));
Source

pub fn addr(self) -> usize

Returns this pointer’s address.

This operation discards provenance information, and any pointer created from this address value will be invalid.

Compare <*mut T>::addr().

Source

pub fn expose_addr(self) -> usize

Exposes this pointer’s address.

This operation discards provenance information, but allows a pointer to be reconstituted later with Ptr::from_exposed_addr().

Compare <*mut T>::expose_addr().

Source

pub const fn to_non_null(self) -> Option<NonNull<T>>

Converts this pointer into a NonNull pointer; returns None if this pointer is null.

let x = 1997;
assert_eq!(
  Ptr::from(&x).to_non_null(),
  Some(NonNull::from(&x)),
);

assert!(Ptr::<i32>::null().to_non_null().is_none());
Source

pub const unsafe fn to_non_null_unchecked(self) -> NonNull<T>

Converts this non-null pointer into a NonNull pointer without checking.

let x = 1997;
let p = Ptr::from(&x);

assert!(!p.is_null());
assert_eq!(
  unsafe { Ptr::from(&x).to_non_null_unchecked() },
  NonNull::from(&x),
);
§Safety

Ptr::is_null() must return false for this pointer.

Source

pub const fn cast<U>(self) -> Ptr<U>

Casts this pointer to another type.

Note that U: Sized, because creating a pointer to an unsized type requires extra metadata (and no stable API exists to do so yet).

let x = -1;
let y = unsafe {
  Ptr::from(&x).cast::<u32>().read()
};

assert_eq!(y, !0);
Source

pub const unsafe fn deref(&self) -> &T

Dereferences this pointer, producing a reference.

This function takes &self, to avoid creating an unbound lifetime in the common case.

let x = -1;
let p = Ptr::from(&x).cast::<u32>();

assert_eq!(unsafe { p.deref() }, &!0);
§Safety

This operation is equivalent to dereferencing a raw pointer. The following is an incomplete list of requirements:

self must be non-null, well-aligned, and refer to memory appropriately initialized for T; also, it must not create a reference that aliases any active &mut U.

Source

pub const unsafe fn deref_unbound<'a>(self) -> &'a T

Dereferences this pointer, producing a reference.

Unlike Ptr::deref(), this function can produce unbound references.

§Safety

This operation is equivalent to dereferencing a raw pointer. The following is an incomplete list of requirements:

self must be non-null, well-aligned, and refer to memory appropriately initialized for T; also, it must not create a reference that aliases any active &mut U.

Source

pub unsafe fn deref_mut(&self) -> &mut T

Dereferences this pointer, producing a mutable reference.

This function takes &mut self, to avoid creating an unbound lifetime in the common case.

let mut x = 0;
let p = Ptr::from(&mut x).cast::<u32>();
*unsafe { p.deref_mut() } = !0;

assert_eq!(x, -1);
§Safety

This operation is equivalent to dereferencing a raw pointer. The following is an incomplete list of requirements:

self must be non-null, well-aligned, and refer to memory appropriately initialized for T; also, it must not create a reference that aliases any active &mut U.

Source

pub unsafe fn deref_mut_unbound<'a>(self) -> &'a mut T

Dereferences this pointer, producing a reference.

Unlike Ptr::deref_mut(), this function can produce unbound references.

§Safety

This operation is equivalent to dereferencing a raw pointer. The following is an incomplete list of requirements:

self must be non-null, well-aligned, and refer to memory appropriately initialized for T; also, it must not create a reference that aliases any active &mut U.

Source

pub unsafe fn destroy(self)

Destroys the pointed-to value; equivalent to std::ptr::drop_in_place().

struct Handle<'a>(&'a Cell<i32>);
impl<'a> Handle<'a> {
  fn new(c: &'a Cell<i32>) -> Self {
    c.set(c.get() + 1);
    Self(c)
  }
}

impl Drop for Handle<'_> {
  fn drop(&mut self) {
    self.0.set(self.0.get() - 1);
  }
}

let counter = Cell::new(0);
let mut handle = Handle::new(&counter);

assert_eq!(counter.get(), 1);

let p = Ptr::from(&mut handle);
unsafe {
  p.destroy();
  p.write(Handle::new(&counter));
}

assert_eq!(counter.get(), 1);

Tip: given a Ptr<T>, you can destroy an array of n of them with ptr.to_slice(n).destroy().

§Safety

This operation is equivalent to dereferencing a raw pointer. The following is an incomplete list of requirements:

self must be valid for reading and writing, properly aligned, and properly initialized. See std::ptr::drop_in_place() for more information.

Source§

impl<T> Ptr<T>

Source

pub const fn null() -> Self

Creates a new null pointer.

Source

pub const fn dangling() -> Self

Creates a new, non-null, dangling pointer.

assert_ne!(Ptr::<i32>::null(), Ptr::<i32>::dangling());
Source

pub const fn invalid(addr: usize) -> Self

Creates a pointer with the given address and the “invalid” provenance.

Compare [std::ptr::invalid()].

Source

pub const fn from_exposed_addr(addr: usize) -> Self

Reconstitutes a pointer using an address previously constructed with Ptr::expose_addr().

const KEY: usize = 0xf0f0f0f0f0f0f0f0;

let x = 1997;
let p = Ptr::from(&x);
let addr = p.expose_addr() ^ KEY;

let q = Ptr::<i32>::from_exposed_addr(addr ^ KEY);
assert_eq!(p, q);

Compare [std::ptr::from_exposed_addr()].

Source

pub fn with_addr(self, addr: usize) -> Ptr<T>

Creates a new pointer with the given address using the provenance information from self.

Compare <*mut T>::with_addr().

Source

pub fn map_addr(self, f: impl FnOnce(usize) -> usize) -> Self

Transforms the address of self while preserving its provenance.

This is a convenience wrapper over Ptr::with_addr().

Source

pub fn is_aligned(self) -> bool

Returns whether this pointer is appropriately aligned for its type.

let x = 1997;
let p = Ptr::from(&x);
let q = unsafe { p.at(ByteOffset(1)) };

assert!(p.is_aligned());
assert!(!q.is_aligned());
Source

pub fn misalignment(self) -> usize

Returns this pointer’s “address misalignment”; i.e., its address modulo the pointee type’s alignment.

let x = 1997;
let p = Ptr::from(&x);
let q = unsafe { p.at(ByteOffset(1)) };

assert_eq!(p.misalignment(), 0);
assert_eq!(q.misalignment(), 1);
Source

pub fn align_down(self) -> Self

Makes this pointer well-aligned by rounding its address down.

let x = [1997, 42];
let p = Ptr::from(&x).element();
let q = unsafe { p.at(ByteOffset(1)) };

unsafe {
  assert_eq!(p.align_down().read(), 1997);
  assert_eq!(q.align_down().read(), 1997);
}
Source

pub fn align_up(self) -> Self

Makes this pointer well-aligned by rounding its address up.

let x = [1997, 42];
let p = Ptr::from(&x).element();
let q = unsafe { p.at(ByteOffset(1)) };

unsafe {
  assert_eq!(p.align_up().read(), 1997);
  assert_eq!(q.align_up().read(), 42);
}
Source

pub unsafe fn at<U>(self, offset: impl Offset<T, U>) -> Ptr<U>

Performs pointer arithmetic to produce a new pointer.

If an integer i (of any type, possibly signed) is passed in as the offset, it will compute the address of the ith T relative to this pointer. To obtain a pointer to the ith byte instead, wrap the integer in an offset::ByteOffset.

let x = [1997, 42];
let p = Ptr::from(&x).element();

unsafe {
  assert_eq!(p.at(1).read(), 42);
  assert_eq!(p.at(ByteOffset(4)).read(), 42);
}

If an offset::Field is passed in as the offset, it will compute the address of that field within the pointer. If it’s a negative field offset, it will treat this as a pointer to a field and compute the address of the outer struct. Note that such negative field offsets are only valid if this pointer was created from a reference to the top of the outer struct originally.

struct Foo {
  a: u8,
  bar: Bar,
}

struct Bar(i32, i32, i32);

let x = Foo { a: 5, bar: Bar(-1, -2, -3) };
let p = Ptr::from(&x);

unsafe {
  assert_eq!(p.at(field!(Foo.bar.2)).read(), -3);
}

offset::NotInBounds can be used to disable out-of-bounds undefined behavior for this function, but the resulting pointer may be invalid for reads and writes.

let x = [1997, 42];
let p = Ptr::from(&x).element();

unsafe {
  let invalid = p.at(NotInBounds(2000));
  // invalid.read()  // UB!
  let valid_again = invalid.at(NotInBounds(-1999));
  assert_eq!(valid_again.read(), 42);
}
§Safety

See the safety doc for offset::Measurement::apply().

Source

pub const unsafe fn at_raw(self, offset: Measurement) -> Ptr<T>

Performs pointer arithmetic to produce a new pointer.

Unlike Ptr::at(), this function is const, but takes an explicit offset::Measurement value.

let x = [1997, 42];
let p = Ptr::from(&x).element();

let m = Measurement::by_bytes(4);
unsafe {
  assert_eq!(p.at_raw(m).read(), 42);
}
§Safety

See the safety doc for offset::Measurement::apply().

Source

pub fn to_slice(self, len: usize) -> Ptr<[T]>

Casts this pointer to a Ptr<[T]>, with the given length.

Source

pub const fn to_uninit(self) -> Ptr<MaybeUninit<T>>

Casts this pointer to a Ptr<MaybeUninit<T>>.

Source

pub unsafe fn read(self) -> T

Reads the value at self.

This does not “move”; it effectively performs a bytewise copy of the value behind the pointer.

let x = 1997;
let p = Ptr::from(&x);

assert_eq!(unsafe { p.read() }, 1997);
§Safety

This operation is equivalent to dereferencing a raw pointer. The following is an incomplete list of requirements:

self must be valid for reads, properly aligned, and properly initialized. See std::ptr::read() for more information.

Source

pub unsafe fn read_at<U>(self, idx: impl Offset<T, U>) -> U

Reads the value at self.at(idx).

This is a convenience function for reading at a specified offset.

struct Player {
  name: String,
  health: f32,
}

let x = Player { name: "Gep".into(), health: 20.0 };
let p = Ptr::from(&x);

unsafe {
  assert_eq!(p.read_at(field!(Player.health)), 20.0);
}
§Safety

The requirements of Ptr::at() must be satisfied, as well as those for Ptr::read() (on the result of the pointer arithmetic operation).

Source

pub unsafe fn write(self, val: T)

Writes to the value at self.

Note: does not run the destructor of self’s pointee before overwriting it.

let mut x = 1997;
let p = Ptr::from(&mut x);

unsafe { p.write(42); }
assert_eq!(x, 42);
§Safety

This operation is equivalent to dereferencing a raw pointer. The following is an incomplete list of requirements:

self must be valid for writes, properly aligned, and properly initialized. See std::ptr::write() for more information.

Source

pub unsafe fn write_at<U>(self, idx: impl Offset<T, U>, val: U)

Writes to the value at self.at(idx).

This is a convenience function for writing at a specified offset.

struct Player {
  name: String,
  health: f32,
}

let mut x = Player { name: "Gep".into(), health: 20.0 };
let p = Ptr::from(&mut x);

unsafe {
  p.write_at(field!(Player.health), 30.0);
}
assert_eq!(x.health, 30.0);
§Safety

The requirements of Ptr::at() must be satisfied, as well as those for Ptr::write() (on the result of the pointer arithmetic operation).

Source

pub unsafe fn clear_to_zero(self)

Zeroes the value at self.

let mut x = 1997;
let p = Ptr::from(&mut x);

unsafe { p.clear_to_zero(); }
assert_eq!(x, 0);
§Safety

The requirements of Ptr::write() must be met. Also, if the pointee is not a type for which zero is a valid representation (e.g., a reference), the pointer will be invalid for reads.

Source

pub unsafe fn clear_to_zero_at<U>(self, idx: impl Offset<T, U>)

Zeroes the value at self.

This is a convenience function for zeroing at a specified offset.

struct Player {
  name: String,
  health: f32,
}

let mut x = Player { name: "Gep".into(), health: 20.0 };
let p = Ptr::from(&mut x);

unsafe {
  p.clear_to_zero_at(field!(Player.health));
}
assert_eq!(x.health, 0.0);
§Safety

The requirements of Ptr::at() must be satisfied, as well as those for Ptr::clear_to_zero() (on the result of the pointer arithmetic operation).

Source

pub unsafe fn destroy_at<U>(self, idx: impl Offset<T, U>)

Destroys the value at self.at(idx).

This is a convenience function for destroying at a specified offset.

§Safety

The requirements of Ptr::at() must be satisfied, as well as those for Ptr::destroy() (on the result of the pointer arithmetic operation).

Source

pub unsafe fn replace(self, val: T) -> T

Replaces the value at self.

This is like Ptr::read(), but it writes a new value after reading.

let mut x = 1997;
let p = Ptr::from(&mut x);

unsafe {
  assert_eq!(p.replace(42), 1997);
}
assert_eq!(x, 42);
§Safety

The requirements of Ptr::read() and Ptr::write() must be satisfied.

Source

pub unsafe fn replace_at<U>(self, idx: impl Offset<T, U>, val: U) -> U

Replaces the value at self.

This is a convenience function for replacing at a specified offset.

struct Player {
  name: String,
  health: f32,
}

let mut x = Player { name: "Gep".into(), health: 20.0 };
let p = Ptr::from(&mut x);

unsafe {
  assert_eq!(p.replace_at(field!(Player.health), 30.0), 20.0);
}
assert_eq!(x.health, 30.0);
§Safety

The requirements of Ptr::at() must be satisfied, as well as those Ptr::read() and Ptr::write() (on the result of the pointer arithmetic operation).

Source

pub unsafe fn deref_at<U>(&self, idx: impl Offset<T, U>) -> &U

Dereferences self.at(idx), producing a reference.

This is a convenience function for deref-ing at a specified offset.

struct Player {
  name: String,
  health: f32,
}

let mut x = Player { name: "Gep".into(), health: 20.0 };
let p = Ptr::from(&mut x);

let name = unsafe { p.deref_at(field!(Player.name)) };
assert_eq!(name, "Gep");
§Safety

The requirements of Ptr::at() must be satisfied, as well as those Ptr::deref() (on the result of the pointer arithmetic operation).

Source

pub unsafe fn deref_unbound_at<'a, U>(self, idx: impl Offset<T, U>) -> &'a U

Dereferences self.at(idx), producing a reference.

This is a convenience function for deref-ing at a specified offset; this is the unbound version of Ptr::deref_at().

§Safety

The requirements of Ptr::at() must be satisfied, as well as those Ptr::deref() (on the result of the pointer arithmetic operation).

Source

pub unsafe fn deref_mut_at<U>(&self, idx: impl Offset<T, U>) -> &mut U

Dereferences self.at(idx), producing a mutable reference.

This is a convenience function for deref-ing at a specified offset.

struct Player {
  name: String,
  health: f32,
}

let mut x = Player { name: "Gep".into(), health: 20.0 };
let p = Ptr::from(&mut x);

{
  let name = unsafe { p.deref_mut_at(field!(Player.name)) };
  name.clear();
  name.push_str("Jim");
}

assert_eq!(x.name, "Jim")
§Safety

The requirements of Ptr::at() must be satisfied, as well as those Ptr::deref_mut() (on the result of the pointer arithmetic operation).

Source

pub unsafe fn deref_mut_unbound_at<'a, U>( self, idx: impl Offset<T, U>, ) -> &'a mut U

Dereferences self.at(idx), producing a mutable reference.

This is a convenience function for deref-ing at a specified offset; this is the unbound version of Ptr::deref_mut_at().

§Safety

The requirements of Ptr::at() must be satisfied, as well as those Ptr::deref_mut() (on the result of the pointer arithmetic operation).

Source§

impl<T> Ptr<[T]>

Source

pub const fn element(self) -> Ptr<T>

Flattens this pointer into a pointer to the first element.

let x = [1, 2, 3];
let p = Ptr::from(&x[..]);

assert_eq!(p.element(), Ptr::from(&x[0]));
Source§

impl<T, const N: usize> Ptr<[T; N]>

Source

pub const fn element(self) -> Ptr<T>

Flattens this pointer into a pointer to the first element.

let x = [1, 2, 3];
let p = Ptr::from(&x);

assert_eq!(p.element(), Ptr::from(&x[0]));

Trait Implementations§

Source§

impl<T: ?Sized> Clone for Ptr<T>

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: ?Sized> Debug for Ptr<T>

Source§

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

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

impl<T: ?Sized> From<&T> for Ptr<T>

Source§

fn from(value: &T) -> Self

Converts to this type from the input type.
Source§

impl<T: ?Sized> From<&mut T> for Ptr<T>

Source§

fn from(value: &mut T) -> Self

Converts to this type from the input type.
Source§

impl<T: ?Sized> From<*const T> for Ptr<T>

Source§

fn from(value: *const T) -> Self

Converts to this type from the input type.
Source§

impl<T: ?Sized> From<*mut T> for Ptr<T>

Source§

fn from(value: *mut T) -> Self

Converts to this type from the input type.
Source§

impl<T: ?Sized> From<NonNull<T>> for Ptr<T>

Source§

fn from(value: NonNull<T>) -> Self

Converts to this type from the input type.
Source§

impl<T: ?Sized> From<NonNull<T>> for Ptr<T>

Source§

fn from(value: NonNull<T>) -> Self

Converts to this type from the input type.
Source§

impl<T: ?Sized> From<Ptr<T>> for *const T

Source§

fn from(value: Ptr<T>) -> Self

Converts to this type from the input type.
Source§

impl<T: ?Sized> From<Ptr<T>> for *mut T

Source§

fn from(value: Ptr<T>) -> Self

Converts to this type from the input type.
Source§

impl<T: ?Sized> PartialEq<NonNull<T>> for Ptr<T>

Source§

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

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

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

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T: ?Sized> PartialEq<Ptr<T>> for NonNull<T>

Source§

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

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

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

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T: ?Sized> PartialEq for Ptr<T>

Source§

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

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

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

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T: ?Sized> Pointer for Ptr<T>

Source§

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

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

impl<T: ?Sized> Copy for Ptr<T>

Source§

impl<T: ?Sized> Eq for Ptr<T>

Source§

impl<T: ?Sized> MutMarker for Ptr<T>

Auto Trait Implementations§

§

impl<T> Freeze for Ptr<T>
where T: ?Sized,

§

impl<T> RefUnwindSafe for Ptr<T>
where T: RefUnwindSafe + ?Sized,

§

impl<T> !Send for Ptr<T>

§

impl<T> !Sync for Ptr<T>

§

impl<T> Unpin for Ptr<T>
where T: ?Sized,

§

impl<T> UnwindSafe for Ptr<T>
where T: RefUnwindSafe + ?Sized,

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

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>,

Source§

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.