use core::ops::Deref;
use core::ops::DerefMut;
use bytemuck::AnyBitPattern;
use bytemuck::Pod;
use bytemuck::Zeroable;
#[repr(C, align(16))]
#[derive(Copy, Clone, Pod, Zeroable, Default, Debug)]
pub struct Align16U128(pub u128);
impl Deref for Align16U128 {
type Target = u128;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Align16U128 {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl AsRef<u128> for Align16U128 {
fn as_ref(&self) -> &u128 {
&self.0
}
}
impl AsMut<u128> for Align16U128 {
fn as_mut(&mut self) -> &mut u128 {
&mut self.0
}
}
impl From<u128> for Align16U128 {
fn from(value: u128) -> Self {
Self(value)
}
}
impl From<Align16U128> for u128 {
fn from(value: Align16U128) -> Self {
value.0
}
}
impl core::fmt::Display for Align16U128 {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", self.0)
}
}
#[repr(C, align(16))]
#[derive(Copy, Clone, Pod, Zeroable, Default, Debug)]
pub struct Align16I128(pub i128);
impl Deref for Align16I128 {
type Target = i128;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Align16I128 {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl AsRef<i128> for Align16I128 {
fn as_ref(&self) -> &i128 {
&self.0
}
}
impl AsMut<i128> for Align16I128 {
fn as_mut(&mut self) -> &mut i128 {
&mut self.0
}
}
impl From<i128> for Align16I128 {
fn from(value: i128) -> Self {
Self(value)
}
}
impl From<Align16I128> for i128 {
fn from(value: Align16I128) -> Self {
value.0
}
}
impl core::fmt::Display for Align16I128 {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", self.0)
}
}
#[repr(C)]
#[derive(Copy, Clone, Eq, PartialEq, Pod, Zeroable)]
pub struct PodBool(u8);
impl core::fmt::Debug for PodBool {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if let Ok(b) = self.try_as_bool() {
write!(f, "PodBool({})", b)
} else {
write!(f, "PodBool(InvalidValue({}))", self.0)
}
}
}
impl From<bool> for PodBool {
fn from(v: bool) -> Self {
Self(u8::from(v))
}
}
pub struct InvalidPodBool {}
impl PodBool {
pub fn as_bool(&self) -> bool {
match self.0 {
0 => false,
1 => true,
#[allow(clippy::panic)]
_ => panic!("invalid value in PodBool"),
}
}
pub fn try_as_bool(&self) -> Result<bool, InvalidPodBool> {
match self.0 {
0 => Ok(false),
1 => Ok(true),
_ => Err(InvalidPodBool {}),
}
}
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct TransparentPad<T, const PAD: usize>(pub T, [u8; PAD]);
#[allow(unsafe_code)]
unsafe impl<T: Zeroable, const PAD: usize> Zeroable for TransparentPad<T, PAD> {}
#[allow(unsafe_code)]
unsafe impl<T: AnyBitPattern, const PAD: usize> AnyBitPattern for TransparentPad<T, PAD> {}
#[doc(hidden)] #[macro_export]
macro_rules! impl_checked_bit_pattern_for_transparent_pad {
($inner:ident) => {
#[allow(unsafe_code)]
unsafe impl<const PAD: usize> bytemuck::CheckedBitPattern
for $crate::TransparentPad<$inner, PAD>
{
type Bits = $crate::TransparentPad<<$inner as bytemuck::CheckedBitPattern>::Bits, PAD>;
fn is_valid_bit_pattern(bits: &Self::Bits) -> bool {
<$inner as bytemuck::CheckedBitPattern>::is_valid_bit_pattern(&bits.0)
}
}
};
}
impl<T, const PAD: usize> TransparentPad<T, PAD> {
pub fn new(inner: T) -> Self {
Self(inner, [0u8; PAD])
}
}
impl<T, const PAD: usize> AsRef<T> for TransparentPad<T, PAD> {
fn as_ref(&self) -> &T {
&self.0
}
}
impl<T, const PAD: usize> AsMut<T> for TransparentPad<T, PAD> {
fn as_mut(&mut self) -> &mut T {
&mut self.0
}
}
impl<T, const PAD: usize> core::ops::Deref for TransparentPad<T, PAD> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T, const PAD: usize> core::ops::DerefMut for TransparentPad<T, PAD> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}