Skip to content

Commit

Permalink
get rid of macros
Browse files Browse the repository at this point in the history
  • Loading branch information
isaacholt100 committed Jan 6, 2025
1 parent 6d9db86 commit 57801c6
Show file tree
Hide file tree
Showing 63 changed files with 5,298 additions and 5,579 deletions.
18 changes: 7 additions & 11 deletions src/bint/bigint_helpers.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
macro_rules! bigint_helpers {
($BUint: ident, $BInt: ident, $Digit: ident) => {
#[doc = doc::bigint_helpers::impl_desc!()]
impl<const N: usize> $BInt<N> {
crate::int::bigint_helpers::impls!(I);
}
};
use super::BIntD8;

#[doc = doc::bigint_helpers::impl_desc!()]
impl<const N: usize> BIntD8<N> {
crate::int::bigint_helpers::impls!(I);
}

#[cfg(test)]
crate::test::all_digit_tests! {
mod tests {
use crate::test::types::itest;

crate::int::bigint_helpers::tests!(itest);
}

use crate::doc;

crate::macro_impl!(bigint_helpers);
175 changes: 54 additions & 121 deletions src/bint/cast.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
use super::BIntD8;
use crate::{BUintD8, digit, Digit};

macro_rules! bint_as {
($BInt: ident, $Digit: ident; $($int: ty), *) => {
($($int: ty), *) => {
$(
impl<const N: usize> CastFrom<$BInt<N>> for $int {
impl<const N: usize> CastFrom<BIntD8<N>> for $int {
#[inline]
fn cast_from(from: $BInt<N>) -> Self {
fn cast_from(from: BIntD8<N>) -> Self {
if from.is_negative() {
let digits = from.bits.digits;
let mut out = !0;
let mut i = 0;
while i << digit::$Digit::BIT_SHIFT < <$int>::BITS as usize && i < N {
out &= !((!digits[i]) as $int << (i << digit::$Digit::BIT_SHIFT));
while i << digit::BIT_SHIFT < <$int>::BITS as usize && i < N {
out &= !((!digits[i]) as $int << (i << digit::BIT_SHIFT));
i += 1;
}
out
Expand All @@ -23,31 +26,31 @@ macro_rules! bint_as {
}

macro_rules! as_bint {
($BInt: ident, $BUint: ident; $($ty: ty), *) => {
($($ty: ty), *) => {
$(
impl<const N: usize> CastFrom<$ty> for $BInt<N> {
impl<const N: usize> CastFrom<$ty> for BIntD8<N> {
#[inline]
fn cast_from(from: $ty) -> Self {
Self::from_bits($BUint::cast_from(from))
Self::from_bits(BUintD8::cast_from(from))
}
}
)*
}
}

macro_rules! bint_cast_from_float {
($f: ty, $BUint: ident <$N: ident>) => {
($f: ty) => {
#[inline]
fn cast_from(from: $f) -> Self {
if from.is_sign_negative() {
let u = $BUint::<$N>::cast_from(-from);
let u = BUintD8::<N>::cast_from(-from);
if u >= Self::MIN.to_bits() {
Self::MIN
} else {
-Self::from_bits(u)
}
} else {
let u = $BUint::<$N>::cast_from(from);
let u = BUintD8::<N>::cast_from(from);
let i = Self::from_bits(u);
if i.is_negative() {
Self::MAX
Expand All @@ -62,130 +65,60 @@ macro_rules! bint_cast_from_float {
pub(crate) use bint_cast_from_float;

use crate::cast::CastFrom;
use crate::digit;

macro_rules! cast {
($BUint: ident, $BInt: ident, $Digit: ident) => {
bint_as!($BInt, $Digit; u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
bint_as!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);

impl<const N: usize> CastFrom<$BInt<N>> for f32 {
#[inline]
fn cast_from(from: $BInt<N>) -> Self {
let f = f32::cast_from(from.unsigned_abs());
if from.is_negative() {
-f
} else {
f
}
}
impl<const N: usize> CastFrom<BIntD8<N>> for f32 {
#[inline]
fn cast_from(from: BIntD8<N>) -> Self {
let f = f32::cast_from(from.unsigned_abs());
if from.is_negative() {
-f
} else {
f
}
}
}

impl<const N: usize> CastFrom<$BInt<N>> for f64 {
#[inline]
fn cast_from(from: $BInt<N>) -> Self {
let f = f64::cast_from(from.unsigned_abs());
if from.is_negative() {
-f
} else {
f
}
}
impl<const N: usize> CastFrom<BIntD8<N>> for f64 {
#[inline]
fn cast_from(from: BIntD8<N>) -> Self {
let f = f64::cast_from(from.unsigned_abs());
if from.is_negative() {
-f
} else {
f
}
}
}

as_bint!($BInt, $BUint; u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, bool, char);
as_bint!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, bool, char);

impl<const N: usize, const M: usize> CastFrom<$BUint<M>> for $BInt<N> {
#[inline]
fn cast_from(from: $BUint<M>) -> Self {
Self::from_bits($BUint::cast_from(from))
}
}
impl<const N: usize, const M: usize> CastFrom<BUintD8<M>> for BIntD8<N> {
#[inline]
fn cast_from(from: BUintD8<M>) -> Self {
Self::from_bits(BUintD8::cast_from(from))
}
}

impl<const N: usize, const M: usize> CastFrom<$BInt<M>> for $BInt<N> {
#[inline]
fn cast_from(from: $BInt<M>) -> Self {
Self::from_bits($BUint::cast_from(from))
}
}
impl<const N: usize, const M: usize> CastFrom<BIntD8<M>> for BIntD8<N> {
#[inline]
fn cast_from(from: BIntD8<M>) -> Self {
Self::from_bits(BUintD8::cast_from(from))
}
}

impl<const N: usize> CastFrom<f32> for $BInt<N> {
crate::bint::cast::bint_cast_from_float!(f32, $BUint<N>);
}
impl<const N: usize> CastFrom<f32> for BIntD8<N> {
crate::bint::cast::bint_cast_from_float!(f32);
}

impl<const N: usize> CastFrom<f64> for $BInt<N> {
crate::bint::cast::bint_cast_from_float!(f64, $BUint<N>);
}
};
impl<const N: usize> CastFrom<f64> for BIntD8<N> {
crate::bint::cast::bint_cast_from_float!(f64);
}

#[cfg(test)]
crate::test::all_digit_tests! {
mod tests {
use crate::test::types::itest;

crate::int::cast::tests!(itest);
}

crate::macro_impl!(cast);

macro_rules! bint_as_different_digit_bigint {
($BUint: ident, $BInt: ident, $Digit: ident; $(($OtherBInt: ident, $OtherDigit: ident)), *) => {
$(
impl<const N: usize, const M: usize> crate::cast::CastFrom<$OtherBInt<M>> for $BUint<N> {
#[must_use = doc::must_use_op!()]
#[inline]
fn cast_from(from: $OtherBInt<M>) -> Self {
if !from.is_negative() || M * $OtherDigit::BITS as usize >= N * $Digit::BITS as usize { // $OtherBInt::BITS <= $Int::BITS
Self::cast_from(from.to_bits())
} else {
let mut out = Self::MAX;
if $Digit::BITS < $OtherDigit::BITS {
const DIVIDE_COUNT: usize = ($OtherDigit::BITS / $Digit::BITS) as usize;
let stop_index: usize = if <$OtherBInt<M>>::BITS > <$BUint<N>>::BITS {
N
} else {
M * DIVIDE_COUNT
};
let mut i = 0;
while i < stop_index {
let wider_digit = from.bits.digits[i / DIVIDE_COUNT];
let mini_shift = i % DIVIDE_COUNT;
let digit = (wider_digit >> (mini_shift << digit::$Digit::BIT_SHIFT)) as $Digit;
out.digits[i] = digit;
i += 1;
}
} else {
const DIVIDE_COUNT: usize = ($Digit::BITS / $OtherDigit::BITS) as usize;
let stop_index: usize = if <$OtherBInt<M>>::BITS > <$BUint<N>>::BITS {
N * DIVIDE_COUNT
} else {
M
};
let mut current_digit: $Digit = $Digit::MAX;
let mut i = 0;
while i < stop_index {
let mini_shift = i % DIVIDE_COUNT;
current_digit &= !((!from.bits.digits[i] as $Digit) << (mini_shift << digit::$OtherDigit::BIT_SHIFT));
if mini_shift == DIVIDE_COUNT - 1 || i == stop_index - 1 {
out.digits[i / DIVIDE_COUNT] = current_digit;
current_digit = $Digit::MAX;
}
i += 1;
}
}
out
}
}
}

impl<const N: usize, const M: usize> crate::cast::CastFrom<$OtherBInt<M>> for $BInt<N> {
#[must_use = doc::must_use_op!()]
#[inline]
fn cast_from(from: $OtherBInt<M>) -> Self {
Self::from_bits($BUint::<N>::cast_from(from))
}
}
)*
};
}

pub(crate) use bint_as_different_digit_bigint;
Loading

0 comments on commit 57801c6

Please sign in to comment.