use std::marker::PhantomData;
pub struct FlagPtr<T> {
val: usize,
_phantom: PhantomData<T>,
}
impl<T> Default for FlagPtr<T> {
fn default() -> Self {
Self {
val: 0,
_phantom: Default::default(),
}
}
}
impl<T> FlagPtr<T> {
const MASK: usize = 0b111;
pub fn get_ptr(&self) -> *mut T {
(self.val & !Self::MASK) as *mut T
}
pub fn set_ptr(&mut self, ptr: *mut T) {
let ptr = ptr as usize;
assert_eq!(ptr & Self::MASK, 0);
self.val = (ptr & !Self::MASK) | (self.val & Self::MASK);
}
pub fn get_flag(&self) -> usize {
self.val & Self::MASK
}
pub fn set_flag(&mut self, flag: usize) {
assert_eq!(flag & !Self::MASK, 0);
self.val = (self.val & !Self::MASK) | (flag & Self::MASK);
}
}
#[derive(Default)]
pub struct FlagU64 {
val: u64,
}
impl FlagU64 {
pub fn get_val(&self) -> u64 {
self.val >> 1
}
pub fn get_flag(&self) -> bool {
(self.val & 0x1) == 1
}
pub fn set_val(&mut self, val: u64) {
self.val = (self.val & 0x1) | (val << 1); }
pub fn set_flag(&mut self, flag: bool) {
self.val = (self.val & !0x1) | u64::from(flag)
}
}
pub struct FlagU32 {
val: u32,
}
impl FlagU32 {
pub fn get_val(&self) -> u32 {
self.val >> 1
}
pub fn get_flag(&self) -> bool {
(self.val & 0x1) == 1
}
pub fn set_val(&mut self, val: u32) {
self.val = (self.val & 0x1) | (val << 1); }
pub fn set_flag(&mut self, flag: bool) {
self.val = (self.val & !0x1) | u32::from(flag)
}
}
#[repr(align(8))]
pub struct Align8<T> {
pub inner: T,
}
impl<T> From<T> for Align8<T> {
fn from(inner: T) -> Self {
Align8 { inner }
}
}