Skip to content

Commit

Permalink
From ints array
Browse files Browse the repository at this point in the history
  • Loading branch information
haxelion committed Aug 6, 2024
1 parent 38169a8 commit eddafab
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 2 deletions.
13 changes: 13 additions & 0 deletions src/auto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,19 @@ macro_rules! impl_tryfrom { ($($type:ty),+) => {

impl_tryfrom!(u8, u16, u32, u64, u128, usize);

impl<I: Integer> From<&[I]> for BV
where
u64: StaticCast<I>,
{
fn from(slice: &[I]) -> Self {
let mut bv = BV::zeros(slice.len() * I::BITS);
for (i, v) in slice.iter().enumerate() {
bv.set_int(i, *v);
}
bv
}
}

// ------------------------------------------------------------------------------------------------
// BV - Unary operator & shifts
// ------------------------------------------------------------------------------------------------
Expand Down
13 changes: 13 additions & 0 deletions src/dynamic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,19 @@ macro_rules! impl_from_ints {($($st:ty),+) => {

impl_from_ints!(u8, u16, u32, u64, u128, usize);

impl<I: Integer> From<&[I]> for BVD
where
u64: StaticCast<I>,
{
fn from(slice: &[I]) -> Self {
let mut bvd = BVD::zeros(slice.len() * I::BITS);
for (i, v) in slice.iter().enumerate() {
bvd.set_int(i, *v);
}
bvd
}
}

impl<I: Integer, const N: usize> From<&BVF<I, N>> for BVD {
fn from(rhs: &BVF<I, N>) -> BVD {
BVD {
Expand Down
16 changes: 16 additions & 0 deletions src/fixed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,22 @@ macro_rules! impl_tryfrom { ($($type:ty),+) => {

impl_tryfrom!(u8, u16, u32, u64, u128, usize);

impl<I: Integer + StaticCast<J>, J: Integer, const N: usize> TryFrom<&[J]> for BVF<I, N> {
type Error = ConvertionError;

fn try_from(slice: &[J]) -> Result<Self, Self::Error> {
if slice.len() * J::BITS <= Self::capacity() {
let mut bvf = BVF::<I, N>::zeros(slice.len() * J::BITS);
for (i, v) in slice.iter().enumerate() {
bvf.set_int(i, *v);
}
Ok(bvf)
} else {
Err(ConvertionError::NotEnoughCapacity)
}
}
}

impl<I1: Integer, I2: Integer, const N1: usize, const N2: usize> TryFrom<&BVF<I1, N1>>
for BVF<I2, N2>
where
Expand Down
67 changes: 65 additions & 2 deletions src/tests/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::fmt::Debug;
use crate::auto::BV;
use crate::dynamic::BVD;
use crate::fixed::BVF;
use crate::tests::{bvf_bvf_inner_unroll, bvf_inner_unroll, random_test_bv};
use crate::utils::{Integer, StaticCast};
use crate::tests::{bvf_bvf_inner_unroll, bvf_inner_unroll, random_bv, random_test_bv};
use crate::utils::{IArray, Integer, StaticCast};
use crate::{BitVector, ConvertionError};

use num_bigint::BigInt;
Expand Down Expand Up @@ -276,3 +276,66 @@ fn from_bv_bvf() {
fn from_bv_bvd() {
from_inner::<BV, BVD>(512);
}

fn from_array_inner<B, I>(max_capacity: usize)
where
<B as IArray>::I: StaticCast<I>,
B: BitVector + for<'a> TryFrom<&'a [I], Error: Debug>,
I: Integer,
{
for length in 0..(max_capacity / I::BITS * I::BITS) {
let bv1 = random_bv::<B>(length);
let array: Vec<I> = (0..bv1.int_len::<I>())
.map(|i| bv1.get_int(i).unwrap())
.collect();
let bv2 = B::try_from(&array[..]).unwrap();
assert_eq!(bv1, bv2);
}
}

fn from_bvf_array_inner<I: Integer, const N: usize>() {
from_array_inner::<BVF<I, N>, u8>(BVF::<I, N>::capacity());
from_array_inner::<BVF<I, N>, u16>(BVF::<I, N>::capacity());
from_array_inner::<BVF<I, N>, u32>(BVF::<I, N>::capacity());
from_array_inner::<BVF<I, N>, u64>(BVF::<I, N>::capacity());
from_array_inner::<BVF<I, N>, u128>(BVF::<I, N>::capacity());
}

#[test]
fn from_bvf_array() {
bvf_inner_unroll!(from_bvf_array_inner, {u8, u16, u32, u64, u128}, {1, 2, 3, 4, 5});
assert_eq!(
BVF::<u8, 3>::try_from(&[1u16; 2][..]),
Err(ConvertionError::NotEnoughCapacity)
);
assert_eq!(
BVF::<u16, 3>::try_from(&[1u32; 2][..]),
Err(ConvertionError::NotEnoughCapacity)
);
assert_eq!(
BVF::<u32, 3>::try_from(&[1u64; 2][..]),
Err(ConvertionError::NotEnoughCapacity)
);
assert_eq!(
BVF::<u64, 3>::try_from(&[1u128; 2][..]),
Err(ConvertionError::NotEnoughCapacity)
);
}

#[test]
fn from_bvd_array() {
from_array_inner::<BVD, u8>(256);
from_array_inner::<BVD, u16>(256);
from_array_inner::<BVD, u32>(256);
from_array_inner::<BVD, u64>(256);
from_array_inner::<BVD, u128>(256);
}

#[test]
fn from_bv_array() {
from_array_inner::<BV, u8>(256);
from_array_inner::<BV, u16>(256);
from_array_inner::<BV, u32>(256);
from_array_inner::<BV, u64>(256);
from_array_inner::<BV, u128>(256);
}

0 comments on commit eddafab

Please sign in to comment.