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