ruint/
utils.rs

1#[cfg(feature = "alloc")]
2#[allow(unused_imports)]
3use alloc::vec::Vec;
4
5/// Like `a % b` but returns `b` instead of `0`.
6#[allow(dead_code)] // This is used by some support features.
7#[must_use]
8pub(crate) const fn rem_up(a: usize, b: usize) -> usize {
9    let rem = a % b;
10    if rem > 0 {
11        rem
12    } else {
13        b
14    }
15}
16
17#[allow(dead_code)] // This is used by some support features.
18#[inline]
19fn last_idx<T: PartialEq>(x: &[T], value: &T) -> usize {
20    x.iter().rposition(|b| b != value).map_or(0, |idx| idx + 1)
21}
22
23#[allow(dead_code)] // This is used by some support features.
24#[inline]
25#[must_use]
26pub(crate) fn trim_end_slice<'a, T: PartialEq>(slice: &'a [T], value: &T) -> &'a [T] {
27    &slice[..last_idx(slice, value)]
28}
29
30#[cfg(feature = "alloc")]
31#[inline]
32pub(crate) fn trim_end_vec<T: PartialEq>(vec: &mut Vec<T>, value: &T) {
33    vec.truncate(last_idx(vec, value));
34}
35
36// Branch prediction hints.
37#[cfg(feature = "nightly")]
38pub(crate) use core::intrinsics::{likely, unlikely};
39
40#[cfg(not(feature = "nightly"))]
41pub(crate) use core::convert::identity as likely;
42#[cfg(not(feature = "nightly"))]
43pub(crate) use core::convert::identity as unlikely;
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    #[test]
50    fn test_trim() {
51        assert_eq!(trim_end_slice(&[], &0), &[] as &[i32]);
52        assert_eq!(trim_end_slice(&[0], &0), &[] as &[i32]);
53        assert_eq!(trim_end_slice(&[0, 1], &0), &[0, 1]);
54        assert_eq!(trim_end_slice(&[0, 1, 0], &0), &[0, 1]);
55        assert_eq!(trim_end_slice(&[0, 1, 0, 0], &0), &[0, 1]);
56        assert_eq!(trim_end_slice(&[0, 1, 0, 0, 0], &0), &[0, 1]);
57        assert_eq!(trim_end_slice(&[0, 1, 0, 1, 0], &0), &[0, 1, 0, 1]);
58
59        let trim_end_vec = |mut v: Vec<i32>, x: &i32| {
60            trim_end_vec(&mut v, x);
61            v
62        };
63        assert_eq!(trim_end_vec(vec![], &0), &[] as &[i32]);
64        assert_eq!(trim_end_vec(vec![0], &0), &[] as &[i32]);
65        assert_eq!(trim_end_vec(vec![0, 1], &0), &[0, 1]);
66        assert_eq!(trim_end_vec(vec![0, 1, 0], &0), &[0, 1]);
67        assert_eq!(trim_end_vec(vec![0, 1, 0, 0], &0), &[0, 1]);
68        assert_eq!(trim_end_vec(vec![0, 1, 0, 0, 0], &0), &[0, 1]);
69        assert_eq!(trim_end_vec(vec![0, 1, 0, 1, 0], &0), &[0, 1, 0, 1]);
70    }
71}