Should num include a trait for upcasting / widening? I.e. all numerical casts that can be performed with no loss of information. Or is this more appropriate for a separate crate?
Here's a graph of the allowed upcasts: http://i.imgur.com/foiXWWS.png (not including self loops).
scratch impl follows
/// A trait for promotion of smaller numeric type into larger that/// still allow the same range of values, without loss of information.////// See discussion about this concept here:/// https://internals.rust-lang.org/t/implicit-widening-polymorphic-indexing-and-similar-ideas/1141////// ## Examples////// ```/// use upcastnum::Upcast;////// fn add1<T: Upcast<i32>>(x: T) -> i32 {/// x.upcast() + 1/// }////// assert_eq!(add1(1i32), 2);/// assert_eq!(add1(1i8), 2);/// assert_eq!(add1(1u8), 2);/// assert_eq!(add1(1i16), 2);/// ```pubtraitUpcast<T>{fnupcast(self) -> T;}/// Convenience to be able to type-qualify upcasting directly on the method call.////// ## Examples////// ```/// use upcastnum::UpcastTo;/// let x = 1.upcast_to::<f64>() + 2.upcast_to::<f64>();/// assert_eq!(x, 3.);/// ```pubtraitUpcastTo{#[inline(always)]fnupcast_to<T>(self) -> TwhereSelf:Sized + Upcast<T>{self.upcast()}}impl<T>UpcastToforT{}macro_rules! upcast {($from: ty => $to: ty) => {implUpcast<$to> for $from {
#[inline(always)]fn upcast(self) -> $to {selfas $to }}}}upcast!(i8 => i8);upcast!(i8 => i16);upcast!(i8 => i32);upcast!(i8 => i64);upcast!(u8 => u8);upcast!(u8 => u16);upcast!(u8 => u32);upcast!(u8 => u64);upcast!(u8 => i16);upcast!(u8 => i32);upcast!(u8 => i64);upcast!(i16 => i16);upcast!(i16 => i32);upcast!(i16 => i64);upcast!(u16 => u16);upcast!(u16 => u32);upcast!(u16 => u64);upcast!(u16 => i32);upcast!(u16 => i64);upcast!(i32 => i32);upcast!(i32 => i64);upcast!(u32 => u32);upcast!(u32 => u64);upcast!(u32 => i64);upcast!(i64 => i64);upcast!(u64 => u64);// floating pointupcast!(f32 => f32);upcast!(f32 => f64);upcast!(f64 => f64);upcast!(i8 => f32);upcast!(i8 => f64);upcast!(u8 => f32);upcast!(u8 => f64);upcast!(i16 => f32);upcast!(i16 => f64);upcast!(u16 => f32);upcast!(u16 => f64);upcast!(i32 => f64);upcast!(u32 => f64);
Should num include a trait for upcasting / widening? I.e. all numerical casts that can be performed with no loss of information. Or is this more appropriate for a separate crate?
Here's a graph of the allowed upcasts: http://i.imgur.com/foiXWWS.png (not including self loops).
scratch impl follows