diff --git a/src/base/construction.rs b/src/base/construction.rs index 7ac24306..c740ce88 100644 --- a/src/base/construction.rs +++ b/src/base/construction.rs @@ -238,7 +238,7 @@ where SB: Storage, { assert!(!columns.is_empty(), "At least one column must be given."); - let ncols = C::try_to_usize().unwrap_or(columns.len()); + let ncols = C::try_to_usize().unwrap_or_else(|| columns.len()); let nrows = columns[0].len(); assert!( columns.len() == ncols, diff --git a/src/base/interpolation.rs b/src/base/interpolation.rs index faa630d9..afd3ccc7 100644 --- a/src/base/interpolation.rs +++ b/src/base/interpolation.rs @@ -81,7 +81,7 @@ impl> Unit> { { // TODO: the result is wrong when self and rhs are collinear with opposite direction. self.try_slerp(rhs, t, N::default_epsilon()) - .unwrap_or(Unit::new_unchecked(self.clone_owned())) + .unwrap_or_else(|| Unit::new_unchecked(self.clone_owned())) } /// Computes the spherical linear interpolation between two unit vectors. diff --git a/src/base/matrix.rs b/src/base/matrix.rs index e945a594..8035d2f8 100644 --- a/src/base/matrix.rs +++ b/src/base/matrix.rs @@ -298,20 +298,6 @@ impl> Matrix { unsafe { Self::from_data_statically_unchecked(data) } } - /// The total number of elements of this matrix. - /// - /// # Examples: - /// - /// ``` - /// # use nalgebra::Matrix3x4; - /// let mat = Matrix3x4::::zeros(); - /// assert_eq!(mat.len(), 12); - #[inline] - pub fn len(&self) -> usize { - let (nrows, ncols) = self.shape(); - nrows * ncols - } - /// The shape of this matrix returned as the tuple (number of rows, number of columns). /// /// # Examples: diff --git a/src/base/min_max.rs b/src/base/min_max.rs index 90af0142..0bddd4b0 100644 --- a/src/base/min_max.rs +++ b/src/base/min_max.rs @@ -57,7 +57,7 @@ impl> Matrix { N: SimdPartialOrd + Zero, { self.fold_with( - |e| e.map(|e| e.inlined_clone()).unwrap_or(N::zero()), + |e| e.map(|e| e.inlined_clone()).unwrap_or_else(N::zero), |a, b| a.simd_max(b.inlined_clone()), ) } @@ -75,7 +75,7 @@ impl> Matrix { N: Zero + SimdPartialOrd + SimdSigned, { self.fold_with( - |e| e.map(|e| e.simd_abs()).unwrap_or(N::zero()), + |e| e.map(|e| e.simd_abs()).unwrap_or_else(N::zero), |a, b| a.simd_min(b.simd_abs()), ) } @@ -97,7 +97,7 @@ impl> Matrix { self.fold_with( |e| { e.map(|e| e.simd_norm1()) - .unwrap_or(N::SimdRealField::zero()) + .unwrap_or_else(N::SimdRealField::zero) }, |a, b| a.simd_min(b.simd_norm1()), ) @@ -117,7 +117,7 @@ impl> Matrix { N: SimdPartialOrd + Zero, { self.fold_with( - |e| e.map(|e| e.inlined_clone()).unwrap_or(N::zero()), + |e| e.map(|e| e.inlined_clone()).unwrap_or_else(N::zero), |a, b| a.simd_min(b.inlined_clone()), ) } diff --git a/src/base/properties.rs b/src/base/properties.rs index a3664d48..d1119afe 100644 --- a/src/base/properties.rs +++ b/src/base/properties.rs @@ -10,11 +10,33 @@ use crate::base::storage::Storage; use crate::base::{DefaultAllocator, Matrix, Scalar, SquareMatrix}; impl> Matrix { - /// Indicates if this is an empty matrix. + /// The total number of elements of this matrix. + /// + /// # Examples: + /// + /// ``` + /// # use nalgebra::Matrix3x4; + /// let mat = Matrix3x4::::zeros(); + /// assert_eq!(mat.len(), 12); + /// ``` + #[inline] + pub fn len(&self) -> usize { + let (nrows, ncols) = self.shape(); + nrows * ncols + } + + /// Returns true if the matrix contains no elements. + /// + /// # Examples: + /// + /// ``` + /// # use nalgebra::Matrix3x4; + /// let mat = Matrix3x4::::zeros(); + /// assert!(!mat.is_empty()); + /// ``` #[inline] pub fn is_empty(&self) -> bool { - let (nrows, ncols) = self.shape(); - nrows == 0 || ncols == 0 + self.len() == 0 } /// Indicates if this is a square matrix. diff --git a/src/base/storage.rs b/src/base/storage.rs index c09551c0..038884e3 100644 --- a/src/base/storage.rs +++ b/src/base/storage.rs @@ -72,7 +72,7 @@ pub unsafe trait Storage: Debug + Sized { /// Gets the address of the i-th matrix component without performing bound-checking. #[inline] unsafe fn get_address_unchecked_linear(&self, i: usize) -> *const N { - self.ptr().wrapping_offset(i as isize) + self.ptr().wrapping_add(i) } /// Gets the address of the i-th matrix component without performing bound-checking. @@ -124,7 +124,7 @@ pub unsafe trait StorageMut: Storage { /// Gets the mutable address of the i-th matrix component without performing bound-checking. #[inline] unsafe fn get_address_unchecked_linear_mut(&mut self, i: usize) -> *mut N { - self.ptr_mut().wrapping_offset(i as isize) + self.ptr_mut().wrapping_add(i) } /// Gets the mutable address of the i-th matrix component without performing bound-checking. diff --git a/src/base/vec_storage.rs b/src/base/vec_storage.rs index 37f31213..03f032e8 100644 --- a/src/base/vec_storage.rs +++ b/src/base/vec_storage.rs @@ -85,6 +85,12 @@ impl VecStorage { pub fn len(&self) -> usize { self.data.len() } + + /// Returns true if the underlying vector contains no elements. + #[inline] + pub fn is_empty(&self) -> bool { + self.len() == 0 + } } impl Into> for VecStorage { diff --git a/src/geometry/isometry_conversion.rs b/src/geometry/isometry_conversion.rs index bdb128f9..e3416cac 100644 --- a/src/geometry/isometry_conversion.rs +++ b/src/geometry/isometry_conversion.rs @@ -187,7 +187,7 @@ where #[inline] fn from(arr: [Isometry; 2]) -> Self { let tra = Translation::from([arr[0].translation.clone(), arr[1].translation.clone()]); - let rot = R::from([arr[0].rotation.clone(), arr[0].rotation.clone()]); + let rot = R::from([arr[0].rotation, arr[0].rotation]); Self::from_parts(tra, rot) } @@ -212,10 +212,10 @@ where arr[3].translation.clone(), ]); let rot = R::from([ - arr[0].rotation.clone(), - arr[1].rotation.clone(), - arr[2].rotation.clone(), - arr[3].rotation.clone(), + arr[0].rotation, + arr[1].rotation, + arr[2].rotation, + arr[3].rotation, ]); Self::from_parts(tra, rot) @@ -245,14 +245,14 @@ where arr[7].translation.clone(), ]); let rot = R::from([ - arr[0].rotation.clone(), - arr[1].rotation.clone(), - arr[2].rotation.clone(), - arr[3].rotation.clone(), - arr[4].rotation.clone(), - arr[5].rotation.clone(), - arr[6].rotation.clone(), - arr[7].rotation.clone(), + arr[0].rotation, + arr[1].rotation, + arr[2].rotation, + arr[3].rotation, + arr[4].rotation, + arr[5].rotation, + arr[6].rotation, + arr[7].rotation, ]); Self::from_parts(tra, rot) @@ -290,22 +290,22 @@ where arr[15].translation.clone(), ]); let rot = R::from([ - arr[0].rotation.clone(), - arr[1].rotation.clone(), - arr[2].rotation.clone(), - arr[3].rotation.clone(), - arr[4].rotation.clone(), - arr[5].rotation.clone(), - arr[6].rotation.clone(), - arr[7].rotation.clone(), - arr[8].rotation.clone(), - arr[9].rotation.clone(), - arr[10].rotation.clone(), - arr[11].rotation.clone(), - arr[12].rotation.clone(), - arr[13].rotation.clone(), - arr[14].rotation.clone(), - arr[15].rotation.clone(), + arr[0].rotation, + arr[1].rotation, + arr[2].rotation, + arr[3].rotation, + arr[4].rotation, + arr[5].rotation, + arr[6].rotation, + arr[7].rotation, + arr[8].rotation, + arr[9].rotation, + arr[10].rotation, + arr[11].rotation, + arr[12].rotation, + arr[13].rotation, + arr[14].rotation, + arr[15].rotation, ]); Self::from_parts(tra, rot) diff --git a/src/geometry/isometry_ops.rs b/src/geometry/isometry_ops.rs index 20e96f3e..ecca9bb2 100644 --- a/src/geometry/isometry_ops.rs +++ b/src/geometry/isometry_ops.rs @@ -219,7 +219,7 @@ md_assign_impl_all!( (U3, U3), (U3, U3) for; self: Isometry>, rhs: UnitQuaternion; [val] => self.rotation *= rhs; - [ref] => self.rotation *= rhs.clone(); + [ref] => self.rotation *= *rhs; ); md_assign_impl_all!( @@ -236,7 +236,7 @@ md_assign_impl_all!( (U2, U2), (U2, U2) for; self: Isometry>, rhs: UnitComplex; [val] => self.rotation *= rhs; - [ref] => self.rotation *= rhs.clone(); + [ref] => self.rotation *= *rhs; ); md_assign_impl_all!( @@ -378,9 +378,9 @@ isometry_from_composition_impl_all!( self: UnitQuaternion, right: Translation, Output = Isometry>; [val val] => Isometry::from_parts(Translation::from(&self * right.vector), self); - [ref val] => Isometry::from_parts(Translation::from( self * right.vector), self.clone()); + [ref val] => Isometry::from_parts(Translation::from( self * right.vector), *self); [val ref] => Isometry::from_parts(Translation::from(&self * &right.vector), self); - [ref ref] => Isometry::from_parts(Translation::from( self * &right.vector), self.clone()); + [ref ref] => Isometry::from_parts(Translation::from( self * &right.vector), *self); ); // Isometry × Rotation @@ -442,9 +442,9 @@ isometry_from_composition_impl_all!( self: Isometry>, rhs: UnitQuaternion, Output = Isometry>; [val val] => Isometry::from_parts(self.translation, self.rotation * rhs); - [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs); // TODO: do not clone. - [val ref] => Isometry::from_parts(self.translation, self.rotation * rhs.clone()); - [ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs.clone()); + [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation * rhs); // TODO: do not clone. + [val ref] => Isometry::from_parts(self.translation, self.rotation * *rhs); + [ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation * *rhs); ); // UnitQuaternion × Isometry @@ -469,9 +469,9 @@ isometry_from_composition_impl_all!( self: Isometry>, rhs: UnitQuaternion, Output = Isometry>; [val val] => Isometry::from_parts(self.translation, self.rotation / rhs); - [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs); // TODO: do not clone. - [val ref] => Isometry::from_parts(self.translation, self.rotation / rhs.clone()); - [ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs.clone()); + [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation / rhs); // TODO: do not clone. + [val ref] => Isometry::from_parts(self.translation, self.rotation / *rhs); + [ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation / *rhs); ); // UnitQuaternion ÷ Isometry @@ -505,8 +505,8 @@ isometry_from_composition_impl_all!( self: Translation, right: UnitQuaternion, Output = Isometry>; [val val] => Isometry::from_parts(self, right); [ref val] => Isometry::from_parts(self.clone(), right); - [val ref] => Isometry::from_parts(self, right.clone()); - [ref ref] => Isometry::from_parts(self.clone(), right.clone()); + [val ref] => Isometry::from_parts(self, *right); + [ref ref] => Isometry::from_parts(self.clone(), *right); ); // Isometry × UnitComplex @@ -516,9 +516,9 @@ isometry_from_composition_impl_all!( self: Isometry>, rhs: UnitComplex, Output = Isometry>; [val val] => Isometry::from_parts(self.translation, self.rotation * rhs); - [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs); // TODO: do not clone. - [val ref] => Isometry::from_parts(self.translation, self.rotation * rhs.clone()); - [ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs.clone()); + [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation * rhs); // TODO: do not clone. + [val ref] => Isometry::from_parts(self.translation, self.rotation * *rhs); + [ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation * *rhs); ); // Isometry ÷ UnitComplex @@ -528,7 +528,7 @@ isometry_from_composition_impl_all!( self: Isometry>, rhs: UnitComplex, Output = Isometry>; [val val] => Isometry::from_parts(self.translation, self.rotation / rhs); - [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs); // TODO: do not clone. - [val ref] => Isometry::from_parts(self.translation, self.rotation / rhs.clone()); - [ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs.clone()); + [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation / rhs); // TODO: do not clone. + [val ref] => Isometry::from_parts(self.translation, self.rotation / *rhs); + [ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation / *rhs); ); diff --git a/src/geometry/orthographic.rs b/src/geometry/orthographic.rs index 9840f271..bd1e73c7 100644 --- a/src/geometry/orthographic.rs +++ b/src/geometry/orthographic.rs @@ -26,7 +26,7 @@ impl Copy for Orthographic3 {} impl Clone for Orthographic3 { #[inline] fn clone(&self) -> Self { - Self::from_matrix_unchecked(self.matrix.clone()) + Self::from_matrix_unchecked(self.matrix) } } diff --git a/src/geometry/perspective.rs b/src/geometry/perspective.rs index c11b7632..bd8abac2 100644 --- a/src/geometry/perspective.rs +++ b/src/geometry/perspective.rs @@ -27,7 +27,7 @@ impl Copy for Perspective3 {} impl Clone for Perspective3 { #[inline] fn clone(&self) -> Self { - Self::from_matrix_unchecked(self.matrix.clone()) + Self::from_matrix_unchecked(self.matrix) } } diff --git a/src/geometry/point.rs b/src/geometry/point.rs index e0c26054..0684b3b0 100644 --- a/src/geometry/point.rs +++ b/src/geometry/point.rs @@ -194,6 +194,19 @@ where self.coords.len() } + /// Returns true if the point contains no elements. + /// + /// # Example + /// ``` + /// # use nalgebra::{Point2, Point3}; + /// let p = Point2::new(1.0, 2.0); + /// assert!(!p.is_empty()); + /// ``` + #[inline] + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + /// The stride of this point. This is the number of buffer element separating each component of /// this point. #[inline] diff --git a/src/geometry/quaternion.rs b/src/geometry/quaternion.rs index 8c4537dc..e860a8b8 100755 --- a/src/geometry/quaternion.rs +++ b/src/geometry/quaternion.rs @@ -335,7 +335,7 @@ where where N: RealField, { - let mut res = self.clone(); + let mut res = *self; if res.try_inverse_mut() { Some(res) @@ -520,16 +520,13 @@ where let v = self.vector(); let nn = v.norm_squared(); let le = nn.simd_le(eps * eps); - le.if_else( - || Self::identity(), - || { - let w_exp = self.scalar().simd_exp(); - let n = nn.simd_sqrt(); - let nv = v * (w_exp * n.simd_sin() / n); + le.if_else(Self::identity, || { + let w_exp = self.scalar().simd_exp(); + let n = nn.simd_sqrt(); + let nv = v * (w_exp * n.simd_sin() / n); - Self::from_parts(w_exp * n.simd_cos(), nv) - }, - ) + Self::from_parts(w_exp * n.simd_cos(), nv) + }) } /// Raise the quaternion to a given floating power. diff --git a/src/geometry/rotation_specialization.rs b/src/geometry/rotation_specialization.rs index 11b63cde..5cb7cb33 100644 --- a/src/geometry/rotation_specialization.rs +++ b/src/geometry/rotation_specialization.rs @@ -453,7 +453,7 @@ where sqz + (N::one() - sqz) * cos, )) }, - || Self::identity(), + Self::identity, ) } diff --git a/src/geometry/similarity_ops.rs b/src/geometry/similarity_ops.rs index 959ac3a3..319d8647 100644 --- a/src/geometry/similarity_ops.rs +++ b/src/geometry/similarity_ops.rs @@ -240,7 +240,7 @@ md_assign_impl_all!( (U3, U3), (U3, U3) for; self: Similarity>, rhs: UnitQuaternion; [val] => self.isometry.rotation *= rhs; - [ref] => self.isometry.rotation *= rhs.clone(); + [ref] => self.isometry.rotation *= *rhs; ); md_assign_impl_all!( @@ -257,7 +257,7 @@ md_assign_impl_all!( (U2, U2), (U2, U2) for; self: Similarity>, rhs: UnitComplex; [val] => self.isometry.rotation *= rhs; - [ref] => self.isometry.rotation *= rhs.clone(); + [ref] => self.isometry.rotation *= *rhs; ); md_assign_impl_all!( diff --git a/src/geometry/unit_complex_ops.rs b/src/geometry/unit_complex_ops.rs index af1a32f1..ef227023 100644 --- a/src/geometry/unit_complex_ops.rs +++ b/src/geometry/unit_complex_ops.rs @@ -306,9 +306,9 @@ complex_op_impl_all!( self: UnitComplex, rhs: Translation, Output = Isometry>; [val val] => Isometry::from_parts(Translation::from(&self * rhs.vector), self); - [ref val] => Isometry::from_parts(Translation::from( self * rhs.vector), self.clone()); + [ref val] => Isometry::from_parts(Translation::from( self * rhs.vector), *self); [val ref] => Isometry::from_parts(Translation::from(&self * &rhs.vector), self); - [ref ref] => Isometry::from_parts(Translation::from( self * &rhs.vector), self.clone()); + [ref ref] => Isometry::from_parts(Translation::from( self * &rhs.vector), *self); ); // Translation × UnitComplex @@ -319,8 +319,8 @@ complex_op_impl_all!( Output = Isometry>; [val val] => Isometry::from_parts(self, right); [ref val] => Isometry::from_parts(self.clone(), right); - [val ref] => Isometry::from_parts(self, right.clone()); - [ref ref] => Isometry::from_parts(self.clone(), right.clone()); + [val ref] => Isometry::from_parts(self, *right); + [ref ref] => Isometry::from_parts(self.clone(), *right); ); // UnitComplex ×= UnitComplex diff --git a/src/linalg/inverse.rs b/src/linalg/inverse.rs index 79d64121..2cb10351 100644 --- a/src/linalg/inverse.rs +++ b/src/linalg/inverse.rs @@ -40,7 +40,7 @@ impl> SquareMatrix { match dim { 0 => true, 1 => { - let determinant = self.get_unchecked((0, 0)).clone(); + let determinant = *self.get_unchecked((0, 0)); if determinant.is_zero() { false } else { diff --git a/src/linalg/permutation_sequence.rs b/src/linalg/permutation_sequence.rs index 0b45510c..47255832 100644 --- a/src/linalg/permutation_sequence.rs +++ b/src/linalg/permutation_sequence.rs @@ -144,6 +144,11 @@ where self.len } + /// Returns true if the permutation sequence contains no elements. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + /// The determinant of the matrix corresponding to this permutation. #[inline] pub fn determinant(&self) -> N {