#![allow(clippy::float_cmp, clippy::unreadable_literal, clippy::unwrap_used)]
#![cfg(feature = "stage-counters")]
mod support;
use std::sync::{Mutex, MutexGuard, PoisonError};
use arithmetica::counters::{Counts, Predicate, reset, snapshot};
use arithmetica::{Sign, orient2d};
use support::{
Triple, all_orders, axis_aligned_triples, duplicate_triples, general_collinear_triple,
};
static SERIAL: Mutex<()> = Mutex::new(());
fn serialize() -> MutexGuard<'static, ()> {
SERIAL.lock().unwrap_or_else(PoisonError::into_inner)
}
fn counted(t: Triple) -> (Sign, Counts) {
reset();
let sign = orient2d(t[0], t[1], t[2]).expect("the fixtures are finite");
(sign, snapshot(Predicate::Orient2d))
}
fn assert_answered_without_stage_four(fixtures: &[(&'static str, Triple)]) {
let _guard = serialize();
let mut calls = 0_u32;
let mut reached_stage_four = Vec::new();
for &(name, triple) in fixtures {
for (i, order) in all_orders(triple).into_iter().enumerate() {
let (sign, counts) = counted(order);
assert_eq!(sign, Sign::Zero, "{name}, order {i}");
calls += 1;
if counts.exact != 0 || counts.exact_zero != 0 || counts.fast != 1 {
reached_stage_four.push(format!("{name}, order {i}: {counts:?}"));
}
}
}
assert!(
reached_stage_four.is_empty(),
"{} of {calls} exactly degenerate calls were not answered on the fast path:\n{}",
reached_stage_four.len(),
reached_stage_four.join("\n")
);
}
#[test]
fn duplicate_point_is_answered_without_stage_four() {
assert_answered_without_stage_four(&duplicate_triples());
}
#[test]
fn axis_aligned_triple_is_answered_without_stage_four() {
assert_answered_without_stage_four(&axis_aligned_triples());
}
#[test]
fn general_collinear_triple_still_reaches_stage_four() {
let _guard = serialize();
for (i, order) in all_orders(general_collinear_triple())
.into_iter()
.enumerate()
{
let (sign, counts) = counted(order);
assert_eq!(sign, Sign::Zero, "order {i}");
assert_eq!(counts.exact, 1, "order {i}: {counts:?}");
assert_eq!(counts.exact_zero, 1, "order {i}: {counts:?}");
assert_eq!(counts.fast, 0, "order {i}: {counts:?}");
}
}