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}