use super::PolyOverQ;
use flint_sys::fmpq_poly::{fmpq_poly_clear, fmpq_poly_init, fmpq_poly_set};
use std::mem::MaybeUninit;
unsafe impl Send for PolyOverQ {}
unsafe impl Sync for PolyOverQ {}
impl Clone for PolyOverQ {
fn clone(&self) -> Self {
let mut poly = MaybeUninit::uninit();
unsafe {
fmpq_poly_init(poly.as_mut_ptr());
let mut poly = poly.assume_init();
fmpq_poly_set(&mut poly, &self.poly);
Self { poly }
}
}
}
impl Drop for PolyOverQ {
fn drop(&mut self) {
unsafe {
fmpq_poly_clear(&mut self.poly);
}
}
}
#[cfg(test)]
mod test_clone {
use super::PolyOverQ;
use std::str::FromStr;
#[test]
fn same_reference_small() {
let a = PolyOverQ::from_str("4 1/1 -1/-2 -2/2 3/-4").unwrap();
let b = a.clone();
assert_eq!(
unsafe { *a.poly.coeffs.offset(0) }.0,
unsafe { *b.poly.coeffs.offset(0) }.0
);
assert_eq!(
unsafe { *a.poly.coeffs.offset(1) }.0,
unsafe { *b.poly.coeffs.offset(1) }.0
); assert_eq!(
unsafe { *a.poly.coeffs.offset(2) }.0,
unsafe { *b.poly.coeffs.offset(2) }.0
); assert_eq!(
unsafe { *a.poly.coeffs.offset(3) }.0,
unsafe { *b.poly.coeffs.offset(3) }.0
);
assert_eq!(a.poly.den[0].0, b.poly.den[0].0);
assert_eq!(a.poly.length, b.poly.length);
}
#[test]
fn same_reference_large() {
let a =
PolyOverQ::from_str(&format!("4 {}/1 1/{} -2/2 3/-4", i64::MAX, i64::MIN)).unwrap();
let b = a.clone();
assert_ne!(
unsafe { *a.poly.coeffs.offset(0) }.0,
unsafe { *b.poly.coeffs.offset(0) }.0
); assert_eq!(
unsafe { *a.poly.coeffs.offset(1) }.0,
unsafe { *b.poly.coeffs.offset(1) }.0
); assert_ne!(
unsafe { *a.poly.coeffs.offset(2) }.0,
unsafe { *b.poly.coeffs.offset(2) }.0
); assert_ne!(
unsafe { *a.poly.coeffs.offset(3) }.0,
unsafe { *b.poly.coeffs.offset(3) }.0
);
assert_ne!(a.poly.den[0].0, b.poly.den[0].0);
assert_eq!(a.poly.length, b.poly.length);
}
}
#[cfg(test)]
mod test_drop {
use super::PolyOverQ;
use std::{collections::HashSet, str::FromStr};
fn create_and_drop_modulus() -> (i64, i64, i64) {
let a = PolyOverQ::from_str(&format!("2 {}/1 -2/-3", i64::MAX)).unwrap();
(
unsafe { *a.poly.coeffs.offset(0) }.0,
unsafe { *a.poly.coeffs.offset(1) }.0,
a.poly.den[0].0,
)
}
#[test]
fn free_memory() {
let mut storage_addresses = HashSet::new();
for _i in 0..5 {
storage_addresses.insert(create_and_drop_modulus());
}
assert!(storage_addresses.len() < 5);
}
}