Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Support for `u8` and `i8` scalars, mapping to `glam::U8Vec{N}` and `glam::I8Vec{N}`.
- Implement right-hand side scalar `Add`, `Sub`, and `Mul` (#69).
- Implement scalar `Point` operations (#71).
- Implement `Mul<Vector{2,3}>` and `Mul<Point{2,3}>` for `Matrix{3,4}`.

### Breaking changes
Expand Down
30 changes: 30 additions & 0 deletions src/impl_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,14 @@ pub(crate) use vector_ops;
macro_rules! point_ops {
($point_type_name:ident, $vector_type_name:ident) => {
crate::impl_ops::impl_ops! {
Add<$point_type_name>::add for $point_type_name -> $point_type_name;
Add<$vector_type_name>::add for $point_type_name -> $point_type_name;
Sub<$point_type_name>::sub for $point_type_name -> $vector_type_name;
Sub<$vector_type_name>::sub for $point_type_name -> $point_type_name;
Rem<$point_type_name>::rem for $point_type_name -> $vector_type_name;
}
crate::impl_ops::impl_assign_ops! {
AddAssign<$point_type_name>::add_assign for $point_type_name;
AddAssign<$vector_type_name>::add_assign for $point_type_name;
SubAssign<$vector_type_name>::sub_assign for $point_type_name;
RemAssign<$vector_type_name>::rem_assign for $point_type_name;
Expand All @@ -74,7 +76,35 @@ macro_rules! point_ops {
crate::wrap(core::ops::Neg::neg(crate::peel(self)))
}
}

// Need specific impls for each scalar types because the scalar is an associated type,
// so the compiler would think that the trait impls could overlap.
crate::impl_ops::point_ops!(@scalar $point_type_name, [f32, f64, i32, u32, i64, u64, i16, u16]);
};

(@scalar $base_type_name:ident, [$($scalar:ident),*]) => {
$(
crate::impl_ops::impl_scalar_ops! {
Add<$scalar>::add for $base_type_name -> $base_type_name;
Sub<$scalar>::sub for $base_type_name -> $base_type_name;
Mul<$scalar>::mul for $base_type_name -> $base_type_name;
Div<$scalar>::div for $base_type_name -> $base_type_name;
Rem<$scalar>::rem for $base_type_name -> $base_type_name;
}
crate::impl_ops::impl_scalar_ops_rhs! {
Add<$scalar>::add for $base_type_name -> $base_type_name;
Sub<$scalar>::sub for $base_type_name -> $base_type_name;
Mul<$scalar>::mul for $base_type_name -> $base_type_name;
}
crate::impl_ops::impl_scalar_assign_ops! {
AddAssign<$scalar>::add_assign for $base_type_name;
SubAssign<$scalar>::sub_assign for $base_type_name;
MulAssign<$scalar>::mul_assign for $base_type_name;
DivAssign<$scalar>::div_assign for $base_type_name;
RemAssign<$scalar>::rem_assign for $base_type_name;
}
)*
}
}
pub(crate) use point_ops;

Expand Down
49 changes: 39 additions & 10 deletions src/point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,45 @@ mod tests {

type Point = super::Point3<f32>;

#[test]
#[expect(clippy::op_ref)]
fn ops_by_scalar_ref() {
let a = Point::new(1.0, 2.0, 3.0);
let b = 2.0;
let added = a + b;
let subtracted = a - b;
let multiplied = a * b;

assert_eq!(a + &b, added);
assert_eq!(&a + b, added);
assert_eq!(&a + &b, added);
assert_eq!(b + &a, added);
assert_eq!(&b + a, added);
assert_eq!(&b + &a, added);
assert_eq!(a - &b, subtracted);
assert_eq!(&a - b, subtracted);
assert_eq!(&a - &b, subtracted);
assert_eq!(b - &a, subtracted);
assert_eq!(&b - a, subtracted);
assert_eq!(&b - &a, subtracted);
assert_eq!(a * &b, multiplied);
assert_eq!(&a * b, multiplied);
assert_eq!(&a * &b, multiplied);
assert_eq!(b * &a, multiplied);
assert_eq!(&b * a, multiplied);
assert_eq!(&b * &a, multiplied);

let mut a2 = a;
a2 += &b;
assert_eq!(a2, added);
let mut a2 = a;
a2 -= &b;
assert_eq!(a2, subtracted);
let mut a2 = a;
a2 *= &b;
assert_eq!(a2, multiplied);
}

#[test]
fn subtraction_yields_vector() {
let p = Point::ONE;
Expand All @@ -331,16 +370,6 @@ mod tests {
assert_eq!(v, Vector3::<f32>::ZERO);
}

#[test]
fn not_scalable() {
let p = Point::default();

// This should not compile:
// let q = p * 2.0;

let _ = p;
}

#[test]
fn vec3a() {
let a: glam::Vec3A = Point::new(0.0, 1.0, 2.0).to_vec3a();
Expand Down