pub use partition::interval::Interval;
pub use partition::boxes::{Box2, Box3};
pub use partition::ncube::Ncube;
pub use partition::unitquad::UnitQuad;
#[cfg(any(test, feature = "arbitrary"))]
use quickcheck::TestResult;
pub trait Subdivide: Sized {
fn subdivide(&self) -> Vec<Self>;
}
pub trait Partition<T>: Subdivide + Sized {
fn contains(&self, elem: &T) -> bool;
fn dispatch(&self, elem: &T) -> usize {
for (i, part) in self.subdivide().iter().enumerate() {
if part.contains(elem) {
return i;
}
}
panic!("partition dispatch impossible");
}
}
#[cfg(any(test, feature = "arbitrary"))]
pub fn prop_is_total_elem<P: Partition<T>, T>(partition: P, elem: T) -> TestResult {
if partition.contains(&elem) {
TestResult::from_bool(
partition.subdivide().iter()
.filter(|sub| sub.contains(&elem)).count()
== 1
)
}
else {
TestResult::discard()
}
}
#[cfg(any(test, feature = "arbitrary"))]
pub fn prop_is_total_non_elem<P: Partition<T>, T>(partition: P, elem: T) -> TestResult {
if partition.contains(&elem) {
TestResult::discard()
}
else {
TestResult::from_bool(
partition.subdivide().iter()
.all(|sub| !sub.contains(&elem))
)
}
}
#[cfg(any(test, feature = "arbitrary"))]
pub fn prop_consistent_dispatch<P: Partition<T>, T>(partition: P, elem: T) -> TestResult {
if partition.contains(&elem) {
TestResult::from_bool(partition.subdivide()[partition.dispatch(&elem)].contains(&elem))
}
else {
TestResult::discard()
}
}
#[cfg(test)]
macro_rules! partition_quickcheck (
($testfn: ident, $p: ty, $t: ty) => (
mod $testfn {
use $crate::partition::{
prop_is_total_elem, prop_is_total_non_elem,
prop_consistent_dispatch
};
use quickcheck::{quickcheck, TestResult};
use super::*;
#[test]
fn is_total_elem() {
quickcheck(prop_is_total_elem::<$p, $t> as fn($p, $t) -> TestResult);
}
#[test]
fn is_total_non_elem() {
quickcheck(prop_is_total_non_elem::<$p, $t> as fn($p, $t) -> TestResult);
}
#[test]
fn consistent_dispatch() {
quickcheck(prop_consistent_dispatch::<$p, $t> as fn($p, $t) -> TestResult);
}
}
)
);
pub trait Mid {
fn mid(&self, other: &Self) -> Self;
}
impl Mid for f64 {
fn mid(&self, other: &f64) -> f64 { (*self + *other) / 2.0 }
}
impl Mid for f32 {
fn mid(&self, other: &f32) -> f32 { (*self + *other) / 2.0 }
}
mod interval;
mod boxes;
mod ncube;
mod unitquad;
pub mod cubemap;