use super::*;
use crate::{
order::BitOrder,
store::BitStore,
};
use alloc::vec::Vec;
use core::{
iter::{
FromIterator,
FusedIterator,
},
ptr::NonNull,
};
impl<O, T> Extend<bool> for BitVec<O, T>
where O: BitOrder, T: BitStore {
fn extend<I: IntoIterator<Item=bool>>(&mut self, src: I) {
let iter = src.into_iter();
match iter.size_hint() {
(_, Some(hi)) => self.reserve(hi),
(lo, None) => self.reserve(lo),
}
iter.for_each(|b| self.push(b));
}
}
impl<O, T> FromIterator<bool> for BitVec<O, T>
where O: BitOrder, T: BitStore {
fn from_iter<I: IntoIterator<Item=bool>>(src: I) -> Self {
let iter = src.into_iter();
let mut bv = match iter.size_hint() {
| (_, Some(len))
| (len, _)
=> Self::with_capacity(len),
};
for bit in iter {
bv.push(bit);
}
bv
}
}
impl<O, T> IntoIterator for BitVec<O, T>
where O: BitOrder, T: BitStore {
type Item = bool;
type IntoIter = IntoIter<O, T>;
fn into_iter(self) -> Self::IntoIter {
IntoIter {
region: self.pointer,
bitvec: self,
}
}
}
impl<'a, O, T> IntoIterator for &'a BitVec<O, T>
where O: BitOrder, T: 'a + BitStore {
type Item = &'a bool;
type IntoIter = <&'a BitSlice<O, T> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
<&'a BitSlice<O, T> as IntoIterator>::into_iter(self)
}
}
pub struct Drain<'a, O, T>
where O: BitOrder, T: 'a + BitStore {
pub(super) bitvec: NonNull<BitVec<O, T>>,
pub(super) iter: crate::slice::iter::Iter<'a, O, T>,
pub(super) tail_start: usize,
pub(super) tail_len: usize,
}
impl<'a, O, T> Drain<'a, O, T>
where O: BitOrder, T: 'a + BitStore {
unsafe fn fill<I: Iterator<Item=bool>>(&mut self, stream: &mut I) -> bool {
let bv = self.bitvec.as_mut();
let drain_from = bv.len();
let drain_upto = self.tail_start;
for n in drain_from .. drain_upto {
if let Some(bit) = stream.next() {
bv.push(bit);
}
else {
for (to, from) in (n .. n + self.tail_len).zip(drain_upto ..) {
bv.swap(from, to);
}
self.tail_start = n;
return false;
}
}
true
}
unsafe fn move_tail(&mut self, by: usize) {
let bv = self.bitvec.as_mut();
bv.reserve(by);
let new_tail = self.tail_start + by;
let old_len = bv.len();
let new_len = self.tail_start + self.tail_len + by;
bv.set_len(new_len);
for n in (0 .. self.tail_len).rev() {
bv.swap(self.tail_start + n, new_tail + n);
}
bv.set_len(old_len);
self.tail_start = new_tail;
}
}
impl<'a, O, T> DoubleEndedIterator for Drain<'a, O, T>
where O: BitOrder, T: 'a + BitStore {
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.next_back().copied()
}
}
impl<'a, O, T> ExactSizeIterator for Drain<'a, O, T>
where O: BitOrder, T: 'a + BitStore {}
impl<'a, O, T> FusedIterator for Drain<'a, O, T>
where O: BitOrder, T: 'a + BitStore {}
impl<'a, O, T> Iterator for Drain<'a, O, T>
where O: BitOrder, T: 'a + BitStore {
type Item = bool;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().copied()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
fn count(self) -> usize {
self.len()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.iter.nth(n).copied()
}
fn last(mut self) -> Option<Self::Item> {
self.iter.next_back().copied()
}
}
impl<'a, O, T> Drop for Drain<'a, O, T>
where O: BitOrder, T: 'a + BitStore {
fn drop(&mut self) { unsafe {
let bv: &mut BitVec<O, T> = self.bitvec.as_mut();
let start = bv.len();
let tail = self.tail_start;
let tail_len = self.tail_len;
let full_len = tail + tail_len;
let end_len = start + tail_len;
bv.set_len(full_len);
for (from, to) in (tail .. full_len).zip(start .. end_len) {
bv.swap(from, to);
}
bv.set_len(end_len);
} }
}
#[repr(C)]
pub struct IntoIter<O, T>
where O: BitOrder, T: BitStore {
pub(super) bitvec: BitVec<O, T>,
pub(super) region: BitPtr<T>,
}
impl<O, T> IntoIter<O, T>
where O: BitOrder, T: BitStore {
fn iterator(&self) -> <&BitSlice<O, T> as IntoIterator>::IntoIter {
self.region.into_bitslice().into_iter()
}
}
impl<O, T> DoubleEndedIterator for IntoIter<O, T>
where O: BitOrder, T: BitStore {
fn next_back(&mut self) -> Option<Self::Item> {
let mut slice_iter = self.iterator();
let out = slice_iter.next_back().copied();
self.region = slice_iter.bitptr();
out
}
}
impl<O, T> ExactSizeIterator for IntoIter<O, T>
where O: BitOrder, T: BitStore {}
impl<O, T> FusedIterator for IntoIter<O, T>
where O: BitOrder, T: BitStore {}
impl<O, T> Iterator for IntoIter<O, T>
where O: BitOrder, T: BitStore {
type Item = bool;
fn next(&mut self) -> Option<Self::Item> {
let mut slice_iter = self.iterator();
let out = slice_iter.next().copied();
self.region = slice_iter.bitptr();
out
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iterator().size_hint()
}
fn count(self) -> usize {
self.bitvec.len()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let mut slice_iter = self.iterator();
let out = slice_iter.nth(n).copied();
self.region = slice_iter.bitptr();
out
}
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
}
pub struct Splice<'a, O, T, I>
where O: BitOrder, T: 'a + BitStore, I: Iterator<Item=bool> {
pub(super) drain: Drain<'a, O, T>,
pub(super) splice: I,
}
impl<'a, O, T, I> DoubleEndedIterator for Splice<'a, O, T, I>
where O: BitOrder, T: 'a + BitStore, I: Iterator<Item=bool> {
fn next_back(&mut self) -> Option<Self::Item> {
self.drain.next_back()
}
}
impl<'a, O, T, I> ExactSizeIterator for Splice<'a, O, T, I>
where O: BitOrder, T: 'a + BitStore, I: Iterator<Item=bool> {}
impl<'a, O, T, I> FusedIterator for Splice<'a, O, T, I>
where O: BitOrder, T: 'a + BitStore, I: Iterator<Item=bool> {}
impl<'a, O, T, I> Iterator for Splice<'a, O, T, I>
where O: BitOrder, T: 'a + BitStore, I: Iterator<Item=bool> {
type Item = bool;
fn next(&mut self) -> Option<Self::Item> {
self.drain.next().map(|bit| {
if let Some(new_bit) = self.splice.next() {
unsafe { self.drain.bitvec.as_mut() }.push(new_bit);
}
bit
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.drain.size_hint()
}
fn count(self) -> usize {
self.drain.len()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.drain.nth(n)
}
fn last(mut self) -> Option<Self::Item> {
self.drain.next_back()
}
}
impl<'a, O, T, I> Drop for Splice<'a, O, T, I>
where O: BitOrder, T: 'a + BitStore, I: Iterator<Item=bool> {
fn drop(&mut self) { unsafe {
if self.drain.tail_len == 0 {
self.drain.bitvec.as_mut().extend(self.splice.by_ref());
return;
}
if !self.drain.fill(&mut self.splice) {
return;
}
let (lower, _) = self.splice.size_hint();
if lower > 0 {
self.drain.move_tail(lower);
if !self.drain.fill(&mut self.splice) {
return;
}
}
let mut remnant = self.splice.by_ref().collect::<Vec<_>>().into_iter();
if remnant.len() > 0 {
self.drain.move_tail(remnant.len());
self.drain.fill(&mut remnant);
}
} }
}