Skip to content

Commit

Permalink
Amend single-argument API with const_assert to confirm validity of tr…
Browse files Browse the repository at this point in the history
…ailing_zeros as log_2
  • Loading branch information
chyyran committed Aug 26, 2022
1 parent e21196f commit 64f9980
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 15 deletions.
6 changes: 3 additions & 3 deletions src/decode/lzma.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::decode::lzbuffer::{LzBuffer, LzCircularBuffer};
use crate::decode::rangecoder::{bittree_probs_len, BitTree, LenDecoder, RangeDecoder};
use crate::decode::rangecoder::{BitTree, LenDecoder, RangeDecoder};
use crate::decompress::{Options, UnpackedSize};
use crate::error;
use crate::util::vec2d::Vec2D;
Expand Down Expand Up @@ -167,8 +167,8 @@ pub(crate) struct DecoderState {
pub(crate) lzma_props: LzmaProperties,
unpacked_size: Option<u64>,
literal_probs: Vec2D<u16>,
pos_slot_decoder: [BitTree<{ bittree_probs_len::<6>() }>; 4],
align_decoder: BitTree<{ bittree_probs_len::<4>() }>,
pos_slot_decoder: [BitTree<{ 1 << 6 }>; 4],
align_decoder: BitTree<{ 1 << 4 }>,
pos_decoders: [u16; 115],
is_match: [u16; 192], // true = LZ, false = literal
is_rep: [u16; 12],
Expand Down
21 changes: 15 additions & 6 deletions src/decode/rangecoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,17 @@ where
}
}

// const fn helper to parameterize the length of the bittree probability array.
pub const fn bittree_probs_len<const NUM_BITS: usize>() -> usize {
1 << NUM_BITS
macro_rules! const_assert {
($($list:ident : $ty:ty),* => $expr:expr) => {{
struct Assert<$(const $list: $ty,)*>;
impl<$(const $list: $ty,)*> Assert<$($list,)*> {
const OK: u8 = 0 - !($expr) as u8;
}
Assert::<$($list,)*>::OK
}};
($expr:expr) => {
const OK: u8 = 0 - !($expr) as u8;
};
}

#[derive(Debug, Clone)]
Expand All @@ -162,6 +170,7 @@ pub struct BitTree<const PROBS_ARRAY_LEN: usize> {

impl<const PROBS_ARRAY_LEN: usize> BitTree<PROBS_ARRAY_LEN> {
pub fn new() -> Self {
const_assert!(PROBS_ARRAY_LEN: usize => (1 << (PROBS_ARRAY_LEN.trailing_zeros() as usize)) == PROBS_ARRAY_LEN);
BitTree {
probs: [0x400; PROBS_ARRAY_LEN],
}
Expand Down Expand Up @@ -190,9 +199,9 @@ impl<const PROBS_ARRAY_LEN: usize> BitTree<PROBS_ARRAY_LEN> {
pub struct LenDecoder {
choice: u16,
choice2: u16,
low_coder: [BitTree<{ bittree_probs_len::<3>() }>; 16],
mid_coder: [BitTree<{ bittree_probs_len::<3>() }>; 16],
high_coder: BitTree<{ bittree_probs_len::<8>() }>,
low_coder: [BitTree<{ 1 << 3 }>; 16],
mid_coder: [BitTree<{ 1 << 3 }>; 16],
high_coder: BitTree<{ 1 << 8 }>,
}

impl LenDecoder {
Expand Down
12 changes: 6 additions & 6 deletions src/encode/rangecoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,15 +276,15 @@ mod test {
#[test]
fn test_encode_decode_bittree_zeros() {
seq!(NUM_BITS in 0..16 {
encode_decode_bittree::<NUM_BITS, {decode::rangecoder::bittree_probs_len::<NUM_BITS>()}>
encode_decode_bittree::<NUM_BITS, {1 << NUM_BITS}>
(&[0; 10000]);
});
}

#[test]
fn test_encode_decode_bittree_ones() {
seq!(NUM_BITS in 0..16 {
encode_decode_bittree::<NUM_BITS, {decode::rangecoder::bittree_probs_len::<NUM_BITS>()}>
encode_decode_bittree::<NUM_BITS, {1 << NUM_BITS}>
(&[(1 << NUM_BITS) - 1; 10000]);
});
}
Expand All @@ -294,7 +294,7 @@ mod test {
seq!(NUM_BITS in 0..16 {
let max = 1 << NUM_BITS;
let values: Vec<u32> = (0..max).collect();
encode_decode_bittree::<NUM_BITS, {decode::rangecoder::bittree_probs_len::<NUM_BITS>()}>
encode_decode_bittree::<NUM_BITS, {1 << NUM_BITS}>
(&values);
});
}
Expand Down Expand Up @@ -323,15 +323,15 @@ mod test {
#[test]
fn test_encode_decode_reverse_bittree_zeros() {
seq!(NUM_BITS in 0..16 {
encode_decode_reverse_bittree::<NUM_BITS, {decode::rangecoder::bittree_probs_len::<NUM_BITS>()}>
encode_decode_reverse_bittree::<NUM_BITS, {1 << NUM_BITS}>
(&[0; 10000]);
});
}

#[test]
fn test_encode_decode_reverse_bittree_ones() {
seq!(NUM_BITS in 0..16 {
encode_decode_reverse_bittree::<NUM_BITS, {decode::rangecoder::bittree_probs_len::<NUM_BITS>()}>
encode_decode_reverse_bittree::<NUM_BITS, {1 << NUM_BITS}>
(&[(1 << NUM_BITS) - 1; 10000]);
});
}
Expand All @@ -341,7 +341,7 @@ mod test {
seq!(NUM_BITS in 0..16 {
let max = 1 << NUM_BITS;
let values: Vec<u32> = (0..max).collect();
encode_decode_reverse_bittree::<NUM_BITS, {decode::rangecoder::bittree_probs_len::<NUM_BITS>()}>
encode_decode_reverse_bittree::<NUM_BITS, {1 << NUM_BITS}>
(&values);
});
}
Expand Down

0 comments on commit 64f9980

Please sign in to comment.