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>
impl<T, const N: usize> TagNonNull<T, N>
sourcepub const TAG_MASK: usize = _
pub const TAG_MASK: usize = _
The bitmask for the lower bits available for storing the tag value.
sourcepub const POINTER_MASK: usize = _
pub const POINTER_MASK: usize = _
The bitmask for the (higher) bits for storing the pointer itself.
sourcepub const unsafe fn new_unchecked(marked_ptr: TagPtr<T, N>) -> Self
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.
sourcepub const unsafe fn from_usize(val: usize) -> Self
pub const unsafe fn from_usize(val: usize) -> Self
Creates a new pointer from the numeric (integer) representation of a potentially marked pointer.
sourcepub const fn into_raw(self) -> NonNull<T>
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.
sourcepub const fn cast<U>(self) -> TagNonNull<U, N>
pub const fn cast<U>(self) -> TagNonNull<U, N>
Casts to a pointer of another type.
sourcepub fn into_usize(self) -> usize
pub fn into_usize(self) -> usize
Returns the numeric (integer) representation of the pointer with its tag value.
sourcepub const fn into_marked_ptr(self) -> TagPtr<T, N>
pub const fn into_marked_ptr(self) -> TagPtr<T, N>
Converts self
into a (nullable) marked pointer.
sourcepub fn compose(ptr: NonNull<T>, tag: usize) -> Self
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.
sourcepub fn try_compose(ptr: NonNull<T>, tag: usize) -> Result<Self, Null>
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.
sourcepub unsafe fn compose_unchecked(ptr: NonNull<T>, tag: usize) -> Self
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.
sourcepub fn split_tag(self) -> (Self, usize)
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.
sourcepub fn set_tag(self, tag: usize) -> Self
pub fn set_tag(self, tag: usize) -> Self
Sets the marked pointer’s tag value to tag
and overwrites any previous value.
sourcepub fn update_tag(self, func: impl FnOnce(usize) -> usize) -> Self
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.
sourcepub unsafe fn add_tag(self, value: usize) -> Self
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).
sourcepub unsafe fn sub_tag(self, value: usize) -> Self
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).
sourcepub fn decompose(self) -> (NonNull<T>, usize)
pub fn decompose(self) -> (NonNull<T>, usize)
Decomposes the marked pointer, returning the raw pointer and the separated tag value.
sourcepub fn decompose_ptr(self) -> *mut T
pub fn decompose_ptr(self) -> *mut T
Decomposes the marked pointer, returning only the separated raw pointer.
sourcepub fn decompose_non_null(self) -> NonNull<T>
pub fn decompose_non_null(self) -> NonNull<T>
Decomposes the marked pointer, returning only the separated raw NonNull
pointer.
sourcepub fn decompose_tag(self) -> usize
pub fn decompose_tag(self) -> usize
Decomposes the marked pointer, returning only the separated tag value.
sourcepub unsafe fn as_ref(&self) -> &T
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.
sourcepub unsafe fn as_mut(&mut self) -> &mut T
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.
sourcepub unsafe fn decompose_ref(&self) -> (&T, usize)
pub unsafe fn decompose_ref(&self) -> (&T, usize)
Trait Implementations§
source§impl<T, const N: usize> Clone for TagNonNull<T, N>
impl<T, const N: usize> Clone for TagNonNull<T, N>
source§impl<T, const N: usize> Debug for TagNonNull<T, N>
impl<T, const N: usize> Debug for TagNonNull<T, N>
source§impl<T, const N: usize> From<TagNonNull<T, N>> for TagPtr<T, N>
impl<T, const N: usize> From<TagNonNull<T, N>> for TagPtr<T, N>
source§fn from(ptr: TagNonNull<T, N>) -> Self
fn from(ptr: TagNonNull<T, N>) -> Self
source§impl<T, const N: usize> Hash for TagNonNull<T, N>
impl<T, const N: usize> Hash for TagNonNull<T, N>
source§impl<T, const N: usize> Ord for TagNonNull<T, N>
impl<T, const N: usize> Ord for TagNonNull<T, N>
source§impl<T, const N: usize> PartialEq for TagNonNull<T, N>
impl<T, const N: usize> PartialEq for TagNonNull<T, N>
source§impl<T, const N: usize> PartialOrd for TagNonNull<T, N>
impl<T, const N: usize> PartialOrd for TagNonNull<T, N>
source§impl<T, const N: usize> Pointer for TagNonNull<T, N>
impl<T, const N: usize> Pointer for TagNonNull<T, N>
impl<T, const N: usize> Copy for TagNonNull<T, N>
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)