use core::{
cmp,
fmt::{
self,
Debug,
Formatter,
},
iter::FusedIterator,
marker::PhantomData,
mem,
};
use super::{
BitSlice,
BitSliceIndex,
};
use crate::{
devel as dvl,
order::{
BitOrder,
Lsb0,
Msb0,
},
ptr::{
BitPtrRange,
BitRef,
Const,
Mut,
},
store::BitStore,
};
#[cfg(not(tarpaulin_include))]
impl<'a, O, T> IntoIterator for &'a BitSlice<O, T>
where
O: BitOrder,
T: BitStore,
{
type IntoIter = Iter<'a, O, T>;
type Item = <Self::IntoIter as Iterator>::Item;
#[inline(always)]
fn into_iter(self) -> Self::IntoIter {
Iter::new(self)
}
}
#[cfg(not(tarpaulin_include))]
impl<'a, O, T> IntoIterator for &'a mut BitSlice<O, T>
where
O: BitOrder,
T: BitStore,
{
type IntoIter = IterMut<'a, O, T>;
type Item = <Self::IntoIter as Iterator>::Item;
#[inline(always)]
fn into_iter(self) -> Self::IntoIter {
IterMut::new(self)
}
}
#[repr(transparent)]
pub struct Iter<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
range: BitPtrRange<Const, O, T>,
_ref: PhantomData<&'a BitSlice<O, T>>,
}
impl<'a, O, T> Iter<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline]
pub(super) fn new(slice: &'a BitSlice<O, T>) -> Self {
Self {
range: unsafe { slice.as_bitptr().range(slice.len()) },
_ref: PhantomData,
}
}
#[inline]
pub fn as_bitslice(&self) -> &'a BitSlice<O, T> {
self.range.clone().into_bitspan().to_bitslice_ref()
}
#[doc(hidden)]
#[inline(always)]
#[cfg(not(tarpaulin_include))]
#[deprecated = "Use `as_bitslice` to view the underlying slice"]
pub fn as_slice(&self) -> &'a BitSlice<O, T> {
self.as_bitslice()
}
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn by_ref(self) -> BitRefIter<'a, O, T> {
BitRefIter {
inner: self.by_val(),
}
}
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn by_val(self) -> BitValIter<'a, O, T> {
BitValIter { inner: self }
}
#[inline(always)]
#[cfg(not(tarpaulin_include))]
#[deprecated = "`Iterator::copied` does not exist on this iterator. Use \
`by_val` instead to achieve the same effect."]
pub fn copied(self) -> BitValIter<'a, O, T> {
self.by_val()
}
}
#[cfg(not(tarpaulin_include))]
impl<O, T> Clone for Iter<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline(always)]
fn clone(&self) -> Self {
Self {
range: self.range.clone(),
..*self
}
}
}
#[cfg(not(tarpaulin_include))]
impl<O, T> AsRef<BitSlice<O, T>> for Iter<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline(always)]
fn as_ref(&self) -> &BitSlice<O, T> {
self.as_bitslice()
}
}
#[cfg(not(tarpaulin_include))]
impl<O, T> Debug for Iter<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
fmt.debug_tuple("Iter").field(&self.as_bitslice()).finish()
}
}
#[repr(transparent)]
#[derive(Clone, Debug)]
pub struct BitRefIter<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
inner: BitValIter<'a, O, T>,
}
impl<'a, O, T> Iterator for BitRefIter<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
type Item = &'a bool;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
self.inner
.next()
.map(|bit| if bit { &true } else { &false })
}
#[inline(always)]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.inner
.nth(n)
.map(|bit| if bit { &true } else { &false })
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
#[inline(always)]
fn count(self) -> usize {
self.len()
}
#[inline(always)]
fn last(self) -> Option<Self::Item> {
self.inner
.last()
.map(|bit| if bit { &true } else { &false })
}
}
impl<O, T> DoubleEndedIterator for BitRefIter<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline(always)]
fn next_back(&mut self) -> Option<Self::Item> {
self.inner
.next_back()
.map(|bit| if bit { &true } else { &false })
}
#[inline(always)]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.inner
.nth_back(n)
.map(|bit| if bit { &true } else { &false })
}
}
impl<O, T> ExactSizeIterator for BitRefIter<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline(always)]
fn len(&self) -> usize {
self.inner.len()
}
}
impl<O, T> FusedIterator for BitRefIter<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
}
#[repr(transparent)]
#[derive(Clone, Debug)]
pub struct BitValIter<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
inner: Iter<'a, O, T>,
}
impl<O, T> Iterator for BitValIter<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
type Item = bool;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
self.inner.range.next().map(|bp| unsafe { bp.read() })
}
#[inline(always)]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.inner.range.nth(n).map(|bp| unsafe { bp.read() })
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
#[inline(always)]
fn count(self) -> usize {
self.inner.count()
}
#[inline(always)]
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
}
impl<O, T> DoubleEndedIterator for BitValIter<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline(always)]
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.range.next_back().map(|bp| unsafe { bp.read() })
}
#[inline(always)]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.inner.range.nth_back(n).map(|bp| unsafe { bp.read() })
}
}
impl<O, T> ExactSizeIterator for BitValIter<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline(always)]
fn len(&self) -> usize {
self.inner.len()
}
}
impl<O, T> FusedIterator for BitValIter<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
}
#[repr(transparent)]
pub struct IterMut<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
range: BitPtrRange<Mut, O, T::Alias>,
_ref: PhantomData<&'a mut BitSlice<O, T::Alias>>,
}
impl<'a, O, T> IterMut<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline]
pub(super) fn new(slice: &'a mut BitSlice<O, T>) -> Self {
let len = slice.len();
Self {
range: unsafe { slice.alias_mut().as_mut_bitptr().range(len) },
_ref: PhantomData,
}
}
#[inline]
pub fn into_bitslice(self) -> &'a mut BitSlice<O, T::Alias> {
self.range.into_bitspan().to_bitslice_mut()
}
#[doc(hidden)]
#[inline(always)]
#[cfg(not(tarpaulin_include))]
#[deprecated = "Use `into_bitslice` to view the underlying slice"]
pub fn into_slice(self) -> &'a mut BitSlice<O, T::Alias> {
self.into_bitslice()
}
#[inline]
pub(crate) fn as_bitslice(&self) -> &BitSlice<O, T::Alias> {
unsafe { core::ptr::read(self) }.into_bitslice()
}
}
#[cfg(not(tarpaulin_include))]
impl<O, T> Debug for IterMut<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
fmt.debug_tuple("IterMut")
.field(&self.as_bitslice())
.finish()
}
}
macro_rules! iter {
($($t:ident => $i:ty),+ $(,)?) => { $(
impl<'a, O, T> Iterator for $t<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
type Item = $i;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.range
.next()
.map(|bp| unsafe { BitRef::from_bitptr(bp) })
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
self.range.size_hint()
}
#[inline(always)]
fn count(self) -> usize {
self.len()
}
#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.range
.nth(n)
.map(|bp| unsafe { BitRef::from_bitptr(bp) })
}
#[inline(always)]
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
}
impl<'a, O, T> DoubleEndedIterator for $t <'a, O, T>
where
O: BitOrder,
T: BitStore,
{
#[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<O, T> ExactSizeIterator for $t <'_, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline(always)]
fn len(&self) -> usize {
self.range.len()
}
}
impl<O, T> FusedIterator for $t <'_, O, T>
where
O: BitOrder,
T: BitStore
{
}
unsafe impl<O, T> Send for $t <'_, O, T>
where
O: BitOrder,
T: BitStore,
{
}
unsafe impl<O, T> Sync for $t <'_, O, T>
where
O: BitOrder,
T: BitStore,
{
}
)+ };
}
iter!(
Iter => <usize as BitSliceIndex<'a, O, T>>::Immut,
IterMut => <usize as BitSliceIndex<'a, O, T::Alias>>::Mut,
);
macro_rules! group {
(
$iter:ident => $item:ty $( where $alias:ident )? {
$next:item
$nth:item
$next_back:item
$nth_back:item
$len:item
}
) => {
impl<'a, O, T> Iterator for $iter <'a, O, T>
where
O: BitOrder,
T: BitStore,
{
type Item = $item;
#[inline]
$next
#[inline]
$nth
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len();
(len, Some(len))
}
#[inline(always)]
fn count(self) -> usize {
self.len()
}
#[inline(always)]
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
}
impl<'a, O, T> DoubleEndedIterator for $iter <'a, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline]
$next_back
#[inline]
$nth_back
}
impl<O, T> ExactSizeIterator for $iter <'_, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline]
$len
}
impl<O, T> FusedIterator for $iter <'_, O, T>
where
O: BitOrder,
T: BitStore,
{
}
}
}
#[derive(Clone, Debug)]
pub struct Windows<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
slice: &'a BitSlice<O, T>,
width: usize,
}
group!(Windows => &'a BitSlice<O, T> {
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 {
return 0;
}
len - self.width + 1
}
});
#[derive(Clone, Debug)]
pub struct Chunks<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
slice: &'a BitSlice<O, T>,
width: usize,
}
group!(Chunks => &'a BitSlice<O, T> {
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 (out, rest) = unsafe {
self.slice
.get_unchecked(start ..)
.split_at_unchecked(cmp::min(len, self.width))
};
self.slice = rest;
Some(out)
}
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)]
pub struct ChunksMut<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
slice: &'a mut BitSlice<O, T::Alias>,
width: usize,
}
group!(ChunksMut => &'a mut BitSlice<O, T::Alias> {
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, 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 (rest, out) =
unsafe { slice.split_at_unchecked_mut_noalias(len - size) };
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)]
pub struct ChunksExact<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
slice: &'a BitSlice<O, T>,
extra: &'a BitSlice<O, T>,
width: usize,
}
impl<'a, O, T> ChunksExact<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline]
pub(super) fn new(slice: &'a BitSlice<O, T>, width: usize) -> Self {
let len = slice.len();
let rem = len % width;
let (slice, extra) = unsafe { slice.split_at_unchecked(len - rem) };
Self {
slice,
extra,
width,
}
}
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn remainder(&self) -> &'a BitSlice<O, T> {
self.extra
}
}
group!(ChunksExact => &'a BitSlice<O, T> {
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.width >= 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)]
pub struct ChunksExactMut<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
slice: &'a mut BitSlice<O, T::Alias>,
extra: &'a mut BitSlice<O, T::Alias>,
width: usize,
}
impl<'a, O, T> ChunksExactMut<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline]
pub(super) fn new(slice: &'a mut BitSlice<O, T>, width: usize) -> Self {
let len = slice.len();
let rem = len % width;
let (slice, extra) = unsafe { slice.split_at_unchecked_mut(len - rem) };
Self {
slice,
extra,
width,
}
}
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn into_remainder(self) -> &'a mut BitSlice<O, T::Alias> {
self.extra
}
}
group!(ChunksExactMut => &'a mut BitSlice<O, T::Alias> {
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)]
pub struct RChunks<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
slice: &'a BitSlice<O, T>,
width: usize,
}
group!(RChunks => &'a BitSlice<O, T> {
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)]
pub struct RChunksMut<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
slice: &'a mut BitSlice<O, T::Alias>,
width: usize,
}
group!(RChunksMut => &'a mut BitSlice<O, T::Alias> {
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)]
pub struct RChunksExact<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
slice: &'a BitSlice<O, T>,
extra: &'a BitSlice<O, T>,
width: usize,
}
impl<'a, O, T> RChunksExact<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline]
pub(super) fn new(slice: &'a BitSlice<O, T>, width: usize) -> Self {
let (extra, slice) =
unsafe { slice.split_at_unchecked(slice.len() % width) };
Self {
slice,
extra,
width,
}
}
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn remainder(&self) -> &'a BitSlice<O, T> {
self.extra
}
}
group!(RChunksExact => &'a BitSlice<O, T> {
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)]
pub struct RChunksExactMut<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
slice: &'a mut BitSlice<O, T::Alias>,
extra: &'a mut BitSlice<O, T::Alias>,
width: usize,
}
impl<'a, O, T> RChunksExactMut<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline]
pub(super) fn new(slice: &'a mut BitSlice<O, T>, width: usize) -> Self {
let (extra, slice) =
unsafe { slice.split_at_unchecked_mut(slice.len() % width) };
Self {
slice,
extra,
width,
}
}
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn into_remainder(self) -> &'a mut BitSlice<O, T::Alias> {
self.extra
}
}
group!(RChunksExactMut => &'a mut BitSlice<O, T::Alias> {
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, O, T> $t <'a, O, T>
where
O: BitOrder,
T: BitStore
{
#[inline]
#[allow(clippy::redundant_field_names)]
pub(super) fn new(
slice: &'a $($m)? BitSlice<O, T>,
width: usize,
) -> Self {
Self { slice: slice $( . $a () )?, 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, O, T, P> $iter <'a, O, T, P>
where
O: BitOrder,
T: BitStore,
P: FnMut(usize, &bool) -> bool,
{
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub(super) fn new(slice: $item, pred: P) -> Self {
Self {
slice,
pred,
done: false,
}
}
}
impl<O, T, P> Debug for $iter <'_, O, T, P>
where
O: BitOrder,
T: BitStore,
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, O, T, P> Iterator for $iter <'a, O, T, P>
where
O: BitOrder,
T: BitStore,
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, O, T, P> DoubleEndedIterator for $iter <'a, O, T, P>
where
O: BitOrder,
T: BitStore,
P: FnMut(usize, &bool) -> bool,
{
#[inline]
$next_back
}
impl<'a, O, T, P> core::iter::FusedIterator for $iter <'a, O, T, P>
where
O: BitOrder,
T: BitStore,
P: FnMut(usize, &bool) -> bool,
{
}
impl<'a, O, T, P> SplitIter for $iter <'a, O, T, P>
where
O: BitOrder,
T: BitStore,
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)]
pub struct Split<'a, O, T, P>
where
O: BitOrder,
T: BitStore,
P: FnMut(usize, &bool) -> bool,
{
slice: &'a BitSlice<O, T>,
pred: P,
done: bool,
}
split!(Split => &'a BitSlice<O, T> {
fn next(&mut self) -> Option<Self::Item> {
if self.done {
return None;
}
match self.slice
.iter()
.by_ref()
.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_ref()
.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)
},
}
}
});
pub struct SplitMut<'a, O, T, P>
where
O: BitOrder,
T: BitStore,
P: FnMut(usize, &bool) -> bool,
{
slice: &'a mut BitSlice<O, T::Alias>,
pred: P,
done: bool,
}
split!(SplitMut => &'a mut BitSlice<O, T::Alias> {
fn next(&mut self) -> Option<Self::Item> {
if self.done {
return None;
}
let idx_opt = {
let pred = &mut self.pred;
self.slice
.iter()
.by_ref()
.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_ref()
.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)]
pub struct RSplit<'a, O, T, P>
where
O: BitOrder,
T: BitStore,
P: FnMut(usize, &bool) -> bool,
{
slice: &'a BitSlice<O, T>,
pred: P,
done: bool,
}
split!(RSplit => &'a BitSlice<O, T> {
fn next(&mut self) -> Option<Self::Item> {
let mut split = Split::<'a, O, T, &mut P> {
slice: mem::take(&mut self.slice),
pred: &mut self.pred,
done: self.done,
};
let out = split.next_back();
self.slice = mem::take(&mut split.slice);
self.done = split.done;
out
}
fn next_back(&mut self) -> Option<Self::Item> {
let mut split = Split::<'a, O, T, &mut P> {
slice: mem::take(&mut self.slice),
pred: &mut self.pred,
done: self.done,
};
let out = split.next();
self.slice = mem::take(&mut split.slice);
self.done = split.done;
out
}
});
pub struct RSplitMut<'a, O, T, P>
where
O: BitOrder,
T: BitStore,
P: FnMut(usize, &bool) -> bool,
{
slice: &'a mut BitSlice<O, T::Alias>,
pred: P,
done: bool,
}
split!(RSplitMut => &'a mut BitSlice<O, T::Alias> {
fn next(&mut self) -> Option<Self::Item> {
let mut split = SplitMut::<'a, O, T, &mut P> {
slice: mem::take(&mut self.slice),
pred: &mut self.pred,
done: self.done,
};
let out = split.next_back();
self.slice = mem::take(&mut split.slice);
self.done = split.done;
out
}
fn next_back(&mut self) -> Option<Self::Item> {
let mut split = SplitMut::<'a, O, T, &mut P> {
slice: mem::take(&mut self.slice),
pred: &mut self.pred,
done: self.done,
};
let out = split.next();
self.slice = mem::take(&mut split.slice);
self.done = split.done;
out
}
});
#[doc(hidden)]
trait SplitIter: DoubleEndedIterator {
fn finish(&mut self) -> Option<Self::Item>;
}
pub struct SplitN<'a, O, T, P>
where
O: BitOrder,
T: BitStore,
P: FnMut(usize, &bool) -> bool,
{
inner: Split<'a, O, T, P>,
count: usize,
}
pub struct SplitNMut<'a, O, T, P>
where
O: BitOrder,
T: BitStore,
P: FnMut(usize, &bool) -> bool,
{
inner: SplitMut<'a, O, T, P>,
count: usize,
}
pub struct RSplitN<'a, O, T, P>
where
O: BitOrder,
T: BitStore,
P: FnMut(usize, &bool) -> bool,
{
inner: RSplit<'a, O, T, P>,
count: usize,
}
pub struct RSplitNMut<'a, O, T, P>
where
O: BitOrder,
T: BitStore,
P: FnMut(usize, &bool) -> bool,
{
inner: RSplitMut<'a, O, T, P>,
count: usize,
}
macro_rules! split_n {
($outer:ident => $inner:ident => $item:ty $( where $alias:ident )?) => {
impl<'a, O, T, P> $outer <'a, O, T, P>
where
O: BitOrder,
T: BitStore,
P: FnMut(usize, &bool) -> bool,
{
#[inline]
pub(super) fn new(
slice: $item,
pred: P,
count: usize,
) -> Self
{Self{
inner: <$inner<'a, O, T, P>>::new(slice, pred),
count,
}}
}
impl<O, T, P> Debug for $outer <'_, O, T, P>
where
O: BitOrder,
T: BitStore,
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, O, T, P> Iterator for $outer <'a, O, T, P>
where
O: BitOrder,
T: BitStore,
P: FnMut(usize, &bool) -> bool,
$( T::$alias: radium::Radium<<<T as BitStore>::Alias as BitStore>::Mem>, )?
{
type Item = <$inner <'a, O, T, 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(self.count, h)))
}
}
impl<O, T, P> core::iter::FusedIterator for $outer <'_, O, T, P>
where
O: BitOrder,
T: BitStore,
P: FnMut(usize, &bool) -> bool,
$( T::$alias: radium::Radium<<<T as BitStore>::Alias as BitStore>::Mem>, )?
{
}
};
}
split_n!(SplitN => Split => &'a BitSlice<O, T>);
split_n!(SplitNMut => SplitMut => &'a mut BitSlice<O, T::Alias> );
split_n!(RSplitN => RSplit => &'a BitSlice<O, T>);
split_n!(RSplitNMut => RSplitMut => &'a mut BitSlice<O, T::Alias> );
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct IterOnes<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
inner: &'a BitSlice<O, T>,
front: usize,
}
impl<'a, O, T> IterOnes<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub(super) fn new(slice: &'a BitSlice<O, T>) -> Self {
Self {
inner: slice,
front: 0,
}
}
}
#[cfg(not(tarpaulin_include))]
impl<O, T> Default for IterOnes<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline(always)]
fn default() -> Self {
Self {
inner: Default::default(),
front: 0,
}
}
}
impl<O, T> Iterator for IterOnes<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
type Item = usize;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let pos = if dvl::match_order::<O, Lsb0>() {
let slice = unsafe {
&*(self.inner as *const _ as *const BitSlice<Lsb0, T>)
};
slice.sp_iter_ones_first()
}
else if dvl::match_order::<O, Msb0>() {
let slice = unsafe {
&*(self.inner as *const _ as *const BitSlice<Msb0, T>)
};
slice.sp_iter_ones_first()
}
else {
self.inner.iter().by_val().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
},
}
}
#[cfg_attr(not(tarpaulin_include), inline(always))]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len();
(len, Some(len))
}
#[cfg_attr(not(tarpaulin_include), inline(always))]
fn count(self) -> usize {
self.len()
}
#[cfg_attr(not(tarpaulin_include), inline(always))]
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
}
impl<O, T> DoubleEndedIterator for IterOnes<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
fn next_back(&mut self) -> Option<Self::Item> {
let pos = if dvl::match_order::<O, Lsb0>() {
let slice = unsafe {
&*(self.inner as *const _ as *const BitSlice<Lsb0, T>)
};
slice.sp_iter_ones_last()
}
else if dvl::match_order::<O, Msb0>() {
let slice = unsafe {
&*(self.inner as *const _ as *const BitSlice<Msb0, T>)
};
slice.sp_iter_ones_last()
}
else {
self.inner.iter().by_val().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<O, T> ExactSizeIterator for IterOnes<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline]
fn len(&self) -> usize {
self.inner.count_ones()
}
}
impl<O, T> FusedIterator for IterOnes<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct IterZeros<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
inner: &'a BitSlice<O, T>,
front: usize,
}
impl<'a, O, T> IterZeros<'a, O, T>
where
O: BitOrder,
T: BitStore,
{
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub(super) fn new(slice: &'a BitSlice<O, T>) -> Self {
Self {
inner: slice,
front: 0,
}
}
}
#[cfg(not(tarpaulin_include))]
impl<O, T> Default for IterZeros<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline(always)]
fn default() -> Self {
Self {
inner: Default::default(),
front: 0,
}
}
}
impl<O, T> Iterator for IterZeros<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
let pos = if dvl::match_order::<O, Lsb0>() {
let slice = unsafe {
&*(self.inner as *const _ as *const BitSlice<Lsb0, T>)
};
slice.sp_iter_zeros_first()
}
else if dvl::match_order::<O, Msb0>() {
let slice = unsafe {
&*(self.inner as *const _ as *const BitSlice<Msb0, T>)
};
slice.sp_iter_zeros_first()
}
else {
self.inner.iter().by_val().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
},
}
}
#[cfg_attr(not(tarpaulin_include), inline(always))]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len();
(len, Some(len))
}
#[cfg_attr(not(tarpaulin_include), inline(always))]
fn count(self) -> usize {
self.len()
}
#[cfg_attr(not(tarpaulin_include), inline(always))]
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
}
impl<O, T> DoubleEndedIterator for IterZeros<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
fn next_back(&mut self) -> Option<Self::Item> {
let pos = if dvl::match_order::<O, Lsb0>() {
let slice = unsafe {
&*(self.inner as *const _ as *const BitSlice<Lsb0, T>)
};
slice.sp_iter_zeros_last()
}
else if dvl::match_order::<O, Msb0>() {
let slice = unsafe {
&*(self.inner as *const _ as *const BitSlice<Msb0, T>)
};
slice.sp_iter_zeros_last()
}
else {
self.inner.iter().by_val().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<O, T> ExactSizeIterator for IterZeros<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline]
fn len(&self) -> usize {
self.inner.count_zeros()
}
}
impl<O, T> FusedIterator for IterZeros<'_, O, T>
where
O: BitOrder,
T: BitStore,
{
}
macro_rules! noalias {
( $(
$from:ident $( ( $p:ident ) )?
=> $alias:ty
=> $to:ident
=> $item:ty
=> $map:path
;
)+ ) => { $(
pub struct $to <'a, O, T $( , $p )? >
where
O: BitOrder,
T: BitStore,
$( $p : FnMut(usize, &bool) -> bool, )?
{
inner: $from <'a, O, T $( , $p )? >,
}
impl<'a, O, T $( , $p )? > $from <'a, O, T $( , $p )? >
where
O: BitOrder,
T: BitStore,
$( $p : FnMut(usize, &bool) -> bool, )?
{
#[inline(always)]
pub unsafe fn remove_alias(self) -> $to <'a, O, T $( , $p )? > {
$to ::new(self)
}
}
impl<'a, O, T $( , $p )? > $to <'a, O, T $( , $p )? >
where
O: BitOrder,
T: BitStore,
$( $p : FnMut(usize, &bool) -> bool, )?
{
#[inline(always)]
fn new(inner: $from<'a, O, T $( , $p )? >) -> Self {
Self { inner }
}
}
impl<'a, O, T $( , $p )? > Iterator for $to <'a, O, T $( , $p )? >
where
O: BitOrder,
T: BitStore,
$( $p : FnMut(usize, &bool) -> bool, )?
{
type Item = $item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|item| unsafe { $map(item) })
}
#[cfg_attr(not(tarpaulin_include), inline(always))]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
#[cfg_attr(not(tarpaulin_include), inline(always))]
fn count(self) -> usize {
self.inner.count()
}
#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.inner.nth(n).map(|item| unsafe { $map(item) })
}
#[inline]
fn last(self) -> Option<Self::Item> {
self.inner.last().map(|item| unsafe { $map(item) })
}
}
impl<'a, O, T $( , $p )? > DoubleEndedIterator for $to <'a, O, T $( , $p )? >
where
O: BitOrder,
T: BitStore,
$from <'a, O, T $( , $p )? >: DoubleEndedIterator<Item = $alias >,
$( $p : FnMut(usize, &bool) -> bool, )?
{
#[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, O, T $( , $p )? > ExactSizeIterator for $to <'a, O, T $( , $p )? >
where
O: BitOrder,
T: BitStore,
$from <'a, O, T $( , $p )? >: ExactSizeIterator,
$( $p : FnMut(usize, &bool) -> bool, )?
{
#[cfg_attr(not(tarpaulin_include), inline(always))]
fn len(&self) -> usize {
self.inner.len()
}
}
impl<O, T $( , $p )? > FusedIterator for $to <'_, O, T $( , $p )? >
where
O: BitOrder,
T: BitStore,
$( $p : FnMut(usize, &bool) -> bool, )?
{
}
unsafe impl<O, T $( , $p )? > Send for $to <'_, O, T $( , $p )? >
where
O: BitOrder,
T: BitStore,
$( $p : FnMut(usize, &bool) -> bool, )?
{
}
unsafe impl<O, T $( , $p )? > Sync for $to <'_, O, T $( , $p )? >
where
O: BitOrder,
T: BitStore,
$( $p : FnMut(usize, &bool) -> bool, )?
{
}
)+ };
}
noalias! {
IterMut => <usize as BitSliceIndex<'a, O, T::Alias>>::Mut
=> IterMutNoAlias => <usize as BitSliceIndex<'a, O, T>>::Mut
=> BitRef::remove_alias;
ChunksMut => &'a mut BitSlice<O, T::Alias>
=> ChunksMutNoAlias => &'a mut BitSlice<O, T>
=> BitSlice::unalias_mut;
ChunksExactMut => &'a mut BitSlice<O, T::Alias>
=> ChunksExactMutNoAlias => &'a mut BitSlice<O, T>
=> BitSlice::unalias_mut;
RChunksMut => &'a mut BitSlice<O, T::Alias>
=> RChunksMutNoAlias => &'a mut BitSlice<O, T>
=> BitSlice::unalias_mut;
RChunksExactMut => &'a mut BitSlice<O, T::Alias>
=> RChunksExactMutNoAlias => &'a mut BitSlice<O, T>
=> BitSlice::unalias_mut;
SplitMut (P) => &'a mut BitSlice<O, T::Alias>
=> SplitMutNoAlias => &'a mut BitSlice<O, T>
=> BitSlice::unalias_mut;
RSplitMut (P) => &'a mut BitSlice<O, T::Alias>
=> RSplitMutNoAlias => &'a mut BitSlice<O, T>
=> BitSlice::unalias_mut;
SplitNMut (P) => &'a mut BitSlice<O, T::Alias>
=> SplitNMutNoAlias => &'a mut BitSlice<O, T>
=> BitSlice::unalias_mut;
RSplitNMut (P) => &'a mut BitSlice<O, T::Alias>
=> RSplitNMutNoAlias => &'a mut BitSlice<O, T>
=> BitSlice::unalias_mut;
}