Skip to content

Commit

Permalink
Merge pull request godot-rust#666 from jamesmcm/vector_iter_impl_sum_…
Browse files Browse the repository at this point in the history
…product

Sum, Product implementations for Iterator<Vector*>
  • Loading branch information
Bromeon authored Apr 22, 2024
2 parents 55f4717 + 13307df commit ca58618
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 15 deletions.
15 changes: 15 additions & 0 deletions godot-core/src/builtin/vectors/vector3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,21 @@ mod test {
assert_eq_approx!(vector1.slerp(vector2, 0.5).length(), real!(6.258_311));
}

#[test]
fn iter_sum() {
let vecs = vec![
Vector3::new(1.0, 2.0, 3.0),
Vector3::new(4.0, 5.0, 6.0),
Vector3::new(7.0, 8.0, 9.0),
];

let sum_refs = vecs.iter().sum();
let sum = vecs.into_iter().sum();

assert_eq_approx!(sum, Vector3::new(12.0, 15.0, 18.0));
assert_eq_approx!(sum_refs, Vector3::new(12.0, 15.0, 18.0));
}

#[cfg(feature = "serde")]
#[test]
fn serde_roundtrip() {
Expand Down
11 changes: 11 additions & 0 deletions godot-core/src/builtin/vectors/vector4i.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,4 +223,15 @@ mod test {
Some(Vector4Axis::W),
);
}

#[test]
fn test_iter_elementwise_prod() {
let vecs = vec![Vector4i::new(1, 2, 3, 4), Vector4i::new(5, 6, 7, 8)];
let expected = Vector4i::new(5, 12, 21, 32);
let prod_refs: Vector4i = vecs.iter().product();
let prod: Vector4i = vecs.into_iter().product();

assert_eq!(prod_refs, expected);
assert_eq!(prod, expected);
}
}
58 changes: 43 additions & 15 deletions godot-core/src/builtin/vectors/vector_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ macro_rules! impl_vector_unary_operator {
(
// Name of the vector type.
$Vector:ty,
// Type of each individual component, for example `i32`.
$Scalar:ty,
// Names of the components, with parentheses, for example `(x, y)`.
($($components:ident),*),
// Name of the operator trait, for example `Neg`.
Expand All @@ -38,8 +36,6 @@ macro_rules! impl_vector_vector_binary_operator {
(
// Name of the vector type.
$Vector:ty,
// Type of each individual component, for example `i32`.
$Scalar:ty,
// Names of the components, with parentheses, for example `(x, y)`.
($($components:ident),*),
// Name of the operator trait, for example `Add`.
Expand Down Expand Up @@ -119,8 +115,6 @@ macro_rules! impl_vector_vector_assign_operator {
(
// Name of the vector type.
$Vector:ty,
// Type of each individual component, for example `i32`.
$Scalar:ty,
// Names of the components, with parentheses, for example `(x, y)`.
($($components:ident),*),
// Name of the operator trait, for example `AddAssign`.
Expand Down Expand Up @@ -163,6 +157,38 @@ macro_rules! impl_vector_scalar_assign_operator {
}
}

/// Implements a reduction (sum or product) over an iterator of vectors.
macro_rules! impl_iter_vector_reduction {
(
// Name of the vector type.
$Vector:ty,
// Name of the reduction trait: `Sum` or `Product`.
$Operator:ident,
// Name of the function on the operator trait, for example `add`.
$func:ident
) => {
impl std::iter::$Operator<Self> for $Vector {
#[doc = concat!("Element-wise ", stringify!($func), " of all vectors in the iterator.")]
fn $func<I>(iter: I) -> Self
where
I: Iterator<Item = Self>,
{
Self::from_glam(iter.map(Self::to_glam).$func())
}
}

impl<'a> std::iter::$Operator<&'a Self> for $Vector {
#[doc = concat!("Element-wise ", stringify!($func), " of all vectors in the iterator.")]
fn $func<I>(iter: I) -> Self
where
I: Iterator<Item = &'a Self>,
{
Self::from_glam(iter.map(|x| Self::to_glam(*x)).$func())
}
}
};
}

/// Implements all common arithmetic operators on a built-in vector type.
macro_rules! impl_vector_operators {
(
Expand All @@ -173,19 +199,21 @@ macro_rules! impl_vector_operators {
// Names of the components, with parentheses, for example `(x, y)`.
($($components:ident),*)
) => {
impl_vector_unary_operator!($Vector, $Scalar, ($($components),*), Neg, neg);
impl_vector_vector_binary_operator!($Vector, $Scalar, ($($components),*), Add, add);
impl_vector_vector_binary_operator!($Vector, $Scalar, ($($components),*), Sub, sub);
impl_vector_vector_binary_operator!($Vector, $Scalar, ($($components),*), Mul, mul);
impl_vector_unary_operator!($Vector, ($($components),*), Neg, neg);
impl_vector_vector_binary_operator!($Vector, ($($components),*), Add, add);
impl_vector_vector_binary_operator!($Vector, ($($components),*), Sub, sub);
impl_vector_vector_binary_operator!($Vector, ($($components),*), Mul, mul);
impl_vector_scalar_binary_operator!($Vector, $Scalar, ($($components),*), Mul, mul);
impl_scalar_vector_binary_operator!($Vector, $Scalar, ($($components),*), Mul, mul);
impl_vector_vector_binary_operator!($Vector, $Scalar, ($($components),*), Div, div);
impl_vector_vector_binary_operator!($Vector, ($($components),*), Div, div);
impl_vector_scalar_binary_operator!($Vector, $Scalar, ($($components),*), Div, div);
impl_vector_vector_assign_operator!($Vector, $Scalar, ($($components),*), AddAssign, add_assign);
impl_vector_vector_assign_operator!($Vector, $Scalar, ($($components),*), SubAssign, sub_assign);
impl_vector_vector_assign_operator!($Vector, $Scalar, ($($components),*), MulAssign, mul_assign);
impl_iter_vector_reduction!($Vector, Sum, sum);
impl_iter_vector_reduction!($Vector, Product, product);
impl_vector_vector_assign_operator!($Vector, ($($components),*), AddAssign, add_assign);
impl_vector_vector_assign_operator!($Vector, ($($components),*), SubAssign, sub_assign);
impl_vector_vector_assign_operator!($Vector, ($($components),*), MulAssign, mul_assign);
impl_vector_scalar_assign_operator!($Vector, $Scalar, ($($components),*), MulAssign, mul_assign);
impl_vector_vector_assign_operator!($Vector, $Scalar, ($($components),*), DivAssign, div_assign);
impl_vector_vector_assign_operator!($Vector, ($($components),*), DivAssign, div_assign);
impl_vector_scalar_assign_operator!($Vector, $Scalar, ($($components),*), DivAssign, div_assign);
}
}
Expand Down

0 comments on commit ca58618

Please sign in to comment.