Skip to content

Commit

Permalink
Refactored IArray / IArrayMut so that it's more useful as a generic b…
Browse files Browse the repository at this point in the history
…ound
  • Loading branch information
haxelion committed Jul 10, 2024
1 parent 8bec73d commit 813b25f
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 134 deletions.
41 changes: 24 additions & 17 deletions src/auto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,33 +82,40 @@ impl BV {
// BV - Integer Array traits
// ------------------------------------------------------------------------------------------------

impl<I: Integer> IArray<I> for BV
where
u64: StaticCast<I>,
{
fn int_len(&self) -> usize {
impl IArray for BV {
type I = u64;

fn int_len<J: Integer>(&self) -> usize
where
u64: StaticCast<J>,
{
match self {
BV::Fixed(bvf) => IArray::<I>::int_len(bvf),
BV::Dynamic(bvd) => IArray::<I>::int_len(bvd),
BV::Fixed(bvf) => IArray::int_len(bvf),
BV::Dynamic(bvd) => IArray::int_len(bvd),
}
}

fn get_int(&self, idx: usize) -> Option<I> {
fn get_int<J: Integer>(&self, idx: usize) -> Option<J>
where
u64: StaticCast<J>,
{
match self {
BV::Fixed(bvf) => IArray::<I>::get_int(bvf, idx),
BV::Dynamic(bvd) => IArray::<I>::get_int(bvd, idx),
BV::Fixed(bvf) => IArray::get_int(bvf, idx),
BV::Dynamic(bvd) => IArray::get_int(bvd, idx),
}
}
}

impl<I: Integer> IArrayMut<I> for BV
where
u64: StaticCast<I>,
{
fn set_int(&mut self, idx: usize, v: I) -> Option<I> {
impl IArrayMut for BV {
type I = u64;

fn set_int<J: Integer>(&mut self, idx: usize, v: J) -> Option<J>
where
u64: StaticCast<J>,
{
match self {
BV::Fixed(bvf) => IArrayMut::<I>::set_int(bvf, idx, v),
BV::Dynamic(bvd) => IArrayMut::<I>::set_int(bvd, idx, v),
BV::Fixed(bvf) => IArrayMut::set_int(bvf, idx, v),
BV::Dynamic(bvd) => IArrayMut::set_int(bvd, idx, v),
}
}
}
Expand Down
69 changes: 38 additions & 31 deletions src/dynamic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,30 +88,37 @@ impl BVD {
// BVD - Integer Array traits
// ------------------------------------------------------------------------------------------------

impl<I: Integer> IArray<I> for BVD
where
u64: StaticCast<I>,
{
fn int_len(&self) -> usize {
(self.len() + size_of::<I>() * 8 - 1) / (size_of::<I>() * 8)
impl IArray for BVD {
type I = u64;

fn int_len<J: Integer>(&self) -> usize
where
u64: StaticCast<J>,
{
(self.len() + size_of::<J>() * 8 - 1) / (size_of::<J>() * 8)
}

fn get_int(&self, idx: usize) -> Option<I> {
if idx < IArray::<I>::int_len(self) {
IArray::<I>::get_int(self.data.as_ref(), idx)
fn get_int<J: Integer>(&self, idx: usize) -> Option<J>
where
u64: StaticCast<J>,
{
if idx < IArray::int_len::<J>(self) {
IArray::get_int::<J>(self.data.as_ref(), idx)
} else {
None
}
}
}

impl<I: Integer> IArrayMut<I> for BVD
where
u64: StaticCast<I>,
{
fn set_int(&mut self, idx: usize, v: I) -> Option<I> {
if idx < IArray::<I>::int_len(self) {
IArrayMut::<I>::set_int(self.data.as_mut(), idx, v)
impl IArrayMut for BVD {
type I = u64;

fn set_int<J: Integer>(&mut self, idx: usize, v: J) -> Option<J>
where
u64: StaticCast<J>,
{
if idx < IArray::int_len::<J>(self) {
IArrayMut::set_int::<J>(self.data.as_mut(), idx, v)
} else {
None
}
Expand Down Expand Up @@ -748,8 +755,8 @@ impl PartialEq for BVD {

impl<I: Integer, const N: usize> PartialEq<BVF<I, N>> for BVD {
fn eq(&self, other: &BVF<I, N>) -> bool {
for i in 0..usize::max(self.len(), IArray::<u64>::int_len(other)) {
if *self.data.get(i).unwrap_or(&0) != IArray::<u64>::get_int(other, i).unwrap_or(0) {
for i in 0..usize::max(self.len(), IArray::int_len::<u64>(other)) {
if *self.data.get(i).unwrap_or(&0) != IArray::get_int(other, i).unwrap_or(0) {
return false;
}
}
Expand All @@ -773,12 +780,12 @@ impl PartialOrd for BVD {

impl<I: Integer, const N: usize> PartialOrd<BVF<I, N>> for BVD {
fn partial_cmp(&self, other: &BVF<I, N>) -> Option<Ordering> {
for i in (0..usize::max(self.len(), IArray::<u64>::int_len(other))).rev() {
for i in (0..usize::max(self.len(), IArray::int_len::<u64>(other))).rev() {
match self
.data
.get(i)
.unwrap_or(&0)
.cmp(&IArray::<u64>::get_int(other, i).unwrap_or(0))
.cmp(&IArray::get_int(other, i).unwrap_or(0))
{
Ordering::Equal => continue,
ord => return Some(ord),
Expand Down Expand Up @@ -831,7 +838,7 @@ macro_rules! impl_from_ints {($($st:ty),+) => {
let array = [st];
BVD {
length: <$st>::BITS as usize,
data: (0..IArray::<u64>::int_len(array.as_ref())).map(|i| IArray::<u64>::get_int(array.as_ref(), i).unwrap()).collect(),
data: (0..IArray::int_len::<u64>(array.as_ref())).map(|i| IArray::get_int(array.as_ref(), i).unwrap()).collect(),
}
}
}
Expand Down Expand Up @@ -867,8 +874,8 @@ impl<I: Integer, const N: usize> From<&BVF<I, N>> for BVD {
fn from(rhs: &BVF<I, N>) -> BVD {
BVD {
length: rhs.len(),
data: (0..IArray::<u64>::int_len(rhs))
.map(|i| IArray::<u64>::get_int(rhs, i).unwrap())
data: (0..IArray::int_len::<u64>(rhs))
.map(|i| IArray::get_int(rhs, i).unwrap())
.collect(),
}
}
Expand Down Expand Up @@ -1111,10 +1118,10 @@ macro_rules! impl_binop_assign {

impl<I: Integer, const N: usize> $trait<&BVF<I, N>> for BVD {
fn $method(&mut self, rhs: &BVF<I, N>) {
for i in 0..usize::min(IArray::<u64>::int_len(rhs), self.data.len()) {
self.data[i].$method(IArray::<u64>::get_int(rhs, i).unwrap());
for i in 0..usize::min(IArray::int_len::<u64>(rhs), self.data.len()) {
self.data[i].$method(IArray::get_int::<u64>(rhs, i).unwrap());
}
for i in usize::min(IArray::<u64>::int_len(rhs), self.data.len())..self.data.len() {
for i in usize::min(IArray::int_len::<u64>(rhs), self.data.len())..self.data.len() {
self.data[i].$method(0);
}
}
Expand Down Expand Up @@ -1180,13 +1187,13 @@ macro_rules! impl_addsub_assign {
impl<I: Integer, const N: usize> $trait<&BVF<I, N>> for BVD {
fn $method(&mut self, rhs: &BVF<I, N>) {
let mut carry = 0;
for i in 0..IArray::<u64>::int_len(rhs) {
for i in 0..IArray::int_len::<u64>(rhs) {
let (d1, c1) = self.data[i].$overflowing_method(carry);
let (d2, c2) = d1.$overflowing_method(IArray::<u64>::get_int(rhs, i).unwrap());
let (d2, c2) = d1.$overflowing_method(IArray::get_int(rhs, i).unwrap());
self.data[i] = d2;
carry = (c1 | c2) as u64;
}
for i in IArray::<u64>::int_len(rhs)..Self::capacity_from_bit_len(self.length) {
for i in IArray::int_len::<u64>(rhs)..Self::capacity_from_bit_len(self.length) {
let (d, c) = self.data[i].$overflowing_method(carry);
self.data[i] = d;
carry = c as u64;
Expand Down Expand Up @@ -1311,12 +1318,12 @@ impl<I: Integer, const N: usize> Mul<&BVF<I, N>> for &BVD {
type Output = BVD;
fn mul(self, rhs: &BVF<I, N>) -> BVD {
let mut res = BVD::zeros(self.length);
let len = IArray::<u64>::int_len(&res);
let len = IArray::int_len::<u64>(&res);

for i in 0..len {
let mut carry = 0;
for j in 0..(len - i) {
let product = self.data[i].wmul(IArray::<u64>::get_int(rhs, j).unwrap_or(0));
let product = self.data[i].wmul(IArray::get_int(rhs, j).unwrap_or(0));
carry = res.data[i + j].cadd(product.0, carry) + product.1;
}
}
Expand Down
81 changes: 43 additions & 38 deletions src/fixed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,30 +71,37 @@ impl<I: Integer, const N: usize> BVF<I, N> {
// BVF - Integer Array traits
// ------------------------------------------------------------------------------------------------

impl<I: Integer, J: Integer, const N: usize> IArray<I> for BVF<J, N>
where
J: StaticCast<I>,
{
fn int_len(&self) -> usize {
(self.length + size_of::<I>() * 8 - 1) / (size_of::<I>() * 8)
impl<I: Integer, const N: usize> IArray for BVF<I, N> {
type I = I;

fn int_len<J: Integer>(&self) -> usize
where
I: StaticCast<J>,
{
(self.length + size_of::<J>() * 8 - 1) / (size_of::<J>() * 8)
}

fn get_int(&self, idx: usize) -> Option<I> {
if idx < IArray::<I>::int_len(self) {
IArray::<I>::get_int(self.data.as_ref(), idx)
fn get_int<J: Integer>(&self, idx: usize) -> Option<J>
where
I: StaticCast<J>,
{
if idx < IArray::int_len::<J>(self) {
IArray::get_int::<J>(self.data.as_ref(), idx)
} else {
None
}
}
}

impl<I: Integer, J: Integer, const N: usize> IArrayMut<I> for BVF<J, N>
where
J: StaticCast<I>,
{
fn set_int(&mut self, idx: usize, v: I) -> Option<I> {
if idx < IArray::<I>::int_len(self) {
IArrayMut::<I>::set_int(self.data.as_mut(), idx, v)
impl<I: Integer, const N: usize> IArrayMut for BVF<I, N> {
type I = I;

fn set_int<J: Integer>(&mut self, idx: usize, v: J) -> Option<J>
where
I: StaticCast<J>,
{
if idx < IArray::int_len::<J>(self) {
IArrayMut::set_int::<J>(self.data.as_mut(), idx, v)
} else {
None
}
Expand Down Expand Up @@ -732,9 +739,9 @@ where
I2: StaticCast<I1>,
{
fn eq(&self, other: &BVF<I1, N1>) -> bool {
for i in 0..usize::max(IArray::<I1>::int_len(self), IArray::<I1>::int_len(other)) {
if IArray::<I1>::get_int(self, i).unwrap_or(I1::ZERO)
!= IArray::<I1>::get_int(other, i).unwrap_or(I1::ZERO)
for i in 0..usize::max(IArray::int_len::<I1>(self), IArray::int_len::<I1>(other)) {
if IArray::get_int(self, i).unwrap_or(I1::ZERO)
!= IArray::get_int(other, i).unwrap_or(I1::ZERO)
{
return false;
}
Expand Down Expand Up @@ -767,10 +774,10 @@ where
I2: StaticCast<I1>,
{
fn partial_cmp(&self, other: &BVF<I1, N1>) -> Option<std::cmp::Ordering> {
for i in (0..usize::max(IArray::<I1>::int_len(self), IArray::<I1>::int_len(other))).rev() {
match IArray::<I1>::get_int(self, i)
for i in (0..usize::max(IArray::int_len::<I1>(self), IArray::int_len::<I1>(other))).rev() {
match IArray::get_int(self, i)
.unwrap_or(I1::ZERO)
.cmp(&IArray::<I1>::get_int(other, i).unwrap_or(I1::ZERO))
.cmp(&IArray::get_int(other, i).unwrap_or(I1::ZERO))
{
Ordering::Equal => continue,
ord => return Some(ord),
Expand Down Expand Up @@ -853,7 +860,7 @@ macro_rules! impl_tryfrom { ($($type:ty),+) => {
Err(ConvertionError::NotEnoughCapacity)
}
else {
Ok(IArray::<$type>::get_int(bv, 0).unwrap())
Ok(IArray::get_int(bv, 0).unwrap())
}
}
}
Expand Down Expand Up @@ -883,8 +890,8 @@ where
Err(ConvertionError::NotEnoughCapacity)
} else {
let mut data = [I2::ZERO; N2];
for i in 0..usize::min(N2, IArray::<I2>::int_len(bvf)) {
data[i] = IArray::<I2>::get_int(bvf, i).unwrap();
for i in 0..usize::min(N2, IArray::int_len::<I2>(bvf)) {
data[i] = IArray::get_int(bvf, i).unwrap();
}
Ok(BVF::<I2, N2> {
data,
Expand Down Expand Up @@ -935,8 +942,8 @@ where
Err(ConvertionError::NotEnoughCapacity)
} else {
let mut data = [I::ZERO; N];
for i in 0..IArray::<I>::int_len(bv) {
data[i] = IArray::<I>::get_int(bv, i).unwrap();
for i in 0..IArray::int_len::<I>(bv) {
data[i] = IArray::get_int(bv, i).unwrap();
}
Ok(BVF::<I, N> {
data,
Expand Down Expand Up @@ -1128,7 +1135,7 @@ macro_rules! impl_binop_assign {
}
} else {
for i in 0..N1 {
self.data[i].$method(IArray::<I1>::get_int(rhs, i).unwrap_or(I1::ZERO));
self.data[i].$method(IArray::get_int(rhs, i).unwrap_or(I1::ZERO));
}
}
}
Expand All @@ -1150,7 +1157,7 @@ macro_rules! impl_binop_assign {
{
fn $method(&mut self, rhs: &BVD) {
for i in 0..N {
self.data[i].$method(IArray::<I>::get_int(rhs, i).unwrap_or(I::ZERO));
self.data[i].$method(IArray::get_int(rhs, i).unwrap_or(I::ZERO));
}
}
}
Expand Down Expand Up @@ -1213,10 +1220,8 @@ macro_rules! impl_addsub_assign {
} else {
let mut carry = I1::ZERO;
for i in 0..N1 {
carry = self.data[i].$carry_method(
IArray::<I1>::get_int(rhs, i).unwrap_or(I1::ZERO),
carry,
);
carry = self.data[i]
.$carry_method(IArray::get_int(rhs, i).unwrap_or(I1::ZERO), carry);
}
self.mod2n(self.length);
}
Expand All @@ -1241,7 +1246,7 @@ macro_rules! impl_addsub_assign {
let mut carry = I::ZERO;
for i in 0..N {
carry = self.data[i]
.$carry_method(IArray::<I>::get_int(rhs, i).unwrap_or(I::ZERO), carry);
.$carry_method(IArray::get_int(rhs, i).unwrap_or(I::ZERO), carry);
}
self.mod2n(self.length);
}
Expand Down Expand Up @@ -1330,11 +1335,11 @@ where
type Output = BVF<I1, N1>;
fn mul(self, rhs: &BVF<I2, N2>) -> BVF<I1, N1> {
let mut res = BVF::<I1, N1>::zeros(self.length);
let len = IArray::<I1>::int_len(&res);
let len = IArray::int_len::<I1>(&res);
for i in 0..len {
let mut carry = I1::ZERO;
for j in 0..(len - i) {
let product = self.data[i].wmul(IArray::<I1>::get_int(rhs, j).unwrap_or(I1::ZERO));
let product = self.data[i].wmul(IArray::get_int(rhs, j).unwrap_or(I1::ZERO));
carry = res.data[i + j].cadd(product.0, carry) + product.1;
}
}
Expand Down Expand Up @@ -1381,11 +1386,11 @@ where
type Output = BVF<I, N>;
fn mul(self, rhs: &BVD) -> BVF<I, N> {
let mut res = BVF::<I, N>::zeros(self.length);
let len = IArray::<I>::int_len(&res);
let len = IArray::int_len::<I>(&res);
for i in 0..len {
let mut carry = I::ZERO;
for j in 0..(len - i) {
let product = self.data[i].wmul(IArray::<I>::get_int(rhs, j).unwrap_or(I::ZERO));
let product = self.data[i].wmul(IArray::get_int(rhs, j).unwrap_or(I::ZERO));
carry = res.data[i + j].cadd(product.0, carry) + product.1;
}
}
Expand Down
Loading

0 comments on commit 813b25f

Please sign in to comment.