diff --git a/src/auto.rs b/src/auto.rs index ef685e1..711fedf 100644 --- a/src/auto.rs +++ b/src/auto.rs @@ -82,33 +82,40 @@ impl BV { // BV - Integer Array traits // ------------------------------------------------------------------------------------------------ -impl IArray for BV -where - u64: StaticCast, -{ - fn int_len(&self) -> usize { +impl IArray for BV { + type I = u64; + + fn int_len(&self) -> usize + where + u64: StaticCast, + { match self { - BV::Fixed(bvf) => IArray::::int_len(bvf), - BV::Dynamic(bvd) => IArray::::int_len(bvd), + BV::Fixed(bvf) => IArray::int_len(bvf), + BV::Dynamic(bvd) => IArray::int_len(bvd), } } - fn get_int(&self, idx: usize) -> Option { + fn get_int(&self, idx: usize) -> Option + where + u64: StaticCast, + { match self { - BV::Fixed(bvf) => IArray::::get_int(bvf, idx), - BV::Dynamic(bvd) => IArray::::get_int(bvd, idx), + BV::Fixed(bvf) => IArray::get_int(bvf, idx), + BV::Dynamic(bvd) => IArray::get_int(bvd, idx), } } } -impl IArrayMut for BV -where - u64: StaticCast, -{ - fn set_int(&mut self, idx: usize, v: I) -> Option { +impl IArrayMut for BV { + type I = u64; + + fn set_int(&mut self, idx: usize, v: J) -> Option + where + u64: StaticCast, + { match self { - BV::Fixed(bvf) => IArrayMut::::set_int(bvf, idx, v), - BV::Dynamic(bvd) => IArrayMut::::set_int(bvd, idx, v), + BV::Fixed(bvf) => IArrayMut::set_int(bvf, idx, v), + BV::Dynamic(bvd) => IArrayMut::set_int(bvd, idx, v), } } } diff --git a/src/dynamic.rs b/src/dynamic.rs index bfa22dc..2c26b2a 100644 --- a/src/dynamic.rs +++ b/src/dynamic.rs @@ -88,30 +88,37 @@ impl BVD { // BVD - Integer Array traits // ------------------------------------------------------------------------------------------------ -impl IArray for BVD -where - u64: StaticCast, -{ - fn int_len(&self) -> usize { - (self.len() + size_of::() * 8 - 1) / (size_of::() * 8) +impl IArray for BVD { + type I = u64; + + fn int_len(&self) -> usize + where + u64: StaticCast, + { + (self.len() + size_of::() * 8 - 1) / (size_of::() * 8) } - fn get_int(&self, idx: usize) -> Option { - if idx < IArray::::int_len(self) { - IArray::::get_int(self.data.as_ref(), idx) + fn get_int(&self, idx: usize) -> Option + where + u64: StaticCast, + { + if idx < IArray::int_len::(self) { + IArray::get_int::(self.data.as_ref(), idx) } else { None } } } -impl IArrayMut for BVD -where - u64: StaticCast, -{ - fn set_int(&mut self, idx: usize, v: I) -> Option { - if idx < IArray::::int_len(self) { - IArrayMut::::set_int(self.data.as_mut(), idx, v) +impl IArrayMut for BVD { + type I = u64; + + fn set_int(&mut self, idx: usize, v: J) -> Option + where + u64: StaticCast, + { + if idx < IArray::int_len::(self) { + IArrayMut::set_int::(self.data.as_mut(), idx, v) } else { None } @@ -748,8 +755,8 @@ impl PartialEq for BVD { impl PartialEq> for BVD { fn eq(&self, other: &BVF) -> bool { - for i in 0..usize::max(self.len(), IArray::::int_len(other)) { - if *self.data.get(i).unwrap_or(&0) != IArray::::get_int(other, i).unwrap_or(0) { + for i in 0..usize::max(self.len(), IArray::int_len::(other)) { + if *self.data.get(i).unwrap_or(&0) != IArray::get_int(other, i).unwrap_or(0) { return false; } } @@ -773,12 +780,12 @@ impl PartialOrd for BVD { impl PartialOrd> for BVD { fn partial_cmp(&self, other: &BVF) -> Option { - for i in (0..usize::max(self.len(), IArray::::int_len(other))).rev() { + for i in (0..usize::max(self.len(), IArray::int_len::(other))).rev() { match self .data .get(i) .unwrap_or(&0) - .cmp(&IArray::::get_int(other, i).unwrap_or(0)) + .cmp(&IArray::get_int(other, i).unwrap_or(0)) { Ordering::Equal => continue, ord => return Some(ord), @@ -831,7 +838,7 @@ macro_rules! impl_from_ints {($($st:ty),+) => { let array = [st]; BVD { length: <$st>::BITS as usize, - data: (0..IArray::::int_len(array.as_ref())).map(|i| IArray::::get_int(array.as_ref(), i).unwrap()).collect(), + data: (0..IArray::int_len::(array.as_ref())).map(|i| IArray::get_int(array.as_ref(), i).unwrap()).collect(), } } } @@ -867,8 +874,8 @@ impl From<&BVF> for BVD { fn from(rhs: &BVF) -> BVD { BVD { length: rhs.len(), - data: (0..IArray::::int_len(rhs)) - .map(|i| IArray::::get_int(rhs, i).unwrap()) + data: (0..IArray::int_len::(rhs)) + .map(|i| IArray::get_int(rhs, i).unwrap()) .collect(), } } @@ -1111,10 +1118,10 @@ macro_rules! impl_binop_assign { impl $trait<&BVF> for BVD { fn $method(&mut self, rhs: &BVF) { - for i in 0..usize::min(IArray::::int_len(rhs), self.data.len()) { - self.data[i].$method(IArray::::get_int(rhs, i).unwrap()); + for i in 0..usize::min(IArray::int_len::(rhs), self.data.len()) { + self.data[i].$method(IArray::get_int::(rhs, i).unwrap()); } - for i in usize::min(IArray::::int_len(rhs), self.data.len())..self.data.len() { + for i in usize::min(IArray::int_len::(rhs), self.data.len())..self.data.len() { self.data[i].$method(0); } } @@ -1180,13 +1187,13 @@ macro_rules! impl_addsub_assign { impl $trait<&BVF> for BVD { fn $method(&mut self, rhs: &BVF) { let mut carry = 0; - for i in 0..IArray::::int_len(rhs) { + for i in 0..IArray::int_len::(rhs) { let (d1, c1) = self.data[i].$overflowing_method(carry); - let (d2, c2) = d1.$overflowing_method(IArray::::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::::int_len(rhs)..Self::capacity_from_bit_len(self.length) { + for i in IArray::int_len::(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; @@ -1311,12 +1318,12 @@ impl Mul<&BVF> for &BVD { type Output = BVD; fn mul(self, rhs: &BVF) -> BVD { let mut res = BVD::zeros(self.length); - let len = IArray::::int_len(&res); + let len = IArray::int_len::(&res); for i in 0..len { let mut carry = 0; for j in 0..(len - i) { - let product = self.data[i].wmul(IArray::::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; } } diff --git a/src/fixed.rs b/src/fixed.rs index 2223963..27893a9 100644 --- a/src/fixed.rs +++ b/src/fixed.rs @@ -71,30 +71,37 @@ impl BVF { // BVF - Integer Array traits // ------------------------------------------------------------------------------------------------ -impl IArray for BVF -where - J: StaticCast, -{ - fn int_len(&self) -> usize { - (self.length + size_of::() * 8 - 1) / (size_of::() * 8) +impl IArray for BVF { + type I = I; + + fn int_len(&self) -> usize + where + I: StaticCast, + { + (self.length + size_of::() * 8 - 1) / (size_of::() * 8) } - fn get_int(&self, idx: usize) -> Option { - if idx < IArray::::int_len(self) { - IArray::::get_int(self.data.as_ref(), idx) + fn get_int(&self, idx: usize) -> Option + where + I: StaticCast, + { + if idx < IArray::int_len::(self) { + IArray::get_int::(self.data.as_ref(), idx) } else { None } } } -impl IArrayMut for BVF -where - J: StaticCast, -{ - fn set_int(&mut self, idx: usize, v: I) -> Option { - if idx < IArray::::int_len(self) { - IArrayMut::::set_int(self.data.as_mut(), idx, v) +impl IArrayMut for BVF { + type I = I; + + fn set_int(&mut self, idx: usize, v: J) -> Option + where + I: StaticCast, + { + if idx < IArray::int_len::(self) { + IArrayMut::set_int::(self.data.as_mut(), idx, v) } else { None } @@ -732,9 +739,9 @@ where I2: StaticCast, { fn eq(&self, other: &BVF) -> bool { - for i in 0..usize::max(IArray::::int_len(self), IArray::::int_len(other)) { - if IArray::::get_int(self, i).unwrap_or(I1::ZERO) - != IArray::::get_int(other, i).unwrap_or(I1::ZERO) + for i in 0..usize::max(IArray::int_len::(self), IArray::int_len::(other)) { + if IArray::get_int(self, i).unwrap_or(I1::ZERO) + != IArray::get_int(other, i).unwrap_or(I1::ZERO) { return false; } @@ -767,10 +774,10 @@ where I2: StaticCast, { fn partial_cmp(&self, other: &BVF) -> Option { - for i in (0..usize::max(IArray::::int_len(self), IArray::::int_len(other))).rev() { - match IArray::::get_int(self, i) + for i in (0..usize::max(IArray::int_len::(self), IArray::int_len::(other))).rev() { + match IArray::get_int(self, i) .unwrap_or(I1::ZERO) - .cmp(&IArray::::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), @@ -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()) } } } @@ -883,8 +890,8 @@ where Err(ConvertionError::NotEnoughCapacity) } else { let mut data = [I2::ZERO; N2]; - for i in 0..usize::min(N2, IArray::::int_len(bvf)) { - data[i] = IArray::::get_int(bvf, i).unwrap(); + for i in 0..usize::min(N2, IArray::int_len::(bvf)) { + data[i] = IArray::get_int(bvf, i).unwrap(); } Ok(BVF:: { data, @@ -935,8 +942,8 @@ where Err(ConvertionError::NotEnoughCapacity) } else { let mut data = [I::ZERO; N]; - for i in 0..IArray::::int_len(bv) { - data[i] = IArray::::get_int(bv, i).unwrap(); + for i in 0..IArray::int_len::(bv) { + data[i] = IArray::get_int(bv, i).unwrap(); } Ok(BVF:: { data, @@ -1128,7 +1135,7 @@ macro_rules! impl_binop_assign { } } else { for i in 0..N1 { - self.data[i].$method(IArray::::get_int(rhs, i).unwrap_or(I1::ZERO)); + self.data[i].$method(IArray::get_int(rhs, i).unwrap_or(I1::ZERO)); } } } @@ -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::::get_int(rhs, i).unwrap_or(I::ZERO)); + self.data[i].$method(IArray::get_int(rhs, i).unwrap_or(I::ZERO)); } } } @@ -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::::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); } @@ -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::::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); } @@ -1330,11 +1335,11 @@ where type Output = BVF; fn mul(self, rhs: &BVF) -> BVF { let mut res = BVF::::zeros(self.length); - let len = IArray::::int_len(&res); + let len = IArray::int_len::(&res); for i in 0..len { let mut carry = I1::ZERO; for j in 0..(len - i) { - let product = self.data[i].wmul(IArray::::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; } } @@ -1381,11 +1386,11 @@ where type Output = BVF; fn mul(self, rhs: &BVD) -> BVF { let mut res = BVF::::zeros(self.length); - let len = IArray::::int_len(&res); + let len = IArray::int_len::(&res); for i in 0..len { let mut carry = I::ZERO; for j in 0..(len - i) { - let product = self.data[i].wmul(IArray::::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; } } diff --git a/src/tests/utils.rs b/src/tests/utils.rs index 9f1408f..87bddc3 100644 --- a/src/tests/utils.rs +++ b/src/tests/utils.rs @@ -38,15 +38,15 @@ where let byte_len = size_of::() * N1; let n2 = (byte_len + size_of::() - 1) / size_of::(); - assert_eq!(N1, IArray::::int_len(array.as_ref())); - assert_eq!(n2, IArray::::int_len(array.as_ref())); - assert_eq!(None, IArray::::get_int(array.as_ref(), N1)); - assert_eq!(None, IArray::::get_int(array.as_ref(), n2)); + assert_eq!(N1, IArray::int_len::(array.as_ref())); + assert_eq!(n2, IArray::int_len::(array.as_ref())); + assert_eq!(None, IArray::get_int::(array.as_ref(), N1)); + assert_eq!(None, IArray::get_int::(array.as_ref(), n2)); for i in 0..N1 { - assert_eq!(IArray::::get_int(array.as_ref(), i), Some(I1::ZERO)); + assert_eq!(IArray::get_int::(array.as_ref(), i), Some(I1::ZERO)); } for i in 0..n2 { - assert_eq!(IArray::::get_int(array.as_ref(), i), Some(I2::ZERO)); + assert_eq!(IArray::get_int::(array.as_ref(), i), Some(I2::ZERO)); } } @@ -61,15 +61,15 @@ where I2: Integer + StaticCast + StaticCast, { let mut array = [I1::ZERO; N1]; - for i in 0..IArray::::int_len(array.as_ref()) { + for i in 0..IArray::int_len::(array.as_ref()) { assert_eq!( - IArrayMut::::set_int(array.as_mut(), i, I2::cast_from(i)), + IArrayMut::set_int::(array.as_mut(), i, I2::cast_from(i)), Some(I2::ZERO) ); } - for i in 0..IArray::::int_len(array.as_ref()) { + for i in 0..IArray::int_len::(array.as_ref()) { assert_eq!( - IArray::::get_int(array.as_ref(), i), + IArray::get_int::(array.as_ref(), i), Some(I2::cast_from(i)) ); } diff --git a/src/utils.rs b/src/utils.rs index 35e42ba..4e5b874 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -334,36 +334,49 @@ impl Integer for u128 { } } -pub trait IArray { - fn int_len(&self) -> usize; - - fn get_int(&self, idx: usize) -> Option; +pub trait IArray { + type I: Integer; + fn int_len(&self) -> usize + where + Self::I: StaticCast; + + fn get_int(&self, idx: usize) -> Option + where + Self::I: StaticCast; } -pub trait IArrayMut: IArray { - fn set_int(&mut self, idx: usize, v: I) -> Option; +pub trait IArrayMut { + type I: Integer; + fn set_int(&mut self, idx: usize, v: J) -> Option + where + Self::I: StaticCast; } #[cfg(not(any(target_endian = "big", target_endian = "little")))] compile_error!("Unknown target endianness"); #[cfg(target_endian = "little")] -impl IArray for [I1] -where - I1: StaticCast, -{ - fn int_len(&self) -> usize { - (size_of_val(self) + size_of::() - 1) / size_of::() +impl IArray for [I] { + type I = I; + + fn int_len(&self) -> usize + where + I: StaticCast, + { + (size_of_val(self) + size_of::() - 1) / size_of::() } - fn get_int(&self, idx: usize) -> Option { + fn get_int(&self, idx: usize) -> Option + where + I: StaticCast, + { // The conditional check should be optimized during specialization. // These asserts should be validated by our tests. - if size_of::() >= size_of::() { + if size_of::() >= size_of::() { unsafe { - debug_assert!(size_of::() % size_of::() == 0); - debug_assert!(align_of::() % align_of::() == 0); - let (head, mid, tail) = self.align_to::(); + debug_assert!(size_of::() % size_of::() == 0); + debug_assert!(align_of::() % align_of::() == 0); + let (head, mid, tail) = self.align_to::(); debug_assert!(head.is_empty() && tail.is_empty()); if idx < mid.len() { Some(mid[idx]) @@ -372,15 +385,15 @@ where } } } else { - debug_assert!(size_of::() % size_of::() == 0); - let s = size_of::() / size_of::(); - let mut v = I2::ZERO; - if idx >= IArray::::int_len(self) { + debug_assert!(size_of::() % size_of::() == 0); + let s = size_of::() / size_of::(); + let mut v = J::ZERO; + if idx >= IArray::int_len::(self) { return None; } for i in 0..s { - v |= StaticCast::::cast_to(*self.get(idx * s + i).unwrap_or(&I1::ZERO)) - << (size_of::() * 8 * i); + v |= StaticCast::::cast_to(*self.get(idx * s + i).unwrap_or(&I::ZERO)) + << (size_of::() * 8 * i); } Some(v) } @@ -388,18 +401,20 @@ where } #[cfg(target_endian = "little")] -impl IArrayMut for [I1] -where - I1: StaticCast, -{ - fn set_int(&mut self, idx: usize, v: I2) -> Option { +impl IArrayMut for [I] { + type I = I; + + fn set_int(&mut self, idx: usize, v: J) -> Option + where + I: StaticCast, + { // The conditional check should be optimized during specialization. // These asserts should be validated by our tests. - if size_of::() >= size_of::() { + if size_of::() >= size_of::() { unsafe { - debug_assert!(size_of::() % size_of::() == 0); - debug_assert!(align_of::() % align_of::() == 0); - let (head, mid, tail) = self.align_to_mut::(); + debug_assert!(size_of::() % size_of::() == 0); + debug_assert!(align_of::() % align_of::() == 0); + let (head, mid, tail) = self.align_to_mut::(); debug_assert!(head.is_empty() && tail.is_empty()); if idx < mid.len() { let old = mid[idx]; @@ -410,16 +425,16 @@ where } } } else { - debug_assert!(size_of::() % size_of::() == 0); - let s = size_of::() / size_of::(); - let mut old = I2::ZERO; - if idx >= IArray::::int_len(self) { + debug_assert!(size_of::() % size_of::() == 0); + let s = size_of::() / size_of::(); + let mut old = J::ZERO; + if idx >= IArray::int_len::(self) { return None; } for i in 0..s { if let Some(p) = self.get_mut(idx * s + i) { - old |= StaticCast::::cast_to(*p) << (size_of::() * 8 * i); - *p = StaticCast::::cast_from(v >> (size_of::() * 8 * i)); + old |= StaticCast::::cast_to(*p) << (size_of::() * 8 * i); + *p = StaticCast::::cast_from(v >> (size_of::() * 8 * i)); } } Some(old)