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
126            const VALUES : &[usize] = &[
127                // insert list:
128                0,
129                1,
130                2, 4, 8, 16, 32, 64, 128, 256,
131                u16::MAX as usize,
132                u32::MAX as usize,
133                u64::MAX as usize,
134            ];
135
136            for &value in VALUES {
137                let expected = value;
138                let instance = CustomType { value: value as u64 };
139                let actual = instance.to_usize();
140
141                assert_eq!(expected, actual);
142            }
143        }
144    }
145
146
147    #[cfg(feature = "implement-ToUSize-for-built_ins")]
148    mod TEST_BUILTIN_TYPES {
149        #![allow(non_snake_case)]
150        #![allow(unexpected_cfgs)]
151
152        use super::*;
153
154
155        #[test]
156        fn TEST_RANGE_OF_usize_VALUES() {
157
158            const VALUES : &[usize] = &[
159                // insert list:
160                0,
161                1,
162                2,
163                4,
164                8,
165                16,
166                32,
167                64,
168                128,
169                256,
170                usize::MAX,
171            ];
172
173            for &value in VALUES {
174                let expected = value;
175                let actual = value.to_usize();
176
177                assert_eq!(expected, actual);
178            }
179        }
180
181        #[cfg(any(
182            target_pointer_width = "16",
183            target_pointer_width = "32",
184            target_pointer_width = "64",
185            target_pointer_width = "128",
186        ))]
187        #[test]
188        fn TEST_RANGE_OF_u16_VALUES_REF() {
189
190            const VALUES : &[u16] = &[
191                // insert list:
192                0,
193                1,
194                2,
195                4,
196                8,
197                16,
198                32,
199                64,
200                128,
201                256,
202                u16::MAX,
203            ];
204
205            for &value in VALUES {
206                let expected = value as usize;
207                let value = &value;
208                let actual = value.to_usize();
209
210                assert_eq!(expected, actual);
211            }
212        }
213
214        #[cfg(any(
215            target_pointer_width = "32",
216            target_pointer_width = "64",
217            target_pointer_width = "128",
218        ))]
219        #[test]
220        fn TEST_RANGE_OF_u32_VALUES_REF() {
221
222            const VALUES : &[u32] = &[
223                // insert list:
224                0,
225                1,
226                2,
227                4,
228                8,
229                16,
230                32,
231                64,
232                128,
233                256,
234                u32::MAX,
235            ];
236
237            for &value in VALUES {
238                let expected = value as usize;
239                let value = &value;
240                let actual = value.to_usize();
241
242                assert_eq!(expected, actual);
243            }
244        }
245
246        #[test]
247        fn TEST_RANGE_OF_usize_VALUES_REF() {
248
249            const VALUES : &[usize] = &[
250                // insert list:
251                0,
252                1,
253                2,
254                4,
255                8,
256                16,
257                32,
258                64,
259                128,
260                256,
261                usize::MAX,
262            ];
263
264            for &value in VALUES {
265                let expected = value;
266                let value = &value;
267                let actual = value.to_usize();
268
269                assert_eq!(expected, actual);
270            }
271        }
272
273        #[test]
274        fn TEST_RANGE_OF_usize_VALUES_IN_Box() {
275
276            const VALUES : &[usize] = &[
277                // insert list:
278                0,
279                1,
280                2,
281                4,
282                8,
283                16,
284                32,
285                64,
286                128,
287                256,
288                usize::MAX,
289            ];
290
291            for &value in VALUES {
292                let expected = value;
293                let instance = Box::new(value);
294                let actual = instance.to_usize();
295
296                assert_eq!(expected, actual);
297            }
298        }
299
300        #[test]
301        fn TEST_RANGE_OF_usize_VALUES_IN_REF_Box() {
302
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
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
357            const VALUES : &[usize] = &[
358                // insert list:
359                0,
360                1,
361                2,
362                4,
363                8,
364                16,
365                32,
366                64,
367                128,
368                256,
369                usize::MAX,
370            ];
371
372            for &value in VALUES {
373                let expected = value;
374                let instance = &std_rc::Rc::new(value);
375                let actual = instance.to_usize();
376
377                assert_eq!(expected, actual);
378            }
379        }
380    }
381}
382
383
384// ///////////////////////////// end of file //////////////////////////// //
385