Skip to content

Commit ca58618

Browse files
authored
Merge pull request #666 from jamesmcm/vector_iter_impl_sum_product
Sum, Product implementations for Iterator<Vector*>
2 parents 55f4717 + 13307df commit ca58618

File tree

3 files changed

+69
-15
lines changed

3 files changed

+69
-15
lines changed

godot-core/src/builtin/vectors/vector3.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,21 @@ mod test {
414414
assert_eq_approx!(vector1.slerp(vector2, 0.5).length(), real!(6.258_311));
415415
}
416416

417+
#[test]
418+
fn iter_sum() {
419+
let vecs = vec![
420+
Vector3::new(1.0, 2.0, 3.0),
421+
Vector3::new(4.0, 5.0, 6.0),
422+
Vector3::new(7.0, 8.0, 9.0),
423+
];
424+
425+
let sum_refs = vecs.iter().sum();
426+
let sum = vecs.into_iter().sum();
427+
428+
assert_eq_approx!(sum, Vector3::new(12.0, 15.0, 18.0));
429+
assert_eq_approx!(sum_refs, Vector3::new(12.0, 15.0, 18.0));
430+
}
431+
417432
#[cfg(feature = "serde")]
418433
#[test]
419434
fn serde_roundtrip() {

godot-core/src/builtin/vectors/vector4i.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,4 +223,15 @@ mod test {
223223
Some(Vector4Axis::W),
224224
);
225225
}
226+
227+
#[test]
228+
fn test_iter_elementwise_prod() {
229+
let vecs = vec![Vector4i::new(1, 2, 3, 4), Vector4i::new(5, 6, 7, 8)];
230+
let expected = Vector4i::new(5, 12, 21, 32);
231+
let prod_refs: Vector4i = vecs.iter().product();
232+
let prod: Vector4i = vecs.into_iter().product();
233+
234+
assert_eq!(prod_refs, expected);
235+
assert_eq!(prod, expected);
236+
}
226237
}

godot-core/src/builtin/vectors/vector_macros.rs

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ macro_rules! impl_vector_unary_operator {
1212
(
1313
// Name of the vector type.
1414
$Vector:ty,
15-
// Type of each individual component, for example `i32`.
16-
$Scalar:ty,
1715
// Names of the components, with parentheses, for example `(x, y)`.
1816
($($components:ident),*),
1917
// Name of the operator trait, for example `Neg`.
@@ -38,8 +36,6 @@ macro_rules! impl_vector_vector_binary_operator {
3836
(
3937
// Name of the vector type.
4038
$Vector:ty,
41-
// Type of each individual component, for example `i32`.
42-
$Scalar:ty,
4339
// Names of the components, with parentheses, for example `(x, y)`.
4440
($($components:ident),*),
4541
// Name of the operator trait, for example `Add`.
@@ -119,8 +115,6 @@ macro_rules! impl_vector_vector_assign_operator {
119115
(
120116
// Name of the vector type.
121117
$Vector:ty,
122-
// Type of each individual component, for example `i32`.
123-
$Scalar:ty,
124118
// Names of the components, with parentheses, for example `(x, y)`.
125119
($($components:ident),*),
126120
// Name of the operator trait, for example `AddAssign`.
@@ -163,6 +157,38 @@ macro_rules! impl_vector_scalar_assign_operator {
163157
}
164158
}
165159

160+
/// Implements a reduction (sum or product) over an iterator of vectors.
161+
macro_rules! impl_iter_vector_reduction {
162+
(
163+
// Name of the vector type.
164+
$Vector:ty,
165+
// Name of the reduction trait: `Sum` or `Product`.
166+
$Operator:ident,
167+
// Name of the function on the operator trait, for example `add`.
168+
$func:ident
169+
) => {
170+
impl std::iter::$Operator<Self> for $Vector {
171+
#[doc = concat!("Element-wise ", stringify!($func), " of all vectors in the iterator.")]
172+
fn $func<I>(iter: I) -> Self
173+
where
174+
I: Iterator<Item = Self>,
175+
{
176+
Self::from_glam(iter.map(Self::to_glam).$func())
177+
}
178+
}
179+
180+
impl<'a> std::iter::$Operator<&'a Self> for $Vector {
181+
#[doc = concat!("Element-wise ", stringify!($func), " of all vectors in the iterator.")]
182+
fn $func<I>(iter: I) -> Self
183+
where
184+
I: Iterator<Item = &'a Self>,
185+
{
186+
Self::from_glam(iter.map(|x| Self::to_glam(*x)).$func())
187+
}
188+
}
189+
};
190+
}
191+
166192
/// Implements all common arithmetic operators on a built-in vector type.
167193
macro_rules! impl_vector_operators {
168194
(
@@ -173,19 +199,21 @@ macro_rules! impl_vector_operators {
173199
// Names of the components, with parentheses, for example `(x, y)`.
174200
($($components:ident),*)
175201
) => {
176-
impl_vector_unary_operator!($Vector, $Scalar, ($($components),*), Neg, neg);
177-
impl_vector_vector_binary_operator!($Vector, $Scalar, ($($components),*), Add, add);
178-
impl_vector_vector_binary_operator!($Vector, $Scalar, ($($components),*), Sub, sub);
179-
impl_vector_vector_binary_operator!($Vector, $Scalar, ($($components),*), Mul, mul);
202+
impl_vector_unary_operator!($Vector, ($($components),*), Neg, neg);
203+
impl_vector_vector_binary_operator!($Vector, ($($components),*), Add, add);
204+
impl_vector_vector_binary_operator!($Vector, ($($components),*), Sub, sub);
205+
impl_vector_vector_binary_operator!($Vector, ($($components),*), Mul, mul);
180206
impl_vector_scalar_binary_operator!($Vector, $Scalar, ($($components),*), Mul, mul);
181207
impl_scalar_vector_binary_operator!($Vector, $Scalar, ($($components),*), Mul, mul);
182-
impl_vector_vector_binary_operator!($Vector, $Scalar, ($($components),*), Div, div);
208+
impl_vector_vector_binary_operator!($Vector, ($($components),*), Div, div);
183209
impl_vector_scalar_binary_operator!($Vector, $Scalar, ($($components),*), Div, div);
184-
impl_vector_vector_assign_operator!($Vector, $Scalar, ($($components),*), AddAssign, add_assign);
185-
impl_vector_vector_assign_operator!($Vector, $Scalar, ($($components),*), SubAssign, sub_assign);
186-
impl_vector_vector_assign_operator!($Vector, $Scalar, ($($components),*), MulAssign, mul_assign);
210+
impl_iter_vector_reduction!($Vector, Sum, sum);
211+
impl_iter_vector_reduction!($Vector, Product, product);
212+
impl_vector_vector_assign_operator!($Vector, ($($components),*), AddAssign, add_assign);
213+
impl_vector_vector_assign_operator!($Vector, ($($components),*), SubAssign, sub_assign);
214+
impl_vector_vector_assign_operator!($Vector, ($($components),*), MulAssign, mul_assign);
187215
impl_vector_scalar_assign_operator!($Vector, $Scalar, ($($components),*), MulAssign, mul_assign);
188-
impl_vector_vector_assign_operator!($Vector, $Scalar, ($($components),*), DivAssign, div_assign);
216+
impl_vector_vector_assign_operator!($Vector, ($($components),*), DivAssign, div_assign);
189217
impl_vector_scalar_assign_operator!($Vector, $Scalar, ($($components),*), DivAssign, div_assign);
190218
}
191219
}

0 commit comments

Comments
 (0)