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
use super::BitChunk;
/// Merges 2 [`BitChunk`]s into a single [`BitChunk`] so that the new items represents
/// the bitmap where bits from `next` are placed in `current` according to `offset`.
/// # Panic
/// The caller must ensure that `0 < offset < size_of::<T>() * 8`
/// # Example
/// ```rust,ignore
/// let current = 0b01011001;
/// let next = 0b01011011;
/// let result = merge_reversed(current, next, 1);
/// assert_eq!(result, 0b10101100);
/// ```
#[inline]
pub fn merge_reversed<T>(mut current: T, mut next: T, offset: usize) -> T
where
T: BitChunk,
{
// 8 _bits_:
// current = [c0, c1, c2, c3, c4, c5, c6, c7]
// next = [n0, n1, n2, n3, n4, n5, n6, n7]
// offset = 3
// expected = [n5, n6, n7, c0, c1, c2, c3, c4]
// 1. unset most significants of `next` up to `offset`
let inverse_offset = std::mem::size_of::<T>() * 8 - offset;
next <<= inverse_offset;
// next = [n5, n6, n7, 0 , 0 , 0 , 0 , 0 ]
// 2. unset least significants of `current` up to `offset`
current >>= offset;
// current = [0 , 0 , 0 , c0, c1, c2, c3, c4]
current | next
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_merge_reversed() {
let current = 0b00000000;
let next = 0b00000001;
let result = merge_reversed::<u8>(current, next, 1);
assert_eq!(result, 0b10000000);
let current = 0b01011001;
let next = 0b01011011;
let result = merge_reversed::<u8>(current, next, 1);
assert_eq!(result, 0b10101100);
}
#[test]
fn test_merge_reversed_offset2() {
let current = 0b00000000;
let next = 0b00000001;
let result = merge_reversed::<u8>(current, next, 3);
assert_eq!(result, 0b00100000);
}
}