macro_rules! decl_decimal_bitwise {
(wide $Type:ident, $Storage:ty) => {
$crate::macros::bitwise::decl_decimal_bitwise!(@common $Type, $Storage);
impl<const SCALE: u32> $Type<SCALE> {
#[inline]
#[must_use]
pub fn unsigned_shr(self, n: u32) -> Self {
Self((self.0.cast_unsigned() >> n).cast_signed())
}
#[inline]
#[must_use]
pub fn rotate_left(self, n: u32) -> Self {
Self(self.0.rotate_left(n))
}
#[inline]
#[must_use]
pub fn rotate_right(self, n: u32) -> Self {
Self(self.0.rotate_right(n))
}
#[inline]
#[must_use]
pub fn leading_zeros(self) -> u32 {
self.0.leading_zeros()
}
#[inline]
#[must_use]
pub fn trailing_zeros(self) -> u32 {
self.0.trailing_zeros()
}
#[inline]
#[must_use]
pub fn count_ones(self) -> u32 {
self.0.count_ones()
}
#[inline]
#[must_use]
pub fn count_zeros(self) -> u32 {
self.0.count_zeros()
}
#[inline]
#[must_use]
pub fn is_power_of_two(self) -> bool {
self.0.cast_unsigned().is_power_of_two()
}
#[inline]
#[must_use]
pub fn next_power_of_two(self) -> Self {
Self(self.0.cast_unsigned().next_power_of_two().cast_signed())
}
}
};
($Type:ident, $Storage:ty) => {
$crate::macros::bitwise::decl_decimal_bitwise!(@common $Type, $Storage);
impl<const SCALE: u32> $Type<SCALE> {
#[inline]
#[must_use]
pub const fn unsigned_shr(self, n: u32) -> Self {
Self(((self.0 as <$Storage as $crate::macros::bitwise::Unsigned>::U) >> n) as $Storage)
}
#[inline]
#[must_use]
pub const fn rotate_left(self, n: u32) -> Self {
Self(self.0.rotate_left(n))
}
#[inline]
#[must_use]
pub const fn rotate_right(self, n: u32) -> Self {
Self(self.0.rotate_right(n))
}
#[inline]
#[must_use]
pub const fn leading_zeros(self) -> u32 {
self.0.leading_zeros()
}
#[inline]
#[must_use]
pub const fn trailing_zeros(self) -> u32 {
self.0.trailing_zeros()
}
#[inline]
#[must_use]
pub const fn count_ones(self) -> u32 {
self.0.count_ones()
}
#[inline]
#[must_use]
pub const fn count_zeros(self) -> u32 {
self.0.count_zeros()
}
#[inline]
#[must_use]
pub const fn is_power_of_two(self) -> bool {
(self.0 as <$Storage as $crate::macros::bitwise::Unsigned>::U).is_power_of_two()
}
#[inline]
#[must_use]
pub const fn next_power_of_two(self) -> Self {
Self(
(self.0 as <$Storage as $crate::macros::bitwise::Unsigned>::U)
.next_power_of_two() as $Storage,
)
}
}
};
(@common $Type:ident, $Storage:ty) => {
impl<const SCALE: u32> ::core::ops::BitAnd for $Type<SCALE> {
type Output = Self;
#[inline]
fn bitand(self, rhs: Self) -> Self {
Self(self.0 & rhs.0)
}
}
impl<const SCALE: u32> ::core::ops::BitAndAssign for $Type<SCALE> {
#[inline]
fn bitand_assign(&mut self, rhs: Self) {
self.0 = self.0 & rhs.0;
}
}
impl<const SCALE: u32> ::core::ops::BitOr for $Type<SCALE> {
type Output = Self;
#[inline]
fn bitor(self, rhs: Self) -> Self {
Self(self.0 | rhs.0)
}
}
impl<const SCALE: u32> ::core::ops::BitOrAssign for $Type<SCALE> {
#[inline]
fn bitor_assign(&mut self, rhs: Self) {
self.0 = self.0 | rhs.0;
}
}
impl<const SCALE: u32> ::core::ops::BitXor for $Type<SCALE> {
type Output = Self;
#[inline]
fn bitxor(self, rhs: Self) -> Self {
Self(self.0 ^ rhs.0)
}
}
impl<const SCALE: u32> ::core::ops::BitXorAssign for $Type<SCALE> {
#[inline]
fn bitxor_assign(&mut self, rhs: Self) {
self.0 = self.0 ^ rhs.0;
}
}
impl<const SCALE: u32> ::core::ops::Shl<u32> for $Type<SCALE> {
type Output = Self;
#[inline]
fn shl(self, n: u32) -> Self {
Self(self.0 << n)
}
}
impl<const SCALE: u32> ::core::ops::ShlAssign<u32> for $Type<SCALE> {
#[inline]
fn shl_assign(&mut self, n: u32) {
self.0 = self.0 << n;
}
}
impl<const SCALE: u32> ::core::ops::Shr<u32> for $Type<SCALE> {
type Output = Self;
#[inline]
fn shr(self, n: u32) -> Self {
Self(self.0 >> n)
}
}
impl<const SCALE: u32> ::core::ops::ShrAssign<u32> for $Type<SCALE> {
#[inline]
fn shr_assign(&mut self, n: u32) {
self.0 = self.0 >> n;
}
}
impl<const SCALE: u32> ::core::ops::Not for $Type<SCALE> {
type Output = Self;
#[inline]
fn not(self) -> Self {
Self(!self.0)
}
}
};
}
pub(crate) trait Unsigned {
type U;
}
impl Unsigned for i32 {
type U = u32;
}
impl Unsigned for i64 {
type U = u64;
}
impl Unsigned for i128 {
type U = u128;
}
pub(crate) use decl_decimal_bitwise;