#![no_std]
extern crate core;
use core::{fmt, mem};
#[derive(Clone, Copy, PartialEq)]
#[repr(transparent)]
pub struct PtrBool<T> {
inner: *mut T,
}
impl<T> PtrBool<T> {
#[inline]
fn get_ptr(&self) -> *mut T {
(self.inner as usize & !1) as *mut T
}
#[inline]
fn get_bool(&self) -> bool {
self.inner as usize & 1 == 1
}
}
impl<T> PtrBool<T> {
pub fn new(mut ptr: *mut T, bool_: bool) -> Option<Self> {
if ptr as usize % 2 != 0 || mem::align_of::<T>() <= 1 {
return None;
}
if bool_ {
ptr = (ptr as usize | 1) as *mut T;
}
Some(Self { inner: ptr })
}
pub fn null(bool_: bool) -> Option<Self> {
PtrBool::new(core::ptr::null::<T>() as *mut T, bool_)
}
pub fn as_bool(&self) -> bool {
self.get_bool()
}
pub fn set_bool(&mut self, bool_: bool) {
self.inner = (self.get_ptr() as usize | if bool_ == true { 1 } else { 0 }) as *mut T;
}
pub fn as_ptr(&self) -> *const T {
self.get_ptr()
}
pub fn as_mut_ptr(&self) -> *mut T {
self.get_ptr()
}
pub fn is_null(&self) -> bool {
self.get_ptr().is_null()
}
pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
self.get_ptr().as_ref()
}
pub unsafe fn as_ref_unchecked<'a>(&self) -> &'a T {
&*self.get_ptr()
}
pub unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> {
self.get_ptr().as_mut()
}
pub unsafe fn as_mut_unchecked<'a>(&self) -> &'a mut T {
&mut *self.get_ptr()
}
}
impl<T> fmt::Debug for PtrBool<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("PtrBool")
.field(&self.clone().get_ptr())
.field(&self.clone().get_bool())
.finish()
}
}
impl<T> fmt::Display for PtrBool<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("PtrBool")
.field(&self.clone().get_ptr())
.field(&self.clone().get_bool())
.finish()
}
}
impl<T> fmt::Pointer for PtrBool<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("PtrBool")
.field(&self.clone().get_ptr())
.field(&self.clone().get_bool())
.finish()
}
}