Skip to content

Commit e3e0629

Browse files
committed
Implement by-ref operators for vectors, and remove by-value implementations
We can't yet remove the operator methods, due to rust-lang/rust#20671 This also removes the implementations of `Zero` and `One` for vectors.
1 parent 4374dea commit e3e0629

File tree

4 files changed

+101
-88
lines changed

4 files changed

+101
-88
lines changed

src/aabb.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ pub trait Aabb<S: BaseNum, V: Vector<S>, P: Point<S, V>>: Sized {
8282

8383
/// Multiply every point in the AABB by a vector, returning a new AABB.
8484
fn mul_v(&self, v: &V) -> Self {
85-
let min : P = Point::from_vec(&self.min().to_vec().mul_v(v));
86-
let max : P = Point::from_vec(&self.max().to_vec().mul_v(v));
85+
let min = P::from_vec(&self.min().to_vec().mul_v(v));
86+
let max = P::from_vec(&self.max().to_vec().mul_v(v));
8787
Aabb::new(min, max)
8888
}
8989
}

src/quaternion.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,13 @@ impl<S: BaseFloat> Quaternion<S> {
9090
/// The sum of this quaternion and `other`
9191
#[inline]
9292
pub fn add_q(&self, other: &Quaternion<S>) -> Quaternion<S> {
93-
Quaternion::from_sv(self.s + other.s, self.v + other.v)
93+
Quaternion::from_sv(self.s + other.s, &self.v + &other.v)
9494
}
9595

9696
/// The difference between this quaternion and `other`
9797
#[inline]
9898
pub fn sub_q(&self, other: &Quaternion<S>) -> Quaternion<S> {
99-
Quaternion::from_sv(self.s - other.s, self.v - other.v)
99+
Quaternion::from_sv(self.s - other.s, &self.v - &other.v)
100100
}
101101

102102
/// The result of multipliplying the quaternion by `other`

src/transform.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ impl<
262262
R: Rotation<S, V, P> + Clone,
263263
> ToComponents<S, V, P, R> for Decomposed<S, V, R> {
264264
fn decompose(&self) -> (V, R, V) {
265-
(V::one().mul_s(self.scale), self.rot.clone(), self.disp.clone())
265+
(V::identity().mul_s(self.scale), self.rot.clone(), self.disp.clone())
266266
}
267267
}
268268

src/vector.rs

Lines changed: 96 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -22,38 +22,37 @@
2222
//! vector are also provided:
2323
//!
2424
//! ```rust
25-
//! use cgmath::{Vector, Vector2, Vector3, Vector4, zero, vec2, vec3};
25+
//! use cgmath::{Vector, Vector2, Vector3, Vector4, vec2, vec3};
2626
//!
2727
//! assert_eq!(Vector2::new(1.0f64, 0.0f64), Vector2::unit_x());
28-
//! assert_eq!(vec3(0.0f64, 0.0f64, 0.0f64), zero());
28+
//! assert_eq!(vec3(0.0f64, 0.0f64, 0.0f64), Vector3::zero());
2929
//! assert_eq!(Vector2::from_value(1.0f64), vec2(1.0, 1.0));
3030
//! ```
3131
//!
3232
//! Vectors can be manipulated with typical mathematical operations (addition,
3333
//! subtraction, element-wise multiplication, element-wise division, negation)
34-
//! using the built-in operators. The additive and multiplicative neutral
35-
//! elements (zero and one) are also provided by this library
34+
//! using the built-in operators.
3635
//!
3736
//! ```rust
38-
//! use cgmath::{Vector2, Vector3, Vector4, one, zero};
37+
//! use cgmath::{Vector, Vector2, Vector3, Vector4};
3938
//!
4039
//! let a: Vector2<f64> = Vector2::new(3.0, 4.0);
4140
//! let b: Vector2<f64> = Vector2::new(-3.0, -4.0);
4241
//!
43-
//! assert_eq!(a + b, zero());
44-
//! assert_eq!(-(a * b), Vector2::new(9.0f64, 16.0f64));
45-
//! assert_eq!(a / one(), a);
42+
//! assert_eq!(&a + &b, Vector2::zero());
43+
//! assert_eq!(-(&a * &b), Vector2::new(9.0f64, 16.0f64));
44+
//! assert_eq!(&a / &Vector2::identity(), a);
4645
//!
4746
//! // As with Rust's `int` and `f32` types, Vectors of different types cannot
4847
//! // be added and so on with impunity. The following will fail to compile:
4948
//! // let c = a + Vector3::new(1.0, 0.0, 2.0);
5049
//!
5150
//! // Instead, we need to convert the Vector2 to a Vector3 by "extending" it
5251
//! // with the value for the last coordinate:
53-
//! let c: Vector3<f64> = a.extend(0.0) + Vector3::new(1.0, 0.0, 2.0);
52+
//! let c: Vector3<f64> = &a.extend(0.0) + &Vector3::new(1.0, 0.0, 2.0);
5453
//!
5554
//! // Similarly, we can "truncate" a Vector4 down to a Vector3:
56-
//! let d: Vector3<f64> = c + Vector4::unit_x().truncate();
55+
//! let d: Vector3<f64> = &c + &Vector4::unit_x().truncate();
5756
//!
5857
//! assert_eq!(d, Vector3::new(5.0f64, 4.0f64, 2.0f64));
5958
//! ```
@@ -64,12 +63,12 @@
6463
//! and [cross products](http://en.wikipedia.org/wiki/Cross_product).
6564
//!
6665
//! ```rust
67-
//! use cgmath::{Vector, Vector2, Vector3, Vector4, dot, zero};
66+
//! use cgmath::{Vector, Vector2, Vector3, Vector4, dot};
6867
//!
6968
//! // All vectors implement the dot product as a method:
7069
//! let a: Vector2<f64> = Vector2::new(3.0, 6.0);
7170
//! let b: Vector2<f64> = Vector2::new(-2.0, 1.0);
72-
//! assert_eq!(a.dot(&b), zero());
71+
//! assert_eq!(a.dot(&b), 0.0);
7372
//!
7473
//! // But there is also a top-level function:
7574
//! assert_eq!(a.dot(&b), dot(a, b));
@@ -112,9 +111,32 @@ use num::{BaseNum, BaseFloat};
112111
/// A trait that specifies a range of numeric operations for vectors. Not all
113112
/// of these make sense from a linear algebra point of view, but are included
114113
/// for pragmatic reasons.
115-
pub trait Vector<S: BaseNum>: Array1<S> + Zero + One {
114+
pub trait Vector<S: BaseNum>: Array1<S> + Clone // where
115+
// FIXME: blocked by rust-lang/rust#20671
116+
//
117+
// for<'a, 'b> &'a Self: Add<&'b Self, Output = Self>,
118+
// for<'a, 'b> &'a Self: Sub<&'b Self, Output = Self>,
119+
// for<'a, 'b> &'a Self: Mul<&'b Self, Output = Self>,
120+
// for<'a, 'b> &'a Self: Div<&'b Self, Output = Self>,
121+
// for<'a, 'b> &'a Self: Rem<&'b Self, Output = Self>,
122+
// for<'a, 'b> &'a Self: Sub<&'b Self, Output = Self>,
123+
//
124+
// for<'a> &'a Self: Add<S, Output = Self>,
125+
// for<'a> &'a Self: Sub<S, Output = Self>,
126+
// for<'a> &'a Self: Mul<S, Output = Self>,
127+
// for<'a> &'a Self: Div<S, Output = Self>,
128+
// for<'a> &'a Self: Rem<S, Output = Self>,
129+
{
116130
/// Construct a vector from a single value, replicating it.
117131
fn from_value(s: S) -> Self;
132+
133+
/// The zero vector (with all components set to zero)
134+
#[inline]
135+
fn zero() -> Self { Self::from_value(S::zero()) }
136+
/// The identity vector (with all components set to one)
137+
#[inline]
138+
fn identity() -> Self { Self::from_value(S::one()) }
139+
118140
/// Add a scalar to this vector, returning a new vector.
119141
#[must_use]
120142
fn add_s(&self, s: S) -> Self;
@@ -215,19 +237,6 @@ macro_rules! vec {
215237
$Self_::new($($field),+)
216238
}
217239

218-
impl<$S: Zero + BaseNum> Zero for $Self_<$S> {
219-
#[inline]
220-
fn zero() -> $Self_<S> { $Self_ { $($field: $S::zero()),+ } }
221-
222-
#[inline]
223-
fn is_zero(&self) -> bool { $((self.$field.is_zero()) )&&+ }
224-
}
225-
226-
impl<$S: One + BaseNum> One for $Self_<$S> {
227-
#[inline]
228-
fn one() -> $Self_<$S> { $Self_ { $($field: S::one()),+ } }
229-
}
230-
231240
impl<$S: NumCast + Copy> $Self_<$S> {
232241
/// Component-wise casting to another type
233242
#[inline]
@@ -240,94 +249,98 @@ macro_rules! vec {
240249

241250
impl<S: BaseNum> Vector<S> for $Self_<S> {
242251
#[inline] fn from_value(s: S) -> $Self_<S> { $Self_ { $($field: s),+ } }
243-
#[inline] fn add_s(&self, s: S) -> $Self_<S> { $Self_::new($(self.$field + s),+) }
244-
#[inline] fn sub_s(&self, s: S) -> $Self_<S> { $Self_::new($(self.$field - s),+) }
245-
#[inline] fn mul_s(&self, s: S) -> $Self_<S> { $Self_::new($(self.$field * s),+) }
246-
#[inline] fn div_s(&self, s: S) -> $Self_<S> { $Self_::new($(self.$field / s),+) }
247-
#[inline] fn rem_s(&self, s: S) -> $Self_<S> { $Self_::new($(self.$field % s),+) }
248-
249-
#[inline] fn add_v(&self, v: &$Self_<S>) -> $Self_<S> { $Self_::new($(self.$field + v.$field),+) }
250-
#[inline] fn sub_v(&self, v: &$Self_<S>) -> $Self_<S> { $Self_::new($(self.$field - v.$field),+) }
251-
#[inline] fn mul_v(&self, v: &$Self_<S>) -> $Self_<S> { $Self_::new($(self.$field * v.$field),+) }
252-
#[inline] fn div_v(&self, v: &$Self_<S>) -> $Self_<S> { $Self_::new($(self.$field / v.$field),+) }
253-
#[inline] fn rem_v(&self, v: &$Self_<S>) -> $Self_<S> { $Self_::new($(self.$field % v.$field),+) }
254-
255-
#[inline] fn add_self_s(&mut self, s: S) { $(self.$field = self.$field + s;)+ }
256-
#[inline] fn sub_self_s(&mut self, s: S) { $(self.$field = self.$field - s;)+ }
257-
#[inline] fn mul_self_s(&mut self, s: S) { $(self.$field = self.$field * s;)+ }
258-
#[inline] fn div_self_s(&mut self, s: S) { $(self.$field = self.$field / s;)+ }
259-
#[inline] fn rem_self_s(&mut self, s: S) { $(self.$field = self.$field % s;)+ }
260-
261-
#[inline] fn add_self_v(&mut self, v: &$Self_<S>) { $(self.$field = self.$field + v.$field;)+ }
262-
#[inline] fn sub_self_v(&mut self, v: &$Self_<S>) { $(self.$field = self.$field - v.$field;)+ }
263-
#[inline] fn mul_self_v(&mut self, v: &$Self_<S>) { $(self.$field = self.$field * v.$field;)+ }
264-
#[inline] fn div_self_v(&mut self, v: &$Self_<S>) { $(self.$field = self.$field / v.$field;)+ }
265-
#[inline] fn rem_self_v(&mut self, v: &$Self_<S>) { $(self.$field = self.$field % v.$field;)+ }
252+
253+
#[inline] fn add_s(&self, s: S) -> $Self_<S> { self + s }
254+
#[inline] fn sub_s(&self, s: S) -> $Self_<S> { self - s }
255+
#[inline] fn mul_s(&self, s: S) -> $Self_<S> { self * s }
256+
#[inline] fn div_s(&self, s: S) -> $Self_<S> { self / s }
257+
#[inline] fn rem_s(&self, s: S) -> $Self_<S> { self % s }
258+
259+
#[inline] fn add_v(&self, v: &$Self_<S>) -> $Self_<S> { self + v }
260+
#[inline] fn sub_v(&self, v: &$Self_<S>) -> $Self_<S> { self - v }
261+
#[inline] fn mul_v(&self, v: &$Self_<S>) -> $Self_<S> { self * v }
262+
#[inline] fn div_v(&self, v: &$Self_<S>) -> $Self_<S> { self / v }
263+
#[inline] fn rem_v(&self, v: &$Self_<S>) -> $Self_<S> { self % v }
264+
265+
#[inline] fn add_self_s(&mut self, s: S) { *self = &*self + s; }
266+
#[inline] fn sub_self_s(&mut self, s: S) { *self = &*self - s; }
267+
#[inline] fn mul_self_s(&mut self, s: S) { *self = &*self * s; }
268+
#[inline] fn div_self_s(&mut self, s: S) { *self = &*self / s; }
269+
#[inline] fn rem_self_s(&mut self, s: S) { *self = &*self % s; }
270+
271+
#[inline] fn add_self_v(&mut self, v: &$Self_<S>) { *self = &*self + v; }
272+
#[inline] fn sub_self_v(&mut self, v: &$Self_<S>) { *self = &*self - v; }
273+
#[inline] fn mul_self_v(&mut self, v: &$Self_<S>) { *self = &*self * v; }
274+
#[inline] fn div_self_v(&mut self, v: &$Self_<S>) { *self = &*self / v; }
275+
#[inline] fn rem_self_v(&mut self, v: &$Self_<S>) { *self = &*self % v; }
266276

267277
#[inline] fn comp_add(&self) -> S { fold!(add, { $(self.$field),+ }) }
268278
#[inline] fn comp_mul(&self) -> S { fold!(mul, { $(self.$field),+ }) }
269279
#[inline] fn comp_min(&self) -> S { fold!(partial_min, { $(self.$field),+ }) }
270280
#[inline] fn comp_max(&self) -> S { fold!(partial_max, { $(self.$field),+ }) }
271281
}
272282

273-
impl<S: BaseNum> Add for $Self_<S> {
274-
type Output = $Self_<S>;
275-
276-
#[inline]
277-
fn add(self, v: $Self_<S>) -> $Self_<S> { self.add_v(&v) }
278-
}
279-
280-
impl<S: BaseNum> Sub for $Self_<S> {
281-
type Output = $Self_<S>;
282-
283-
#[inline]
284-
fn sub(self, v: $Self_<S>) -> $Self_<S> { self.sub_v(&v) }
285-
}
286-
287283
impl<S: Neg<Output = S>> Neg for $Self_<S> {
288284
type Output = $Self_<S>;
289285

290286
#[inline]
291287
fn neg(self) -> $Self_<S> { $Self_::new($(-self.$field),+) }
292288
}
293289

294-
impl<S: BaseNum> Mul for $Self_<S> {
295-
type Output = $Self_<S>;
296-
290+
impl<S: BaseFloat> ApproxEq<S> for $Self_<S> {
297291
#[inline]
298-
fn mul(self, v: $Self_<S>) -> $Self_<S> { self.mul_v(&v) }
292+
fn approx_eq_eps(&self, other: &$Self_<S>, epsilon: &S) -> bool {
293+
$(self.$field.approx_eq_eps(&other.$field, epsilon))&&+
294+
}
299295
}
300296

301-
impl<S: BaseNum> Div for $Self_<S> {
302-
type Output = $Self_<S>;
303-
297+
impl<S: BaseFloat + Rand> Rand for $Self_<S> {
304298
#[inline]
305-
fn div(self, v: $Self_<S>) -> $Self_<S> { self.div_v(&v) }
299+
fn rand<R: Rng>(rng: &mut R) -> $Self_<S> {
300+
$Self_ { $($field: rng.gen()),+ }
301+
}
306302
}
303+
}
304+
}
307305

308-
impl<S: BaseNum> Rem for $Self_<S> {
309-
type Output = $Self_<S>;
310-
311-
#[inline]
312-
fn rem(self, v: $Self_<S>) -> $Self_<S> { self.rem_v(&v) }
313-
}
306+
macro_rules! impl_binary_operator {
307+
($Binop:ident :: $binop:ident, $VectorN:ident { $($field:ident),+ }) => {
308+
impl<'a, S: BaseNum> $Binop<S> for &'a $VectorN<S> {
309+
type Output = $VectorN<S>;
314310

315-
impl<S: BaseFloat> ApproxEq<S> for $Self_<S> {
316311
#[inline]
317-
fn approx_eq_eps(&self, other: &$Self_<S>, epsilon: &S) -> bool {
318-
$(self.$field.approx_eq_eps(&other.$field, epsilon))&&+
312+
fn $binop(self, s: S) -> $VectorN<S> {
313+
$VectorN::new($(self.$field.$binop(s)),+)
319314
}
320315
}
321316

322-
impl<S: BaseFloat + Rand> Rand for $Self_<S> {
317+
impl<'a, 'b, S: BaseNum> $Binop<&'a $VectorN<S>> for &'b $VectorN<S> {
318+
type Output = $VectorN<S>;
319+
323320
#[inline]
324-
fn rand<R: Rng>(rng: &mut R) -> $Self_<S> {
325-
$Self_ { $($field: rng.gen()),+ }
321+
fn $binop(self, other: &'a $VectorN<S>) -> $VectorN<S> {
322+
$VectorN::new($(self.$field.$binop(other.$field)),+)
326323
}
327324
}
328325
}
329326
}
330327

328+
impl_binary_operator!(Add::add, Vector2 { x, y });
329+
impl_binary_operator!(Add::add, Vector3 { x, y, z });
330+
impl_binary_operator!(Add::add, Vector4 { x, y, z, w });
331+
impl_binary_operator!(Sub::sub, Vector2 { x, y });
332+
impl_binary_operator!(Sub::sub, Vector3 { x, y, z });
333+
impl_binary_operator!(Sub::sub, Vector4 { x, y, z, w });
334+
impl_binary_operator!(Mul::mul, Vector2 { x, y });
335+
impl_binary_operator!(Mul::mul, Vector3 { x, y, z });
336+
impl_binary_operator!(Mul::mul, Vector4 { x, y, z, w });
337+
impl_binary_operator!(Div::div, Vector2 { x, y });
338+
impl_binary_operator!(Div::div, Vector3 { x, y, z });
339+
impl_binary_operator!(Div::div, Vector4 { x, y, z, w });
340+
impl_binary_operator!(Rem::rem, Vector2 { x, y });
341+
impl_binary_operator!(Rem::rem, Vector3 { x, y, z });
342+
impl_binary_operator!(Rem::rem, Vector4 { x, y, z, w });
343+
331344
macro_rules! fold {
332345
(&$method:ident, { $x:expr, $y:expr }) => { $x.$method(&$y) };
333346
(&$method:ident, { $x:expr, $y:expr, $z:expr }) => { $x.$method(&$y).$method(&$z) };

0 commit comments

Comments
 (0)