base_traits/traits/
to_f64.rs

1// src/traits/to_f64.rs : `ToF64`
2
3/// Trait defining instance method `to_f64() : f64` that provides a
4/// no-cost or low-cost conversion into `f64`.
5///
6/// It is expected that the implementing type "is-a" `f64` in a logical
7/// manner.
8///
9/// # Additional Implementations on Foreign Types
10///
11/// ## Built-in Types
12///
13/// If the feature `"implement-ToF64-for-built_ins"`
14/// is defined (as it is by `"default"`), then this is also implemented
15/// for the following type(s):
16/// - [`i8`];
17/// - [`i16`];
18/// - [`i32`];
19/// - [`i64`];
20/// - [`i128`];
21/// - [`u8`];
22/// - [`u16`];
23/// - [`u32`];
24/// - [`u64`];
25/// - [`u128`];
26/// - [`isize`];
27/// - [`usize`];
28/// - [`f32`];
29/// - [`f64`];
30pub trait ToF64 {
31    fn to_f64(&self) -> f64;
32}
33
34
35impl<T : ToF64 + ?Sized> ToF64 for Box<T> {
36    fn to_f64(&self) -> f64 {
37        (**self).to_f64()
38    }
39}
40
41impl<T : ToF64 + ?Sized> ToF64 for std::rc::Rc<T> {
42    fn to_f64(&self) -> f64 {
43        (**self).to_f64()
44    }
45}
46
47
48#[cfg(feature = "implement-ToF64-for-built_ins")]
49mod impl_for_built_ins {
50    #![allow(non_snake_case)]
51
52    macro_rules! implement_ToF64_ {
53        ($type:tt) => {
54            impl super::ToF64 for $type {
55                #[inline]
56                fn to_f64(&self) -> f64 {
57                    *self as f64
58                }
59            }
60        };
61    }
62
63    implement_ToF64_!(i8);
64    implement_ToF64_!(i16);
65    implement_ToF64_!(i32);
66    implement_ToF64_!(i64);
67    implement_ToF64_!(i128);
68
69    implement_ToF64_!(u8);
70    implement_ToF64_!(u16);
71    implement_ToF64_!(u32);
72    implement_ToF64_!(u64);
73    implement_ToF64_!(u128);
74
75    implement_ToF64_!(isize);
76    implement_ToF64_!(usize);
77
78    implement_ToF64_!(f32);
79    implement_ToF64_!(f64);
80}
81
82
83#[cfg(test)]
84mod tests {
85    #![allow(non_snake_case)]
86
87    use super::ToF64;
88
89    use std::rc::Rc;
90
91
92    #[allow(unused)]
93    fn as_ToF64<T : ToF64>(t : &T) -> &impl ToF64 {
94        t
95    }
96
97
98    mod TEST_CUSTOM_TYPE {
99        #![allow(non_snake_case)]
100
101        use super::*;
102
103
104        #[derive(Debug)]
105        struct CustomType {
106            value : String,
107        }
108
109        impl ToF64 for CustomType {
110            fn to_f64(&self) -> f64 {
111                self.value.parse::<f64>().unwrap()
112            }
113        }
114
115
116        #[test]
117        fn TEST_WHEN_ZERO() {
118            let ct = CustomType { value : "0.0".into() };
119
120            assert_eq!(0.0, ct.to_f64());
121
122            let ct = &ct;
123
124            assert_eq!(0.0, ct.to_f64());
125        }
126
127        #[test]
128        fn TEST_WHEN_NONZERO() {
129            let ct = CustomType { value : "1.0".into() };
130
131            assert_ne!(0.0, ct.to_f64());
132
133            let ct = &ct;
134
135            assert_ne!(0.0, ct.to_f64());
136        }
137
138        #[test]
139        fn TEST_WHEN_ZERO_IN_Box() {
140            {
141                let v = CustomType { value : "0.0".into() };
142                let ct = Box::new(v);
143
144                assert_eq!(0.0, ct.to_f64());
145
146                let ct = &ct;
147
148                assert_eq!(0.0, ct.to_f64());
149            }
150
151            {
152                let v = CustomType { value : "0.0".into() };
153                let ct = &Box::new(v);
154
155                assert_eq!(0.0, ct.to_f64());
156
157                let ct = &ct;
158
159                assert_eq!(0.0, ct.to_f64());
160            }
161
162            {
163                let v = CustomType { value : "0.0".into() };
164                let ct = Box::new(&v);
165
166                assert_eq!(0.0, ct.to_f64());
167
168                let ct = &ct;
169
170                assert_eq!(0.0, ct.to_f64());
171            }
172
173            {
174                let v = CustomType { value : "0.0".into() };
175                let ct = &Box::new(&v);
176
177                assert_eq!(0.0, ct.to_f64());
178
179                let ct = &ct;
180
181                assert_eq!(0.0, ct.to_f64());
182            }
183        }
184
185        #[test]
186        fn TEST_WHEN_ZERO_IN_Rc() {
187            {
188                let ct = Rc::new(CustomType { value : "0.0".into() });
189
190                assert_eq!(0.0, ct.to_f64());
191
192                let ct = &ct;
193
194                assert_eq!(0.0, ct.to_f64());
195            }
196
197            {
198                let ct = &Rc::new(CustomType { value : "0.0".into() });
199
200                assert_eq!(0.0, ct.to_f64());
201
202                let ct = &ct;
203
204                assert_eq!(0.0, ct.to_f64());
205            }
206
207            {
208                let v = CustomType { value : "0.0".into() };
209                let ct = Rc::new(&v);
210
211                assert_eq!(0.0, ct.to_f64());
212
213                let ct = &ct;
214
215                assert_eq!(0.0, ct.to_f64());
216            }
217
218            {
219                let v = CustomType { value : "0.0".into() };
220                let ct = &Rc::new(&v);
221
222                assert_eq!(0.0, ct.to_f64());
223
224                let ct = &ct;
225
226                assert_eq!(0.0, ct.to_f64());
227            }
228        }
229    }
230
231
232    #[cfg(feature = "implement-ToF64-for-built_ins")]
233    mod TEST_BUILTIN_TYPES {
234        #![allow(non_snake_case)]
235
236        use super::*;
237
238
239        mod TEST_i8 {
240            #![allow(non_snake_case)]
241
242            use super::*;
243
244
245            #[test]
246            fn TEST_ZERO() {
247                let v = 0i8;
248
249                assert_eq!(0.0, v.to_f64());
250
251                let ie = as_ToF64(&v);
252
253                assert_eq!(0.0, ie.to_f64());
254            }
255
256            #[test]
257            fn TEST_NONZERO() {
258                let v = -123i8;
259
260                assert_ne!(0.0, v.to_f64());
261
262                let ie = as_ToF64(&v);
263
264                assert_ne!(0.0, ie.to_f64());
265            }
266        }
267
268
269        mod TEST_f32 {
270            #![allow(non_snake_case)]
271
272            use super::*;
273
274
275            #[test]
276            fn TEST_ZERO() {
277                let v = 0.0f32;
278
279                assert_eq!(0.0, v.to_f64());
280
281                let ie = as_ToF64(&v);
282
283                assert_eq!(0.0, ie.to_f64());
284            }
285
286            #[test]
287            fn TEST_NONZERO() {
288                let v = -123.456f32;
289
290                assert_ne!(0.0, v.to_f64());
291
292                let ie = as_ToF64(&v);
293
294                assert_ne!(0.0, ie.to_f64());
295            }
296        }
297
298
299        mod TEST_f64 {
300            #![allow(non_snake_case)]
301
302            use super::*;
303
304
305            #[test]
306            fn TEST_ZERO() {
307                let v = 0.0f64;
308
309                assert_eq!(0.0, v.to_f64());
310
311                let ie = as_ToF64(&v);
312
313                assert_eq!(0.0, ie.to_f64());
314            }
315
316            #[test]
317            fn TEST_NONZERO() {
318                let v = -123.456f64;
319
320                assert_ne!(0.0, v.to_f64());
321
322                let ie = as_ToF64(&v);
323
324                assert_ne!(0.0, ie.to_f64());
325            }
326
327            #[test]
328            fn TEST_ZERO_IN_Box() {
329                let v = Box::new(0.0f64);
330
331                assert_eq!(0.0, v.to_f64());
332
333                let ie = as_ToF64(&v);
334
335                assert_eq!(0.0, ie.to_f64());
336            }
337
338            #[test]
339            fn TEST_ZERO_IN_Box_ref() {
340                let v = &Box::new(0.0f64);
341
342                assert_eq!(0.0, v.to_f64());
343
344                let ie = as_ToF64(v);
345
346                assert_eq!(0.0, ie.to_f64());
347            }
348        }
349    }
350}
351
352
353// ///////////////////////////// end of file //////////////////////////// //
354