Skip to main content

base_traits/traits/
to_usize.rs

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