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