bv/traits/
bits_mut_ext.rs1use BlockType;
2use super::{Bits, BitsMut};
3
4pub trait BitsMutExt: BitsMut {
6 fn bit_assign<T: Bits<Block = Self::Block>>(&mut self, other: T) {
12 assert_eq!( self.bit_len(), other.bit_len(),
13 "BitsMutExt::bit_assign: arguments have different lengths" );
14
15 let bit_len = self.bit_len();
16 let full_blocks = Self::Block::div_nbits(bit_len);
17 let extra_bits = Self::Block::mod_nbits(bit_len);
18
19 for i in 0 .. full_blocks {
20 let block = other.get_raw_block(i);
21 self.set_block(i, block);
22 }
23
24 if extra_bits > 0 {
25 let block = other.get_raw_block(full_blocks);
26 self.set_bits(bit_len - extra_bits as u64, extra_bits, block);
27 }
28 }
29
30 fn bit_and_assign<T: Bits<Block = Self::Block>>(&mut self, other: T) {
36 self.bit_zip_assign(other, |b1, b2| b1 & b2);
37 }
38
39 fn bit_or_assign<T: Bits<Block = Self::Block>>(&mut self, other: T) {
45 self.bit_zip_assign(other, |b1, b2| b1 | b2);
46 }
47
48 fn bit_xor_assign<T: Bits<Block = Self::Block>>(&mut self, other: T) {
54 self.bit_zip_assign(other, |b1, b2| b1 ^ b2);
55 }
56
57 fn bit_zip_assign<T, F>(&mut self, other: T, mut fun: F)
67 where T: Bits<Block = Self::Block>,
68 F: FnMut(Self::Block, Self::Block) -> Self::Block {
69
70 assert_eq!( self.bit_len(), other.bit_len(),
71 "BitsMutExt::bit_zip_assign: arguments have different lengths" );
72
73 let bit_len = self.bit_len();
74 let full_blocks = Self::Block::div_nbits(bit_len);
75 let extra_bits = Self::Block::mod_nbits(bit_len);
76
77 for i in 0 .. full_blocks {
78 let self_block = self.get_raw_block(i);
79 let other_block = other.get_raw_block(i);
80 let combined_block = fun(self_block, other_block);
81 self.set_block(i, combined_block);
82 }
83
84 if extra_bits > 0 {
85 let self_block = self.get_block(full_blocks);
86 let other_block = other.get_block(full_blocks);
87 let combined_block = fun(self_block, other_block);
88 self.set_bits(bit_len - extra_bits as u64, extra_bits, combined_block);
89 }
90 }
91}
92
93impl<T: BitsMut> BitsMutExt for T {}
94
95#[cfg(test)]
96mod test {
97 use {BitVec, BitSliceable, BitSliceableMut};
98 use super::*;
99
100 #[test]
101 fn bit_and_assign() {
102 let mut bv1: BitVec = bit_vec![false, false, true, true];
103 let bv2: BitVec = bit_vec![false, true, true, false];
104
105 bv1.bit_and_assign(&bv2);
106 assert_eq!( bv1, bit_vec![false, false, true, false] );
107 }
108
109 #[test]
110 #[should_panic]
111 fn bit_and_assign_bad_sizes() {
112 let mut bv1: BitVec = bit_vec![false, false, true, true, true];
113 let bv2: BitVec = bit_vec![false, true, true, false];
114
115 bv1.bit_and_assign(&bv2);
116 }
117
118 #[test]
119 fn bit_xor_assign_slice() {
120 let mut v1 = vec![0b00_0011_11u8];
121 let v2 = [0b0_1010_101u8];
122
123 v1.bit_slice_mut(2..6)
124 .bit_xor_assign(v2.bit_slice(3..7));
125
126 assert_eq!(v1, vec![0b00100111])
127 }
128}