#![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()) }
	}
}