Skip to content

Commit 90303d8

Browse files
committed
Added the iter() method to BitSlice and implemented the IntoIterator trait for &BitSlice.
1 parent bb4f7b4 commit 90303d8

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed

src/bit_slice.rs

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,24 @@ impl<'a, S: BitStorage + 'a> BitSlice<'a, S> {
5050
}
5151
}
5252

53+
pub fn iter(&self) -> Iter<S> {
54+
Iter {
55+
pointer: self.pointer,
56+
capacity: self.capacity,
57+
data_index_counter: 0,
58+
remainder_counter: 0,
59+
phantom: PhantomData
60+
}
61+
}
62+
5363
#[inline]
5464
fn get_unchecked(&self, index: usize) -> bool {
5565
let (data_index, remainder) = self.compute_data_index_and_remainder(index);
66+
self.get_unchecked_by_data_index_and_remainder(data_index, remainder)
67+
}
68+
69+
#[inline]
70+
fn get_unchecked_by_data_index_and_remainder(&self, data_index: usize, remainder: S) -> bool {
5671
let element = unsafe { *self.pointer.offset(data_index as isize) };
5772
(element & (S::one() << remainder)) != S::zero()
5873
}
@@ -119,6 +134,60 @@ impl<'a, S: BitStorage + 'a> Index<usize> for BitSlice<'a, S> {
119134
}
120135
}
121136

137+
pub struct Iter<'a, S: BitStorage + 'a> {
138+
pointer: *const S,
139+
capacity: usize,
140+
data_index_counter: usize,
141+
remainder_counter: usize,
142+
phantom: PhantomData<&'a S>
143+
}
144+
145+
unsafe impl<'a, S: BitStorage + 'a> Send for Iter<'a, S> {}
146+
unsafe impl<'a, S: BitStorage + 'a> Sync for Iter<'a, S> {}
147+
148+
impl<'a, S: BitStorage + 'a> IntoIterator for &'a BitSlice<'a, S> {
149+
type Item = bool;
150+
type IntoIter = Iter<'a, S>;
151+
152+
fn into_iter(self) -> Iter<'a, S> {
153+
self.iter()
154+
}
155+
}
156+
157+
impl<'a, S: BitStorage + 'a> Iterator for Iter<'a, S> {
158+
type Item = bool;
159+
160+
fn next(&mut self) -> Option<bool> {
161+
let remainder: S = num::cast(self.remainder_counter).unwrap();
162+
let next = self.get_unchecked_by_data_index_and_remainder(self.data_index_counter, remainder);
163+
164+
if self.calculate_index() == self.capacity {
165+
return None;
166+
}
167+
168+
self.remainder_counter += 1;
169+
if self.remainder_counter == S::storage_size() {
170+
self.remainder_counter = 0;
171+
self.data_index_counter += 1;
172+
}
173+
174+
Some(next)
175+
}
176+
}
177+
178+
impl<'a, S: BitStorage + 'a> Iter<'a, S> {
179+
#[inline]
180+
fn get_unchecked_by_data_index_and_remainder(&self, data_index: usize, remainder: S) -> bool {
181+
let element = unsafe { *self.pointer.offset(data_index as isize) };
182+
(element & (S::one() << remainder)) != S::zero()
183+
}
184+
185+
#[inline]
186+
fn calculate_index(&self) -> usize {
187+
(self.data_index_counter * S::storage_size()) + self.remainder_counter
188+
}
189+
}
190+
122191
#[cfg(test)]
123192
mod tests {
124193
use super::super::{BitSlice,BitVector};
@@ -291,4 +360,87 @@ mod tests {
291360
let slice = create_bitslice_u8_16_from_bitvector_u8_32(&vec_8_32);
292361
slice.split_at(4);
293362
}
363+
364+
#[test]
365+
fn test_iter() {
366+
let mut vec_8_4 = BitVector::<u8>::with_capacity(4, false);
367+
vec_8_4.set(0, true);
368+
vec_8_4.set(3, true);
369+
370+
let (_, slice_8_4) = vec_8_4.split_at(0);
371+
let slice_8_4_iter_vec: Vec<_> = slice_8_4.iter().collect();
372+
assert_eq!(slice_8_4_iter_vec, [true, false, false, true]);
373+
374+
let mut vec_8_8 = BitVector::<u8>::with_capacity(8, false);
375+
vec_8_8.set(0, true);
376+
vec_8_8.set(3, true);
377+
vec_8_8.set(4, true);
378+
vec_8_8.set(6, true);
379+
380+
let (_, slice_8_8) = vec_8_8.split_at(0);
381+
let slice_8_8_iter_vec: Vec<_> = slice_8_8.iter().collect();
382+
assert_eq!(slice_8_8_iter_vec, [true, false, false, true, true, false, true, false]);
383+
384+
let mut vec_8_16 = BitVector::<u8>::with_capacity(16, false);
385+
vec_8_16.set(0, true);
386+
vec_8_16.set(3, true);
387+
vec_8_16.set(4, true);
388+
vec_8_16.set(6, true);
389+
vec_8_16.set(9, true);
390+
vec_8_16.set(10, true);
391+
vec_8_16.set(11, true);
392+
vec_8_16.set(13, true);
393+
394+
let (_, slice_8_16) = vec_8_16.split_at(0);
395+
let slice_8_16_iter_vec: Vec<_> = slice_8_16.iter().collect();
396+
assert_eq!(slice_8_16_iter_vec, [true, false, false, true, true, false, true, false, false, true, true, true, false, true, false, false]);
397+
398+
let (left, right) = vec_8_16.split_at(8);
399+
let vec_8_16_iter_vec: Vec<_> = vec_8_16.iter().collect();
400+
let left_plus_right_iter_vec: Vec<_> = left.iter().chain(right.iter()).collect();
401+
402+
assert_eq!(vec_8_16_iter_vec, left_plus_right_iter_vec);
403+
}
404+
405+
#[test]
406+
fn test_into_iter_on_reference() {
407+
let mut vec_8_4 = BitVector::<u8>::with_capacity(4, false);
408+
vec_8_4.set(0, true);
409+
vec_8_4.set(3, true);
410+
411+
let (_, slice_8_4) = vec_8_4.split_at(0);
412+
let slice_8_4_iter_vec: Vec<_> = (&slice_8_4).into_iter().collect();
413+
assert_eq!(slice_8_4_iter_vec, [true, false, false, true]);
414+
415+
let mut vec_8_8 = BitVector::<u8>::with_capacity(8, false);
416+
vec_8_8.set(0, true);
417+
vec_8_8.set(3, true);
418+
vec_8_8.set(4, true);
419+
vec_8_8.set(6, true);
420+
421+
let (_, slice_8_8) = vec_8_8.split_at(0);
422+
let slice_8_8_iter_vec: Vec<_> = (&slice_8_8).into_iter().collect();
423+
assert_eq!(slice_8_8_iter_vec, [true, false, false, true, true, false, true, false]);
424+
425+
let mut vec_8_16 = BitVector::<u8>::with_capacity(16, false);
426+
vec_8_16.set(0, true);
427+
vec_8_16.set(3, true);
428+
vec_8_16.set(4, true);
429+
vec_8_16.set(6, true);
430+
vec_8_16.set(9, true);
431+
vec_8_16.set(10, true);
432+
vec_8_16.set(11, true);
433+
vec_8_16.set(13, true);
434+
435+
let (_, slice_8_16) = vec_8_16.split_at(0);
436+
let slice_8_16_iter_vec: Vec<_> = (&slice_8_16).into_iter().collect();
437+
assert_eq!(slice_8_16_iter_vec, [true, false, false, true, true, false, true, false, false, true, true, true, false, true, false, false]);
438+
439+
let (left, right) = vec_8_16.split_at(8);
440+
let vec_8_16_iter_vec: Vec<_> = vec_8_16.iter().collect();
441+
let left_iter = (&left).into_iter();
442+
let left_plus_right_iter_vec: Vec<_> = left_iter.chain(&right).collect();
443+
444+
assert_eq!(vec_8_16_iter_vec, left_plus_right_iter_vec);
445+
}
294446
}

0 commit comments

Comments
 (0)