Skip to content

Commit

Permalink
feat(bitfield): add Pack::pair_with (#294)
Browse files Browse the repository at this point in the history
This commit adds a `pair_with` method to `Pack{N}` types that allows
creating a packing pair with another already defined packing spec.
  • Loading branch information
hawkw committed Aug 9, 2022
1 parent 03055f0 commit 47b08b7
Showing 1 changed file with 23 additions and 14 deletions.
37 changes: 23 additions & 14 deletions bitfield/src/pack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -589,33 +589,42 @@ macro_rules! make_packers {
///
/// The packing pair can be used to pack bits from one location
/// into another location, and vice versa.
pub const fn pair_at(&self, at: u32) -> $Pair<T> {
let dst = $Pack::<$Bits, ()>::starting_at(at, self.bits()).typed();
let at = at.saturating_sub(1);
// TODO(eliza): validate that `at + self.bits() < N_BITS` in
pub const fn pair_at(&self, at: u32) -> $Pair {
let dst = $Pack::starting_at(at, self.bits());
self.pair_with(&dst.typed())
}

/// Returns a pair type for packing bits from the range
/// specified by `self` after the specified packing spec.
pub const fn pair_after(&self, after: &Self) -> $Pair {
self.pair_at(after.shift_next())
}

/// Returns a pair type for packing bits from the range
/// specified by `self` into the range specified by `with`.
///
/// # Note
/// The two ranges must be the same size. This can be asserted
/// by the `assert_valid` method on the returned pair type.
pub const fn pair_with(&self, dst: &Self) -> $Pair {
// TODO(eliza): validate that `dst.shift + self.bits() < N_BITS` in
// const fn somehow lol
let (dst_shl, dst_shr) = if at > self.shift {
let (dst_shl, dst_shr) = if dst.shift > self.shift {
// If the destination is greater than `self`, we need to
// shift left.
((at - self.shift) as $Bits, 0)
((dst.shift - self.shift) as $Bits, 0)
} else {
// Otherwise, shift down.
(0, (self.shift - at) as $Bits)
(0, (self.shift - dst.shift) as $Bits)
};
$Pair {
src: self.typed(),
dst,
dst: dst.typed(),
dst_shl,
dst_shr,
}
}

/// Returns a pair type for packing bits from the range
/// specified by `self` after the specified packing spec.
pub const fn pair_after(&self, after: &Self) -> $Pair<T> {
self.pair_at(after.shift_next())
}

/// Pack the [`self.bits()`] least-significant bits from `value` into `base`.
///
/// # Panics
Expand Down

0 comments on commit 47b08b7

Please sign in to comment.