base_traits/traits/
as_f64.rs

1// src/traits/as_f64.rs : `AsF64`
2
3/// Trait defining instance method `as_f64() : f64` that provides a
4/// cost-free conversion into `f64`.
5///
6/// It is expected that the implementing type "is-a" `f64` in a direct
7/// manner as well as in a logical manner.
8///
9/// # Additional Implementations on Foreign Types
10///
11/// ## Built-in Types
12///
13/// If the feature `"implement-AsF64-for-built_ins"`
14/// is defined (as it is by `"default"`), then this is also implemented
15/// for the following type(s):
16/// - [`f64`];
17pub trait AsF64 {
18    fn as_f64(&self) -> f64;
19}
20
21
22#[cfg(all(not(test), not(feature = "nostd")))]
23impl<T : AsF64 + ?Sized> AsF64 for Box<T> {
24    fn as_f64(&self) -> f64 {
25        (**self).as_f64()
26    }
27}
28
29#[cfg(all(not(test), not(feature = "nostd")))]
30impl<T : AsF64 + ?Sized> AsF64 for std::rc::Rc<T> {
31    fn as_f64(&self) -> f64 {
32        (**self).as_f64()
33    }
34}
35
36
37#[cfg(feature = "implement-AsF64-for-built_ins")]
38mod impl_for_built_ins {
39    #![allow(non_snake_case)]
40
41
42    impl super::AsF64 for f64 {
43        #[inline]
44        fn as_f64(&self) -> f64 {
45            *self
46        }
47    }
48
49    impl super::AsF64 for &f64 {
50        #[inline]
51        fn as_f64(&self) -> f64 {
52            **self
53        }
54    }
55}
56
57
58#[cfg(test)]
59mod tests {
60    #![allow(non_snake_case)]
61
62    use super::AsF64;
63
64    use std::rc::Rc;
65
66
67    #[allow(unused)]
68    fn as_AsF64<T : AsF64>(t : &T) -> &impl AsF64 {
69        t
70    }
71
72
73    mod TEST_CUSTOM_TYPE {
74        #![allow(non_snake_case)]
75
76        use super::*;
77
78
79        #[derive(Debug)]
80        struct CustomType {
81            value : f64,
82        }
83
84        impl AsF64 for CustomType {
85            fn as_f64(&self) -> f64 {
86                self.value
87            }
88        }
89
90
91        #[test]
92        fn TEST_WHEN_ZERO() {
93            let ct = CustomType { value : 0.0 };
94
95            assert_eq!(0.0, ct.as_f64());
96
97            let ct = &ct;
98
99            assert_eq!(0.0, ct.as_f64());
100        }
101
102        #[test]
103        fn TEST_WHEN_NONZERO() {
104            let ct = CustomType { value : 1.0 };
105
106            assert_ne!(0.0, ct.as_f64());
107
108            let ct = &ct;
109
110            assert_ne!(0.0, ct.as_f64());
111        }
112
113        #[test]
114        fn TEST_WHEN_ZERO_IN_Box() {
115            {
116                let ct = Box::new(CustomType { value : 0.0 });
117
118                assert_eq!(0.0, ct.as_f64());
119
120                let ct = &ct;
121
122                assert_eq!(0.0, ct.as_f64());
123            }
124
125            {
126                let ct = &Box::new(CustomType { value : 0.0 });
127
128                assert_eq!(0.0, ct.as_f64());
129
130                let ct = &ct;
131
132                assert_eq!(0.0, ct.as_f64());
133            }
134
135            {
136                let ct = Box::new(&CustomType { value : 0.0 });
137
138                assert_eq!(0.0, ct.as_f64());
139
140                let ct = &ct;
141
142                assert_eq!(0.0, ct.as_f64());
143            }
144
145            {
146                let ct = &Box::new(&CustomType { value : 0.0 });
147
148                assert_eq!(0.0, ct.as_f64());
149
150                let ct = &ct;
151
152                assert_eq!(0.0, ct.as_f64());
153            }
154        }
155
156        #[test]
157        fn TEST_WHEN_ZERO_IN_Rc() {
158            {
159                let ct = Rc::new(CustomType { value : 0.0 });
160
161                assert_eq!(0.0, ct.as_f64());
162
163                let ct = &ct;
164
165                assert_eq!(0.0, ct.as_f64());
166            }
167
168            {
169                let ct = &Rc::new(CustomType { value : 0.0 });
170
171                assert_eq!(0.0, ct.as_f64());
172
173                let ct = &ct;
174
175                assert_eq!(0.0, ct.as_f64());
176            }
177
178            {
179                let ct = Rc::new(&CustomType { value : 0.0 });
180
181                assert_eq!(0.0, ct.as_f64());
182
183                let ct = &ct;
184
185                assert_eq!(0.0, ct.as_f64());
186            }
187
188            {
189                let ct = &Rc::new(&CustomType { value : 0.0 });
190
191                assert_eq!(0.0, ct.as_f64());
192
193                let ct = &ct;
194
195                assert_eq!(0.0, ct.as_f64());
196            }
197        }
198    }
199
200
201    #[cfg(feature = "implement-AsF64-for-built_ins")]
202    mod TEST_BUILTIN_TYPES {
203        #![allow(non_snake_case)]
204
205        use super::*;
206
207
208        mod TEST_f64 {
209            #![allow(non_snake_case)]
210
211            use super::*;
212
213
214            #[test]
215            fn TEST_ZERO() {
216                let v = 0.0f64;
217
218                assert_eq!(0.0, v.as_f64());
219
220                let ie = as_AsF64(&v);
221
222                assert_eq!(0.0, ie.as_f64());
223            }
224
225            #[test]
226            fn TEST_NONZERO() {
227                let v = -123.456f64;
228
229                assert_ne!(0.0, v.as_f64());
230
231                let ie = as_AsF64(&v);
232
233                assert_ne!(0.0, ie.as_f64());
234            }
235        }
236    }
237}
238
239
240// ///////////////////////////// end of file //////////////////////////// //
241