From: Ian Jackson Date: Sun, 8 May 2022 09:45:04 +0000 (+0100) Subject: geometry: Introduce some affordances, and add a use case for each X-Git-Tag: otter-1.1.0~262 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=472836983b34c8c498d4f95a5921ac44a927f34a;p=otter.git geometry: Introduce some affordances, and add a use case for each Signed-off-by: Ian Jackson --- diff --git a/base/geometry.rs b/base/geometry.rs index 0552b3de..fcaed93a 100644 --- a/base/geometry.rs +++ b/base/geometry.rs @@ -99,6 +99,15 @@ impl PosPromote for PosC where T: Into + Copy + Debug { pub struct PosCFromIteratorError; display_as_debug!{PosCFromIteratorError} +macro_rules! pos_zip_map { { + $( $input:expr ),* => $closure:expr +} => { + PosC::try_from_iter_2( + izip!($( $input .coords(), )*) + .map($closure) + ) +} } + impl PosC { pub const fn new(x: T, y: T) -> Self { PosC{ coords: [x,y] } } pub fn both(v: T) -> Self where T: Copy { PosC::new(v,v) } @@ -106,10 +115,14 @@ impl PosC { PosC::both(::zero()) } + fn coords(self) -> impl ExactSizeIterator + FusedIterator { + self.coords.into_iter() + } + #[throws(CoordinateOverflow)] pub fn len2(self) -> f64 where PosC: PosPromote { - self.promote().coords.iter() - .try_fold(0., |b, &c| { + self.promote().coords() + .try_fold(0., |b, c| { let c2 = c.checked_mul(c)?; b.checked_add(c2) })? @@ -172,14 +185,7 @@ impl Add> for PosC { type Output = Result; #[throws(CoordinateOverflow)] fn add(self, rhs: PosC) -> PosC { - PosC::try_from_iter_2( - itertools::zip_eq( - self.coords.iter().cloned(), - rhs .coords.iter().cloned(), - ).map( - |(a,b)| a.checked_add(b) - ) - )? + pos_zip_map!( self, rhs => |(a,b)| a.checked_add(b) )? } } diff --git a/base/prelude.rs b/base/prelude.rs index c5da23f0..d482250a 100644 --- a/base/prelude.rs +++ b/base/prelude.rs @@ -8,7 +8,7 @@ pub use std::convert::{TryFrom, TryInto}; pub use std::f64::consts::TAU; pub use std::fmt::{self, Debug, Display, Formatter, Write as _}; pub use std::hash::{Hash, Hasher}; -pub use std::iter; +pub use std::iter::{self, FusedIterator}; pub use std::mem; pub use std::num::{TryFromIntError, Wrapping}; pub use std::ops::{Deref, DerefMut, Index, IndexMut}; diff --git a/src/prelude.rs b/src/prelude.rs index 37e78ec8..eeec8a9a 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -30,7 +30,7 @@ pub use std::io; pub use std::io::ErrorKind; pub use std::io::{BufRead, BufReader, BufWriter, Read, Write}; pub use std::iter; -pub use std::iter::repeat_with; +pub use std::iter::{repeat_with}; pub use std::marker::PhantomData; pub use std::num::{NonZeroUsize, TryFromIntError, Wrapping}; pub use std::os::linux::fs::MetadataExt as _; // todo why linux for st_mode??