regex_lite/
int.rs

1use core::num::NonZeroUsize;
2
3/// An extension trait that adds routines to the `u32` primitive type.
4pub(crate) trait U32 {
5    fn as_usize(self) -> usize;
6}
7
8impl U32 for u32 {
9    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        self as usize
13    }
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)]
33pub(crate) struct NonMaxUsize(NonZeroUsize);
34
35impl 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    pub(crate) fn new(value: usize) -> Option<NonMaxUsize> {
40        NonZeroUsize::new(value.wrapping_add(1)).map(NonMaxUsize)
41    }
42
43    /// Return the underlying `usize` value. The returned value is guaranteed
44    /// to not equal `usize::MAX`.
45    pub(crate) fn get(self) -> usize {
46        self.0.get().wrapping_sub(1)
47    }
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'.
52impl core::fmt::Debug for NonMaxUsize {
53    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
54        write!(f, "{:?}", self.get())
55    }
56}