tagptr

Struct TagNonNull

source
pub struct TagNonNull<T, const N: usize> { /* private fields */ }
Expand description

A non-nullable tagged raw pointer type similar to NonNull which can use up to N of its lower bits to store additional information (the tag).

This type has the same in-memory representation as a NonNull<T>. See the crate level documentation for restrictions on the value of N.

§Invariants

This type imposes stricter construction requirements than a regular NonNull, since it requires the pointer to be non-null even after its N tag bits are stripped off as well. For instance, the value 0x1 can be used to construct a valid (but not dereferencable) NonNull since it is not zero, but it can not be used to construct e.g. a valid TagNonNull<u64, 1>, since its only non-zero bit would be considered to represent the tag and the value of the pointer would be 0. For valid, well-aligned pointers, this is usually not a concern.

Implementations§

source§

impl<T, const N: usize> TagNonNull<T, N>

source

pub const TAG_BITS: usize = N

The number of available tag bits for this type.

source

pub const TAG_MASK: usize = _

The bitmask for the lower bits available for storing the tag value.

source

pub const POINTER_MASK: usize = _

The bitmask for the (higher) bits for storing the pointer itself.

source

pub const unsafe fn new_unchecked(marked_ptr: TagPtr<T, N>) -> Self

Creates a new marked non-null pointer from marked_ptr without checking if it is null.

§Safety

The caller has to ensure that marked_ptr is not null. This includes null pointers with non-zero tag values.

source

pub const unsafe fn from_usize(val: usize) -> Self

Creates a new pointer from the numeric (integer) representation of a potentially marked pointer.

source

pub const fn into_raw(self) -> NonNull<T>

Returns the internal representation of the pointer as is, i.e. any potential tag value is not stripped.

source

pub const fn cast<U>(self) -> TagNonNull<U, N>

Casts to a pointer of another type.

source

pub fn into_usize(self) -> usize

Returns the numeric (integer) representation of the pointer with its tag value.

source

pub const fn into_marked_ptr(self) -> TagPtr<T, N>

Converts self into a (nullable) marked pointer.

source

pub fn new(marked_ptr: TagPtr<T, N>) -> Result<Self, Null>

Creates a new non-null pointer from marked_ptr.

§Errors

Fails if marked_ptr is null, in which case a Null instance is returned containing argument pointer’s tag value.

source

pub const fn dangling() -> Self

Creates a new pointer that is dangling but well aligned.

source

pub fn compose(ptr: NonNull<T>, tag: usize) -> Self

Composes a new marked pointer from a raw ptr and a tag value.

The supplied ptr is assumed to be well-aligned (i.e. has no tag bits set) and calling this function may lead to unexpected results when this is not the case.

§Panics

Panics if ptr is mis-aligned for N tag bits and contains only zero bits in the upper bits, i.e., it would be parsed as a marked null pointer.

source

pub fn try_compose(ptr: NonNull<T>, tag: usize) -> Result<Self, Null>

Attempts to compose a new marked pointer from a raw (non-null) ptr and a tag value.

§Errors

Fails if ptr is mis-aligned for N tag bits and contains only zero bits in the upper bits, i.e., it would be parsed as a marked null pointer. In this case a Null instance is returned containing the argument pointer’s tag value.

source

pub unsafe fn compose_unchecked(ptr: NonNull<T>, tag: usize) -> Self

Composes a new marked pointer from a raw (non-null) ptr and a tag value without checking if ptr is valid.

§Safety

The caller has to ensure that ptr is non-null even after considering its N lower bits as tag bits.

source

pub fn clear_tag(self) -> Self

Clears the marked pointer’s tag value.

source

pub fn split_tag(self) -> (Self, usize)

Splits the tag value from the marked pointer, returning both the cleared pointer and the separated tag value.

source

pub fn set_tag(self, tag: usize) -> Self

Sets the marked pointer’s tag value to tag and overwrites any previous value.

source

pub fn update_tag(self, func: impl FnOnce(usize) -> usize) -> Self

Updates the marked pointer’s tag value to the result of func, which is called with the current tag value.

source

pub unsafe fn add_tag(self, value: usize) -> Self

Adds value to the current tag without regard for the previous value.

This method does not perform any checks so it may silently overflow the tag bits, result in a pointer to a different value, a null pointer or an unaligned pointer.

§Safety

The caller has to ensure that the resulting pointer is not null (neither marked nor unmarked).

source

pub unsafe fn sub_tag(self, value: usize) -> Self

Subtracts value from the current tag without regard for the previous value.

This method does not perform any checks so it may silently overflow the tag bits, result in a pointer to a different value, a null pointer or an unaligned pointer.

§Safety

The caller has to ensure that the resulting pointer is not null (neither marked nor unmarked).

source

pub fn decompose(self) -> (NonNull<T>, usize)

Decomposes the marked pointer, returning the raw pointer and the separated tag value.

source

pub fn decompose_ptr(self) -> *mut T

Decomposes the marked pointer, returning only the separated raw pointer.

source

pub fn decompose_non_null(self) -> NonNull<T>

Decomposes the marked pointer, returning only the separated raw NonNull pointer.

source

pub fn decompose_tag(self) -> usize

Decomposes the marked pointer, returning only the separated tag value.

source

pub unsafe fn as_ref(&self) -> &T

Decomposes the marked pointer, returning a reference and discarding the tag value.

§Safety

While this method and its mutable counterpart are useful for null-safety, it is important to note that this is still an unsafe operation because the returned value could be pointing to invalid memory.

When calling this method, you have to ensure that either the pointer is null or all of the following is true:

  • it is properly aligned
  • it must point to an initialized instance of T; in particular, the pointer must be “de-referencable” in the sense defined here.

This applies even if the result of this method is unused! (The part about being initialized is not yet fully decided, but until it is the only safe approach is to ensure that they are indeed initialized.)

Additionally, the lifetime 'a returned is arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. You must enforce Rust’s aliasing rules. In particular, for the duration of this lifetime, the memory this pointer points to must not get accessed (read or written) through any other pointer.

source

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

Decomposes the marked pointer, returning a mutable reference and discarding the tag value.

§Safety

As with as_ref, this is unsafe because it cannot verify the validity of the returned pointer, nor can it ensure that the lifetime 'a returned is indeed a valid lifetime for the contained data.

When calling this method, you have to ensure that either the pointer is null or all of the following is true:

  • it is properly aligned
  • it must point to an initialized instance of T; in particular, the pointer must be “de-referencable” in the sense defined here.

This applies even if the result of this method is unused! (The part about being initialized is not yet fully decided, but until it is the only safe approach is to ensure that they are indeed initialized.)

Additionally, the lifetime 'a returned is arbitrarily chosen and does not necessarily reflect the actual lifetime of the data. You must enforce Rust’s aliasing rules. In particular, for the duration of this lifetime, the memory this pointer points to must not get accessed (read or written) through any other pointer.

source

pub unsafe fn decompose_ref(&self) -> (&T, usize)

Decomposes the marked pointer, returning a reference and the separated tag.

§Safety

The same safety caveats as with as_ref apply.

source

pub unsafe fn decompose_mut(&mut self) -> (&mut T, usize)

Decomposes the marked pointer, returning a mutable reference and the separated tag.

§Safety

The same safety caveats as with as_mut apply.

Trait Implementations§

source§

impl<T, const N: usize> Clone for TagNonNull<T, N>

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, const N: usize> Debug for TagNonNull<T, N>

source§

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

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

impl<T, const N: usize> From<&T> for TagNonNull<T, N>

source§

fn from(reference: &T) -> Self

Converts to this type from the input type.
source§

impl<T, const N: usize> From<&mut T> for TagNonNull<T, N>

source§

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

Converts to this type from the input type.
source§

impl<T, const N: usize> From<TagNonNull<T, N>> for TagPtr<T, N>

source§

fn from(ptr: TagNonNull<T, N>) -> Self

Converts to this type from the input type.
source§

impl<T, const N: usize> Hash for TagNonNull<T, N>

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, const N: usize> Ord for TagNonNull<T, N>

source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
source§

impl<T, const N: usize> PartialEq for TagNonNull<T, N>

source§

fn eq(&self, other: &Self) -> 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, const N: usize> PartialOrd for TagNonNull<T, N>

source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

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

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

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

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · source§

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

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

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

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
source§

impl<T, const N: usize> Pointer for TagNonNull<T, N>

source§

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

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

impl<T, const N: usize> TryFrom<*const T> for TagNonNull<T, N>

source§

type Error = Null

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

fn try_from(ptr: *const T) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl<T, const N: usize> TryFrom<*mut T> for TagNonNull<T, N>

source§

type Error = Null

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

fn try_from(ptr: *mut T) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl<T, const N: usize> TryFrom<NonNull<T>> for TagNonNull<T, N>

source§

type Error = Null

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

fn try_from(ptr: NonNull<T>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl<T, const N: usize> TryFrom<TagPtr<T, N>> for TagNonNull<T, N>

source§

type Error = Null

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

fn try_from(ptr: TagPtr<T, N>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl<T, const N: usize> Copy for TagNonNull<T, N>

source§

impl<T, const N: usize> Eq for TagNonNull<T, N>

Auto Trait Implementations§

§

impl<T, const N: usize> Freeze for TagNonNull<T, N>

§

impl<T, const N: usize> RefUnwindSafe for TagNonNull<T, N>
where T: RefUnwindSafe,

§

impl<T, const N: usize> !Send for TagNonNull<T, N>

§

impl<T, const N: usize> !Sync for TagNonNull<T, N>

§

impl<T, const N: usize> Unpin for TagNonNull<T, N>

§

impl<T, const N: usize> UnwindSafe for TagNonNull<T, N>
where T: RefUnwindSafe,

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, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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>,

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.