Skip to main content

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