numscale/
lib.rs

1#![cfg_attr(not(test), no_std)]
2#![feature(const_trait_impl)]
3#![feature(const_fn_floating_point_arithmetic)]
4
5#[const_trait]
6pub trait NumScale<F>
7{
8    fn scale(self, x: F) -> Self;
9}
10
11impl const NumScale<f64> for f64
12{
13    fn scale(self, x: f64) -> Self
14    {
15        self*x
16    }
17}
18impl const NumScale<f32> for f64
19{
20    fn scale(self, x: f32) -> Self
21    {
22        self*x as f64
23    }
24}
25impl const NumScale<f32> for f32
26{
27    fn scale(self, x: f32) -> Self
28    {
29        self*x
30    }
31}
32impl const NumScale<f64> for f32
33{
34    fn scale(self, x: f64) -> Self
35    {
36        self*x as f32
37    }
38}
39
40macro_rules! impl_scale_num {
41    ($num:ty) => {
42        impl const NumScale<f32> for $num
43        {
44            fn scale(self, x: f32) -> Self
45            {
46                (self as f32*x) as Self
47            }
48        }
49        impl const NumScale<f64> for $num
50        {
51            fn scale(self, x: f64) -> Self
52            {
53                (self as f64*x) as Self
54            }
55        }
56    };
57}
58
59impl_scale_num!(usize);
60impl_scale_num!(isize);
61
62impl_scale_num!(u8);
63impl_scale_num!(u16);
64impl_scale_num!(u32);
65impl_scale_num!(u64);
66impl_scale_num!(u128);
67
68impl_scale_num!(i8);
69impl_scale_num!(i16);
70impl_scale_num!(i32);
71impl_scale_num!(i64);
72impl_scale_num!(i128);
73
74#[cfg(test)]
75mod test
76{
77    use std::{println, fmt::Display, any::type_name};
78
79    use crate::NumScale;
80
81    #[test]
82    fn it_works()
83    {
84        const N: usize = 32;
85        let x: Vec<f64> = (0..N).map(|i| i as f64/(N - 1) as f64).collect();
86        test_num([u8::MAX].into_iter(), &x);
87        println!("u8");
88        test_num([u16::MAX].into_iter(), &x);
89        println!("u16");
90        test_num([u32::MAX].into_iter(), &x);
91        println!("u32");
92        test_num([u64::MAX].into_iter(), &x);
93        println!("u64");
94        test_num([u128::MAX].into_iter(), &x);
95        println!("u128");
96        
97        test_num([i8::MIN, i8::MAX].into_iter(), &x);
98        println!("i8");
99        test_num([i16::MIN, i16::MAX].into_iter(), &x);
100        println!("i16");
101        test_num([i32::MIN, i32::MAX].into_iter(), &x);
102        println!("i32");
103        test_num([i64::MIN, i64::MAX].into_iter(), &x);
104        println!("i64");
105        test_num([i128::MIN, i128::MAX].into_iter(), &x);
106        println!("i128");
107        
108        test_num([usize::MAX].into_iter(), &x);
109        println!("usize");
110        test_num([isize::MIN, isize::MAX].into_iter(), &x);
111        println!("isize");
112    }
113
114    fn test_num<I, F>(iter: I, x: &[F])
115    where
116        F: Copy,
117        I: Iterator,
118        I::Item: NumScale<F> + Copy + Display
119    {
120        for n in iter
121        {
122            for &x in x
123            {
124                println!("{}{}", n.scale(x), type_name::<I::Item>());
125            }
126        }
127    }
128}