Skip to content

Commit 4f1cc18

Browse files
committed
Implemented truncate
1 parent 527a9da commit 4f1cc18

File tree

5 files changed

+74
-31
lines changed

5 files changed

+74
-31
lines changed

src/auto.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -300,13 +300,13 @@ impl BitVector for Bv {
300300
}
301301
}
302302

303-
fn resize(&mut self, new_length: usize, bit: Bit) {
304-
if new_length > self.len() {
305-
self.reserve(new_length - self.len());
303+
fn resize(&mut self, new_len: usize, bit: Bit) {
304+
if new_len > self.len() {
305+
self.reserve(new_len - self.len());
306306
}
307307
match self {
308-
Bv::Fixed(b) => b.resize(new_length, bit),
309-
Bv::Dynamic(b) => b.resize(new_length, bit),
308+
Bv::Fixed(b) => b.resize(new_len, bit),
309+
Bv::Dynamic(b) => b.resize(new_len, bit),
310310
}
311311
}
312312

src/dynamic.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -372,31 +372,31 @@ impl BitVector for Bvd {
372372
Some(bit)
373373
}
374374

375-
fn resize(&mut self, new_length: usize, bit: Bit) {
376-
if new_length < self.length {
377-
for i in (new_length / Self::BIT_UNIT + 1)..Self::capacity_from_bit_len(self.length) {
375+
fn resize(&mut self, new_len: usize, bit: Bit) {
376+
if new_len < self.length {
377+
for i in (new_len / Self::BIT_UNIT + 1)..Self::capacity_from_bit_len(self.length) {
378378
self.data[i] = 0;
379379
}
380-
if let Some(l) = self.data.get_mut(new_length / Self::BIT_UNIT) {
381-
*l &= u64::mask(new_length % Self::BIT_UNIT);
380+
if let Some(l) = self.data.get_mut(new_len / Self::BIT_UNIT) {
381+
*l &= u64::mask(new_len % Self::BIT_UNIT);
382382
}
383-
self.length = new_length;
384-
} else if new_length > self.length {
383+
self.length = new_len;
384+
} else if new_len > self.length {
385385
let sign_pattern = match bit {
386386
Bit::Zero => u64::MIN,
387387
Bit::One => u64::MAX,
388388
};
389-
self.reserve(new_length - self.length);
389+
self.reserve(new_len - self.length);
390390
if let Some(l) = self.data.get_mut(self.length / Self::BIT_UNIT) {
391391
*l |= sign_pattern & !u64::mask(self.length % Self::BIT_UNIT);
392392
}
393-
for i in (self.length / Self::BIT_UNIT + 1)..Self::capacity_from_bit_len(new_length) {
393+
for i in (self.length / Self::BIT_UNIT + 1)..Self::capacity_from_bit_len(new_len) {
394394
self.data[i] = sign_pattern;
395395
}
396-
if let Some(l) = self.data.get_mut(new_length / Self::BIT_UNIT) {
397-
*l &= u64::mask(new_length % Self::BIT_UNIT);
396+
if let Some(l) = self.data.get_mut(new_len / Self::BIT_UNIT) {
397+
*l &= u64::mask(new_len % Self::BIT_UNIT);
398398
}
399-
self.length = new_length;
399+
self.length = new_len;
400400
}
401401
}
402402

src/fixed.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -372,31 +372,31 @@ where
372372
b
373373
}
374374

375-
fn resize(&mut self, new_length: usize, bit: Bit) {
376-
if new_length < self.length {
377-
for i in (new_length / Self::BIT_UNIT + 1)..Self::capacity_from_bit_len(self.length) {
375+
fn resize(&mut self, new_len: usize, bit: Bit) {
376+
if new_len < self.length {
377+
for i in (new_len / Self::BIT_UNIT + 1)..Self::capacity_from_bit_len(self.length) {
378378
self.data[i] = I::ZERO;
379379
}
380-
if let Some(l) = self.data.get_mut(new_length / Self::BIT_UNIT) {
381-
*l &= I::mask(new_length % Self::BIT_UNIT);
380+
if let Some(l) = self.data.get_mut(new_len / Self::BIT_UNIT) {
381+
*l &= I::mask(new_len % Self::BIT_UNIT);
382382
}
383-
self.length = new_length;
384-
} else if new_length > self.length {
385-
debug_assert!(new_length <= Self::capacity());
383+
self.length = new_len;
384+
} else if new_len > self.length {
385+
debug_assert!(new_len <= Self::capacity());
386386
let sign_pattern = match bit {
387387
Bit::Zero => I::MIN,
388388
Bit::One => I::MAX,
389389
};
390390
if let Some(l) = self.data.get_mut(self.length / Self::BIT_UNIT) {
391391
*l |= sign_pattern & !I::mask(self.length % Self::BIT_UNIT);
392392
}
393-
for i in (self.length / Self::BIT_UNIT + 1)..Self::capacity_from_bit_len(new_length) {
393+
for i in (self.length / Self::BIT_UNIT + 1)..Self::capacity_from_bit_len(new_len) {
394394
self.data[i] = sign_pattern;
395395
}
396-
if let Some(l) = self.data.get_mut(new_length / Self::BIT_UNIT) {
397-
*l &= I::mask(new_length % Self::BIT_UNIT);
396+
if let Some(l) = self.data.get_mut(new_len / Self::BIT_UNIT) {
397+
*l &= I::mask(new_len % Self::BIT_UNIT);
398398
}
399-
self.length = new_length;
399+
self.length = new_len;
400400
}
401401
}
402402

src/lib.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ pub trait BitVector:
459459
/// ```
460460
fn pop(&mut self) -> Option<Bit>;
461461

462-
/// Resize the bit vector in place so that its length is equal to `new_length`.
462+
/// Resize the bit vector in place so that its length is equal to `new_len`.
463463
/// This will either truncate or extend the bit vector. If it is extended, new bits are filled
464464
/// with `bit`.
465465
/// Will panic if there is not enough capacity and it is a fixed variant.
@@ -471,7 +471,23 @@ pub trait BitVector:
471471
/// a.resize(10, Bit::One);
472472
/// assert_eq!(a, Bv::from(0b1100000000u16));
473473
/// ```
474-
fn resize(&mut self, new_length: usize, bit: Bit);
474+
fn resize(&mut self, new_len: usize, bit: Bit);
475+
476+
/// Truncate the bit vector in place, keeping the first `new_len` bits.
477+
/// If `new_len` is greater or equal to the bit vector’s current length, this has no effect.
478+
///
479+
/// ```
480+
/// use bva::{Bit, BitVector, Bv};
481+
///
482+
/// let mut a = Bv::from(0b111000110010u16);
483+
/// a.truncate(8);
484+
/// assert_eq!(a, Bv::from(0b00110010u16));
485+
/// ```
486+
fn truncate(&mut self, new_len: usize) {
487+
if new_len < self.len() {
488+
self.resize(new_len, Bit::Zero);
489+
}
490+
}
475491

476492
/// Resize this bit vector using the most significant bit as a sign bit so that its length
477493
/// is equal to `new_length`. If `new_length` is smaller than the current length, this method

src/tests/bitvector.rs

+27
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,33 @@ fn resize_bv() {
632632
resize_inner::<Bv>(256);
633633
}
634634

635+
fn truncate_inner<B: BitVector>(max_capacity: usize) {
636+
let bv: B = random_bv(max_capacity);
637+
638+
for len in (0..bv.len()).rev() {
639+
let mut bv2 = bv.clone();
640+
bv2.truncate(len);
641+
for i in 0..bv2.len() {
642+
assert_eq!(bv.get(i), bv2.get(i));
643+
}
644+
}
645+
}
646+
647+
#[test]
648+
fn truncate_bvf() {
649+
bvf_inner_unroll_cap!(truncate_inner, {u8, u16, u32, u64, u128}, {1, 2, 3, 4, 5});
650+
}
651+
652+
#[test]
653+
fn truncate_bvd() {
654+
truncate_inner::<Bvd>(256);
655+
}
656+
657+
#[test]
658+
fn truncate_bv() {
659+
truncate_inner::<Bv>(256);
660+
}
661+
635662
fn sign_extend_inner<B: BitVector>(max_capacity: usize) {
636663
for capacity in 0..max_capacity {
637664
let bv = random_bv::<B>(capacity);

0 commit comments

Comments
 (0)