From 8ff5d21682f4d6f22be5c6c90139e53c58666c2a Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Fri, 11 Jan 2019 10:24:47 -0500 Subject: [PATCH] Move `rust-gmp` to an internal module This is necessary to publish on `crates.io`. --- classgroup/Cargo.toml | 1 - {rust-gmp/src => classgroup/src/gmp}/ffi.rs | 2 +- .../src/lib.rs => classgroup/src/gmp/mod.rs | 5 - {rust-gmp/src => classgroup/src/gmp}/mpz.rs | 6 +- {rust-gmp/src => classgroup/src/gmp}/sign.rs | 0 {rust-gmp/src => classgroup/src/gmp}/test.rs | 150 +----- classgroup/src/gmp_classgroup/ffi.rs | 4 +- classgroup/src/gmp_classgroup/mod.rs | 7 +- classgroup/src/lib.rs | 6 +- rust-gmp/.gitignore | 3 - rust-gmp/.travis.yml | 4 - rust-gmp/Cargo.toml | 16 - rust-gmp/main.patch | 253 ---------- rust-gmp/src/mpf.rs | 353 -------------- rust-gmp/src/mpq.rs | 443 ------------------ rust-gmp/src/rand.rs | 109 ----- 16 files changed, 15 insertions(+), 1347 deletions(-) rename {rust-gmp/src => classgroup/src/gmp}/ffi.rs (90%) rename rust-gmp/src/lib.rs => classgroup/src/gmp/mod.rs (71%) rename {rust-gmp/src => classgroup/src/gmp}/mpz.rs (99%) rename {rust-gmp/src => classgroup/src/gmp}/sign.rs (100%) rename {rust-gmp/src => classgroup/src/gmp}/test.rs (81%) delete mode 100644 rust-gmp/.gitignore delete mode 100644 rust-gmp/.travis.yml delete mode 100644 rust-gmp/Cargo.toml delete mode 100644 rust-gmp/main.patch delete mode 100644 rust-gmp/src/mpf.rs delete mode 100644 rust-gmp/src/mpq.rs delete mode 100644 rust-gmp/src/rand.rs diff --git a/classgroup/Cargo.toml b/classgroup/Cargo.toml index ae53026..5cb674d 100644 --- a/classgroup/Cargo.toml +++ b/classgroup/Cargo.toml @@ -22,7 +22,6 @@ edition = "2018" [dependencies] num-traits = "0.2" -rust-gmp = { path = "../rust-gmp", version = "0.5.1" } libc = "0.2" [dev-dependencies] diff --git a/rust-gmp/src/ffi.rs b/classgroup/src/gmp/ffi.rs similarity index 90% rename from rust-gmp/src/ffi.rs rename to classgroup/src/gmp/ffi.rs index 1351076..116cd4c 100644 --- a/rust-gmp/src/ffi.rs +++ b/classgroup/src/gmp/ffi.rs @@ -1,4 +1,4 @@ -use mpz::*; +use super::mpz::*; #[link(name = "gmp")] extern "C" { diff --git a/rust-gmp/src/lib.rs b/classgroup/src/gmp/mod.rs similarity index 71% rename from rust-gmp/src/lib.rs rename to classgroup/src/gmp/mod.rs index 44b1ca1..a03f391 100644 --- a/rust-gmp/src/lib.rs +++ b/classgroup/src/gmp/mod.rs @@ -1,5 +1,3 @@ -#![crate_name = "gmp"] - #![warn(deprecated)] #![allow(non_camel_case_types)] @@ -8,9 +6,6 @@ extern crate num_traits; mod ffi; pub mod mpz; -pub mod mpq; -pub mod mpf; -pub mod rand; pub mod sign; #[cfg(test)] diff --git a/rust-gmp/src/mpz.rs b/classgroup/src/gmp/mpz.rs similarity index 99% rename from rust-gmp/src/mpz.rs rename to classgroup/src/gmp/mpz.rs index 87f9895..e11f94e 100644 --- a/rust-gmp/src/mpz.rs +++ b/classgroup/src/gmp/mpz.rs @@ -1,5 +1,5 @@ +#![allow(unsafe_code)] use libc::{c_char, c_int, c_long, c_ulong, c_void, c_double, size_t, strnlen}; -use super::rand::gmp_randstate_t; use super::sign::Sign; use std::convert::From; use std::mem::{uninitialized,size_of}; @@ -12,7 +12,7 @@ use std::ffi::CString; use std::{u32, i32, usize}; use num_traits::{Zero, One}; -use ffi::*; +use super::ffi::*; #[repr(C)] pub struct mpz_struct { @@ -93,8 +93,6 @@ extern "C" { fn __gmpz_root(rop: mpz_ptr, op: mpz_srcptr, n: c_ulong) -> c_int; fn __gmpz_sqrt(rop: mpz_ptr, op: mpz_srcptr); fn __gmpz_millerrabin(n: mpz_srcptr, reps: c_int) -> c_int; - fn __gmpz_urandomb(rop: mpz_ptr, state: gmp_randstate_t, n: mp_bitcnt_t); - fn __gmpz_urandomm(rop: mpz_ptr, state: gmp_randstate_t, n: mpz_srcptr); } #[repr(transparent)] diff --git a/rust-gmp/src/sign.rs b/classgroup/src/gmp/sign.rs similarity index 100% rename from rust-gmp/src/sign.rs rename to classgroup/src/gmp/sign.rs diff --git a/rust-gmp/src/test.rs b/classgroup/src/gmp/test.rs similarity index 81% rename from rust-gmp/src/test.rs rename to classgroup/src/gmp/test.rs index 9f01e6e..69cd400 100644 --- a/rust-gmp/src/test.rs +++ b/classgroup/src/gmp/test.rs @@ -8,6 +8,7 @@ extern "C" { } #[test] +#[allow(unsafe_code)] fn test_limb_size() { // We are assuming that the limb size is the same as the pointer size. assert_eq!(std::mem::size_of::() * 8, @@ -98,7 +99,7 @@ mod mpz { fn test_div_zero() { let x: Mpz = From::::from(1); let y = Mpz::new(); - x / y; + drop(x / y) } #[test] @@ -106,7 +107,7 @@ mod mpz { fn test_rem_zero() { let x: Mpz = From::::from(1); let y = Mpz::new(); - x % y; + drop(x % y) } #[test] @@ -313,7 +314,7 @@ mod mpz { #[test] fn test_popcount() { - Mpz::from_str_radix("1010010011", 2).unwrap().popcount() == 5; + assert_eq!(Mpz::from_str_radix("1010010011", 2).unwrap().popcount(), 5); } #[test] @@ -579,146 +580,3 @@ mod mpz { assert_eq!(format!("{}", zero), "-51213"); } } - -mod rand { - use std::convert::From; - use super::super::mpz::Mpz; - use super::super::rand::RandState; - - #[test] - fn test_randstate() { - let mut state = RandState::new(); - state.seed_ui(42); - for _ in 1u32..1000 { - for x in 1i64..10 { - let upper: Mpz = From::::from(x); - assert!(state.urandom(&upper) < upper); - } - } - } -} - -mod mpq { - use std::convert::From; - use std::u64; - use super::super::mpq::Mpq; - use super::super::mpz::Mpz; - use super::super::sign::Sign; - - #[test] - fn test_one() { - let onea: Mpq = From::::from(1); - let oneb: Mpq = From::::from(1); - assert!(onea == oneb); - } - - #[test] - #[should_panic] - fn test_div_zero() { - let x: Mpq = From::::from(1); - let y = Mpq::new(); - x / y; - } - - #[test] - #[should_panic] - fn test_invert_zero() { - Mpq::new().invert(); - } - - #[test] - fn test_fmt() { - let fourty: Mpq = From::::from(40); - let six: Mpq = From::::from(6); - let fourty_sixths = &fourty / &six; - - assert_eq!(format!("{:?}", fourty), "40"); - assert_eq!(format!("{:?}", -&fourty), "-40"); - assert_eq!(format!("{:?}", fourty_sixths), "20/3"); - assert_eq!(format!("{:?}", -&fourty_sixths), "-20/3"); - } - - #[test] - fn test_floor() { - let half = Mpq::ratio(&Mpz::from(1), &Mpz::from(2)); - assert_eq!(half.floor(), Mpz::from(0)); - - let big = Mpz::from(u64::MAX) * Mpz::from(u64::MAX); - let slightly_more_than_one = Mpq::ratio(&(&big + Mpz::from(1)), &big); - assert_eq!(slightly_more_than_one.floor(), Mpz::from(1)); - - let minus_half = -half; - assert_eq!(minus_half.floor(), Mpz::from(-1)); - } - - #[test] - fn test_ceil() { - let half = Mpq::ratio(&Mpz::from(1), &Mpz::from(2)); - assert_eq!(half.ceil(), Mpz::from(1)); - - let minus_half = -half; - assert_eq!(minus_half.ceil(), Mpz::from(0)); - } - - #[test] - fn test_sign() { - let zero: Mpq = From::::from(0); - let five: Mpq = From::::from(5); - let minus_five: Mpq = From::::from(-5); - - assert_eq!(zero.sign(), Sign::Zero); - assert_eq!(five.sign(), Sign::Positive); - assert_eq!(minus_five.sign(), Sign::Negative); - } - - #[test] - fn test_ratio() { - let zero: Mpz = From::::from(0); - let one: Mpz = From::::from(1); - let minus_one = -&one; - let two = &one + &one; - let four = &two + &two; - - assert_eq!(Mpq::ratio(&one, &minus_one), Mpq::ratio(&minus_one, &one)); - assert_eq!(Mpq::ratio(&zero, &one), Mpq::ratio(&zero, &minus_one)); - assert_eq!(Mpq::ratio(&zero, &one), Mpq::ratio(&zero, &two)); - assert_eq!(Mpq::ratio(&two, &four), Mpq::ratio(&one, &two)); - } - - #[test] - fn test_from_str_radix() { - let zero: Mpz = From::::from(0); - let one: Mpz = From::::from(1); - let minus_one = -&one; - let two = &one + &one; - - assert_eq!(Mpq::from_str_radix("1/-1", 10).unwrap(), Mpq::ratio(&minus_one, &one)); - assert_eq!(Mpq::from_str_radix("0/2", 10).unwrap(), Mpq::ratio(&zero, &one)); - assert_eq!(Mpq::from_str_radix("2/4", 10).unwrap(), Mpq::ratio(&one, &two)); - } -} - -mod mpf { - use super::super::mpf::Mpf; - use super::super::sign::Sign; - - #[test] - #[should_panic] - fn test_div_zero() { - let x = Mpf::new(0); - &x / &x; - } - - #[test] - fn test_sign() { - let zero = Mpf::zero(); - let mut five = Mpf::zero(); - Mpf::set_from_si(&mut five, 5); - let mut minus_five = Mpf::zero(); - Mpf::set_from_si(&mut minus_five, -5); - - assert_eq!(zero.sign(), Sign::Zero); - assert_eq!(five.sign(), Sign::Positive); - assert_eq!(minus_five.sign(), Sign::Negative); - } -} diff --git a/classgroup/src/gmp_classgroup/ffi.rs b/classgroup/src/gmp_classgroup/ffi.rs index bbc2e25..874411f 100644 --- a/classgroup/src/gmp_classgroup/ffi.rs +++ b/classgroup/src/gmp_classgroup/ffi.rs @@ -18,8 +18,8 @@ //! Furthermore, the `rust-gmp` crate doesn’t support many operations that //! this library requires. #![allow(unsafe_code)] -pub use gmp::mpz::Mpz; -use gmp::mpz::{mp_bitcnt_t, mp_limb_t}; +pub use super::super::gmp::mpz::Mpz; +use super::super::gmp::mpz::{mp_bitcnt_t, mp_limb_t}; use libc::{c_int, c_long, c_ulong, c_void, size_t}; // pub use c_ulong; use std::{mem, usize}; diff --git a/classgroup/src/gmp_classgroup/mod.rs b/classgroup/src/gmp_classgroup/mod.rs index bb4fc5a..1f032e4 100644 --- a/classgroup/src/gmp_classgroup/mod.rs +++ b/classgroup/src/gmp_classgroup/mod.rs @@ -13,7 +13,8 @@ // limitations under the License. #![deny(unsafe_code)] use super::ClassGroup; -use gmp::mpz::Mpz; +use super::gmp::mpz::Mpz; +use super::gmp::mpz::ProbabPrimeResult::NotPrime; use num_traits::{One, Zero}; use std::{ borrow::Borrow, @@ -337,7 +338,7 @@ impl> MulAssign for GmpClassGroup { impl super::BigNum for Mpz { fn probab_prime(&self, iterations: u32) -> bool { - self.probab_prime(iterations.max(256) as _) != gmp::mpz::ProbabPrimeResult::NotPrime + self.probab_prime(iterations.max(256) as _) != NotPrime } fn setbit(&mut self, bit_index: usize) { @@ -543,7 +544,7 @@ impl Default for Ctx { pub fn do_compute(discriminant: Mpz, iterations: u64) -> GmpClassGroup { debug_assert!(discriminant < Zero::zero()); - debug_assert!(discriminant.probab_prime(50) != gmp::mpz::ProbabPrimeResult::NotPrime); + debug_assert!(discriminant.probab_prime(50) != NotPrime); let mut f = GmpClassGroup::generator_for_discriminant(discriminant); f.repeated_square(iterations); f diff --git a/classgroup/src/lib.rs b/classgroup/src/lib.rs index 0effa16..8da546b 100644 --- a/classgroup/src/lib.rs +++ b/classgroup/src/lib.rs @@ -15,7 +15,7 @@ use num_traits::{One, Zero}; use std::ops::{Mul, MulAssign, Rem, ShlAssign}; -pub use gmp; +pub mod gmp; pub mod gmp_classgroup; pub use self::gmp_classgroup::{ @@ -177,10 +177,8 @@ mod test { path::PathBuf, }; - use gmp; - use super::{gmp_classgroup::GmpClassGroup, ClassGroup}; - use gmp::mpz::Mpz; + use super::gmp::mpz::Mpz; fn split_into_three_pieces(line: &str, c: char) -> [&str; 3] { let mut iter = line.split(c); diff --git a/rust-gmp/.gitignore b/rust-gmp/.gitignore deleted file mode 100644 index 31cb256..0000000 --- a/rust-gmp/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/target/ -Cargo.lock -*.swp diff --git a/rust-gmp/.travis.yml b/rust-gmp/.travis.yml deleted file mode 100644 index 7c8ecab..0000000 --- a/rust-gmp/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -before_install: - - sudo apt-get update -qq - - sudo apt-get install -y libgmp3-dev -language: rust \ No newline at end of file diff --git a/rust-gmp/Cargo.toml b/rust-gmp/Cargo.toml deleted file mode 100644 index be1b98f..0000000 --- a/rust-gmp/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "rust-gmp" -version = "0.5.1" -authors = [ "thestinger ", "Bartłomiej Kamiński ", "Demi M. Obenour " ] -description = "Rust bindings for GMP" -repository = "https://github.com/fizyk20/rust-gmp" -documentation = "https://docs.rs/rust-gmp" -license = "MIT" -keywords = [ "gmp", "multi", "precision", "arithmetic", "bignum" ] - -[lib] -name = "gmp" - -[dependencies] -libc = "~0.2" -num-traits = "0.1" diff --git a/rust-gmp/main.patch b/rust-gmp/main.patch deleted file mode 100644 index b70ad14..0000000 --- a/rust-gmp/main.patch +++ /dev/null @@ -1,253 +0,0 @@ -diff --git a/src/mpz.rs b/src/mpz.rs -index 6226744..87f9895 100644 ---- a/src/mpz.rs -+++ b/src/mpz.rs -@@ -1,4 +1,4 @@ --use libc::{c_char, c_int, c_long, c_ulong, c_void, c_double, size_t}; -+use libc::{c_char, c_int, c_long, c_ulong, c_void, c_double, size_t, strnlen}; - use super::rand::gmp_randstate_t; - use super::sign::Sign; - use std::convert::From; -@@ -9,7 +9,7 @@ use std::str::FromStr; - use std::error::Error; - use std::ops::{Div, DivAssign, Mul, MulAssign, Add, AddAssign, Sub, SubAssign, Neg, Not, Shl, ShlAssign, Shr, ShrAssign, BitXor, BitXorAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, Rem, RemAssign}; - use std::ffi::CString; --use std::{u32, i32}; -+use std::{u32, i32, usize}; - use num_traits::{Zero, One}; - - use ffi::*; -@@ -97,6 +97,7 @@ extern "C" { - fn __gmpz_urandomm(rop: mpz_ptr, state: gmp_randstate_t, n: mpz_srcptr); - } - -+#[repr(transparent)] - pub struct Mpz { - mpz: mpz_struct, - } -@@ -117,14 +118,17 @@ pub enum ProbabPrimeResult { - } - - impl Mpz { -+ #[inline] - pub unsafe fn inner(&self) -> mpz_srcptr { - &self.mpz - } - -+ #[inline] - pub unsafe fn inner_mut(&mut self) -> mpz_ptr { - &mut self.mpz - } - -+ #[inline] - pub fn new() -> Mpz { - unsafe { - let mut mpz = uninitialized(); -@@ -133,6 +137,7 @@ impl Mpz { - } - } - -+ #[inline] - pub fn new_reserve(n: usize) -> Mpz { - unsafe { - let mut mpz = uninitialized(); -@@ -141,12 +146,14 @@ impl Mpz { - } - } - -+ #[inline] - pub fn reserve(&mut self, n: usize) { - if self.bit_length() < n { - unsafe { __gmpz_realloc2(&mut self.mpz, n as c_ulong) } - } - } - -+ #[inline] - pub fn size_in_base(&self, base: u8) -> usize { - unsafe { - __gmpz_sizeinbase(&self.mpz, base as c_int) as usize -@@ -158,31 +165,22 @@ impl Mpz { - // machinery for a custom type. - pub fn to_str_radix(&self, base: u8) -> String { - unsafe { -+ assert!(base >= 2 && base <= 36, "invalid base"); - // Extra two bytes are for possible minus sign and null terminator -- let len = __gmpz_sizeinbase(&self.mpz, base as c_int) as usize + 2; -+ let len = { -+ let len = __gmpz_sizeinbase(&self.mpz, base as c_int) as usize; -+ assert!(usize::MAX - len >= 2, "capacity overflow"); -+ len + 2 -+ }; - - // Allocate and write into a raw *c_char of the correct length - let mut vector: Vec = Vec::with_capacity(len); -- vector.set_len(len); -- - __gmpz_get_str(vector.as_mut_ptr() as *mut _, base as c_int, &self.mpz); -- -- let mut first_nul = None; -- let mut index : usize = 0; -- for elem in &vector { -- if *elem == 0 { -- first_nul = Some(index); -- break; -- } -- index += 1; -- } -- let first_nul = first_nul.unwrap_or(len); -- -- vector.truncate(first_nul); -- match String::from_utf8(vector) { -- Ok(s) => s, -- Err(_) => panic!("GMP returned invalid UTF-8!") -- } -+ let string_len = strnlen(vector.as_ptr() as *const _, len); -+ assert!(string_len < len); -+ vector.set_len(string_len); -+ // FIXME is this actually a problem? -+ String::from_utf8(vector).expect("GMP returned invalid UTF-8!") - } - } - -@@ -201,6 +199,7 @@ impl Mpz { - } - } - -+ #[inline] - pub fn set(&mut self, other: &Mpz) { - unsafe { __gmpz_set(&mut self.mpz, &other.mpz) } - } -@@ -212,10 +211,12 @@ impl Mpz { - unsafe { __gmpz_set_str(&mut self.mpz, s.as_ptr(), base as c_int) == 0 } - } - -+ #[inline] - pub fn bit_length(&self) -> usize { - unsafe { __gmpz_sizeinbase(&self.mpz, 2) as usize } - } - -+ #[inline] - pub fn compl(&self) -> Mpz { - unsafe { - let mut res = Mpz::new(); -@@ -224,6 +225,7 @@ impl Mpz { - } - } - -+ #[inline] - pub fn abs(&self) -> Mpz { - unsafe { - let mut res = Mpz::new(); -@@ -232,6 +234,7 @@ impl Mpz { - } - } - -+ #[inline] - pub fn div_floor(&self, other: &Mpz) -> Mpz { - unsafe { - if other.is_zero() { -@@ -244,6 +247,7 @@ impl Mpz { - } - } - -+ #[inline] - pub fn mod_floor(&self, other: &Mpz) -> Mpz { - unsafe { - if other.is_zero() { -@@ -270,6 +274,7 @@ impl Mpz { - } - } - -+ #[inline] - pub fn nextprime(&self) -> Mpz { - unsafe { - let mut res = Mpz::new(); -@@ -278,6 +283,7 @@ impl Mpz { - } - } - -+ #[inline] - pub fn gcd(&self, other: &Mpz) -> Mpz { - unsafe { - let mut res = Mpz::new(); -@@ -298,6 +304,7 @@ impl Mpz { - } - } - -+ #[inline] - pub fn lcm(&self, other: &Mpz) -> Mpz { - unsafe { - let mut res = Mpz::new(); -@@ -306,6 +313,7 @@ impl Mpz { - } - } - -+ #[inline] - pub fn is_multiple_of(&self, other: &Mpz) -> bool { - unsafe { - __gmpz_divisible_p(&self.mpz, &other.mpz) != 0 -@@ -341,10 +349,12 @@ impl Mpz { - } - } - -+ #[inline] - pub fn popcount(&self) -> usize { - unsafe { __gmpz_popcount(&self.mpz) as usize } - } - -+ #[inline] - pub fn pow(&self, exp: u32) -> Mpz { - unsafe { - let mut res = Mpz::new(); -@@ -353,6 +363,7 @@ impl Mpz { - } - } - -+ #[inline] - pub fn powm(&self, exp: &Mpz, modulus: &Mpz) -> Mpz { - unsafe { - let mut res = Mpz::new(); -@@ -361,6 +372,7 @@ impl Mpz { - } - } - -+ #[inline] - pub fn powm_sec(&self, exp: &Mpz, modulus: &Mpz) -> Mpz { - unsafe { - let mut res = Mpz::new(); -@@ -369,6 +381,7 @@ impl Mpz { - } - } - -+ #[inline] - pub fn ui_pow_ui(x: u32, y: u32) -> Mpz { - unsafe { - let mut res = Mpz::new(); -@@ -377,22 +390,27 @@ impl Mpz { - } - } - -+ #[inline] - pub fn hamdist(&self, other: &Mpz) -> usize { - unsafe { __gmpz_hamdist(&self.mpz, &other.mpz) as usize } - } - -+ #[inline] - pub fn setbit(&mut self, bit_index: usize) { - unsafe { __gmpz_setbit(&mut self.mpz, bit_index as c_ulong) } - } - -+ #[inline] - pub fn clrbit(&mut self, bit_index: usize) { - unsafe { __gmpz_clrbit(&mut self.mpz, bit_index as c_ulong) } - } - -+ #[inline] - pub fn combit(&mut self, bit_index: usize) { - unsafe { __gmpz_combit(&mut self.mpz, bit_index as c_ulong) } - } - -+ #[inline] - pub fn tstbit(&self, bit_index: usize) -> bool { - unsafe { __gmpz_tstbit(&self.mpz, bit_index as c_ulong) == 1 } - } diff --git a/rust-gmp/src/mpf.rs b/rust-gmp/src/mpf.rs deleted file mode 100644 index b2a5761..0000000 --- a/rust-gmp/src/mpf.rs +++ /dev/null @@ -1,353 +0,0 @@ -use libc::{c_double, c_int, c_long, c_ulong, c_void,c_char, free}; -use std; -use std::mem::uninitialized; -use std::cmp; -use std::cmp::Ordering::{self, Greater, Less, Equal}; -use std::ops::{Div, DivAssign, Mul, MulAssign, Add, AddAssign, Sub, SubAssign, Neg}; -use std::ffi::CString; -use std::string::String; -use super::mpz::mp_bitcnt_t; -use super::mpz::{Mpz, mpz_srcptr}; -use super::mpq::{Mpq, mpq_srcptr}; -use super::sign::Sign; -use num_traits::{Zero, One}; - -type mp_exp_t = c_long; - -#[repr(C)] -pub struct mpf_struct { - _mp_prec: c_int, - _mp_size: c_int, - _mp_exp: mp_exp_t, - _mp_d: *mut c_void -} - -pub type mpf_srcptr = *const mpf_struct; -pub type mpf_ptr = *mut mpf_struct; - -#[link(name = "gmp")] -extern "C" { - fn __gmpf_init2(x: mpf_ptr, prec: mp_bitcnt_t); - fn __gmpf_init_set(rop: mpf_ptr, op: mpf_srcptr); - fn __gmpf_clear(x: mpf_ptr); - fn __gmpf_get_prec(op: mpf_srcptr) -> mp_bitcnt_t; - fn __gmpf_set_prec(rop: mpf_ptr, prec: mp_bitcnt_t); - fn __gmpf_set(rop: mpf_ptr, op: mpf_srcptr); - fn __gmpf_set_z(rop: mpf_ptr, op: mpz_srcptr); - fn __gmpf_set_q(rop: mpf_ptr, op: mpq_srcptr); - - fn __gmpf_set_str(rop: mpf_ptr, str: *const c_char, base: c_int); - fn __gmpf_set_si(rop: mpf_ptr, op: c_long); - fn __gmpf_get_str(str: *const c_char, expptr: *const mp_exp_t, base: i32, n_digits: i32, op: mpf_ptr) -> *mut c_char; - - fn __gmpf_cmp(op1: mpf_srcptr, op2: mpf_srcptr) -> c_int; - fn __gmpf_cmp_d(op1: mpf_srcptr, op2: c_double) -> c_int; - fn __gmpf_cmp_ui(op1: mpf_srcptr, op2: c_ulong) -> c_int; - fn __gmpf_cmp_si(op1: mpf_srcptr, op2: c_long) -> c_int; - fn __gmpf_reldiff(rop: mpf_ptr, op1: mpf_srcptr, op2: mpf_srcptr); - fn __gmpf_add(rop: mpf_ptr, op1: mpf_srcptr, op2: mpf_srcptr); - fn __gmpf_sub(rop: mpf_ptr, op1: mpf_srcptr, op2: mpf_srcptr); - fn __gmpf_mul(rop: mpf_ptr, op1: mpf_srcptr, op2: mpf_srcptr); - fn __gmpf_div(rop: mpf_ptr, op1: mpf_srcptr, op2: mpf_srcptr); - fn __gmpf_neg(rop: mpf_ptr, op: mpf_srcptr); - fn __gmpf_abs(rop: mpf_ptr, op: mpf_srcptr); - fn __gmpf_ceil(rop: mpf_ptr, op: mpf_srcptr); - fn __gmpf_floor(rop: mpf_ptr, op: mpf_srcptr); - fn __gmpf_trunc(rop: mpf_ptr, op: mpf_srcptr); - fn __gmpf_sqrt(rop: mpf_ptr, op: mpf_srcptr); -} - -pub struct Mpf { - mpf: mpf_struct, -} - -unsafe impl Send for Mpf { } -unsafe impl Sync for Mpf { } - -impl Drop for Mpf { - fn drop(&mut self) { unsafe { __gmpf_clear(&mut self.mpf) } } -} - -impl Mpf { - pub unsafe fn inner(&self) -> mpf_srcptr { - &self.mpf - } - - pub unsafe fn inner_mut(&mut self) -> mpf_ptr { - &mut self.mpf - } - - pub fn zero() -> Mpf { Mpf::new(32) } - - pub fn new(precision: usize) -> Mpf { - unsafe { - let mut mpf = uninitialized(); - __gmpf_init2(&mut mpf, precision as c_ulong); - Mpf { mpf: mpf } - } - } - - pub fn set(&mut self, other: &Mpf) { - unsafe { __gmpf_set(&mut self.mpf, &other.mpf) } - } - - pub fn set_z(&mut self, other: &Mpz) { - unsafe { __gmpf_set_z(&mut self.mpf, other.inner()) } - } - - pub fn set_q(&mut self, other: &Mpq) { - unsafe { __gmpf_set_q(&mut self.mpf, other.inner()) } - } - - pub fn get_prec(&self) -> usize { - unsafe { __gmpf_get_prec(&self.mpf) as usize } - } - - pub fn set_prec(&mut self, precision: usize) { - unsafe { __gmpf_set_prec(&mut self.mpf, precision as c_ulong) } - } - - pub fn set_from_str(&mut self, string: &str, base: i32){ - let c_str = CString::new(string).unwrap(); - unsafe { - __gmpf_set_str(&mut self.mpf, c_str.as_ptr(), base as c_int); - } - } - - pub fn set_from_si(&mut self, int: i64){ - unsafe{ - __gmpf_set_si(&mut self.mpf,int as c_long); - } - } - - pub fn get_str(&mut self, n_digits: i32, base: i32, exp: &mut c_long) -> String{ - let out; - unsafe{ - out = CString::from_raw(__gmpf_get_str(std::ptr::null(), exp, base, n_digits, &mut self.mpf)); - } - let r = out.to_str().unwrap().to_string(); - // Free the pointer returned to us, as r already took a copy of the data inside of it - // Stops memory leaking - unsafe { free(out.into_raw() as _) }; - r - } - - pub fn abs(&self) -> Mpf { - unsafe { - let mut res = Mpf::new(self.get_prec()); - __gmpf_abs(&mut res.mpf, &self.mpf); - res - } - } - - pub fn ceil(&self) -> Mpf { - unsafe { - let mut res = Mpf::new(self.get_prec()); - __gmpf_ceil(&mut res.mpf, &self.mpf); - res - } - } - - pub fn floor(&self) -> Mpf { - unsafe { - let mut res = Mpf::new(self.get_prec()); - __gmpf_floor(&mut res.mpf, &self.mpf); - res - } - } - - pub fn trunc(&self) -> Mpf { - unsafe { - let mut res = Mpf::new(self.get_prec()); - __gmpf_trunc(&mut res.mpf, &self.mpf); - res - } - } - - pub fn reldiff(&self, other: &Mpf) -> Mpf { - unsafe { - let mut res = Mpf::new(cmp::max(self.get_prec(), other.get_prec())); - __gmpf_reldiff(&mut res.mpf, &self.mpf, &other.mpf); - res - } - } - - pub fn sqrt(self) -> Mpf { - let mut retval:Mpf; - unsafe { - retval = Mpf::new(__gmpf_get_prec(&self.mpf) as usize); - retval.set_from_si(0); - if __gmpf_cmp_si(&self.mpf, 0) > 0 { - __gmpf_sqrt(&mut retval.mpf, &self.mpf); - } else { - panic!("Square root of negative/zero"); - } - } - retval - } - - pub fn sign(&self) -> Sign { - let size = self.mpf._mp_size; - if size == 0 { - Sign::Zero - } else if size > 0 { - Sign::Positive - } else { - Sign::Negative - } - } -} - -impl Clone for Mpf { - fn clone(&self) -> Mpf { - unsafe { - let mut mpf = uninitialized(); - __gmpf_init_set(&mut mpf, &self.mpf); - Mpf { mpf: mpf } - } - } -} - -impl Eq for Mpf { } -impl PartialEq for Mpf { - fn eq(&self, other: &Mpf) -> bool { - unsafe { __gmpf_cmp(&self.mpf, &other.mpf) == 0 } - } -} - -impl Ord for Mpf { - fn cmp(&self, other: &Mpf) -> Ordering { - let cmp = unsafe { __gmpf_cmp(&self.mpf, &other.mpf) }; - if cmp == 0 { - Equal - } else if cmp > 0 { - Greater - } else { - Less - } - } -} - -impl PartialOrd for Mpf { - fn partial_cmp(&self, other: &Mpf) -> Option { - Some(self.cmp(other)) - } -} - -macro_rules! div_guard { - (Div, $is_zero: expr) => { - if $is_zero { - panic!("divide by zero") - } - }; - ($tr: ident, $what: expr) => {} -} - -macro_rules! impl_oper { - ($tr: ident, $meth: ident, $tr_assign: ident, $meth_assign: ident, $fun: ident) => { - impl<'a> $tr for &'a Mpf { - type Output = Mpf; - #[inline] - fn $meth(self, other: Mpf) -> Mpf { - self.$meth(&other) - } - } - - impl<'a> $tr<&'a Mpf> for Mpf { - type Output = Mpf; - #[inline] - fn $meth(mut self, other: &Mpf) -> Mpf { - self.$meth_assign(other); - self - } - } - - impl $tr for Mpf { - type Output = Mpf; - #[inline] - fn $meth(self, other: Mpf) -> Mpf { - self.$meth(&other) - } - } - - impl<'a, 'b> $tr<&'a Mpf> for &'b Mpf { - type Output = Mpf; - fn $meth(self, other: &Mpf) -> Mpf { - unsafe { - div_guard!($tr, __gmpf_cmp_ui(&other.mpf, 0) == 0); - let mut res = Mpf::new(cmp::max(self.get_prec(), other.get_prec())); - $fun(&mut res.mpf, &self.mpf, &other.mpf); - res - } - } - } - - impl<'a> $tr_assign for Mpf { - #[inline] - fn $meth_assign(&mut self, other: Mpf) { - self.$meth_assign(&other) - } - } - - impl<'a> $tr_assign<&'a Mpf> for Mpf { - #[inline] - fn $meth_assign(&mut self, other: &Mpf) { - unsafe { - div_guard!($tr, __gmpf_cmp_ui(&other.mpf, 0) == 0); - $fun(&mut self.mpf, &self.mpf, &other.mpf) - } - } - } - } -} - -impl_oper!(Add, add, AddAssign, add_assign, __gmpf_add); -impl_oper!(Sub, sub, SubAssign, sub_assign, __gmpf_sub); -impl_oper!(Mul, mul, MulAssign, mul_assign, __gmpf_mul); -impl_oper!(Div, div, DivAssign, div_assign, __gmpf_div); - - -impl<'b> Neg for &'b Mpf { - type Output = Mpf; - fn neg(self) -> Mpf { - unsafe { - let mut res = Mpf::new(self.get_prec()); - __gmpf_neg(&mut res.mpf, &self.mpf); - res - } - } -} - -impl Neg for Mpf { - type Output = Mpf; - #[inline] - fn neg(mut self) -> Mpf { - unsafe { - __gmpf_neg(&mut self.mpf, &self.mpf); - self - } - } -} - -impl Zero for Mpf { - #[inline] - fn zero() -> Mpf { - Mpf::zero() - } - - #[inline] - fn is_zero(&self) -> bool { - unsafe { - __gmpf_cmp_ui(&self.mpf, 0) == 0 - } - } -} - -impl One for Mpf { - #[inline] - fn one() -> Mpf { - let mut res = Mpf::new(32); - res.set_from_si(1); - res - } -} diff --git a/rust-gmp/src/mpq.rs b/rust-gmp/src/mpq.rs deleted file mode 100644 index 8451279..0000000 --- a/rust-gmp/src/mpq.rs +++ /dev/null @@ -1,443 +0,0 @@ -use super::mpz::{mpz_struct, Mpz, mpz_ptr, mpz_srcptr}; -use super::mpf::{Mpf, mpf_srcptr}; -use super::sign::Sign; -use ffi::*; -use libc::{c_char, c_double, c_int, c_ulong}; -use std::ffi::CString; -use std::str::FromStr; -use std::error::Error; -use std::convert::From; -use std::mem::uninitialized; -use std::fmt; -use std::cmp::Ordering::{self, Greater, Less, Equal}; -use std::ops::{Div, DivAssign, Mul, MulAssign, Add, AddAssign, Sub, SubAssign, Neg}; -use num_traits::{Zero, One}; - -#[repr(C)] -pub struct mpq_struct { - _mp_num: mpz_struct, - _mp_den: mpz_struct -} - -pub type mpq_srcptr = *const mpq_struct; -pub type mpq_ptr = *mut mpq_struct; - -#[link(name = "gmp")] -extern "C" { - fn __gmpq_init(x: mpq_ptr); - fn __gmpq_clear(x: mpq_ptr); - fn __gmpq_set(rop: mpq_ptr, op: mpq_srcptr); - fn __gmpq_set_z(rop: mpq_ptr, op: mpz_srcptr); - fn __gmpq_set_ui(rop: mpq_ptr, op1: c_ulong, op2: c_ulong); - fn __gmpq_set_d(rop: mpq_ptr, op: c_double); - fn __gmpq_set_f(rop: mpq_ptr, op: mpf_srcptr); - fn __gmpq_cmp(op1: mpq_srcptr, op2: mpq_srcptr) -> c_int; - fn __gmpq_cmp_ui(op1: mpq_srcptr, num2: c_ulong, den2: c_ulong) -> c_int; - fn __gmpq_equal(op1: mpq_srcptr, op2: mpq_srcptr) -> c_int; - fn __gmpq_add(sum: mpq_ptr, addend1: mpq_srcptr, addend2: mpq_srcptr); - fn __gmpq_sub(difference: mpq_ptr, minuend: mpq_srcptr, subtrahend: mpq_srcptr); - fn __gmpq_mul(product: mpq_ptr, multiplier: mpq_srcptr, multiplicand: mpq_srcptr); - fn __gmpq_div(product: mpq_ptr, multiplier: mpq_srcptr, multiplicand: mpq_srcptr); - fn __gmpq_neg(negated_operand: mpq_ptr, operand: mpq_srcptr); - fn __gmpq_abs(rop: mpq_ptr, op: mpq_srcptr); - fn __gmpq_inv(inverted_number: mpq_ptr, number: mpq_srcptr); - fn __gmpq_get_num(numerator: mpz_ptr, rational: mpq_srcptr); - fn __gmpq_get_den(denominator: mpz_ptr, rational: mpq_srcptr); - fn __gmpq_set_num(rational: mpq_ptr, numerator: mpz_srcptr); - fn __gmpq_set_den(rational: mpq_ptr, denominator: mpz_srcptr); - fn __gmpq_canonicalize(rational: mpq_ptr); - fn __gmpq_get_d(rational: mpq_srcptr) -> c_double; - fn __gmpq_set_str(rop: mpq_ptr, str: *const c_char, base: c_int) -> c_int; -} - -pub struct Mpq { - mpq: mpq_struct, -} - -unsafe impl Send for Mpq { } -unsafe impl Sync for Mpq { } - -impl Drop for Mpq { - fn drop(&mut self) { unsafe { __gmpq_clear(&mut self.mpq) } } -} - -impl Mpq { - pub unsafe fn inner(&self) -> mpq_srcptr { - &self.mpq - } - - pub unsafe fn inner_mut(&mut self) -> mpq_ptr { - &mut self.mpq - } - - pub fn new() -> Mpq { - unsafe { - let mut mpq = uninitialized(); - __gmpq_init(&mut mpq); - Mpq { mpq: mpq } - } - } - - pub fn ratio(num: &Mpz, den: &Mpz) -> Mpq { - unsafe { - let mut res = Mpq::new(); - __gmpq_set_num(&mut res.mpq, num.inner()); - __gmpq_set_den(&mut res.mpq, den.inner()); - // Not canonicalizing is unsafe - __gmpq_canonicalize(&mut res.mpq); - res - } - } - - pub fn from_str_radix(s: &str, base: u8) -> Result { - let s = CString::new(s).map_err(|_| ParseMpqError { _priv: () })?; - let mut res = Mpq::new(); - unsafe { - assert!(base == 0 || (base >= 2 && base <= 62)); - let r = __gmpq_set_str(&mut res.mpq, s.as_ptr(), base as c_int); - - if r == 0 { - // Not canonicalizing is unsafe - __gmpq_canonicalize(&mut res.mpq); - Ok(res) - } else { - Err(ParseMpqError { _priv: () }) - } - } - } - - pub fn set(&mut self, other: &Mpq) { - unsafe { __gmpq_set(&mut self.mpq, &other.mpq) } - } - - pub fn set_z(&mut self, other: &Mpz) { - unsafe { __gmpq_set_z(&mut self.mpq, other.inner()) } - } - - pub fn set_d(&mut self, other: f64) { - unsafe { __gmpq_set_d(&mut self.mpq, other) } - } - - pub fn set_f(&mut self, other: &Mpf) { - unsafe { __gmpq_set_f(&mut self.mpq, other.inner()) } - } - - pub fn get_num(&self) -> Mpz { - unsafe { - let mut res = Mpz::new(); - __gmpq_get_num(res.inner_mut(), &self.mpq); - res - } - } - - pub fn get_den(&self) -> Mpz { - unsafe { - let mut res = Mpz::new(); - __gmpq_get_den(res.inner_mut(), &self.mpq); - res - } - } - - pub fn abs(&self) -> Mpq { - unsafe { - let mut res = Mpq::new(); - __gmpq_abs(&mut res.mpq, &self.mpq); - res - } - } - - pub fn invert(&self) -> Mpq { - unsafe { - if self.is_zero() { - panic!("divide by zero") - } - - let mut res = Mpq::new(); - __gmpq_inv(&mut res.mpq, &self.mpq); - res - } - } - - pub fn floor(&self) -> Mpz { - let mut res = Mpz::new(); - unsafe { - __gmpz_fdiv_q(res.inner_mut(), &self.mpq._mp_num, &self.mpq._mp_den); - } - res - } - - pub fn ceil(&self) -> Mpz { - let mut res = Mpz::new(); - unsafe { - __gmpz_cdiv_q(res.inner_mut(), &self.mpq._mp_num, &self.mpq._mp_den); - } - res - } - - pub fn sign(&self) -> Sign { - self.get_num().sign() - } - - pub fn one() -> Mpq { - let mut res = Mpq::new(); - unsafe { __gmpq_set_ui(&mut res.mpq, 1, 1) } - res - } - - pub fn zero() -> Mpq { Mpq::new() } - pub fn is_zero(&self) -> bool { - unsafe { __gmpq_cmp_ui(&self.mpq, 0, 1) == 0 } - } -} - -#[derive(Debug)] -pub struct ParseMpqError { - _priv: () -} - -impl fmt::Display for ParseMpqError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.description().fmt(f) - } -} - -impl Error for ParseMpqError { - fn description(&self) -> &'static str { - "invalid rational number" - } - - fn cause(&self) -> Option<&'static Error> { - None - } -} - -impl Clone for Mpq { - fn clone(&self) -> Mpq { - let mut res = Mpq::new(); - res.set(self); - res - } -} - -impl Eq for Mpq { } -impl PartialEq for Mpq { - fn eq(&self, other: &Mpq) -> bool { - unsafe { __gmpq_equal(&self.mpq, &other.mpq) != 0 } - } -} - -impl Ord for Mpq { - fn cmp(&self, other: &Mpq) -> Ordering { - let cmp = unsafe { __gmpq_cmp(&self.mpq, &other.mpq) }; - if cmp == 0 { - Equal - } else if cmp < 0 { - Less - } else { - Greater - } - } -} -impl PartialOrd for Mpq { - fn partial_cmp(&self, other: &Mpq) -> Option { - Some(self.cmp(other)) - } -} - -macro_rules! div_guard { - (Div, $what: expr) => { - if $what.is_zero() { - panic!("divide by zero") - } - }; - ($tr: ident, $what: expr) => {} -} - -macro_rules! impl_oper { - ($tr: ident, $meth: ident, $tr_assign: ident, $meth_assign: ident, $fun: ident) => { - impl $tr for Mpq { - type Output = Mpq; - #[inline] - fn $meth(self, other: Mpq) -> Mpq { - self.$meth(&other) - } - } - - impl<'a> $tr<&'a Mpq> for Mpq { - type Output = Mpq; - #[inline] - fn $meth(mut self, other: &Mpq) -> Mpq { - self.$meth_assign(other); - self - } - } - - impl<'a> $tr for &'a Mpq { - type Output = Mpq; - #[inline] - fn $meth(self, mut other: Mpq) -> Mpq { - unsafe { - div_guard!($tr, other); - $fun(&mut other.mpq, &self.mpq, &other.mpq); - other - } - } - } - - impl<'a, 'b> $tr<&'a Mpq> for &'b Mpq { - type Output = Mpq; - fn $meth(self, other: &Mpq) -> Mpq { - unsafe { - div_guard!($tr, *other); - let mut res = Mpq::new(); - $fun(&mut res.mpq, &self.mpq, &other.mpq); - res - } - } - } - - impl<'a> $tr_assign for Mpq { - #[inline] - fn $meth_assign(&mut self, other: Mpq) { - self.$meth_assign(&other) - } - } - - impl<'a> $tr_assign<&'a Mpq> for Mpq { - #[inline] - fn $meth_assign(&mut self, other: &Mpq) { - unsafe { - div_guard!($tr, *other); - $fun(&mut self.mpq, &self.mpq, &other.mpq) - } - } - } - } -} - -impl_oper!(Add, add, AddAssign, add_assign, __gmpq_add); -impl_oper!(Sub, sub, SubAssign, sub_assign, __gmpq_sub); -impl_oper!(Mul, mul, MulAssign, mul_assign, __gmpq_mul); -impl_oper!(Div, div, DivAssign, div_assign, __gmpq_div); - -impl<'b> Neg for &'b Mpq { - type Output = Mpq; - fn neg(self) -> Mpq { - unsafe { - let mut res = Mpq::new(); - __gmpq_neg(&mut res.mpq, &self.mpq); - res - } - } -} - -impl Neg for Mpq { - type Output = Mpq; - #[inline] - fn neg(mut self) -> Mpq { - unsafe { - __gmpq_neg(&mut self.mpq, &self.mpq); - self - } - } -} - -impl From for f64 { - fn from(other: Mpq) -> f64 { - f64::from(&other) - } -} - -impl<'a> From<&'a Mpq> for f64 { - fn from(other: &Mpq) -> f64 { - unsafe { - __gmpq_get_d(&other.mpq) as f64 - } - } -} - -impl From for Mpq { - fn from(other: Mpz) -> Mpq { - Mpq::from(&other) - } -} - -impl<'a> From<&'a Mpz> for Mpq { - fn from(other: &Mpz) -> Mpq { - let mut res = Mpq::new(); - res.set_z(&other); - res - } -} - -impl From for Mpq { - fn from(other: i64) -> Mpq { - From::::from(From::::from(other)) - } -} - -impl From for Mpq { - fn from(other: i32) -> Mpq { - From::::from(From::::from(other)) - } -} - -impl From for Mpq { - fn from(other: u64) -> Mpq { - From::::from(From::::from(other)) - } -} - -impl From for Mpq { - fn from(other: u32) -> Mpq { - From::::from(From::::from(other)) - } -} - -impl FromStr for Mpq { - type Err = ParseMpqError; - fn from_str(s: &str) -> Result { - Mpq::from_str_radix(s, 10) - } -} - - -impl fmt::Debug for Mpq { - /// Renders as `numer/denom`. If denom=1, renders as numer. - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&self, f) - } -} - -impl fmt::Display for Mpq { - /// Renders as `numer/denom`. If denom=1, renders as numer. - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let numer = self.get_num(); - let denom = self.get_den(); - - if denom == From::::from(1) { - write!(f, "{}", numer) - } else { - write!(f, "{}/{}", numer, denom) - } - } -} - -impl Zero for Mpq { - #[inline] - fn zero() -> Mpq { - Mpq::zero() - } - - #[inline] - fn is_zero(&self) -> bool { - self.is_zero() - } -} - -impl One for Mpq { - #[inline] - fn one() -> Mpq { - Mpq::one() - } -} diff --git a/rust-gmp/src/rand.rs b/rust-gmp/src/rand.rs deleted file mode 100644 index cbf6b42..0000000 --- a/rust-gmp/src/rand.rs +++ /dev/null @@ -1,109 +0,0 @@ -use libc::{c_int, c_ulong, c_void}; -use super::mpz::{mpz_struct, Mpz, mpz_ptr, mpz_srcptr, mp_bitcnt_t}; -use std::mem::uninitialized; - -#[repr(C)] -pub struct gmp_randstate_struct { - _mp_seed: mpz_struct, - _mp_alg: c_int, - _mp_algdata: *const c_void -} - -pub type gmp_randstate_t = *mut gmp_randstate_struct; - -#[link(name = "gmp")] -extern "C" { - fn __gmp_randinit_default(state: gmp_randstate_t); - fn __gmp_randinit_mt(state: gmp_randstate_t); - fn __gmp_randinit_lc_2exp(state: gmp_randstate_t, a: mpz_srcptr, c: c_ulong, m2exp: mp_bitcnt_t); - fn __gmp_randinit_lc_2exp_size(state: gmp_randstate_t, size: mp_bitcnt_t); - fn __gmp_randinit_set(state: gmp_randstate_t, op: *const gmp_randstate_struct); - fn __gmp_randclear(state: gmp_randstate_t); - fn __gmp_randseed(state: gmp_randstate_t, seed: mpz_srcptr); - fn __gmp_randseed_ui(state: gmp_randstate_t, seed: c_ulong); - fn __gmpz_urandomb(rop: mpz_ptr, state: gmp_randstate_t, n: mp_bitcnt_t); - fn __gmpz_urandomm(rop: mpz_ptr, state: gmp_randstate_t, n: mpz_srcptr); -} - -pub struct RandState { - state: gmp_randstate_struct, -} - -unsafe impl Send for RandState { } -unsafe impl Sync for RandState { } - -impl Drop for RandState { - fn drop(&mut self) { - unsafe { __gmp_randclear(&mut self.state) } - } -} - -impl RandState { - pub fn new() -> RandState { - unsafe { - let mut state: gmp_randstate_struct = uninitialized(); - __gmp_randinit_default(&mut state); - RandState { state: state } - } - } - - pub fn new_mt() -> RandState { - unsafe { - let mut state: gmp_randstate_struct = uninitialized(); - __gmp_randinit_mt(&mut state); - RandState { state: state } - } - } - - pub fn new_lc_2exp(a: Mpz, c: u64, m2exp: u64) -> RandState { - unsafe { - let mut state: gmp_randstate_struct = uninitialized(); - __gmp_randinit_lc_2exp(&mut state, a.inner(), c as c_ulong, m2exp as c_ulong); - RandState { state: state } - } - } - - pub fn new_lc_2exp_size(size: u64) -> RandState { - unsafe { - let mut state: gmp_randstate_struct = uninitialized(); - __gmp_randinit_lc_2exp_size(&mut state, size as c_ulong); - RandState { state: state } - } - } - - pub fn seed(&mut self, seed: Mpz) { - unsafe { __gmp_randseed(&mut self.state, seed.inner()) } - } - - pub fn seed_ui(&mut self, seed: u64) { - unsafe { __gmp_randseed_ui(&mut self.state, seed as c_ulong) } - } - - /// Generate a uniform random integer in the range 0 to n-1, inclusive - pub fn urandom(&mut self, n: &Mpz) -> Mpz { - unsafe { - let mut res = Mpz::new(); - __gmpz_urandomm(res.inner_mut(), &mut self.state, n.inner()); - res - } - } - - /// Generate a uniformly distributed random integer in the range 0 to 2^n−1, inclusive. - pub fn urandom_2exp(&mut self, n: u64) -> Mpz { - unsafe { - let mut res = Mpz::new(); - __gmpz_urandomb(res.inner_mut(), &mut self.state, n as c_ulong); - res - } - } -} - -impl Clone for RandState { - fn clone(&self) -> RandState { - unsafe { - let mut state: gmp_randstate_struct = uninitialized(); - __gmp_randinit_set(&mut state, &self.state); - RandState { state: state } - } - } -}