54 lines
1.5 KiB
Rust
54 lines
1.5 KiB
Rust
use std::ops::{Bound, Range, RangeBounds};
|
|
|
|
/// Divide `n` by `divisor`, and round up to the nearest integer
|
|
/// if not evenly divisible.
|
|
#[inline]
|
|
pub(super) fn div_round_up(n: usize, divisor: usize) -> usize {
|
|
debug_assert!(divisor != 0, "Division by zero!");
|
|
if n == 0 {
|
|
0
|
|
} else {
|
|
(n - 1) / divisor + 1
|
|
}
|
|
}
|
|
|
|
/// Normalize arbitrary `RangeBounds` to a `Range`
|
|
pub(super) fn simplify_range(range: impl RangeBounds<usize>, len: usize) -> Range<usize> {
|
|
let start = match range.start_bound() {
|
|
Bound::Unbounded => 0,
|
|
Bound::Included(&i) if i <= len => i,
|
|
Bound::Excluded(&i) if i < len => i + 1,
|
|
bound => panic!("range start {:?} should be <= length {}", bound, len),
|
|
};
|
|
let end = match range.end_bound() {
|
|
Bound::Unbounded => len,
|
|
Bound::Excluded(&i) if i <= len => i,
|
|
Bound::Included(&i) if i < len => i + 1,
|
|
bound => panic!("range end {:?} should be <= length {}", bound, len),
|
|
};
|
|
if start > end {
|
|
panic!(
|
|
"range start {:?} should be <= range end {:?}",
|
|
range.start_bound(),
|
|
range.end_bound()
|
|
);
|
|
}
|
|
start..end
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn check_div_round_up() {
|
|
assert_eq!(0, div_round_up(0, 5));
|
|
assert_eq!(1, div_round_up(5, 5));
|
|
assert_eq!(1, div_round_up(1, 5));
|
|
assert_eq!(2, div_round_up(3, 2));
|
|
assert_eq!(
|
|
usize::max_value() / 2 + 1,
|
|
div_round_up(usize::max_value(), 2)
|
|
);
|
|
}
|
|
}
|