chiark / gitweb /
geometry: Introduce some affordances, and add a use case for each
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 8 May 2022 09:45:04 +0000 (10:45 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 8 May 2022 09:45:04 +0000 (10:45 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
base/geometry.rs
base/prelude.rs
src/prelude.rs

index 0552b3def465e8d6197863d74473857feb4d2206..fcaed93a6d2621ba271e359c9c534144446bb967 100644 (file)
@@ -99,6 +99,15 @@ impl<T> PosPromote for PosC<T> where T: Into<f64> + 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<T> PosC<T> {
   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<T> PosC<T> {
     PosC::both(<T as num_traits::Zero>::zero())
   }
 
+  fn coords(self) -> impl ExactSizeIterator<Item=T> + FusedIterator<Item=T> {
+    self.coords.into_iter()
+  }
+
   #[throws(CoordinateOverflow)]
   pub fn len2(self) -> f64 where PosC<T>: 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<T:CheckedArith> Add<PosC<T>> for PosC<T> {
   type Output = Result<Self, CoordinateOverflow>;
   #[throws(CoordinateOverflow)]
   fn add(self, rhs: PosC<T>) -> PosC<T> {
-    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) )?
   }
 }
 
index c5da23f0655360dfb769769663fa3424a9a13493..d482250a9523e78880716f7ccf1fe40f11fd427a 100644 (file)
@@ -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};
index 37e78ec8b5502252606b1787c683e75435e70414..eeec8a9a79c503b8b2dc4678b2cbb86062133750 100644 (file)
@@ -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??