use crate::Exponent;
use crate::OverflowMode;
use crate::{Int, Integer};
use core::cmp::Ordering;
impl<const S: bool, const N: usize, const B: usize, const OM: u8> Integer<S, N, B, OM> {
#[inline]
pub const fn bitand(self, rhs: Self) -> Self {
self.to_digits::<u8>().bitand(rhs.to_digits()).to_integer() }
#[inline]
pub const fn bitor(self, rhs: Self) -> Self {
self.to_digits::<u8>().bitor(rhs.to_digits()).to_integer() }
#[inline]
pub const fn bitxor(self, rhs: Self) -> Self {
self.to_digits::<u8>().bitxor(rhs.to_digits()).to_integer() }
#[inline]
pub const fn not(self) -> Self {
let mut out = self.to_digits::<u8>().not().to_integer(); out.set_sign_bits(); out
}
#[inline]
pub const fn eq(&self, other: &Self) -> bool {
self.as_digits::<u128>().eq(other.as_digits())
}
#[inline]
pub const fn ne(&self, other: &Self) -> bool {
!Self::eq(self, other)
}
#[inline]
pub const fn cmp(&self, other: &Self) -> Ordering {
match (self.is_negative_internal(), other.is_negative_internal()) {
(true, false) => Ordering::Less,
(false, true) => Ordering::Greater,
_ => self.as_digits::<u32>().cmp(other.as_digits()),
}
}
#[inline]
pub const fn max(self, other: Self) -> Self {
match self.cmp(&other) {
Ordering::Less | Ordering::Equal => other,
_ => self,
}
}
#[inline]
pub const fn min(self, other: Self) -> Self {
match self.cmp(&other) {
Ordering::Less | Ordering::Equal => self,
_ => other,
}
}
#[inline]
pub const fn clamp(self, min: Self, max: Self) -> Self {
assert!(min.le(&max));
if let Ordering::Less = self.cmp(&min) {
min
} else if let Ordering::Greater = self.cmp(&max) {
max
} else {
self
}
}
#[inline]
pub const fn lt(&self, other: &Self) -> bool {
match self.cmp(&other) {
Ordering::Less => true,
_ => false,
}
}
#[inline]
pub const fn le(&self, other: &Self) -> bool {
match self.cmp(&other) {
Ordering::Less | Ordering::Equal => true,
_ => false,
}
}
#[inline]
pub const fn gt(&self, other: &Self) -> bool {
match self.cmp(&other) {
Ordering::Greater => true,
_ => false,
}
}
#[inline]
pub const fn ge(&self, other: &Self) -> bool {
match self.cmp(&other) {
Ordering::Greater | Ordering::Equal => true,
_ => false,
}
}
#[inline]
pub const fn add(self, rhs: Self) -> Self {
match Self::OVERFLOW_MODE {
OverflowMode::Wrap => self.wrapping_add(rhs),
OverflowMode::Panic => self.strict_add(rhs),
OverflowMode::Saturate => self.saturating_add(rhs),
}
}
#[inline]
pub const fn mul(self, rhs: Self) -> Self {
match Self::OVERFLOW_MODE {
OverflowMode::Wrap => self.wrapping_mul(rhs),
OverflowMode::Panic => self.strict_mul(rhs),
OverflowMode::Saturate => self.saturating_mul(rhs),
}
}
#[inline]
pub const fn shl(self, rhs: Exponent) -> Self {
match Self::OVERFLOW_MODE {
OverflowMode::Wrap => self.wrapping_shl(rhs),
OverflowMode::Panic => self.strict_shl(rhs),
OverflowMode::Saturate => self.unbounded_shl(rhs),
}
}
#[inline]
pub const fn shr(self, rhs: Exponent) -> Self {
match Self::OVERFLOW_MODE {
OverflowMode::Wrap => self.wrapping_shr(rhs),
OverflowMode::Panic => self.strict_shr(rhs),
OverflowMode::Saturate => self.unbounded_shr(rhs),
}
}
#[inline]
pub const fn sub(self, rhs: Self) -> Self {
match Self::OVERFLOW_MODE {
OverflowMode::Wrap => self.wrapping_sub(rhs),
OverflowMode::Panic => self.strict_sub(rhs),
OverflowMode::Saturate => self.saturating_sub(rhs),
}
}
#[inline]
pub const fn div(self, rhs: Self) -> Self {
match Self::OVERFLOW_MODE {
OverflowMode::Wrap => self.wrapping_div(rhs),
OverflowMode::Panic => self.strict_div(rhs),
OverflowMode::Saturate => self.saturating_div(rhs),
}
}
#[inline]
pub const fn rem(self, rhs: Self) -> Self {
match Self::OVERFLOW_MODE {
OverflowMode::Wrap => self.wrapping_rem(rhs),
OverflowMode::Panic => self.strict_rem(rhs),
OverflowMode::Saturate => self.saturating_rem(rhs),
}
}
}
impl<const N: usize, const B: usize, const OM: u8> Int<N, B, OM> {
#[inline]
pub const fn neg(self) -> Self {
match Self::OVERFLOW_MODE {
OverflowMode::Wrap => self.wrapping_neg(),
OverflowMode::Panic => self.strict_neg(),
OverflowMode::Saturate => self.saturating_neg(),
}
}
}