diff --git a/src/mpz.rs b/src/mpz.rs index 6226744..503968c 100644 --- a/src/mpz.rs +++ b/src/mpz.rs @@ -845,63 +845,54 @@ impl<'a> From<&'a [u8]> for Mpz { } } -impl From for Mpz { - fn from(other: u64) -> Mpz { - unsafe { - let mut res = Mpz::new(); - __gmpz_import(&mut res.mpz, 1, -1, size_of::() as size_t, 0, 0, - &other as *const u64 as *const c_void); - res - } - } -} - -impl From for Mpz { - fn from(other: u32) -> Mpz { - unsafe { - let mut res = Mpz::new(); - __gmpz_import(&mut res.mpz, 1, -1, size_of::() as size_t, 0, 0, - &other as *const u32 as *const c_void); - res - } - } -} - -impl From for Mpz { - fn from(other: i64) -> Mpz { - unsafe { - let mut res = Mpz::new(); - - if other.is_negative() { - __gmpz_import(&mut res.mpz, 1, -1, size_of::() as size_t, 0, 0, - &(other ^ -1i64) as *const i64 as *const c_void); - __gmpz_com(&mut res.mpz, &res.mpz); - } else { - __gmpz_import(&mut res.mpz, 1, -1, size_of::() as size_t, 0, 0, - &other as *const i64 as *const c_void); +macro_rules! impl_from_uint { + ($typ: ident) => { + impl From<$typ> for Mpz { + fn from(other: $typ) -> Mpz { + let mut res = Mpz::new(); + unsafe { + __gmpz_import(&mut res.mpz, 1, -1, size_of::<$typ>() as size_t, 0, 0, + &other as *const $typ as *const c_void); + } + res } - res } } } - -impl From for Mpz { - fn from(other: i32) -> Mpz { - unsafe { - let mut res = Mpz::new(); - - if other.is_negative() { - __gmpz_import(&mut res.mpz, 1, -1, size_of::() as size_t, 0, 0, - &(other ^ -1i32) as *const i32 as *const c_void); - __gmpz_com(&mut res.mpz, &res.mpz); - } else { - __gmpz_import(&mut res.mpz, 1, -1, size_of::() as size_t, 0, 0, - &other as *const i32 as *const c_void); +impl_from_uint!(u128); +impl_from_uint!(u64); +impl_from_uint!(u32); +impl_from_uint!(u16); +impl_from_uint!(u8); +impl_from_uint!(usize); + +macro_rules! impl_from_iint { + ($typ: ident) => { + impl From<$typ> for Mpz { + fn from(other: $typ) -> Mpz { + let mut res = Mpz::new(); + unsafe { + if other.is_negative() { + __gmpz_import(&mut res.mpz, 1, -1, size_of::<$typ>() as size_t, 0, 0, + &(other ^ (-1 as $typ)) as *const $typ as *const c_void); + __gmpz_com(&mut res.mpz, &res.mpz); + } else { + __gmpz_import(&mut res.mpz, 1, -1, size_of::<$typ>() as size_t, 0, 0, + &other as *const $typ as *const c_void); + } + } + res } - res } + } } +impl_from_iint!(i128); +impl_from_iint!(i64); +impl_from_iint!(i32); +impl_from_iint!(i16); +impl_from_iint!(i8); +impl_from_iint!(isize); impl_oper!(BitAnd, bitand, BitAndAssign, bitand_assign, __gmpz_and); impl_oper!(BitOr, bitor, BitOrAssign, bitor_assign, __gmpz_ior); diff --git a/src/test.rs b/src/test.rs index 3af1382..40fc4d9 100644 --- a/src/test.rs +++ b/src/test.rs @@ -186,9 +186,35 @@ mod mpz { #[test] fn test_from_int() { - let x: Mpz = From::::from(150); - assert!(x.to_string() == "150".to_string()); - assert!(x == FromStr::from_str("150").unwrap()); + fn tst(x: T, expected: &str) + where + Mpz: From, + { + let x: Mpz = Mpz::from(x); + assert_eq!(x.to_string(), expected); + assert_eq!(x, FromStr::from_str(expected).unwrap()); + } + + tst(150_u8, "150"); + tst(150_u16, "150"); + tst(150_u32, "150"); + tst(150_u64, "150"); + tst(150_u128, "150"); + tst(150_usize, "150"); + + tst(75_i8, "75"); + tst(150_i16, "150"); + tst(150_i32, "150"); + tst(150_i64, "150"); + tst(150_i128, "150"); + tst(150_isize, "150"); + + tst(-75_i8, "-75"); + tst(-150_i16, "-150"); + tst(-150_i32, "-150"); + tst(-150_i64, "-150"); + tst(-150_i128, "-150"); + tst(-150_isize, "-150"); } #[test]