use super::Modulus;
use crate::{
integer::Z,
macros::for_others::{implement_for_others, implement_trait_reverse},
};
use flint_sys::fmpz::{fmpz, fmpz_cmp, fmpz_equal};
use std::cmp::Ordering;
impl PartialEq for Modulus {
fn eq(&self, other: &Self) -> bool {
unsafe {
1 == flint_sys::fmpz::fmpz_equal(
&self.get_fmpz_mod_ctx_struct().to_owned().n[0],
&other.get_fmpz_mod_ctx_struct().to_owned().n[0],
)
}
}
}
impl Eq for Modulus {}
impl PartialEq<Z> for Modulus {
fn eq(&self, other: &Z) -> bool {
unsafe { 1 == fmpz_equal(&other.value, &self.modulus.n[0]) }
}
}
implement_trait_reverse!(PartialEq, eq, Z, Modulus, bool);
implement_for_others!(Z, Modulus, PartialEq for fmpz i8 i16 i32 i64 u8 u16 u32 u64);
impl PartialOrd for Modulus {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Modulus {
fn cmp(&self, other: &Self) -> Ordering {
let z_1: Z = self.into();
let z_2: Z = other.into();
z_1.cmp(&z_2)
}
}
impl PartialOrd<Z> for Modulus {
fn partial_cmp(&self, other: &Z) -> Option<Ordering> {
Some(unsafe { fmpz_cmp(&self.modulus.n[0], &other.value).cmp(&0) })
}
}
implement_for_others!(Z, Modulus, PartialOrd for fmpz i8 i16 i32 i64 u8 u16 u32 u64);
#[cfg(test)]
mod test_eq {
use super::Modulus;
use crate::integer::Z;
use std::str::FromStr;
#[test]
fn equal_large() {
let a = Modulus::from_str(&"1".repeat(65)).unwrap();
let b = Modulus::from(&Z::from_str(&"1".repeat(65)).unwrap());
let a_clone = a.clone();
assert_eq!(a, b);
assert_eq!(a, a_clone);
assert_eq!(b, a_clone);
}
#[test]
fn equal_small() {
let a = Modulus::from(2);
let b = Modulus::from(&Z::from(2));
let b_clone = b.clone();
assert_eq!(a, b);
assert_eq!(b, b_clone);
assert_eq!(a, b_clone);
}
#[test]
fn unequal() {
let one = Modulus::from(3);
let two = Modulus::from(2);
let large = Modulus::from_str(&"1".repeat(65)).unwrap();
assert_ne!(one, two);
assert_ne!(one, large);
assert_ne!(two, large);
}
}
#[cfg(test)]
mod test_partial_eq_modulus_other {
use super::Z;
use crate::integer_mod_q::Modulus;
#[test]
#[allow(clippy::op_ref)]
fn availability() {
let modulus = Modulus::from(2);
let z = Z::from(2);
assert!(modulus == z);
assert!(modulus == z.value);
assert!(modulus == 2i8);
assert!(modulus == 2u8);
assert!(modulus == 2i16);
assert!(modulus == 2u16);
assert!(modulus == 2i32);
assert!(modulus == 2u32);
assert!(modulus == 2i64);
assert!(modulus == 2u64);
assert!(z == modulus);
assert!(z.value == modulus);
assert!(2i8 == modulus);
assert!(2u8 == modulus);
assert!(2i16 == modulus);
assert!(2u16 == modulus);
assert!(2i32 == modulus);
assert!(2u32 == modulus);
assert!(2i64 == modulus);
assert!(2u64 == modulus);
assert!(&modulus == &z);
assert!(&z == &modulus);
assert!(&modulus == &2i8);
assert!(&2i8 == &modulus);
}
#[test]
fn equal_large() {
let modulus = Modulus::from(u64::MAX);
let z = Z::from(u64::MAX);
assert!(modulus == z);
assert!(modulus != z + 1);
}
}
#[cfg(test)]
mod test_partial_ord {
use crate::integer_mod_q::Modulus;
#[test]
fn order_correct() {
let a = Modulus::from(2);
let b = Modulus::from(3);
assert!(a < b);
assert!(a <= b);
assert!(a <= a);
assert!(b > a);
assert!(b >= a);
assert!(a >= a);
}
#[test]
fn order_large() {
let a = Modulus::from(i64::MAX);
let b = Modulus::from(u64::MAX);
assert!(a < b);
assert!(a <= b);
assert!(a <= a);
assert!(b <= b);
assert!(b > a);
assert!(b >= a);
assert!(a >= a);
assert!(b >= b);
}
}
#[cfg(test)]
mod test_partial_ord_modulus_other {
use super::Modulus;
use crate::integer::Z;
#[test]
#[allow(clippy::op_ref)]
fn availability() {
let modulus = Modulus::from(2);
let z = Z::from(2);
assert!(modulus <= z);
assert!(modulus <= z.value);
assert!(modulus <= 2i8);
assert!(modulus <= 2u8);
assert!(modulus <= 2i16);
assert!(modulus <= 2u16);
assert!(modulus <= 2i32);
assert!(modulus <= 2u32);
assert!(modulus <= 2i64);
assert!(modulus <= 2u64);
assert!(z.value >= modulus);
assert!(2i8 >= modulus);
assert!(2u8 >= modulus);
assert!(2i16 >= modulus);
assert!(2u16 >= modulus);
assert!(2i32 >= modulus);
assert!(2u32 >= modulus);
assert!(2i64 >= modulus);
assert!(2u64 >= modulus);
assert!(&modulus <= &z);
assert!(&modulus <= &2i8);
assert!(&2i8 >= &modulus);
}
}
#[cfg(test)]
mod test_ord {
use crate::integer_mod_q::Modulus;
use std::cmp::{max, min};
#[test]
fn default_implementations() {
let a: Modulus = Modulus::from(10);
let b: Modulus = Modulus::from(42);
assert_eq!(b, max(a.clone(), b.clone()));
assert_eq!(a, min(a.clone(), b.clone()));
assert_eq!(a, Modulus::from(2).clamp(a.clone(), b.clone()));
assert_eq!(a, a.clone().clamp(Modulus::from(2), b.clone()));
assert_eq!(a, b.clamp(Modulus::from(2), a.clone()));
}
}