FlaggedPtr

Struct FlaggedPtr 

Source
pub struct FlaggedPtr<P, F, M, S>
where P: PtrMeta<M>, F: FlagMeta, M: Copy, S: PointerStorage,
{ /* private fields */ }
Expand description

A pointer that stores flags within unused bits of the pointer representation.

This struct combines a pointer and flag information into a single usize value by utilizing unused bits in the pointer due to alignment requirements.

§Type Parameters

  • P: The pointer type (e.g., Box<T>, NonNull<T>, Rc<T>)
  • F: The flag type (must implement FlagMeta)
  • M: Metadata associated with the pointer

§Examples

use flagged_pointer::FlaggedPtr;
use flagged_pointer::alias::FlaggedBox;
use enumflags2::{bitflags, BitFlags};

#[bitflags]
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum Color {
    Red = 1 << 0,
    Blue = 1 << 1,
    Green = 1 << 2,
}

let boxed = Box::new("hello");
let flagged = FlaggedBox::new(boxed, Color::Red | Color::Blue);

assert_eq!(*flagged, "hello");
assert_eq!(flagged.flag(), Color::Red | Color::Blue);

§Example with trait object

use flagged_pointer::alias::*;
use std::sync::Arc;
use ptr_meta::pointee;
use enumflags2::{bitflags,BitFlags};

#[bitflags]
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum Color {
    Red = 1 << 0,
    Blue = 1 << 1,
    Green = 1 << 2,
}

#[ptr_meta::pointee]
trait MyTrait {
   fn method(&self);
}

impl MyTrait for i64 {
   fn method(&self) {
       println!("i32 method");
   }
}

impl MyTrait for String {
   fn method(&self) {
       println!("String method");
   }
}

let trait_obj: FlaggedBoxDyn<dyn MyTrait, BitFlags<Color>> = FlaggedBoxDyn::new(Box::new(42_i64), Color::Red | Color::Blue);
trait_obj.method();
let trait_obj: FlaggedArcDyn<dyn MyTrait, BitFlags<Color>> = FlaggedArcDyn::new(Arc::new("hello".to_string()), Color::Red | Color::Blue);
trait_obj.method();

Implementations§

Source§

impl<P, F, M, S> FlaggedPtr<P, F, M, S>
where P: PtrMeta<M>, F: FlagMeta, M: Copy, S: PointerStorage,

Source

pub fn new(ptr: P, flag: F) -> Self

Creates a new FlaggedPtr from a pointer and flags.

§Arguments
  • ptr: The pointer to store
  • flag: The flags to encode in the unused bits
§Examples
use flagged_pointer::FlaggedPtr;
use flagged_pointer::alias::FlaggedBox;
use enumflags2::bitflags;
use std::ptr::NonNull;

#[bitflags]
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum MyFlags {
    A = 1 << 0,
    B = 1 << 1,
}

let boxed = Box::new(42);
let flagged = FlaggedBox::new(boxed, MyFlags::A | MyFlags::B);
assert_eq!(*flagged, 42);
§Panics

Panics if the pointer and flag bits overlap, which should not happen for properly aligned pointers and reasonable flag values.

Source

pub fn try_new(ptr: P, flag: F) -> Result<Self, FlaggedPointerError<P>>

Creates a new FlaggedPtr from a pointer and flags, returning an error if they overlap.

§Arguments
  • ptr: The pointer to store
  • flag: The flags to encode in the unused bits
§Returns
  • Ok(Self) if the pointer and flag bits do not overlap
  • Err(FlagOverlapError) if they do overlap
§Examples
use flagged_pointer::FlaggedPtr;
use flagged_pointer::alias::FlaggedBox;
use enumflags2::{bitflags,BitFlags};
use std::ptr::NonNull;

#[bitflags]
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum MyFlags {
    A = 1 << 0,
    B = 1 << 1,
}

#[bitflags]
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum MyFlagsInvalid {
    A = 1 << 6,
    B = 1 << 7,
}

let boxed = Box::new(42);
let flagged = FlaggedBox::try_new(boxed.clone(), BitFlags::from(MyFlags::A));
assert!(flagged.is_ok());

let flagged = FlaggedBox::try_new(boxed, BitFlags::from(MyFlagsInvalid::B));
assert!(flagged.is_err());
Source

pub unsafe fn new_unchecked(ptr: P, flag: F) -> Self

§Safety

The caller must ensure that the pointer and flag bits do not overlap.

Source§

impl<P, F, M, S> FlaggedPtr<P, F, M, S>
where P: PtrMeta<M>, F: FlagMeta, M: Copy, S: PointerStorage,

A non-atomic version of FlaggedPtr methods.

Source

pub fn flag(&self) -> F

Returns the flags stored in this pointer.

§Examples
use flagged_pointer::FlaggedPtr;
use flagged_pointer::alias::FlaggedBox;
use enumflags2::bitflags;

#[bitflags]
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum MyFlags {
    A = 1 << 0,
    B = 1 << 1,
}

let boxed = Box::new(123);
let flagged = FlaggedBox::new(boxed, MyFlags::A | MyFlags::B);
assert_eq!(flagged.flag(), MyFlags::A | MyFlags::B);
Source

pub fn dissolve(self) -> (P, F)

Consumes this FlaggedPtr and returns the original pointer and flags.

This is the inverse operation of new().

§Returns

A tuple containing (original_pointer, flags)

§Examples
use flagged_pointer::FlaggedPtr;
use flagged_pointer::alias::FlaggedBox;
use enumflags2::bitflags;

#[bitflags]
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum MyFlags {
    A = 1 << 0,
    B = 1 << 1,
}

let boxed = Box::new(42);
let flagged = FlaggedBox::new(boxed, MyFlags::A | MyFlags::B);
let (recovered_box, flags) = flagged.dissolve();

assert_eq!(*recovered_box, 42);
assert_eq!(flags, MyFlags::A | MyFlags::B);
Source

pub fn as_ptr(&self) -> NonNull<P::Pointee>

Returns a raw pointer to the pointee.

§Safety

The caller must ensure there is no any data race when accessing the pointer.

§Examples
use flagged_pointer::FlaggedPtr;
use flagged_pointer::alias::FlaggedBox;
use enumflags2::bitflags;

#[bitflags]
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum MyFlags {
    A = 1 << 0,
    B = 1 << 1,
}

let boxed = Box::new(123);
let flagged = FlaggedBox::new(boxed, MyFlags::A | MyFlags::B);
let ptr = flagged.as_ptr();
assert_eq!(unsafe { *ptr.as_ref() }, 123);
Source

pub fn into_flag(self) -> F

Consumes this FlaggedPtr and returns the original flags.

§Examples
use flagged_pointer::FlaggedPtr;
use flagged_pointer::alias::FlaggedBox;
use enumflags2::bitflags;

#[bitflags]
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum MyFlags {
    A = 1 << 0,
    B = 1 << 1,
}

let boxed = Box::new(123);
let flagged = FlaggedBox::new(boxed, MyFlags::A | MyFlags::B);
let flag = flagged.into_flag();
assert_eq!(flag, MyFlags::A | MyFlags::B);
Source

pub fn into_ptr(self) -> P

Consumes this FlaggedPtr and returns the original pointer.

§Examples
use flagged_pointer::FlaggedPtr;
use flagged_pointer::alias::FlaggedBox;
use enumflags2::bitflags;

#[bitflags]
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum MyFlags {
    A = 1 << 0,
    B = 1 << 1,
}

let boxed = Box::new(123);
let flagged = FlaggedBox::new(boxed, MyFlags::A | MyFlags::B);
let ptr = flagged.into_ptr();
assert_eq!(unsafe { *ptr.as_ref() }, 123);
Source§

impl<P, F, M> FlaggedPtr<P, F, M, NonNull<()>>
where P: PtrMeta<M>, F: FlagMeta, M: Copy,

Source

pub fn set_flag(&mut self, flag: F) -> F

Sets new flags for this pointer.

§Arguments
  • flag: The new flags to set
§Examples
use flagged_pointer::FlaggedPtr;
use flagged_pointer::alias::FlaggedBox;
use enumflags2::bitflags;

#[bitflags]
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum MyFlags {
    A = 1 << 0,
    B = 1 << 1,
}

let boxed = Box::new(123);
let mut flagged = FlaggedBox::new(boxed, MyFlags::A | MyFlags::B);
flagged.set_flag(MyFlags::B.into());
assert_eq!(flagged.flag(), MyFlags::B);
Source

pub fn try_set_pointer(&mut self, ptr: P) -> Result<P, FlaggedPointerError<P>>

Sets a new pointer for this FlaggedPtr, while preserving the current flags.

§Arguments
  • ptr: The new pointer to set
§Examples
use flagged_pointer::FlaggedPtr;
use flagged_pointer::alias::FlaggedBox;
use enumflags2::bitflags;

#[bitflags]
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum MyFlags {
    A = 1 << 0,
    B = 1 << 1,
}

let boxed = Box::new(123);
let mut flagged = FlaggedBox::new(boxed, MyFlags::A | MyFlags::B);
flagged.try_set_pointer(Box::new(456)).unwrap();
assert_eq!(*flagged.into_ptr(), 456);
Source§

impl<P, F, S> FlaggedPtr<P, F, (), S>

Source

pub fn set_flag(&self, flag: F) -> F

Sets new flags for this pointer.

§Arguments
  • flag: The new flags to set
§Examples
use flagged_pointer::FlaggedPtr;
use flagged_pointer::alias::FlaggedBox;
use enumflags2::bitflags;

#[bitflags]
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum MyFlags {
    A = 1 << 0,
    B = 1 << 1,
}

let boxed = Box::new(123);
let mut flagged = FlaggedBox::new(boxed, MyFlags::A | MyFlags::B);
flagged.set_flag(MyFlags::B.into());
assert_eq!(flagged.flag(), MyFlags::B);
Source

pub fn try_set_pointer(&self, ptr: P) -> Result<P, FlaggedPointerError<P>>

Sets a new pointer for this FlaggedPtr, while preserving the current flags.

§Arguments
  • ptr: The new pointer to set
§Examples
use flagged_pointer::FlaggedPtr;
use flagged_pointer::alias::FlaggedBox;
use enumflags2::bitflags;

#[bitflags]
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum MyFlags {
    A = 1 << 0,
    B = 1 << 1,
}

let boxed = Box::new(123);
let mut flagged = FlaggedBox::new(boxed, MyFlags::A | MyFlags::B);
flagged.try_set_pointer(Box::new(456)).unwrap();
assert_eq!(*flagged.into_ptr(), 456);

Trait Implementations§

Source§

impl<P, F, M> AsMut<<P as PtrMeta<M>>::Pointee> for FlaggedPtr<P, F, M, NonNull<()>>
where P: PtrMeta<M> + DerefMut<Target = P::Pointee>, F: FlagMeta, M: Copy,

Source§

fn as_mut(&mut self) -> &mut P::Pointee

Converts this type into a mutable reference of the (usually inferred) input type.
Source§

impl<P, F, M> AsRef<<P as PtrMeta<M>>::Pointee> for FlaggedPtr<P, F, M, NonNull<()>>
where P: PtrMeta<M> + Deref<Target = P::Pointee>, F: FlagMeta, M: Copy,

Source§

fn as_ref(&self) -> &P::Pointee

Converts this type into a shared reference of the (usually inferred) input type.
Source§

impl<P, F, M> Clone for FlaggedPtr<P, F, M, NonNull<()>>
where P: PtrMeta<M> + Clone, F: FlagMeta, M: Copy,

Source§

fn clone(&self) -> Self

Returns a duplicate 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<P, F, M> Debug for FlaggedPtr<P, F, M, AtomicPtr<()>>
where P: PtrMeta<M> + Deref<Target = P::Pointee>, P::Pointee: Debug, F: FlagMeta + Debug, M: Copy,

Source§

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

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

impl<P, F, M> Debug for FlaggedPtr<P, F, M, NonNull<()>>
where P: PtrMeta<M> + Deref<Target = P::Pointee>, P::Pointee: Debug, F: FlagMeta + Debug, M: Copy,

Source§

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

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

impl<P, F, M> Deref for FlaggedPtr<P, F, M, NonNull<()>>
where P: PtrMeta<M> + Deref<Target = P::Pointee>, F: FlagMeta, M: Copy,

Source§

type Target = <P as PtrMeta<M>>::Pointee

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl<P, F, M> DerefMut for FlaggedPtr<P, F, M, NonNull<()>>
where P: PtrMeta<M> + DerefMut<Target = P::Pointee>, F: FlagMeta, M: Copy,

Source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
Source§

impl<P, F, M, S> Drop for FlaggedPtr<P, F, M, S>
where P: PtrMeta<M>, F: FlagMeta, M: Copy, S: PointerStorage,

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<P, F, M> Hash for FlaggedPtr<P, F, M, NonNull<()>>
where P: PtrMeta<M> + Deref<Target = P::Pointee>, P::Pointee: Hash, F: FlagMeta + Hash, M: Copy,

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<P, F, M> PartialEq for FlaggedPtr<P, F, M, NonNull<()>>
where P: PtrMeta<M> + Deref<Target = P::Pointee>, P::Pointee: PartialEq, F: FlagMeta + PartialEq, M: Copy,

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<P, F, M, S> Pointer for FlaggedPtr<P, F, M, S>
where P: PtrMeta<M>, F: FlagMeta, M: Copy, S: PointerStorage,

Source§

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

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

impl<P, F, M> CloneStableDeref for FlaggedPtr<P, F, M, NonNull<()>>
where P: PtrMeta<M> + Deref<Target = P::Pointee> + CloneStableDeref, F: FlagMeta, M: Copy,

Source§

impl<P, F, M> Eq for FlaggedPtr<P, F, M, NonNull<()>>
where P: PtrMeta<M> + Deref<Target = P::Pointee>, P::Pointee: Eq, F: FlagMeta + Eq, M: Copy,

Source§

impl<P, F, M, S> Send for FlaggedPtr<P, F, M, S>
where P: PtrMeta<M> + Send, F: FlagMeta + Send, M: Send + Copy, S: PointerStorage,

Source§

impl<P, F, M> StableDeref for FlaggedPtr<P, F, M, NonNull<()>>
where P: PtrMeta<M> + Deref<Target = P::Pointee> + StableDeref, F: FlagMeta, M: Copy,

Source§

impl<P, F, M, S> Sync for FlaggedPtr<P, F, M, S>
where P: PtrMeta<M> + Sync, F: FlagMeta + Sync, M: Sync + Copy, S: PointerStorage,

Auto Trait Implementations§

§

impl<P, F, M, S> Freeze for FlaggedPtr<P, F, M, S>
where S: Freeze, M: Freeze,

§

impl<P, F, M, S> RefUnwindSafe for FlaggedPtr<P, F, M, S>

§

impl<P, F, M, S> Unpin for FlaggedPtr<P, F, M, S>
where S: Unpin, M: Unpin, P: Unpin, F: Unpin,

§

impl<P, F, M, S> UnwindSafe for FlaggedPtr<P, F, M, S>

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> Pointee for T

Source§

type Metadata = ()

The metadata type for pointers and references to this type.
Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
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.