From a63843c30adf60dc9d3a2b018609eb2efa140355 Mon Sep 17 00:00:00 2001 From: Mick van Gelderen Date: Mon, 10 Jun 2019 10:48:28 +0200 Subject: [PATCH] Implement zip for VectorN and PointN Impelements #485 --- CHANGELOG.md | 4 ++++ src/point.rs | 26 ++++++++++++++++++++++++++ src/vector.rs | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index af5632c..ee86bd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Added + + - Add `VectorN::zip` and `PointN::zip` + ## [v0.17.0] - 2019-01-17 ### Added diff --git a/src/point.rs b/src/point.rs index 7789b66..17d7bb7 100644 --- a/src/point.rs +++ b/src/point.rs @@ -94,6 +94,16 @@ macro_rules! impl_point { { $PointN { $($field: f(self.$field)),+ } } + + /// Construct a new point where each component is the result of + /// applying the given operation to each pair of components of the + /// given points. + #[inline] + pub fn zip(self, p2: $PointN, mut f: F) -> $PointN + where F: FnMut(S, S2) -> S3 + { + $PointN { $($field: f(self.$field, p2.$field)),+ } + } } /// The short constructor. @@ -483,6 +493,14 @@ mod tests { assert_eq!(p, &POINT2); } } + + #[test] + fn test_zip() { + assert_eq!( + Point2::new(true, false), + Point2::new(-2, 1).zip(Point2::new(-1, -1), |a, b| a < b) + ); + } } mod point3 { @@ -588,5 +606,13 @@ mod tests { assert_eq!(p, &POINT3); } } + + #[test] + fn test_zip() { + assert_eq!( + Point3::new(true, false, false), + Point3::new(-2, 1, 0).zip(Point3::new(-1, -1, -1), |a, b| a < b) + ); + } } } diff --git a/src/vector.rs b/src/vector.rs index 1f569b1..0c758aa 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -114,6 +114,16 @@ macro_rules! impl_vector { { $VectorN { $($field: f(self.$field)),+ } } + + /// Construct a new vector where each component is the result of + /// applying the given operation to each pair of components of the + /// given vectors. + #[inline] + pub fn zip(self, v2: $VectorN, mut f: F) -> $VectorN + where F: FnMut(S, S2) -> S3 + { + $VectorN { $($field: f(self.$field, v2.$field)),+ } + } } /// The short constructor. @@ -1374,6 +1384,14 @@ mod tests { assert!(!Vector2::from([1.0, Float::infinity()]).is_finite()); assert!(Vector2::from([-1.0, 1.0]).is_finite()); } + + #[test] + fn test_zip() { + assert_eq!( + Vector2::new(true, false), + Vector2::new(-2, 1).zip(Vector2::new(-1, -1), |a, b| a < b) + ); + } } mod vector3 { @@ -1487,6 +1505,14 @@ mod tests { assert!(!Vector3::from([1.0, 1.0, Float::infinity()]).is_finite()); assert!(Vector3::from([-1.0, 1.0, 1.0]).is_finite()); } + + #[test] + fn test_zip() { + assert_eq!( + Vector3::new(true, false, false), + Vector3::new(-2, 1, 0).zip(Vector3::new(-1, -1, -1), |a, b| a < b) + ); + } } mod vector4 { @@ -1606,5 +1632,13 @@ mod tests { assert!(!Vector4::from([1.0, 1.0, Float::neg_infinity(), 0.0]).is_finite()); assert!(Vector4::from([-1.0, 0.0, 1.0, 1.0]).is_finite()); } + + #[test] + fn test_zip() { + assert_eq!( + Vector4::new(true, false, false, false), + Vector4::new(-2, 1, 0, 1).zip(Vector4::new(-1, -1, -1, -1), |a, b| a < b) + ); + } } }