base_traits/traits/
to_u64.rs

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