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    use std::rc as std_rc;
105
106
107    mod TEST_CUSTOM_TYPE {
108        #![allow(non_snake_case)]
109
110        use super::ToUSize;
111
112
113        struct CustomType {
114            value : u64,
115        }
116
117        impl ToUSize for CustomType {
118            fn to_usize(&self) -> usize {
119                self.value as usize
120            }
121        }
122
123        #[test]
124        fn TEST_RANGE_OF_VALUES() {
125            const VALUES : &[usize] = &[
126                // insert list:
127                0,
128                1,
129                2,
130                4,
131                8,
132                16,
133                32,
134                64,
135                128,
136                256,
137                u16::MAX as usize,
138                u32::MAX as usize,
139                u64::MAX as usize,
140            ];
141
142            for &value in VALUES {
143                let expected = value;
144                let instance = CustomType { value: value as u64 };
145                let actual = instance.to_usize();
146
147                assert_eq!(expected, actual);
148            }
149        }
150    }
151
152
153    #[cfg(feature = "implement-ToUSize-for-built_ins")]
154    mod TEST_BUILTIN_TYPES {
155        #![allow(non_snake_case)]
156        #![allow(unexpected_cfgs)]
157
158        use super::*;
159
160
161        #[test]
162        fn TEST_RANGE_OF_usize_VALUES() {
163            const VALUES : &[usize] = &[
164                // insert list:
165                0,
166                1,
167                2,
168                4,
169                8,
170                16,
171                32,
172                64,
173                128,
174                256,
175                usize::MAX,
176            ];
177
178            for &value in VALUES {
179                let expected = value;
180                let actual = value.to_usize();
181
182                assert_eq!(expected, actual);
183            }
184        }
185
186        #[cfg(any(
187            target_pointer_width = "16",
188            target_pointer_width = "32",
189            target_pointer_width = "64",
190            target_pointer_width = "128",
191        ))]
192        #[test]
193        fn TEST_RANGE_OF_u16_VALUES_REF() {
194            const VALUES : &[u16] = &[
195                // insert list:
196                0,
197                1,
198                2,
199                4,
200                8,
201                16,
202                32,
203                64,
204                128,
205                256,
206                u16::MAX,
207            ];
208
209            for &value in VALUES {
210                let expected = value as usize;
211                let value = &value;
212                let actual = value.to_usize();
213
214                assert_eq!(expected, actual);
215            }
216        }
217
218        #[cfg(any(
219            target_pointer_width = "32",
220            target_pointer_width = "64",
221            target_pointer_width = "128",
222        ))]
223        #[test]
224        fn TEST_RANGE_OF_u32_VALUES_REF() {
225            const VALUES : &[u32] = &[
226                // insert list:
227                0,
228                1,
229                2,
230                4,
231                8,
232                16,
233                32,
234                64,
235                128,
236                256,
237                u32::MAX,
238            ];
239
240            for &value in VALUES {
241                let expected = value as usize;
242                let value = &value;
243                let actual = value.to_usize();
244
245                assert_eq!(expected, actual);
246            }
247        }
248
249        #[test]
250        fn TEST_RANGE_OF_usize_VALUES_REF() {
251            const VALUES : &[usize] = &[
252                // insert list:
253                0,
254                1,
255                2,
256                4,
257                8,
258                16,
259                32,
260                64,
261                128,
262                256,
263                usize::MAX,
264            ];
265
266            for &value in VALUES {
267                let expected = value;
268                let value = &value;
269                let actual = value.to_usize();
270
271                assert_eq!(expected, actual);
272            }
273        }
274
275        #[test]
276        fn TEST_RANGE_OF_usize_VALUES_IN_Box() {
277            const VALUES : &[usize] = &[
278                // insert list:
279                0,
280                1,
281                2,
282                4,
283                8,
284                16,
285                32,
286                64,
287                128,
288                256,
289                usize::MAX,
290            ];
291
292            for &value in VALUES {
293                let expected = value;
294                let instance = Box::new(value);
295                let actual = instance.to_usize();
296
297                assert_eq!(expected, actual);
298            }
299        }
300
301        #[test]
302        fn TEST_RANGE_OF_usize_VALUES_IN_REF_Box() {
303            const VALUES : &[usize] = &[
304                // insert list:
305                0,
306                1,
307                2,
308                4,
309                8,
310                16,
311                32,
312                64,
313                128,
314                256,
315                usize::MAX,
316            ];
317
318            for &value in VALUES {
319                let expected = value;
320                let instance = &Box::new(value);
321                let actual = instance.to_usize();
322
323                assert_eq!(expected, actual);
324            }
325        }
326
327        #[test]
328        fn TEST_RANGE_OF_usize_VALUES_IN_Rc() {
329            const VALUES : &[usize] = &[
330                // insert list:
331                0,
332                1,
333                2,
334                4,
335                8,
336                16,
337                32,
338                64,
339                128,
340                256,
341                usize::MAX,
342            ];
343
344            for &value in VALUES {
345                let expected = value;
346                let instance = std_rc::Rc::new(value);
347                let actual = instance.to_usize();
348
349                assert_eq!(expected, actual);
350            }
351        }
352
353        #[test]
354        fn TEST_RANGE_OF_usize_VALUES_IN_REF_Rc() {
355            const VALUES : &[usize] = &[
356                // insert list:
357                0,
358                1,
359                2,
360                4,
361                8,
362                16,
363                32,
364                64,
365                128,
366                256,
367                usize::MAX,
368            ];
369
370            for &value in VALUES {
371                let expected = value;
372                let instance = &std_rc::Rc::new(value);
373                let actual = instance.to_usize();
374
375                assert_eq!(expected, actual);
376            }
377        }
378    }
379}
380
381
382// ///////////////////////////// end of file //////////////////////////// //