From 9af1cac45d8093a783c48fdc714353ff4c959be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Sun, 4 Aug 2013 10:36:35 +0200 Subject: [PATCH] Fix `Ord` implementations to be a partial order. When two elements are not comparable, all comparison operators return `false`. --- src/mat.rs | 12 ++++++------ src/tests/vec.rs | 21 +++++++++++++++++++++ src/vec.rs | 21 +++++++++++++-------- src/vec_macros.rs | 23 +++++++++++++++++++++++ 4 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/mat.rs b/src/mat.rs index 75efe48a..e4fd59c5 100644 --- a/src/mat.rs +++ b/src/mat.rs @@ -30,7 +30,7 @@ pub use traits::transpose::*; mod mat_macros; /// Square matrix of dimension 1. -#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] +#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] pub struct Mat1 { m11: N @@ -55,7 +55,7 @@ to_homogeneous_impl!(Mat1, Mat2, 1, 2) from_homogeneous_impl!(Mat1, Mat2, 1, 2) /// Square matrix of dimension 2. -#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] +#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] pub struct Mat2 { m11: N, m12: N, @@ -84,7 +84,7 @@ to_homogeneous_impl!(Mat2, Mat3, 2, 3) from_homogeneous_impl!(Mat2, Mat3, 2, 3) /// Square matrix of dimension 3. -#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] +#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] pub struct Mat3 { m11: N, m12: N, m13: N, @@ -117,7 +117,7 @@ to_homogeneous_impl!(Mat3, Mat4, 3, 4) from_homogeneous_impl!(Mat3, Mat4, 3, 4) /// Square matrix of dimension 4. -#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] +#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] pub struct Mat4 { m11: N, m12: N, m13: N, m14: N, @@ -158,7 +158,7 @@ to_homogeneous_impl!(Mat4, Mat5, 4, 5) from_homogeneous_impl!(Mat4, Mat5, 4, 5) /// Square matrix of dimension 5. -#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] +#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] pub struct Mat5 { m11: N, m12: N, m13: N, m14: N, m15: N, @@ -205,7 +205,7 @@ to_homogeneous_impl!(Mat5, Mat6, 5, 6) from_homogeneous_impl!(Mat5, Mat6, 5, 6) /// Square matrix of dimension 6. -#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] +#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] pub struct Mat6 { m11: N, m12: N, m13: N, m14: N, m15: N, m16: N, diff --git a/src/tests/vec.rs b/src/tests/vec.rs index 19a1750d..7a1c6c5c 100644 --- a/src/tests/vec.rs +++ b/src/tests/vec.rs @@ -264,3 +264,24 @@ fn test_iterator_vec5() #[test] fn test_iterator_vec6() { test_iterator_impl!(Vec6, f64); } + +#[test] +fn test_ord_vec3() +{ + // equality + assert!(Vec3::new(0.5, 0.5, 0.5) == Vec3::new(0.5, 0.5, 0.5)); + assert!(!(Vec3::new(1.5, 0.5, 0.5) == Vec3::new(0.5, 0.5, 0.5))); + assert!(Vec3::new(1.5, 0.5, 0.5) != Vec3::new(0.5, 0.5, 0.5)); + + // comparable + assert!(Vec3::new(0.5, 0.3, 0.3) < Vec3::new(1.0, 2.0, 1.0)); + assert!(Vec3::new(0.5, 0.3, 0.3) <= Vec3::new(1.0, 2.0, 1.0)); + assert!(Vec3::new(2.0, 4.0, 2.0) > Vec3::new(1.0, 2.0, 1.0)); + assert!(Vec3::new(2.0, 4.0, 2.0) >= Vec3::new(1.0, 2.0, 1.0)); + + // not comparable + assert!(!(Vec3::new(0.0, 3.0, 0.0) < Vec3::new(1.0, 2.0, 1.0))); + assert!(!(Vec3::new(0.0, 3.0, 0.0) > Vec3::new(1.0, 2.0, 1.0))); + assert!(!(Vec3::new(0.0, 3.0, 0.0) <= Vec3::new(1.0, 2.0, 1.0))); + assert!(!(Vec3::new(0.0, 3.0, 0.0) >= Vec3::new(1.0, 2.0, 1.0))); +} diff --git a/src/vec.rs b/src/vec.rs index 0d0bd050..823dc0c6 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -27,11 +27,11 @@ pub use traits::scalar_op::*; mod vec_macros; /// Vector of dimension 0. -#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, Rand, Zero, ToStr)] +#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, Rand, Zero, ToStr)] pub struct Vec0; /// Vector of dimension 1. -#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] +#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] pub struct Vec1 { /// First component of the vector. @@ -39,6 +39,7 @@ pub struct Vec1 } new_impl!(Vec1, x) +ord_impl!(Vec1, x) vec_axis_impl!(Vec1, x) vec_cast_impl!(Vec1, x) indexable_impl!(Vec1, 1) @@ -67,7 +68,7 @@ to_homogeneous_impl!(Vec1, Vec2, y, x) from_homogeneous_impl!(Vec1, Vec2, y, x) /// Vector of dimension 2. -#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] +#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] pub struct Vec2 { /// First component of the vector. @@ -77,6 +78,7 @@ pub struct Vec2 } new_impl!(Vec2, x, y) +ord_impl!(Vec2, x, y) vec_axis_impl!(Vec2, x, y) vec_cast_impl!(Vec2, x, y) indexable_impl!(Vec2, 2) @@ -105,7 +107,7 @@ to_homogeneous_impl!(Vec2, Vec3, z, x, y) from_homogeneous_impl!(Vec2, Vec3, z, x, y) /// Vector of dimension 3. -#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] +#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] pub struct Vec3 { @@ -117,8 +119,8 @@ pub struct Vec3 z: N } - new_impl!(Vec3, x, y, z) +ord_impl!(Vec3, x, y, z) vec_axis_impl!(Vec3, x, y, z) vec_cast_impl!(Vec3, x, y, z) indexable_impl!(Vec3, 3) @@ -147,7 +149,7 @@ to_homogeneous_impl!(Vec3, Vec4, w, x, y, z) from_homogeneous_impl!(Vec3, Vec4, w, x, y, z) /// Vector of dimension 4. -#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] +#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] pub struct Vec4 { /// First component of the vector. @@ -161,6 +163,7 @@ pub struct Vec4 } new_impl!(Vec4, x, y, z, w) +ord_impl!(Vec4, x, y, z, w) vec_axis_impl!(Vec4, x, y, z, w) vec_cast_impl!(Vec4, x, y, z, w) indexable_impl!(Vec4, 4) @@ -189,7 +192,7 @@ to_homogeneous_impl!(Vec4, Vec5, a, x, y, z, w) from_homogeneous_impl!(Vec4, Vec5, a, x, y, z, w) /// Vector of dimension 5. -#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] +#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] pub struct Vec5 { /// First component of the vector. @@ -205,6 +208,7 @@ pub struct Vec5 } new_impl!(Vec5, x, y, z, w, a) +ord_impl!(Vec5, x, y, z, w, a) vec_axis_impl!(Vec5, x, y, z, w, a) vec_cast_impl!(Vec5, x, y, z, w, a) indexable_impl!(Vec5, 5) @@ -233,7 +237,7 @@ to_homogeneous_impl!(Vec5, Vec6, b, x, y, z, w, a) from_homogeneous_impl!(Vec5, Vec6, b, x, y, z, w, a) /// Vector of dimension 6. -#[deriving(Eq, Ord, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] +#[deriving(Eq, Encodable, Decodable, Clone, DeepClone, IterBytes, Rand, Zero, ToStr)] pub struct Vec6 { /// First component of the vector. @@ -251,6 +255,7 @@ pub struct Vec6 } new_impl!(Vec6, x, y, z, w, a, b) +ord_impl!(Vec6, x, y, z, w, a, b) vec_axis_impl!(Vec6, x, y, z, w, a, b) vec_cast_impl!(Vec6, x, y, z, w, a, b) indexable_impl!(Vec6, 6) diff --git a/src/vec_macros.rs b/src/vec_macros.rs index b9b314ca..afbea1d7 100644 --- a/src/vec_macros.rs +++ b/src/vec_macros.rs @@ -17,6 +17,29 @@ macro_rules! new_impl( ) ) +macro_rules! ord_impl( + ($t: ident, $comp0: ident $(,$compN: ident)*) => ( + impl Ord for $t + { + #[inline] + fn lt(&self, other: &$t) -> bool + { self.$comp0 < other.$comp0 $(&& self.$compN < other.$compN)* } + + #[inline] + fn le(&self, other: &$t) -> bool + { self.$comp0 <= other.$comp0 $(&& self.$compN <= other.$compN)* } + + #[inline] + fn gt(&self, other: &$t) -> bool + { self.$comp0 > other.$comp0 $(&& self.$compN > other.$compN)* } + + #[inline] + fn ge(&self, other: &$t) -> bool + { self.$comp0 >= other.$comp0 $(&& self.$compN >= other.$compN)* } + } + ) +) + macro_rules! vec_axis_impl( ($t: ident, $comp0: ident $(,$compN: ident)*) => ( impl $t