diff -r edb95d2b83cc -r d2acaaddd9af src/types.rs --- a/src/types.rs Sun Nov 10 09:02:57 2024 -0500 +++ b/src/types.rs Tue Dec 31 09:12:43 2024 -0500 @@ -57,7 +57,8 @@ + CastFrom + CastFrom + CastFrom + CastFrom + CastFrom + CastFrom + CastFrom + CastFrom - + CastFrom + CastFrom { + + CastFrom + CastFrom + + HasScalarField { const ZERO : Self; const ONE : Self; @@ -106,6 +107,9 @@ const RANGE_MAX : Self = <$type>::MAX; const RANGE_MIN : Self = <$type>::MIN; } + impl HasScalarField for $type { + type Field = $type; + } )* } } @@ -163,3 +167,54 @@ } */ + +/// Trait for on-demand cloning as of `Self` as `Target`. +/// +/// Blanket implementations clone references, but do nothing if `Self` equals `Target`. +/// +/// The idea is to allow other traits to be implemented generically, similar to now one +/// can work with references and owned values through [`std::borrow::Borrow`], but, in +/// contrast to the latter, this trait will provide an owned value instead of reference. +pub trait CloneIfNeeded { + /// Clone `self` if needed as `Target`. + fn clone_if_needed(self) -> Target; +} + +impl<'a, T : Clone> CloneIfNeeded for &'a T { + #[inline] + /// Clone + fn clone_if_needed(self) -> T { + self.clone() + } +} + +impl<'a, T : Clone> CloneIfNeeded for &'a mut T { + #[inline] + /// Clone + fn clone_if_needed(self) -> T { + self.clone() + } +} + +impl<'a, T> CloneIfNeeded for T { + #[inline] + /// No clone needed + fn clone_if_needed(self) -> T { + self + } +} + +/// Trait for objects that have an associated scalar field. +pub trait HasScalarField { + type Field : Num; +} + +/// Trait for objects that have an associated real field. +pub trait HasRealField : HasScalarField { + type RealField : Float; +} + +impl HasRealField for T where T : HasScalarField, T::Field : Float { + type RealField = T::Field; +} +