use crate::geometry::Geometry;
use crate::point::Point;
pub trait IndexedAccess: Geometry {
fn get_indexed<const I: usize, const D: usize>(&self) -> <Self::Point as Point>::Scalar;
fn set_indexed<const I: usize, const D: usize>(
&mut self,
value: <Self::Point as Point>::Scalar,
);
}
pub mod corner {
pub const MIN: usize = 0;
pub const MAX: usize = 1;
}
#[cfg(test)]
mod tests {
use super::{IndexedAccess, corner};
use crate::geometry::Geometry;
use crate::point::Point;
use geometry_cs::Cartesian;
use geometry_tag::{BoxTag, PointTag};
struct P2(f64, f64);
impl Geometry for P2 {
type Kind = PointTag;
type Point = Self;
}
impl Point for P2 {
type Scalar = f64;
type Cs = Cartesian;
const DIM: usize = 2;
fn get<const D: usize>(&self) -> f64 {
const {
assert!(D < <P2 as Point>::DIM, "Point::get: dimension out of range");
}
if D == 0 { self.0 } else { self.1 }
}
}
struct B {
corners: [[f64; 2]; 2],
}
impl Geometry for B {
type Kind = BoxTag;
type Point = P2;
}
impl IndexedAccess for B {
fn get_indexed<const I: usize, const D: usize>(&self) -> f64 {
const {
assert!(I < 2, "IndexedAccess::get_indexed: index out of range");
assert!(D < 2, "IndexedAccess::get_indexed: dimension out of range");
}
self.corners[I][D]
}
fn set_indexed<const I: usize, const D: usize>(&mut self, v: f64) {
const {
assert!(I < 2, "IndexedAccess::set_indexed: index out of range");
assert!(D < 2, "IndexedAccess::set_indexed: dimension out of range");
}
self.corners[I][D] = v;
}
}
#[test]
fn indexed_get_set_roundtrip() {
let point = P2(5.0, 6.0);
assert_eq!(point.get::<0>().to_bits(), 5.0_f64.to_bits());
assert_eq!(point.get::<1>().to_bits(), 6.0_f64.to_bits());
let mut b = B {
corners: [[0.0; 2]; 2],
};
b.set_indexed::<{ corner::MIN }, 0>(1.0);
b.set_indexed::<{ corner::MIN }, 1>(2.0);
b.set_indexed::<{ corner::MAX }, 0>(3.0);
b.set_indexed::<{ corner::MAX }, 1>(4.0);
assert_eq!(
b.get_indexed::<{ corner::MIN }, 0>().to_bits(),
1.0_f64.to_bits()
);
assert_eq!(
b.get_indexed::<{ corner::MIN }, 1>().to_bits(),
2.0_f64.to_bits()
);
assert_eq!(
b.get_indexed::<{ corner::MAX }, 0>().to_bits(),
3.0_f64.to_bits()
);
assert_eq!(
b.get_indexed::<{ corner::MAX }, 1>().to_bits(),
4.0_f64.to_bits()
);
}
#[test]
fn corner_constants_match_boost() {
assert_eq!(corner::MIN, 0);
assert_eq!(corner::MAX, 1);
}
}