1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
pub(crate) fn aligned(value: u64, align: u64) -> u64 {
    debug_assert_ne!(align, 0);
    debug_assert_eq!(align.count_ones(), 1);
    if value == 0 {
        0
    } else {
        1u64 + ((value - 1u64) | (align - 1u64))
    }
}

pub(crate) trait IntegerFitting {
    fn fits_usize(self) -> bool;
    fn fits_isize(self) -> bool;

    fn usize_fits(value: usize) -> bool;
    fn isize_fits(value: isize) -> bool;
}

#[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
impl IntegerFitting for u64 {
    fn fits_usize(self) -> bool {
        self <= usize::max_value() as u64
    }
    fn fits_isize(self) -> bool {
        self <= isize::max_value() as u64
    }
    fn usize_fits(_value: usize) -> bool {
        true
    }
    fn isize_fits(value: isize) -> bool {
        value >= 0
    }
}

#[cfg(target_pointer_width = "64")]
impl IntegerFitting for u64 {
    fn fits_usize(self) -> bool {
        true
    }
    fn fits_isize(self) -> bool {
        self <= isize::max_value() as u64
    }
    fn usize_fits(_value: usize) -> bool {
        true
    }
    fn isize_fits(value: isize) -> bool {
        value >= 0
    }
}

#[cfg(not(any(
    target_pointer_width = "16",
    target_pointer_width = "32",
    target_pointer_width = "64"
)))]
impl IntegerFitting for u64 {
    fn fits_usize(self) -> bool {
        true
    }
    fn fits_isize(self) -> bool {
        true
    }
    fn usize_fits(value: usize) -> bool {
        value <= u64::max_value() as usize
    }
    fn isize_fits(value: isize) -> bool {
        value >= 0 && value <= u64::max_value() as isize
    }
}

#[cfg(target_pointer_width = "16")]
impl IntegerFitting for u32 {
    fn fits_usize(self) -> bool {
        self <= usize::max_value() as u32
    }
    fn fits_isize(self) -> bool {
        self <= isize::max_value() as u32
    }
    fn usize_fits(_value: usize) -> bool {
        true
    }
    fn isize_fits(value: isize) -> bool {
        value >= 0
    }
}

#[cfg(target_pointer_width = "32")]
impl IntegerFitting for u32 {
    fn fits_usize(self) -> bool {
        true
    }
    fn fits_isize(self) -> bool {
        self <= isize::max_value() as u32
    }
    fn usize_fits(_value: usize) -> bool {
        true
    }
    fn isize_fits(value: isize) -> bool {
        value >= 0
    }
}

#[cfg(not(any(target_pointer_width = "16", target_pointer_width = "32")))]
impl IntegerFitting for u32 {
    fn fits_usize(self) -> bool {
        true
    }
    fn fits_isize(self) -> bool {
        true
    }
    fn usize_fits(value: usize) -> bool {
        value <= u32::max_value() as usize
    }
    fn isize_fits(value: isize) -> bool {
        value >= 0 && value <= u32::max_value() as isize
    }
}

pub(crate) fn fits_usize<T: IntegerFitting>(value: T) -> bool {
    value.fits_usize()
}

pub(crate) fn fits_u32(value: usize) -> bool {
    u32::usize_fits(value)
}