pub struct FlaggedPtr<P, F, M, S>{ /* 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 implementFlagMeta)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>
impl<P, F, M, S> FlaggedPtr<P, F, M, S>
Sourcepub fn new(ptr: P, flag: F) -> Self
pub fn new(ptr: P, flag: F) -> Self
Creates a new FlaggedPtr from a pointer and flags.
§Arguments
ptr: The pointer to storeflag: 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.
Sourcepub fn try_new(ptr: P, flag: F) -> Result<Self, FlaggedPointerError<P>>
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 storeflag: The flags to encode in the unused bits
§Returns
Ok(Self)if the pointer and flag bits do not overlapErr(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());Sourcepub unsafe fn new_unchecked(ptr: P, flag: F) -> Self
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>
A non-atomic version of FlaggedPtr methods.
impl<P, F, M, S> FlaggedPtr<P, F, M, S>
A non-atomic version of FlaggedPtr methods.
Sourcepub fn flag(&self) -> F
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);Sourcepub fn dissolve(self) -> (P, F)
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);Sourcepub fn as_ptr(&self) -> NonNull<P::Pointee>
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);Sourcepub fn into_flag(self) -> F
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);Sourcepub fn into_ptr(self) -> P
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<()>>
impl<P, F, M> FlaggedPtr<P, F, M, NonNull<()>>
Sourcepub fn set_flag(&mut self, flag: F) -> F
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);Sourcepub fn try_set_pointer(&mut self, ptr: P) -> Result<P, FlaggedPointerError<P>>
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>
impl<P, F, S> FlaggedPtr<P, F, (), S>
Sourcepub fn set_flag(&self, flag: F) -> F
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);Sourcepub fn try_set_pointer(&self, ptr: P) -> Result<P, FlaggedPointerError<P>>
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);