1 //! Unit tests for the `slice` module.
2
3 #![cfg(test)]
4
5 use crate::{
6 index::BitIdx,
7 pointer::BitPtr,
8 prelude::*,
9 };
10
11 #[test]
construction()12 fn construction() {
13 #[cfg(not(miri))]
14 use core::slice;
15
16 let data = 0u8;
17 let bits = data.view_bits::<LocalBits>();
18 assert_eq!(bits.len(), 8);
19
20 #[cfg(not(miri))]
21 assert!(
22 BitSlice::<LocalBits, u8>::from_slice(unsafe {
23 slice::from_raw_parts(
24 1usize as *const _,
25 BitSlice::<LocalBits, u8>::MAX_ELTS,
26 )
27 })
28 .is_none()
29 );
30
31 #[cfg(not(miri))]
32 assert!(
33 BitSlice::<LocalBits, u8>::from_slice_mut(unsafe {
34 slice::from_raw_parts_mut(
35 1usize as *mut _,
36 BitSlice::<LocalBits, u8>::MAX_ELTS,
37 )
38 })
39 .is_none()
40 );
41
42 assert_eq!(
43 unsafe { crate::slice::bits_from_raw_parts(&data, 0, 8) },
44 Some(bits)
45 );
46 assert!(
47 unsafe {
48 crate::slice::bits_from_raw_parts::<LocalBits, _>(&data, 0, !0)
49 }
50 .is_none()
51 );
52
53 let mut data = 0u8;
54 assert_eq!(
55 unsafe {
56 crate::slice::bits_from_raw_parts_mut(&mut data as *mut _, 0, 8)
57 },
58 Some(data.view_bits_mut::<LocalBits>())
59 );
60 }
61
62 #[test]
get_set()63 fn get_set() {
64 let bits = bits![mut LocalBits, u8; 0; 8];
65
66 for n in 0 .. 8 {
67 assert!(!bits.get(n).unwrap());
68 bits.set(n, true);
69 assert!(bits.get(n).unwrap());
70 }
71
72 assert!(bits.get(9).is_none());
73 assert!(bits.get_mut(9).is_none());
74 assert!(bits.get(8 .. 10).is_none());
75 assert!(bits.get_mut(8 .. 10).is_none());
76
77 assert_eq!(bits.first(), Some(&true));
78 *bits.first_mut().unwrap() = false;
79 assert_eq!(bits.last(), Some(&true));
80 *bits.last_mut().unwrap() = false;
81
82 *crate::slice::BitSliceIndex::index_mut(1usize, bits) = false;
83 assert_eq!(bits, bits![0, 0, 1, 1, 1, 1, 1, 0]);
84 assert!(bits.get(100 ..).is_none());
85 assert!(bits.get(.. 100).is_none());
86
87 let (a, b) = (bits![mut Msb0, u8; 0, 1], bits![mut Lsb0, u16; 1, 0]);
88 assert_eq!(a, bits![0, 1]);
89 assert_eq!(b, bits![1, 0]);
90 a.swap_with_bitslice(b);
91 assert_eq!(a, bits![1, 0]);
92 assert_eq!(b, bits![0, 1]);
93 }
94
95 #[test]
memcpy()96 fn memcpy() {
97 let mut dst = bitarr![0; 500];
98 let src = bitarr![1; 500];
99
100 // Equal heads will fall into the fast path.
101 dst[10 .. 20].copy_from_bitslice(&src[74 .. 84]);
102 dst[100 .. 500].copy_from_bitslice(&src[36 .. 436]);
103
104 // Unequal heads will trip the slow path.
105 dst[.. 490].copy_from_bitslice(&src[10 .. 500]);
106 }
107
108 #[test]
query()109 fn query() {
110 let data = [0x0Fu8, !0, 0xF0, 0, 0x0E];
111 let bits = data.view_bits::<Msb0>();
112
113 assert!(bits[36 .. 39].all());
114 assert!(bits[4 .. 20].all());
115 assert!(bits[.. 8].any());
116 assert!(bits[4 .. 20].any());
117 assert!(bits[32 ..].not_all());
118 assert!(bits[.. 4].not_any());
119 assert!(bits[.. 8].some());
120
121 assert_eq!(bits[1 .. 7].count_ones(), 3);
122 assert_eq!(bits[1 .. 7].count_zeros(), 3);
123 assert_eq!(bits[.. 24].count_ones(), 16);
124 assert_eq!(bits[16 ..].count_zeros(), 17);
125
126 assert!(!bits![0].contains(bits![0, 1]));
127 assert!(bits![0, 1, 0].contains(bits![1, 0]));
128 assert!(bits![0, 1, 0].starts_with(bits![0, 1]));
129 assert!(bits![0, 1, 0].ends_with(bits![1, 0]));
130 }
131
132 #[test]
modify()133 fn modify() {
134 let mut data = 0b0000_1111u8;
135
136 let bits = data.view_bits_mut::<LocalBits>();
137 bits.swap(3, 4);
138 assert_eq!(data, 0b0001_0111);
139
140 let bits = data.view_bits_mut::<Lsb0>();
141 bits[1 .. 7].reverse();
142 assert_eq!(data, 0b0110_1001);
143 data.view_bits_mut::<Msb0>()[1 .. 7].reverse();
144
145 let bits = data.view_bits_mut::<Msb0>();
146 bits.copy_within(2 .. 4, 0);
147 assert_eq!(data, 0b0101_0111);
148
149 let bits = data.view_bits_mut::<Msb0>();
150 bits.copy_within(5 .., 2);
151 assert_eq!(data, 0b0111_1111);
152 }
153
154 #[test]
split()155 fn split() {
156 assert!(
157 BitSlice::<LocalBits, usize>::empty()
158 .split_first()
159 .is_none()
160 );
161 assert_eq!(
162 1u8.view_bits::<Lsb0>().split_first(),
163 Some((&true, bits![Lsb0, u8; 0; 7]))
164 );
165
166 assert!(
167 BitSlice::<LocalBits, usize>::empty_mut()
168 .split_first_mut()
169 .is_none()
170 );
171 let mut data = 0u8;
172 let (head, _) = data.view_bits_mut::<Lsb0>().split_first_mut().unwrap();
173 head.set(true);
174 assert_eq!(data, 1);
175
176 assert!(BitSlice::<LocalBits, usize>::empty().split_last().is_none());
177 assert_eq!(
178 1u8.view_bits::<Msb0>().split_last(),
179 Some((&true, bits![Msb0, u8; 0; 7]))
180 );
181
182 assert!(
183 BitSlice::<LocalBits, usize>::empty_mut()
184 .split_first_mut()
185 .is_none()
186 );
187 let mut data = 0u8;
188 let (head, _) = data.view_bits_mut::<Msb0>().split_last_mut().unwrap();
189 head.set(true);
190 assert_eq!(data, 1);
191
192 let mut data = 0b0000_1111u8;
193
194 let bits = data.view_bits::<Msb0>();
195 let (left, right) = bits.split_at(4);
196 assert!(left.not_any());
197 assert!(right.all());
198
199 let bits = data.view_bits_mut::<Msb0>();
200 let (left, right) = bits.split_at_mut(4);
201 left.set_all(true);
202 right.set_all(false);
203 assert_eq!(data, 0b1111_0000u8);
204
205 let data = 0u8;
206 let bits = data.view_bits::<Lsb0>();
207 let base = bits.as_slice().as_ptr();
208 let base_ptr = unsafe { BitPtr::new_unchecked(base, BitIdx::ZERO, 0) };
209 let next_ptr =
210 unsafe { BitPtr::new_unchecked(base.add(1), BitIdx::ZERO, 0) };
211 let (l, _) = bits.split_at(0);
212 let (_, r) = bits.split_at(8);
213 let (l_ptr, r_ptr) = (l.bitptr(), r.bitptr());
214 assert_eq!(l_ptr, base_ptr);
215 assert_eq!(r_ptr, next_ptr);
216 }
217
218 #[test]
iterators()219 fn iterators() {
220 0b0100_1000u8
221 .view_bits::<Msb0>()
222 .split(|_, bit| *bit)
223 .zip([1usize, 2, 3].iter())
224 .for_each(|(bits, len)| assert_eq!(bits.len(), *len));
225
226 let mut data = 0b0100_1000u8;
227 data.view_bits_mut::<Msb0>()
228 .split_mut(|_, bit| *bit)
229 .zip([1usize, 2, 3].iter())
230 .for_each(|(bits, len)| {
231 assert_eq!(bits.len(), *len);
232 bits.set_all(true)
233 });
234 assert_eq!(data, !0);
235
236 0b0100_1000u8
237 .view_bits::<Msb0>()
238 .rsplit(|_, bit| *bit)
239 .zip([3usize, 2, 1].iter())
240 .for_each(|(bits, len)| assert_eq!(bits.len(), *len));
241
242 let mut data = 0b0100_1000u8;
243 data.view_bits_mut::<Msb0>()
244 .rsplit_mut(|_, bit| *bit)
245 .zip([3usize, 2, 1].iter())
246 .for_each(|(bits, len)| {
247 assert_eq!(bits.len(), *len);
248 bits.set_all(true)
249 });
250 assert_eq!(data, !0);
251
252 0b0100_1000u8
253 .view_bits::<Msb0>()
254 .splitn(2, |_, bit| *bit)
255 .zip([1usize, 6].iter())
256 .for_each(|(bits, len)| assert_eq!(bits.len(), *len));
257
258 let mut data = 0b0100_1000u8;
259 data.view_bits_mut::<Msb0>()
260 .splitn_mut(2, |_, bit| *bit)
261 .zip([1usize, 6].iter())
262 .for_each(|(bits, len)| {
263 assert_eq!(bits.len(), *len);
264 bits.set_all(true)
265 });
266 assert_eq!(data, !0);
267
268 0b0100_1000u8
269 .view_bits::<Msb0>()
270 .rsplitn(2, |_, bit| *bit)
271 .zip([3usize, 4].iter())
272 .for_each(|(bits, len)| assert_eq!(bits.len(), *len));
273
274 let mut data = 0b0100_1000u8;
275 data.view_bits_mut::<Msb0>()
276 .rsplitn_mut(2, |_, bit| *bit)
277 .zip([3usize, 4].iter())
278 .for_each(|(bits, len)| {
279 assert_eq!(bits.len(), *len);
280 bits.set_all(true)
281 });
282 assert_eq!(data, !0);
283 }
284
285 #[test]
alignment()286 fn alignment() {
287 let mut data = [0u16; 5];
288 let addr = &data as *const [u16; 5] as *const u16 as usize;
289 let bits = data.view_bits_mut::<LocalBits>();
290
291 let (head, body, tail) = unsafe { bits[5 .. 75].align_to_mut::<u32>() };
292
293 // `data` is aligned to the back half of a `u32`
294 if addr % 4 == 2 {
295 assert_eq!(head.len(), 11);
296 assert_eq!(body.len(), 59);
297 assert!(tail.is_empty());
298 }
299 // `data` is aligned to the front half of a `u32`
300 else {
301 assert!(head.is_empty());
302 assert_eq!(body.len(), 64);
303 assert_eq!(tail.len(), 6);
304 }
305 }
306
307 #[test]
308 #[cfg(feature = "alloc")]
repetition()309 fn repetition() {
310 let bits = bits![0, 0, 1, 1];
311 let bv = bits.repeat(2);
312 assert_eq!(bv, bits![0, 0, 1, 1, 0, 0, 1, 1]);
313 }
314
315 #[test]
pointer_offset()316 fn pointer_offset() {
317 let data = [0u16; 2];
318 let bits = data.view_bits::<Msb0>();
319
320 let a = &bits[10 .. 11];
321 let b = &bits[20 .. 21];
322 assert_eq!(a.offset_from(b), 10);
323 }
324