use crate::isa::{Byte, Word};
use std::fmt::{self, Debug, Display, Formatter};
#[repr(transparent)]
#[derive(Copy)]
#[derive_const(
Clone,
Default,
Eq,
Ord,
PartialEq,
PartialOrd,
)]
pub struct Long(u32);
impl Long {
pub const BITS: u32 = 32;
#[inline(always)]
#[must_use]
pub const fn from_u32(value: u32) -> Self {
Self(value)
}
#[inline]
#[must_use]
pub const fn from_i32(value: i32) -> Self {
Self(value.cast_unsigned())
}
#[inline]
#[must_use]
pub const fn from_be(value: Self) -> Self {
Self(u32::from_be(value.0))
}
#[inline]
#[must_use]
pub const fn from_ne_bytes(bytes: [u8; size_of::<Self>()]) -> Self {
Self(u32::from_ne_bytes(bytes))
}
#[inline]
#[must_use]
pub const fn from_be_bytes(bytes: [u8; size_of::<Self>()]) -> Self {
Self(u32::from_be_bytes(bytes))
}
#[inline]
#[must_use]
pub const fn add_usize(mut self, value: usize) -> Self {
self.0 = self.0.wrapping_add(value as u32);
self
}
#[inline]
#[must_use]
pub const fn sub_usize(mut self, value: usize) -> Self {
self.0 = self.0.wrapping_sub(value as u32);
self
}
#[inline]
#[must_use]
pub const fn offset_isize(mut self, offset: isize) -> Self {
self.0 = self.0.wrapping_add_signed(offset as i32);
self
}
#[inline(always)]
#[must_use]
pub const fn as_u32(self) -> u32 {
self.0
}
#[inline]
#[must_use]
pub const fn as_i32(self) -> i32 {
self.0.cast_signed()
}
#[inline]
#[must_use]
pub const fn as_usize(self) -> usize {
self.0 as usize
}
#[inline]
#[must_use]
pub const fn to_be(self) -> Self {
Self(self.0.to_be())
}
#[inline]
#[must_use]
pub const fn to_ne_bytes(self) -> [u8; size_of::<Self>()] {
self.0.to_ne_bytes()
}
#[inline]
#[must_use]
pub const fn to_be_bytes(self) -> [u8; size_of::<Self>()] {
self.0.to_be_bytes()
}
}
impl Debug for Long {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let prefix = match self.as_u32().max(1).ilog(16) {
0 => "$.......",
1 => "$......",
2 => "$.....",
3 => "$....",
4 => "$...",
5 => "$..",
6 => "$.",
7 => "$",
_ => {
unreachable!();
}
};
write!(f, "{prefix}{:x}", self.as_u32())
}
}
impl Display for Long {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Debug::fmt(self, f)
}
}
const impl From<Byte> for Long {
#[inline]
fn from(value: Byte) -> Self {
Self::from_u32(value.as_u8().into())
}
}
const impl From<i16> for Long {
#[inline]
fn from(value: i16) -> Self {
Self::from_i32(value.into())
}
}
const impl From<i32> for Long {
#[inline(always)]
fn from(value: i32) -> Self {
Self::from_i32(value)
}
}
const impl From<i8> for Long {
#[inline]
fn from(value: i8) -> Self {
Self::from_i32(value.into())
}
}
const impl From<u16> for Long {
#[inline]
fn from(value: u16) -> Self {
Self::from_u32(value.into())
}
}
const impl From<u32> for Long {
#[inline(always)]
fn from(value: u32) -> Self {
Self::from_u32(value)
}
}
const impl From<u8> for Long {
#[inline]
fn from(value: u8) -> Self {
Self::from_u32(value.into())
}
}
const impl From<Word> for Long {
#[inline]
fn from(value: Word) -> Self {
Self::from_u32(value.as_u16().into())
}
}