#![doc = include_str!("../../doc/slice/iter.md")]
use core::{
cmp,
fmt::{
self,
Debug,
Formatter,
},
iter::{
FusedIterator,
Map,
},
marker::PhantomData,
mem,
};
use wyz::comu::{
Const,
Mut,
};
use super::{
BitSlice,
BitSliceIndex,
};
use crate::{
order::{
BitOrder,
Lsb0,
Msb0,
},
ptr::{
BitPtrRange,
BitRef,
},
store::BitStore,
};
#[cfg(not(tarpaulin_include))]
impl<'a, T, O> IntoIterator for &'a BitSlice<T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
type IntoIter = Iter<'a, T, O>;
type Item = <Self::IntoIter as Iterator>::Item;
#[inline]
fn into_iter(self) -> Self::IntoIter {
Iter::new(self)
}
}
#[cfg(not(tarpaulin_include))]
impl<'a, T, O> IntoIterator for &'a mut BitSlice<T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
type IntoIter = IterMut<'a, T, O>;
type Item = <Self::IntoIter as Iterator>::Item;
#[inline]
fn into_iter(self) -> Self::IntoIter {
IterMut::new(self)
}
}
#[repr(transparent)]
#[doc = include_str!("../../doc/slice/iter/Iter.md")]
pub struct Iter<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
range: BitPtrRange<Const, T, O>,
_ref: PhantomData<&'a BitSlice<T, O>>,
}
impl<'a, T, O> Iter<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
#[allow(missing_docs, clippy::missing_docs_in_private_items)]
pub(super) fn new(slice: &'a BitSlice<T, O>) -> Self {
Self {
range: slice.as_bitptr_range(),
_ref: PhantomData,
}
}
#[inline]
#[allow(missing_docs, clippy::missing_docs_in_private_items)]
pub fn as_bitslice(&self) -> &'a BitSlice<T, O> {
unsafe { self.range.clone().into_bitspan().into_bitslice_ref() }
}
#[inline]
#[cfg(not(tarpaulin_include))]
#[deprecated = "use `.as_bitslice()` instead"]
#[allow(missing_docs, clippy::missing_docs_in_private_items)]
pub fn as_slice(&self) -> &'a BitSlice<T, O> {
self.as_bitslice()
}
#[inline]
pub fn by_refs(self) -> BitRefIter<'a, T, O> {
self.by_vals().map(|bit| match bit {
true => &true,
false => &false,
})
}
#[inline]
pub fn by_vals(self) -> BitValIter<'a, T, O> {
BitValIter {
range: self.range,
_life: PhantomData,
}
}
#[inline]
#[cfg(not(tarpaulin_include))]
#[deprecated = "`Iterator::copied` does not exist on this type. Use \
`.by_vals()` instead"]
pub fn copied(self) -> BitValIter<'a, T, O> {
self.by_vals()
}
}
#[cfg(not(tarpaulin_include))]
impl<T, O> Clone for Iter<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
#[inline]
fn clone(&self) -> Self {
Self {
range: self.range.clone(),
..*self
}
}
}
#[cfg(not(tarpaulin_include))]
impl<T, O> AsRef<BitSlice<T, O>> for Iter<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
#[inline]
fn as_ref(&self) -> &BitSlice<T, O> {
self.as_bitslice()
}
}
#[cfg(not(tarpaulin_include))]
impl<T, O> Debug for Iter<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
fmt.debug_tuple("Iter").field(&self.as_bitslice()).finish()
}
}
#[repr(transparent)]
#[doc = include_str!("../../doc/slice/iter/IterMut.md")]
pub struct IterMut<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
range: BitPtrRange<Mut, T::Alias, O>,
_ref: PhantomData<&'a mut BitSlice<T::Alias, O>>,
}
impl<'a, T, O> IterMut<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
#[allow(missing_docs, clippy::missing_docs_in_private_items)]
pub(super) fn new(slice: &'a mut BitSlice<T, O>) -> Self {
Self {
range: slice.alias_mut().as_mut_bitptr_range(),
_ref: PhantomData,
}
}
#[inline]
#[cfg(not(tarpaulin_include))]
pub fn into_bitslice(self) -> &'a mut BitSlice<T::Alias, O> {
unsafe { self.range.into_bitspan().into_bitslice_mut() }
}
#[inline]
#[cfg(not(tarpaulin_include))]
#[deprecated = "use `.into_bitslice()` instead"]
#[allow(missing_docs, clippy::missing_docs_in_private_items)]
pub fn into_slice(self) -> &'a mut BitSlice<T::Alias, O> {
self.into_bitslice()
}
#[inline]
#[cfg(not(tarpaulin_include))]
pub fn as_bitslice(&self) -> &BitSlice<T::Alias, O> {
unsafe { self.range.clone().into_bitspan().into_bitslice_ref() }
}
#[inline]
#[cfg(not(tarpaulin_include))]
#[deprecated = "use `.as_bitslice()` instead"]
#[allow(missing_docs, clippy::missing_docs_in_private_items)]
pub fn as_slice(&self) -> &BitSlice<T::Alias, O> {
self.as_bitslice()
}
}
#[cfg(not(tarpaulin_include))]
impl<T, O> AsRef<BitSlice<T::Alias, O>> for IterMut<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
#[inline]
fn as_ref(&self) -> &BitSlice<T::Alias, O> {
self.as_bitslice()
}
}
#[cfg(not(tarpaulin_include))]
impl<T, O> Debug for IterMut<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
fmt.debug_tuple("IterMut")
.field(&self.as_bitslice())
.finish()
}
}
macro_rules! iter {
($($iter:ident => $item:ty);+ $(;)?) => { $(
impl<'a, T, O> Iterator for $iter<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
type Item = $item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.range.next().map(|bp| unsafe { BitRef::from_bitptr(bp) })
}
#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.range.nth(n).map(|bp| unsafe { BitRef::from_bitptr(bp) })
}
easy_iter!();
}
impl<'a, T, O> DoubleEndedIterator for $iter<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.range
.next_back()
.map(|bp| unsafe { BitRef::from_bitptr(bp) })
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.range
.nth_back(n)
.map(|bp| unsafe { BitRef::from_bitptr(bp) })
}
}
impl<T, O> ExactSizeIterator for $iter<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
#[inline]
fn len(&self) -> usize {
self.range.len()
}
}
impl<T, O> FusedIterator for $iter<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
}
unsafe impl<'a, T, O> Send for $iter<'a, T, O>
where
T: BitStore,
O: BitOrder,
&'a mut BitSlice<T, O>: Send,
{
}
unsafe impl<T, O> Sync for $iter<'_, T, O>
where
T: BitStore,
O: BitOrder,
BitSlice<T, O>: Sync,
{
}
)+ };
}
iter! {
Iter => <usize as BitSliceIndex<'a, T, O>>::Immut;
IterMut => <usize as BitSliceIndex<'a, T::Alias, O>>::Mut;
}
macro_rules! group {
($iter:ident => $item:ty {
$next:item
$nth:item
$next_back:item
$nth_back:item
$len:item
}) => {
impl<'a, T, O> Iterator for $iter<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
type Item = $item;
#[inline]
$next
#[inline]
$nth
easy_iter!();
}
impl<T, O> DoubleEndedIterator for $iter<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
#[inline]
$next_back
#[inline]
$nth_back
}
impl<T, O> ExactSizeIterator for $iter<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
#[inline]
$len
}
impl<T, O> FusedIterator for $iter<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
}
};
}
pub type BitRefIter<'a, T, O> = Map<BitValIter<'a, T, O>, fn(bool) -> &'a bool>;
pub struct BitValIter<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
range: BitPtrRange<Const, T, O>,
_life: PhantomData<&'a BitSlice<T, O>>,
}
group!(BitValIter => bool {
fn next(&mut self) -> Option<Self::Item> {
self.range.next().map(|bp| unsafe { bp.read() })
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.range.nth(n).map(|bp| unsafe { bp.read() })
}
fn next_back(&mut self) -> Option<Self::Item> {
self.range.next_back().map(|bp| unsafe { bp.read() })
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.range.nth_back(n).map(|bp| unsafe { bp.read() })
}
fn len(&self) -> usize {
self.range.len()
}
});
#[derive(Clone, Debug)]
#[doc = include_str!("../../doc/slice/iter/Windows.md")]
pub struct Windows<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
slice: &'a BitSlice<T, O>,
width: usize,
}
group!(Windows => &'a BitSlice<T, O> {
fn next(&mut self) -> Option<Self::Item> {
if self.width > self.slice.len() {
self.slice = Default::default();
return None;
}
unsafe {
let out = self.slice.get_unchecked(.. self.width);
self.slice = self.slice.get_unchecked(1 ..);
Some(out)
}
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, ovf) = self.width.overflowing_add(n);
if end > self.slice.len() || ovf {
self.slice = Default::default();
return None;
}
unsafe {
let out = self.slice.get_unchecked(n .. end);
self.slice = self.slice.get_unchecked(n + 1 ..);
Some(out)
}
}
fn next_back(&mut self) -> Option<Self::Item> {
let len = self.slice.len();
if self.width > len {
self.slice = Default::default();
return None;
}
unsafe {
let out = self.slice.get_unchecked(len - self.width ..);
self.slice = self.slice.get_unchecked(.. len - 1);
Some(out)
}
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, ovf) = self.slice.len().overflowing_sub(n);
if end < self.width || ovf {
self.slice = Default::default();
return None;
}
unsafe {
let out = self.slice.get_unchecked(end - self.width .. end);
self.slice = self.slice.get_unchecked(.. end - 1);
Some(out)
}
}
fn len(&self) -> usize {
let len = self.slice.len();
if self.width > len {
0
}
else {
len - self.width + 1
}
}
});
#[derive(Clone, Debug)]
#[doc = include_str!("../../doc/slice/iter/Chunks.md")]
pub struct Chunks<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
slice: &'a BitSlice<T, O>,
width: usize,
}
group!(Chunks => &'a BitSlice<T, O> {
fn next(&mut self) -> Option<Self::Item> {
let len = self.slice.len();
if len == 0 {
return None;
}
let mid = cmp::min(len, self.width);
let (out, rest) = unsafe { self.slice.split_at_unchecked(mid) };
self.slice = rest;
Some(out)
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let len = self.slice.len();
let (start, ovf) = n.overflowing_mul(self.width);
if start >= len || ovf {
self.slice = Default::default();
return None;
}
let split = start.checked_add(self.width)
.map(|mid| cmp::min(mid, len))
.unwrap_or(len);
unsafe {
let (head, rest) = self.slice.split_at_unchecked(split);
self.slice = rest;
Some(head.get_unchecked(start ..))
}
}
fn next_back(&mut self) -> Option<Self::Item> {
match self.slice.len() {
0 => None,
len => {
let rem = len % self.width;
let size = if rem == 0 { self.width } else { rem };
let (rest, out)
= unsafe { self.slice.split_at_unchecked(len - size) };
self.slice = rest;
Some(out)
},
}
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let len = self.len();
if n >= len {
self.slice = Default::default();
return None;
}
let start = (len - 1 - n) * self.width;
let width = cmp::min(start + self.width, self.slice.len());
let (rest, out) = unsafe {
self.slice
.get_unchecked(.. start + width)
.split_at_unchecked(start)
};
self.slice = rest;
Some(out)
}
fn len(&self) -> usize {
match self.slice.len() {
0 => 0,
len => {
let (n, r) = (len / self.width, len % self.width);
n + (r > 0) as usize
},
}
}
});
#[derive(Debug)]
#[doc = include_str!("../../doc/slice/iter/ChunksMut.md")]
pub struct ChunksMut<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
slice: &'a mut BitSlice<T::Alias, O>,
width: usize,
}
group!(ChunksMut => &'a mut BitSlice<T::Alias, O> {
fn next(&mut self) -> Option<Self::Item> {
let slice = mem::take(&mut self.slice);
let len = slice.len();
if len == 0 {
return None;
}
let mid = cmp::min(len, self.width);
let (out, rest) = unsafe { slice.split_at_unchecked_mut_noalias(mid) };
self.slice = rest;
Some(out)
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let slice = mem::take(&mut self.slice);
let len = slice.len();
let (start, ovf) = n.overflowing_mul(self.width);
if start >= len || ovf {
return None;
}
let (out, rest) = unsafe {
slice
.get_unchecked_mut(start ..)
.split_at_unchecked_mut_noalias(cmp::min(len - start, self.width))
};
self.slice = rest;
Some(out)
}
fn next_back(&mut self) -> Option<Self::Item> {
let slice = mem::take(&mut self.slice);
match slice.len() {
0 => None,
len => {
let rem = len % self.width;
let size = if rem == 0 { self.width } else { rem };
let mid = len - size;
let (rest, out)
= unsafe { slice.split_at_unchecked_mut_noalias(mid) };
self.slice = rest;
Some(out)
},
}
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let len = self.len();
let slice = mem::take(&mut self.slice);
if n >= len {
return None;
}
let start = (len - 1 - n) * self.width;
let width = cmp::min(start + self.width, slice.len());
let (rest, out) = unsafe {
slice
.get_unchecked_mut(.. start + width)
.split_at_unchecked_mut_noalias(start)
};
self.slice = rest;
Some(out)
}
fn len(&self) -> usize {
match self.slice.len() {
0 => 0,
len => {
let (n, r) = (len / self.width, len % self.width);
n + (r > 0) as usize
},
}
}
});
#[derive(Clone, Debug)]
#[doc = include_str!("../../doc/slice/iter/ChunksExact.md")]
pub struct ChunksExact<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
slice: &'a BitSlice<T, O>,
extra: &'a BitSlice<T, O>,
width: usize,
}
impl<'a, T, O> ChunksExact<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
#[allow(missing_docs, clippy::missing_docs_in_private_items)]
pub(super) fn new(slice: &'a BitSlice<T, O>, width: usize) -> Self {
assert_ne!(width, 0, "Chunk width cannot be 0");
let len = slice.len();
let rem = len % width;
let (slice, extra) = unsafe { slice.split_at_unchecked(len - rem) };
Self {
slice,
extra,
width,
}
}
#[inline]
#[cfg(not(tarpaulin_include))]
pub fn remainder(&self) -> &'a BitSlice<T, O> {
self.extra
}
}
group!(ChunksExact => &'a BitSlice<T, O> {
fn next(&mut self) -> Option<Self::Item> {
if self.slice.len() < self.width {
return None;
}
let (out, rest) = unsafe { self.slice.split_at_unchecked(self.width) };
self.slice = rest;
Some(out)
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (start, ovf) = n.overflowing_mul(self.width);
if start >= self.slice.len() || ovf {
self.slice = Default::default();
return None;
}
let (out, rest) = unsafe {
self.slice
.get_unchecked(start ..)
.split_at_unchecked(self.width)
};
self.slice = rest;
Some(out)
}
fn next_back(&mut self) -> Option<Self::Item> {
let len = self.slice.len();
if len < self.width {
return None;
}
let (rest, out) =
unsafe { self.slice.split_at_unchecked(len - self.width) };
self.slice = rest;
Some(out)
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let len = self.len();
if n >= len {
self.slice = Default::default();
return None;
}
let end = (len - n) * self.width;
let (rest, out) = unsafe {
self.slice
.get_unchecked(.. end)
.split_at_unchecked(end - self.width)
};
self.slice = rest;
Some(out)
}
fn len(&self) -> usize {
self.slice.len() / self.width
}
});
#[derive(Debug)]
#[doc = include_str!("../../doc/slice/iter/ChunksExactMut.md")]
pub struct ChunksExactMut<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
slice: &'a mut BitSlice<T::Alias, O>,
extra: &'a mut BitSlice<T::Alias, O>,
width: usize,
}
impl<'a, T, O> ChunksExactMut<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
#[allow(missing_docs, clippy::missing_docs_in_private_items)]
pub(super) fn new(slice: &'a mut BitSlice<T, O>, width: usize) -> Self {
assert_ne!(width, 0, "Chunk width cannot be 0");
let len = slice.len();
let rem = len % width;
let (slice, extra) = unsafe { slice.split_at_unchecked_mut(len - rem) };
Self {
slice,
extra,
width,
}
}
#[inline]
#[cfg(not(tarpaulin_include))]
pub fn into_remainder(self) -> &'a mut BitSlice<T::Alias, O> {
self.extra
}
#[inline]
pub fn take_remainder(&mut self) -> &'a mut BitSlice<T::Alias, O> {
mem::take(&mut self.extra)
}
}
group!(ChunksExactMut => &'a mut BitSlice<T::Alias, O> {
fn next(&mut self) -> Option<Self::Item> {
let slice = mem::take(&mut self.slice);
if slice.len() < self.width {
return None;
}
let (out, rest) =
unsafe { slice.split_at_unchecked_mut_noalias(self.width) };
self.slice = rest;
Some(out)
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let slice = mem::take(&mut self.slice);
let (start, ovf) = n.overflowing_mul(self.width);
if start + self.width >= slice.len() || ovf {
return None;
}
let (out, rest) = unsafe {
slice.get_unchecked_mut(start ..)
.split_at_unchecked_mut_noalias(self.width)
};
self.slice = rest;
Some(out)
}
fn next_back(&mut self) -> Option<Self::Item> {
let slice = mem::take(&mut self.slice);
let len = slice.len();
if len < self.width {
return None;
}
let (rest, out) =
unsafe { slice.split_at_unchecked_mut_noalias(len - self.width) };
self.slice = rest;
Some(out)
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let len = self.len();
let slice = mem::take(&mut self.slice);
if n >= len {
return None;
}
let end = (len - n) * self.width;
let (rest, out) = unsafe {
slice.get_unchecked_mut(.. end)
.split_at_unchecked_mut_noalias(end - self.width)
};
self.slice = rest;
Some(out)
}
fn len(&self) -> usize {
self.slice.len() / self.width
}
});
#[derive(Clone, Debug)]
#[doc = include_str!("../../doc/slice/iter/RChunks.md")]
pub struct RChunks<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
slice: &'a BitSlice<T, O>,
width: usize,
}
group!(RChunks => &'a BitSlice<T, O> {
fn next(&mut self) -> Option<Self::Item> {
let len = self.slice.len();
if len == 0 {
return None;
}
let mid = len - cmp::min(len, self.width);
let (rest, out) = unsafe { self.slice.split_at_unchecked(mid) };
self.slice = rest;
Some(out)
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let len = self.slice.len();
let (num, ovf) = n.overflowing_mul(self.width);
if num >= len || ovf {
self.slice = Default::default();
return None;
}
let end = len - num;
let mid = end.saturating_sub(self.width);
let (rest, out) = unsafe {
self.slice
.get_unchecked(.. end)
.split_at_unchecked(mid)
};
self.slice = rest;
Some(out)
}
fn next_back(&mut self) -> Option<Self::Item> {
match self.slice.len() {
0 => None,
n => {
let rem = n % self.width;
let len = if rem == 0 { self.width } else { rem };
let (out, rest) = unsafe { self.slice.split_at_unchecked(len) };
self.slice = rest;
Some(out)
},
}
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let len = self.len();
if n >= len {
self.slice = Default::default();
return None;
}
let from_end = (len - 1 - n) * self.width;
let end = self.slice.len() - from_end;
let start = end.saturating_sub(self.width);
let (out, rest) = unsafe { self.slice.split_at_unchecked(end) };
self.slice = rest;
Some(unsafe { out.get_unchecked(start ..) })
}
fn len(&self) -> usize {
match self.slice.len() {
0 => 0,
len => {
let (n, r) = (len / self.width, len % self.width);
n + (r > 0) as usize
},
}
}
});
#[derive(Debug)]
#[doc = include_str!("../../doc/slice/iter/RChunksMut.md")]
pub struct RChunksMut<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
slice: &'a mut BitSlice<T::Alias, O>,
width: usize,
}
group!(RChunksMut => &'a mut BitSlice<T::Alias, O> {
fn next(&mut self) -> Option<Self::Item> {
let slice = mem::take(&mut self.slice);
let len = slice.len();
if len == 0 {
return None;
}
let mid = len - cmp::min(len, self.width);
let (rest, out) = unsafe { slice.split_at_unchecked_mut_noalias(mid) };
self.slice = rest;
Some(out)
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let slice = mem::take(&mut self.slice);
let len = slice.len();
let (num, ovf) = n.overflowing_mul(self.width);
if num >= len || ovf {
return None;
}
let end = len - num;
let mid = end.saturating_sub(self.width);
let (rest, out) = unsafe {
slice.get_unchecked_mut(.. end)
.split_at_unchecked_mut_noalias(mid)
};
self.slice = rest;
Some(out)
}
fn next_back(&mut self) -> Option<Self::Item> {
let slice = mem::take(&mut self.slice);
match slice.len() {
0 => None,
n => {
let rem = n % self.width;
let len = if rem == 0 { self.width } else { rem };
let (out, rest) =
unsafe { slice.split_at_unchecked_mut_noalias(len) };
self.slice = rest;
Some(out)
},
}
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let len = self.len();
let slice = mem::take(&mut self.slice);
if n >= len {
return None;
}
let from_end = (len - 1 - n) * self.width;
let end = slice.len() - from_end;
let start = end.saturating_sub(self.width);
let (out, rest) = unsafe { slice.split_at_unchecked_mut_noalias(end) };
self.slice = rest;
Some(unsafe { out.get_unchecked_mut(start ..) })
}
fn len(&self) -> usize {
match self.slice.len() {
0 => 0,
len => {
let (n, r) = (len / self.width, len % self.width);
n + (r > 0) as usize
},
}
}
});
#[derive(Clone, Debug)]
#[doc = include_str!("../../doc/slice/iter/RChunksExact.md")]
pub struct RChunksExact<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
slice: &'a BitSlice<T, O>,
extra: &'a BitSlice<T, O>,
width: usize,
}
impl<'a, T, O> RChunksExact<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
#[allow(missing_docs, clippy::missing_docs_in_private_items)]
pub(super) fn new(slice: &'a BitSlice<T, O>, width: usize) -> Self {
assert_ne!(width, 0, "Chunk width cannot be 0");
let (extra, slice) =
unsafe { slice.split_at_unchecked(slice.len() % width) };
Self {
slice,
extra,
width,
}
}
#[inline]
#[cfg(not(tarpaulin_include))]
pub fn remainder(&self) -> &'a BitSlice<T, O> {
self.extra
}
}
group!(RChunksExact => &'a BitSlice<T, O> {
fn next(&mut self) -> Option<Self::Item> {
let len = self.slice.len();
if len < self.width {
return None;
}
let (rest, out) =
unsafe { self.slice.split_at_unchecked(len - self.width) };
self.slice = rest;
Some(out)
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let len = self.slice.len();
let (split, ovf) = n.overflowing_mul(self.width);
if split >= len || ovf {
self.slice = Default::default();
return None;
}
let end = len - split;
let (rest, out) = unsafe {
self.slice
.get_unchecked(.. end)
.split_at_unchecked(end - self.width)
};
self.slice = rest;
Some(out)
}
fn next_back(&mut self) -> Option<Self::Item> {
if self.slice.len() < self.width {
return None;
}
let (out, rest) = unsafe { self.slice.split_at_unchecked(self.width) };
self.slice = rest;
Some(out)
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let len = self.slice.len();
let (start, ovf) = n.overflowing_mul(self.width);
if start >= len || ovf {
self.slice = Default::default();
return None;
}
let (out, rest) = unsafe {
self.slice.get_unchecked(start ..).split_at_unchecked(self.width)
};
self.slice = rest;
Some(out)
}
fn len(&self) -> usize {
self.slice.len() / self.width
}
});
#[derive(Debug)]
#[doc = include_str!("../../doc/slice/iter/RChunksExactMut.md")]
pub struct RChunksExactMut<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
slice: &'a mut BitSlice<T::Alias, O>,
extra: &'a mut BitSlice<T::Alias, O>,
width: usize,
}
impl<'a, T, O> RChunksExactMut<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
#[allow(missing_docs, clippy::missing_docs_in_private_items)]
pub(super) fn new(slice: &'a mut BitSlice<T, O>, width: usize) -> Self {
assert_ne!(width, 0, "Chunk width cannot be 0");
let (extra, slice) =
unsafe { slice.split_at_unchecked_mut(slice.len() % width) };
Self {
slice,
extra,
width,
}
}
#[inline]
#[cfg(not(tarpaulin_include))]
pub fn into_remainder(self) -> &'a mut BitSlice<T::Alias, O> {
self.extra
}
#[inline]
pub fn take_remainder(&mut self) -> &'a mut BitSlice<T::Alias, O> {
mem::take(&mut self.extra)
}
}
group!(RChunksExactMut => &'a mut BitSlice<T::Alias, O> {
fn next(&mut self) -> Option<Self::Item> {
let slice = mem::take(&mut self.slice);
let len = slice.len();
if len < self.width {
return None;
}
let (rest, out) =
unsafe { slice.split_at_unchecked_mut_noalias(len - self.width) };
self.slice = rest;
Some(out)
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let slice = mem::take(&mut self.slice);
let len = slice.len();
let (split, ovf) = n.overflowing_mul(self.width);
if split >= len || ovf {
return None;
}
let end = len - split;
let (rest, out) = unsafe {
slice.get_unchecked_mut(.. end)
.split_at_unchecked_mut_noalias(end - self.width)
};
self.slice = rest;
Some(out)
}
fn next_back(&mut self) -> Option<Self::Item> {
let slice = mem::take(&mut self.slice);
if slice.len() < self.width {
return None;
}
let (out, rest) =
unsafe { slice.split_at_unchecked_mut_noalias(self.width) };
self.slice = rest;
Some(out)
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let slice = mem::take(&mut self.slice);
let len = slice.len();
let (start, ovf) = n.overflowing_mul(self.width);
if start >= len || ovf {
return None;
}
let (out, rest) = unsafe {
slice.get_unchecked_mut(start ..)
.split_at_unchecked_mut_noalias(self.width)
};
self.slice = rest;
Some(out)
}
fn len(&self) -> usize {
self.slice.len() / self.width
}
});
macro_rules! new_group {
($($t:ident $($m:ident)? $(.$a:ident())?),+ $(,)?) => { $(
impl<'a, T, O> $t<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
#[inline]
#[allow(missing_docs, clippy::missing_docs_in_private_items)]
pub(super) fn new(
slice: &'a $($m)? BitSlice<T, O>,
width: usize,
) -> Self {
assert_ne!(width, 0, "view width cannot be 0");
let slice = slice$(.$a())?;
Self { slice, width }
}
}
)+ };
}
new_group! {
Windows,
Chunks,
ChunksMut mut .alias_mut(),
RChunks,
RChunksMut mut .alias_mut(),
}
macro_rules! split {
(
$iter:ident =>
$item:ty
$(where $alias:ident)? { $next:item $next_back:item }
) => {
impl<'a, T, O, P> $iter<'a, T, O, P>
where
T: 'a + BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
{
pub(super) fn new(slice: $item, pred: P) -> Self {
Self {
slice,
pred,
done: false,
}
}
}
impl<T, O, P> Debug for $iter<'_, T, O, P>
where
T: BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
fmt.debug_struct(stringify!($iter))
.field("slice", &self.slice)
.field("done", &self.done)
.finish()
}
}
impl<'a, T, O, P> Iterator for $iter<'a, T, O, P>
where
T: 'a + BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
{
type Item = $item;
#[inline]
$next
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
if self.done {
(0, Some(0))
}
else {
(1, Some(self.slice.len() + 1))
}
}
}
impl<'a, T, O, P> DoubleEndedIterator for $iter<'a, T, O, P>
where
T: 'a + BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
{
#[inline]
$next_back
}
impl<'a, T, O, P> FusedIterator for $iter<'a, T, O, P>
where
T: 'a + BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
{
}
impl<'a, T, O, P> SplitIter for $iter<'a, T, O, P>
where
T: 'a + BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
{
#[inline]
fn finish(&mut self) -> Option<Self::Item> {
if self.done {
None
}
else {
self.done = true;
Some(mem::take(&mut self.slice))
}
}
}
};
}
#[derive(Clone)]
#[doc = include_str!("../../doc/slice/iter/Split.md")]
pub struct Split<'a, T, O, P>
where
T: 'a + BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
{
slice: &'a BitSlice<T, O>,
pred: P,
done: bool,
}
split!(Split => &'a BitSlice<T, O> {
fn next(&mut self) -> Option<Self::Item> {
if self.done {
return None;
}
match self.slice
.iter()
.by_refs()
.enumerate()
.position(|(idx, bit)| (self.pred)(idx, bit))
{
None => self.finish(),
Some(idx) => unsafe {
let out = self.slice.get_unchecked(.. idx);
self.slice = self.slice.get_unchecked(idx + 1 ..);
Some(out)
},
}
}
fn next_back(&mut self) -> Option<Self::Item> {
if self.done {
return None;
}
match self.slice
.iter()
.by_refs()
.enumerate()
.rposition(|(idx, bit)| (self.pred)(idx, bit))
{
None => self.finish(),
Some(idx) => unsafe {
let out = self.slice.get_unchecked(idx + 1 ..);
self.slice = self.slice.get_unchecked(.. idx);
Some(out)
},
}
}
});
#[doc = include_str!("../../doc/slice/iter/SplitMut.md")]
pub struct SplitMut<'a, T, O, P>
where
T: 'a + BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
{
slice: &'a mut BitSlice<T::Alias, O>,
pred: P,
done: bool,
}
split!(SplitMut => &'a mut BitSlice<T::Alias, O> {
fn next(&mut self) -> Option<Self::Item> {
if self.done {
return None;
}
let idx_opt = {
let pred = &mut self.pred;
self.slice
.iter()
.by_refs()
.enumerate()
.position(|(idx, bit)| (pred)(idx, bit))
};
match idx_opt
{
None => self.finish(),
Some(idx) => unsafe {
let slice = mem::take(&mut self.slice);
let (out, rest) = slice.split_at_unchecked_mut_noalias(idx);
self.slice = rest.get_unchecked_mut(1 ..);
Some(out)
},
}
}
fn next_back(&mut self) -> Option<Self::Item> {
if self.done {
return None;
}
let idx_opt = {
let pred = &mut self.pred;
self.slice
.iter()
.by_refs()
.enumerate()
.rposition(|(idx, bit)| (pred)(idx, bit))
};
match idx_opt
{
None => self.finish(),
Some(idx) => unsafe {
let slice = mem::take(&mut self.slice);
let (rest, out) = slice.split_at_unchecked_mut_noalias(idx);
self.slice = rest;
Some(out.get_unchecked_mut(1 ..))
},
}
}
});
#[derive(Clone)]
#[doc = include_str!("../../doc/slice/iter/SplitInclusive.md")]
pub struct SplitInclusive<'a, T, O, P>
where
T: 'a + BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
{
slice: &'a BitSlice<T, O>,
pred: P,
done: bool,
}
split!(SplitInclusive => &'a BitSlice<T, O> {
fn next(&mut self) -> Option<Self::Item> {
if self.done {
return None;
}
let len = self.slice.len();
let idx = self.slice.iter()
.by_refs()
.enumerate()
.position(|(idx, bit)| (self.pred)(idx, bit))
.map(|idx| idx + 1)
.unwrap_or(len);
if idx == len {
self.done = true;
}
let (out, rest) = unsafe { self.slice.split_at_unchecked(idx) };
self.slice = rest;
Some(out)
}
fn next_back(&mut self) -> Option<Self::Item> {
if self.done {
return None;
}
let idx = if self.slice.is_empty() {
0
}
else {
unsafe { self.slice.get_unchecked(.. self.slice.len() - 1) }
.iter()
.by_refs()
.enumerate()
.rposition(|(idx, bit)| (self.pred)(idx, bit))
.map(|idx| idx + 1)
.unwrap_or(0)
};
if idx == 0 {
self.done = true;
}
let (rest, out) = unsafe { self.slice.split_at_unchecked(idx) };
self.slice = rest;
Some(out)
}
});
#[doc = include_str!("../../doc/slice/iter/SplitInclusiveMut.md")]
pub struct SplitInclusiveMut<'a, T, O, P>
where
T: 'a + BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
{
slice: &'a mut BitSlice<T::Alias, O>,
pred: P,
done: bool,
}
split!(SplitInclusiveMut => &'a mut BitSlice<T::Alias, O> {
fn next(&mut self) -> Option<Self::Item> {
if self.done {
return None;
}
let pred = &mut self.pred;
let len = self.slice.len();
let idx = self.slice.iter()
.by_refs()
.enumerate()
.position(|(idx, bit)| (pred)(idx, bit))
.map(|idx| idx + 1)
.unwrap_or(len);
if idx == len {
self.done = true;
}
let (out, rest) = unsafe {
mem::take(&mut self.slice)
.split_at_unchecked_mut_noalias(idx)
};
self.slice = rest;
Some(out)
}
fn next_back(&mut self) -> Option<Self::Item> {
if self.done {
return None;
}
let pred = &mut self.pred;
let idx = if self.slice.is_empty() {
0
}
else {
unsafe { self.slice.get_unchecked(.. self.slice.len() - 1) }
.iter()
.by_refs()
.enumerate()
.rposition(|(idx, bit)| (pred)(idx, bit))
.map(|idx| idx + 1)
.unwrap_or(0)
};
if idx == 0 {
self.done = true;
}
let (rest, out) = unsafe {
mem::take(&mut self.slice)
.split_at_unchecked_mut_noalias(idx)
};
self.slice = rest;
Some(out)
}
});
#[derive(Clone)]
#[doc = include_str!("../../doc/slice/iter/RSplit.md")]
pub struct RSplit<'a, T, O, P>
where
T: 'a + BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
{
slice: &'a BitSlice<T, O>,
pred: P,
done: bool,
}
split!(RSplit => &'a BitSlice<T, O> {
fn next(&mut self) -> Option<Self::Item> {
let mut split = Split::<'a, T, O, &mut P> {
slice: mem::take(&mut self.slice),
pred: &mut self.pred,
done: self.done,
};
let out = split.next_back();
let Split { slice, done, .. } = split;
self.slice = slice;
self.done = done;
out
}
fn next_back(&mut self) -> Option<Self::Item> {
let mut split = Split::<'a, T, O, &mut P> {
slice: mem::take(&mut self.slice),
pred: &mut self.pred,
done: self.done,
};
let out = split.next();
let Split { slice, done, .. } = split;
self.slice = slice;
self.done = done;
out
}
});
#[doc = include_str!("../../doc/slice/iter/RSplitMut.md")]
pub struct RSplitMut<'a, T, O, P>
where
T: 'a + BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
{
slice: &'a mut BitSlice<T::Alias, O>,
pred: P,
done: bool,
}
split!(RSplitMut => &'a mut BitSlice<T::Alias, O> {
fn next(&mut self) -> Option<Self::Item> {
let mut split = SplitMut::<'a, T, O, &mut P> {
slice: mem::take(&mut self.slice),
pred: &mut self.pred,
done: self.done,
};
let out = split.next_back();
let SplitMut { slice, done, .. } = split;
self.slice = slice;
self.done = done;
out
}
fn next_back(&mut self) -> Option<Self::Item> {
let mut split = SplitMut::<'a, T, O, &mut P> {
slice: mem::take(&mut self.slice),
pred: &mut self.pred,
done: self.done,
};
let out = split.next();
let SplitMut { slice, done, .. } = split;
self.slice = slice;
self.done = done;
out
}
});
trait SplitIter: DoubleEndedIterator {
fn finish(&mut self) -> Option<Self::Item>;
}
#[derive(Clone)]
#[doc = include_str!("../../doc/slice/iter/SplitN.md")]
pub struct SplitN<'a, T, O, P>
where
T: 'a + BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
{
inner: Split<'a, T, O, P>,
count: usize,
}
#[doc = include_str!("../../doc/slice/iter/SplitNMut.md")]
pub struct SplitNMut<'a, T, O, P>
where
T: 'a + BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
{
inner: SplitMut<'a, T, O, P>,
count: usize,
}
#[derive(Clone)]
#[doc = include_str!("../../doc/slice/iter/RSplitN.md")]
pub struct RSplitN<'a, T, O, P>
where
T: 'a + BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
{
inner: RSplit<'a, T, O, P>,
count: usize,
}
#[doc = include_str!("../../doc/slice/iter/RSplitNMut.md")]
pub struct RSplitNMut<'a, T, O, P>
where
T: 'a + BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
{
inner: RSplitMut<'a, T, O, P>,
count: usize,
}
macro_rules! split_n {
($(
$outer:ident => $inner:ident => $item:ty $(where $alias:ident)?
);+ $(;)?) => { $(
impl<'a, T, O, P> $outer<'a, T, O, P>
where
T: 'a + BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
{
#[inline]
#[allow(missing_docs, clippy::missing_docs_in_private_items)]
pub(super) fn new(
slice: $item,
pred: P,
count: usize,
) -> Self {
Self {
inner: <$inner<'a, T, O, P>>::new(slice, pred),
count,
}
}
}
impl<T, O, P> Debug for $outer<'_, T, O, P>
where
T: BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
fmt.debug_struct(stringify!($outer))
.field("slice", &self.inner.slice)
.field("count", &self.count)
.finish()
}
}
impl<'a, T, O, P> Iterator for $outer<'a, T, O, P>
where
T: 'a + BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
$( T::$alias: radium::Radium<<<T as BitStore>::Alias as BitStore>::Mem>, )?
{
type Item = <$inner <'a, T, O, P> as Iterator>::Item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
match self.count {
0 => None,
1 => {
self.count -= 1;
self.inner.finish()
},
_ => {
self.count -= 1;
self.inner.next()
},
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (low, hi) = self.inner.size_hint();
(low, hi.map(|h| cmp::min(h, self.count)).or(Some(self.count)))
}
}
impl<T, O, P> FusedIterator for $outer<'_, T, O, P>
where
T: BitStore,
O: BitOrder,
P: FnMut(usize, &bool) -> bool,
$( T::$alias: radium::Radium<<<T as BitStore>::Alias as BitStore>::Mem>, )?
{
}
)+ };
}
split_n! {
SplitN => Split => &'a BitSlice<T, O>;
SplitNMut => SplitMut => &'a mut BitSlice<T::Alias, O>;
RSplitN => RSplit => &'a BitSlice<T, O>;
RSplitNMut => RSplitMut => &'a mut BitSlice<T::Alias, O>;
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
#[doc = include_str!("../../doc/slice/iter/IterOnes.md")]
pub struct IterOnes<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
inner: &'a BitSlice<T, O>,
front: usize,
}
impl<'a, T, O> IterOnes<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
#[inline]
#[allow(missing_docs, clippy::missing_docs_in_private_items)]
pub(super) fn new(slice: &'a BitSlice<T, O>) -> Self {
Self {
inner: slice,
front: 0,
}
}
}
impl<T, O> Default for IterOnes<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
#[inline]
fn default() -> Self {
Self {
inner: Default::default(),
front: 0,
}
}
}
impl<T, O> Iterator for IterOnes<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
type Item = usize;
easy_iter!();
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let pos = if let Some(bits) = self.inner.coerce::<T, Lsb0>() {
bits.sp_first_one()
}
else if let Some(bits) = self.inner.coerce::<T, Msb0>() {
bits.sp_first_one()
}
else {
self.inner.iter().by_vals().position(|b| b)
};
match pos {
Some(n) => {
let (_, rest) = unsafe { self.inner.split_at_unchecked(n + 1) };
self.inner = rest;
let out = self.front + n;
self.front = out + 1;
Some(out)
},
None => {
*self = Default::default();
None
},
}
}
}
impl<T, O> DoubleEndedIterator for IterOnes<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
let pos = if let Some(bits) = self.inner.coerce::<T, Lsb0>() {
bits.sp_last_one()
}
else if let Some(bits) = self.inner.coerce::<T, Msb0>() {
bits.sp_last_one()
}
else {
self.inner.iter().by_vals().rposition(|b| b)
};
match pos {
Some(n) => {
let (rest, _) = unsafe { self.inner.split_at_unchecked(n) };
self.inner = rest;
Some(self.front + n)
},
None => {
*self = Default::default();
None
},
}
}
}
impl<T, O> ExactSizeIterator for IterOnes<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
#[inline]
fn len(&self) -> usize {
self.inner.count_ones()
}
}
impl<T, O> FusedIterator for IterOnes<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
}
#[doc = include_str!("../../doc/slice/iter/IterZeros.md")]
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct IterZeros<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
inner: &'a BitSlice<T, O>,
front: usize,
}
impl<'a, T, O> IterZeros<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
#[allow(missing_docs, clippy::missing_docs_in_private_items)]
pub(super) fn new(slice: &'a BitSlice<T, O>) -> Self {
Self {
inner: slice,
front: 0,
}
}
}
impl<T, O> Default for IterZeros<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
#[inline]
fn default() -> Self {
Self {
inner: Default::default(),
front: 0,
}
}
}
impl<T, O> Iterator for IterZeros<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
type Item = usize;
easy_iter!();
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let pos = if let Some(bits) = self.inner.coerce::<T, Lsb0>() {
bits.sp_first_zero()
}
else if let Some(bits) = self.inner.coerce::<T, Msb0>() {
bits.sp_first_zero()
}
else {
self.inner.iter().by_vals().position(|b| !b)
};
match pos {
Some(n) => {
let (_, rest) = unsafe { self.inner.split_at_unchecked(n + 1) };
self.inner = rest;
let out = self.front + n;
self.front = out + 1;
Some(out)
},
None => {
*self = Default::default();
None
},
}
}
}
impl<T, O> DoubleEndedIterator for IterZeros<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
let pos = if let Some(bits) = self.inner.coerce::<T, Lsb0>() {
bits.sp_last_zero()
}
else if let Some(bits) = self.inner.coerce::<T, Msb0>() {
bits.sp_last_zero()
}
else {
self.inner.iter().by_vals().rposition(|b| !b)
};
match pos {
Some(n) => {
let (rest, _) = unsafe { self.inner.split_at_unchecked(n) };
self.inner = rest;
Some(self.front + n)
},
None => {
*self = Default::default();
None
},
}
}
}
impl<T, O> ExactSizeIterator for IterZeros<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
#[inline]
fn len(&self) -> usize {
self.inner.count_zeros()
}
}
impl<T, O> FusedIterator for IterZeros<'_, T, O>
where
T: BitStore,
O: BitOrder,
{
}
macro_rules! noalias {
($(
$from:ident $(($p:ident))?
=> $alias:ty
=> $to:ident
=> $item:ty
=> $map:path;
)+) => { $(
#[repr(transparent)]
#[doc = include_str!("../../doc/slice/iter/NoAlias.md")]
pub struct $to<'a, T, O$(, $p)?>
where
T: 'a + BitStore,
O: BitOrder,
$($p: FnMut(usize, &bool) -> bool,)?
{
inner: $from<'a, T, O$(, $p)?>,
}
impl<'a, T, O$(, $p)?> $from<'a, T, O$(, $p)?>
where
T: 'a + BitStore,
O: BitOrder,
$($p: FnMut(usize, &bool) -> bool,)?
{
#[inline]
#[must_use = "You must consume this object, preferably immediately \
upon creation"]
pub unsafe fn remove_alias(self) -> $to<'a, T, O$(, $p)?> {
$to { inner: self }
}
}
impl<'a, T, O$(, $p)?> Iterator for $to<'a, T, O$(, $p)?>
where
T: 'a + BitStore,
O: BitOrder,
$($p: FnMut(usize, &bool) -> bool,)?
{
type Item = $item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|item| unsafe { $map(item) })
}
#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.inner.nth(n).map(|item| unsafe { $map(item) })
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
#[inline]
fn count(self) -> usize {
self.inner.count()
}
#[inline]
fn last(self) -> Option<Self::Item> {
self.inner.last().map(|item| unsafe { $map(item) })
}
}
impl<'a, T, O$(, $p)?> DoubleEndedIterator for $to<'a, T, O$(, $p)?>
where
T: 'a + BitStore,
O: BitOrder,
$($p: FnMut(usize, &bool) -> bool,)?
$from<'a, T, O$(, $p)?>: DoubleEndedIterator<Item = $alias>,
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back().map(|item| unsafe { $map(item) })
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.inner.nth_back(n).map(|item| unsafe { $map(item) })
}
}
impl<'a, T, O$(, $p)?> ExactSizeIterator for $to<'a, T, O$(, $p)?>
where
T: 'a + BitStore,
O: BitOrder,
$($p: FnMut(usize, &bool) -> bool,)?
$from<'a, T, O$(, $p)?>: ExactSizeIterator,
{
#[inline]
fn len(&self) -> usize {
self.inner.len()
}
}
impl<'a, T, O$(, $p)?> FusedIterator for $to<'a, T, O$(, $p)?>
where
T: 'a + BitStore,
O: BitOrder,
$($p: FnMut(usize, &bool) -> bool,)?
$from<'a, T, O$(, $p)?>: FusedIterator,
{
}
)+ };
}
noalias! {
IterMut => <usize as BitSliceIndex<'a, T::Alias, O>>::Mut
=> IterMutNoAlias => <usize as BitSliceIndex<'a, T, O>>::Mut
=> BitRef::remove_alias;
ChunksMut => &'a mut BitSlice<T::Alias, O>
=> ChunksMutNoAlias => &'a mut BitSlice<T, O>
=> BitSlice::unalias_mut;
ChunksExactMut => &'a mut BitSlice<T::Alias, O>
=> ChunksExactMutNoAlias => &'a mut BitSlice<T, O>
=> BitSlice::unalias_mut;
RChunksMut => &'a mut BitSlice<T::Alias, O>
=> RChunksMutNoAlias => &'a mut BitSlice<T, O>
=> BitSlice::unalias_mut;
RChunksExactMut => &'a mut BitSlice<T::Alias, O>
=> RChunksExactMutNoAlias => &'a mut BitSlice<T, O>
=> BitSlice::unalias_mut;
SplitMut (P) => &'a mut BitSlice<T::Alias, O>
=> SplitMutNoAlias => &'a mut BitSlice<T, O>
=> BitSlice::unalias_mut;
SplitInclusiveMut (P) => &'a mut BitSlice<T::Alias, O>
=> SplitInclusiveMutNoAlias => &'a mut BitSlice<T, O>
=> BitSlice::unalias_mut;
RSplitMut (P) => &'a mut BitSlice<T::Alias, O>
=> RSplitMutNoAlias => &'a mut BitSlice<T, O>
=> BitSlice::unalias_mut;
SplitNMut (P) => &'a mut BitSlice<T::Alias, O>
=> SplitNMutNoAlias => &'a mut BitSlice<T, O>
=> BitSlice::unalias_mut;
RSplitNMut (P) => &'a mut BitSlice<T::Alias, O>
=> RSplitNMutNoAlias => &'a mut BitSlice<T, O>
=> BitSlice::unalias_mut;
}
impl<'a, T, O> ChunksExactMutNoAlias<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
#[inline]
pub fn into_remainder(self) -> &'a mut BitSlice<T, O> {
unsafe { BitSlice::unalias_mut(self.inner.into_remainder()) }
}
#[inline]
pub fn take_remainder(&mut self) -> &'a mut BitSlice<T, O> {
unsafe { BitSlice::unalias_mut(self.inner.take_remainder()) }
}
}
impl<'a, T, O> RChunksExactMutNoAlias<'a, T, O>
where
T: 'a + BitStore,
O: BitOrder,
{
#[inline]
pub fn into_remainder(self) -> &'a mut BitSlice<T, O> {
unsafe { BitSlice::unalias_mut(self.inner.into_remainder()) }
}
#[inline]
pub fn take_remainder(&mut self) -> &'a mut BitSlice<T, O> {
unsafe { BitSlice::unalias_mut(self.inner.take_remainder()) }
}
}