/src/regex/regex-lite/src/int.rs
Line | Count | Source |
1 | | use core::num::NonZeroUsize; |
2 | | |
3 | | /// An extension trait that adds routines to the `u32` primitive type. |
4 | | pub(crate) trait U32 { |
5 | | fn as_usize(self) -> usize; |
6 | | } |
7 | | |
8 | | impl U32 for u32 { |
9 | 215M | fn as_usize(self) -> usize { |
10 | | // OK because we require 32 or 64 bit targets. Therefore, every u32 |
11 | | // necessarily fits into a usize. |
12 | 215M | self as usize |
13 | 215M | } |
14 | | } |
15 | | |
16 | | /// A `usize` that can never be `usize::MAX`. |
17 | | /// |
18 | | /// This is similar to `core::num::NonZeroUsize`, but instead of not permitting |
19 | | /// a zero value, this does not permit a max value. |
20 | | /// |
21 | | /// This is useful in certain contexts where one wants to optimize the memory |
22 | | /// usage of things that contain match offsets. Namely, since Rust slices |
23 | | /// are guaranteed to never have a length exceeding `isize::MAX`, we can use |
24 | | /// `usize::MAX` as a sentinel to indicate that no match was found. Indeed, |
25 | | /// types like `Option<NonMaxUsize>` have exactly the same size in memory as a |
26 | | /// `usize`. |
27 | | /// |
28 | | /// This type is defined to be `repr(transparent)` for |
29 | | /// `core::num::NonZeroUsize`, which is in turn defined to be |
30 | | /// `repr(transparent)` for `usize`. |
31 | | #[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)] |
32 | | #[repr(transparent)] |
33 | | pub(crate) struct NonMaxUsize(NonZeroUsize); |
34 | | |
35 | | impl NonMaxUsize { |
36 | | /// Create a new `NonMaxUsize` from the given value. |
37 | | /// |
38 | | /// This returns `None` only when the given value is equal to `usize::MAX`. |
39 | 0 | pub(crate) fn new(value: usize) -> Option<NonMaxUsize> { |
40 | 0 | NonZeroUsize::new(value.wrapping_add(1)).map(NonMaxUsize) |
41 | 0 | } |
42 | | |
43 | | /// Return the underlying `usize` value. The returned value is guaranteed |
44 | | /// to not equal `usize::MAX`. |
45 | 0 | pub(crate) fn get(self) -> usize { |
46 | 0 | self.0.get().wrapping_sub(1) |
47 | 0 | } |
48 | | } |
49 | | |
50 | | // We provide our own Debug impl because seeing the internal repr can be quite |
51 | | // surprising if you aren't expecting it. e.g., 'NonMaxUsize(5)' vs just '5'. |
52 | | impl core::fmt::Debug for NonMaxUsize { |
53 | 0 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { |
54 | 0 | write!(f, "{:?}", self.get()) |
55 | 0 | } |
56 | | } |