use crate::{
bits::Bits,
cursor::{
BigEndian,
Cursor,
},
domain::*,
pointer::BitPtr,
};
use core::{
cmp::{
Eq,
Ord,
Ordering,
PartialEq,
PartialOrd,
},
convert::{
AsMut,
AsRef,
From,
},
fmt::{
self,
Debug,
DebugList,
Display,
Formatter,
},
hash::{
Hash,
Hasher,
},
iter::{
DoubleEndedIterator,
ExactSizeIterator,
FusedIterator,
Iterator,
IntoIterator,
},
marker::{
PhantomData,
Send,
Sync,
},
mem,
ops::{
AddAssign,
BitAndAssign,
BitOrAssign,
BitXorAssign,
Index,
IndexMut,
Neg,
Not,
Range,
RangeFrom,
RangeFull,
RangeInclusive,
RangeTo,
RangeToInclusive,
ShlAssign,
ShrAssign,
},
ptr,
slice,
str,
};
#[cfg(any(feature = "alloc", feature = "std"))]
use crate::vec::BitVec;
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::borrow::ToOwned;
#[cfg(feature = "std")]
use std::borrow::ToOwned;
#[repr(transparent)]
pub struct BitSlice<C = BigEndian, T = u8>
where C: Cursor, T: Bits {
_kind: PhantomData<C>,
_type: PhantomData<T>,
_elts: [()],
}
impl<C, T> BitSlice<C, T>
where C: Cursor, T: Bits {
pub fn empty<'a>() -> &'a Self {
BitPtr::empty().into_bitslice()
}
pub fn empty_mut<'a>() -> &'a mut Self {
BitPtr::empty().into_bitslice_mut()
}
pub fn from_element(elt: &T) -> &Self {
BitPtr::new(elt, 1, 0, T::BITS).into_bitslice()
}
pub fn from_element_mut(elt: &mut T) -> &mut Self {
BitPtr::new(elt, 1, 0, T::BITS).into_bitslice_mut()
}
pub fn from_slice(slice: &[T]) -> &Self {
BitPtr::new(slice.as_ptr(), slice.len(), 0, T::BITS).into_bitslice()
}
pub fn from_slice_mut(slice: &mut [T]) -> &mut Self {
BitPtr::new(slice.as_ptr(), slice.len(), 0, T::BITS).into_bitslice_mut()
}
pub fn len(&self) -> usize {
self.bitptr().len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn first(&self) -> Option<bool> {
self.get(0)
}
pub fn split_first(&self) -> Option<(bool, &Self)> {
if self.is_empty() {
None
}
else {
Some((self[0], &self[1 ..]))
}
}
pub fn split_first_mut(&mut self) -> Option<(bool, &mut Self)> {
if self.is_empty() {
None
}
else {
Some((self[0], &mut self[1 ..]))
}
}
pub fn split_last(&self) -> Option<(bool, &Self)> {
if self.is_empty() {
None
}
else {
let len = self.len();
Some((self[len - 1], &self[.. len - 1]))
}
}
pub fn split_last_mut(&mut self) -> Option<(bool, &mut Self)> {
if self.is_empty() {
None
}
else {
let len = self.len();
Some((self[len - 1], &mut self[.. len - 1]))
}
}
pub fn last(&self) -> Option<bool> {
if self.is_empty() {
None
}
else {
Some(self[self.len() - 1])
}
}
pub fn get(&self, index: usize) -> Option<bool> {
if index >= self.len() {
None
}
else {
Some(self[index])
}
}
pub fn set(&mut self, index: usize, value: bool) {
let len = self.len();
assert!(index < len, "Index out of range: {} >= {}", index, len);
let h = self.bitptr().head();
let (elt, bit) = h.offset::<T>(index as isize);
self.as_mut()[elt as usize].set::<C>(bit, value);
}
pub fn as_ptr(&self) -> *const T {
self.bitptr().pointer()
}
pub fn as_mut_ptr(&mut self) -> *mut T {
self.bitptr().pointer() as *mut T
}
pub fn swap(&mut self, a: usize, b: usize) {
assert!(a < self.len(), "Index {} out of bounds: {}", a, self.len());
assert!(b < self.len(), "Index {} out of bounds: {}", b, self.len());
let bit_a = self[a];
let bit_b = self[b];
self.set(a, bit_b);
self.set(b, bit_a);
}
pub fn reverse(&mut self) {
let mut cur: &mut Self = self;
loop {
let len = cur.len();
if len < 2 {
return;
}
let (h, t) = (cur[0], cur[len - 1]);
cur.set(0, t);
cur.set(len - 1, h);
cur = &mut cur[1 .. len - 1];
}
}
pub fn iter(&self) -> Iter<C, T> {
self.into_iter()
}
pub fn windows(&self, size: usize) -> Windows<C, T> {
assert_ne!(size, 0, "Window width cannot be zero");
Windows {
inner: self,
width: size,
}
}
pub fn chunks(&self, size: usize) -> Chunks<C, T> {
assert_ne!(size, 0, "Chunk width cannot be zero");
Chunks {
inner: self,
width: size,
}
}
pub fn chunks_mut(&mut self, size: usize) -> ChunksMut<C, T> {
assert_ne!(size, 0, "Chunk width cannot be zero");
ChunksMut {
inner: self,
width: size,
}
}
pub fn chunks_exact(&self, size: usize) -> ChunksExact<C, T> {
assert_ne!(size, 0, "Chunk size cannot be zero");
let rem = self.len() % size;
let len = self.len() - rem;
let (inner, extra) = self.split_at(len);
ChunksExact {
inner,
extra,
width: size,
}
}
pub fn chunks_exact_mut(&mut self, size: usize) -> ChunksExactMut<C, T> {
assert_ne!(size, 0, "Chunk size cannot be zero");
let rem = self.len() % size;
let len = self.len() - rem;
let (inner, extra) = self.split_at_mut(len);
ChunksExactMut {
inner,
extra,
width: size,
}
}
pub fn rchunks(&self, size: usize) -> RChunks<C, T> {
assert_ne!(size, 0, "Chunk size cannot be zero");
RChunks {
inner: self,
width: size,
}
}
pub fn rchunks_mut(&mut self, size: usize) -> RChunksMut<C, T> {
assert_ne!(size, 0, "Chunk size cannot be zero");
RChunksMut {
inner: self,
width: size,
}
}
pub fn rchunks_exact(&self, size: usize) -> RChunksExact<C, T> {
assert_ne!(size, 0, "Chunk size cannot be zero");
let (extra, inner) = self.split_at(self.len() % size);
RChunksExact {
inner,
extra,
width: size,
}
}
pub fn rchunks_exact_mut(&mut self, size: usize) -> RChunksExactMut<C, T> {
assert_ne!(size, 0, "Chunk size cannot be zero");
let (extra, inner) = self.split_at_mut(self.len() % size);
RChunksExactMut {
inner,
extra,
width: size,
}
}
pub fn split_at(&self, mid: usize) -> (&Self, &Self) {
assert!(mid <= self.len(), "Index {} out of bounds: {}", mid, self.len());
if mid == self.len() {
(&self, Self::empty())
}
else {
(&self[.. mid], &self[mid ..])
}
}
pub fn split_at_mut(&mut self, mid: usize) -> (&mut Self, &mut Self) {
let (head, tail) = self.split_at(mid);
(head.bitptr().into_bitslice_mut(), tail.bitptr().into_bitslice_mut())
}
pub fn starts_with<D, U>(&self, prefix: &BitSlice<D, U>) -> bool
where D: Cursor, U: Bits {
let plen = prefix.len();
self.len() >= plen && prefix == &self[.. plen]
}
pub fn ends_with<D, U>(&self, suffix: &BitSlice<D, U>) -> bool
where D: Cursor, U: Bits {
let slen = suffix.len();
let len = self.len();
len >= slen && suffix == &self[len - slen ..]
}
pub fn rotate_left(&mut self, by: usize) {
let len = self.len();
assert!(by <= len, "Slices cannot be rotated by more than their length");
if by == 0 || by == len {
return;
}
for _ in 0 .. by {
let tmp = self[0];
for n in 1 .. len {
let bit = self[n];
self.set(n - 1, bit);
}
self.set(len - 1, tmp);
}
}
pub fn rotate_right(&mut self, by: usize) {
let len = self.len();
assert!(by <= len, "Slices cannot be rotated by more than their length");
if by == len {
return;
}
for _ in 0 .. by {
let tmp = self[len - 1];
for n in (0 .. len - 1).rev() {
let bit = self[n];
self.set(n + 1, bit);
}
self.set(0, tmp);
}
}
pub fn all(&self) -> bool {
match self.bitptr().domain() {
BitDomain::Empty => return false,
BitDomain::Minor(head, elt, tail) => {
for n in *head .. *tail {
if !elt.get::<C>(n.into()) {
return false;
}
}
},
BitDomain::Major(h, head, body, tail, t) => {
for n in *h .. T::BITS {
if !head.get::<C>(n.into()) {
return false;
}
}
for n in 0 .. *t {
if !tail.get::<C>(n.into()) {
return false;
}
}
return body.iter().all(|e| *e == T::bits(true));
},
BitDomain::PartialHead(h, head, body) => {
for n in *h .. T::BITS {
if !head.get::<C>(n.into()) {
return false;
}
}
return body.iter().all(|e| *e == T::bits(true));
},
BitDomain::PartialTail(body, tail, t) => {
for n in 0 .. *t {
if !tail.get::<C>(n.into()) {
return false;
}
}
return body.iter().all(|e| *e == T::bits(true));
},
BitDomain::Spanning(body) => {
return body.iter().all(|e| *e == T::bits(true));
},
}
true
}
pub fn any(&self) -> bool {
match self.bitptr().domain() {
BitDomain::Empty => return false,
BitDomain::Minor(head, elt, tail) => {
for n in *head .. *tail {
if elt.get::<C>(n.into()) {
return true;
}
}
},
BitDomain::Major(h, head, body, tail, t) => {
for n in *h .. T::BITS {
if head.get::<C>(n.into()) {
return true;
}
}
for n in 0 .. *t {
if tail.get::<C>(n.into()) {
return true;
}
}
return body.iter().any(|e| *e != T::bits(false));
},
BitDomain::PartialHead(h, head, body) => {
for n in *h .. T::BITS {
if head.get::<C>(n.into()) {
return true;
}
}
return body.iter().any(|e| *e != T::bits(false));
},
BitDomain::PartialTail(body, tail, t) => {
for n in 0 .. *t {
if tail.get::<C>(n.into()) {
return true;
}
}
return body.iter().any(|e| *e != T::bits(false));
},
BitDomain::Spanning(body) => {
return body.iter().any(|e| *e != T::bits(false));
},
}
false
}
pub fn not_all(&self) -> bool {
!self.all()
}
pub fn not_any(&self) -> bool {
!self.any()
}
pub fn some(&self) -> bool {
self.any() && self.not_all()
}
pub fn count_ones(&self) -> usize {
match self.bitptr().domain() {
BitDomain::Empty => 0,
BitDomain::Minor(head, elt, tail) => {
(*head .. *tail)
.map(|n| elt.get::<C>(n.into()))
.filter(|b| *b)
.count()
},
BitDomain::Major(h, head, body, tail, t) => {
(*h .. T::BITS)
.map(|n| head.get::<C>(n.into()))
.filter(|b| *b)
.count() +
body.iter()
.map(T::count_ones)
.sum::<usize>() +
(0 .. *t)
.map(|n| tail.get::<C>(n.into()))
.filter(|b| *b)
.count()
},
BitDomain::PartialHead(h, head, body) => {
(*h .. T::BITS)
.map(|n| head.get::<C>(n.into()))
.filter(|b| *b)
.count() +
body.iter()
.map(T::count_ones)
.sum::<usize>()
},
BitDomain::PartialTail(body, tail, t) => {
body.iter()
.map(T::count_ones)
.sum::<usize>() +
(0 .. *t)
.map(|n| tail.get::<C>(n.into()))
.filter(|b| *b)
.count()
},
BitDomain::Spanning(body) => {
body.iter()
.map(T::count_ones)
.sum::<usize>()
}
}
}
pub fn count_zeros(&self) -> usize {
match self.bitptr().domain() {
BitDomain::Empty => 0,
BitDomain::Minor(head, elt, tail) => {
(*head .. *tail)
.map(|n| !elt.get::<C>(n.into()))
.filter(|b| !*b)
.count()
},
BitDomain::Major(h, head, body, tail, t) => {
(*h .. T::BITS)
.map(|n| head.get::<C>(n.into()))
.filter(|b| !*b)
.count() +
body.iter()
.map(T::count_zeros)
.sum::<usize>() +
(0 .. *t)
.map(|n| tail.get::<C>(n.into()))
.filter(|b| !*b)
.count()
},
BitDomain::PartialHead(h, head, body) => {
(*h .. T::BITS)
.map(|n| head.get::<C>(n.into()))
.filter(|b| !*b)
.count() +
body.iter()
.map(T::count_zeros)
.sum::<usize>()
},
BitDomain::PartialTail(body, tail, t) => {
body.iter()
.map(T::count_zeros)
.sum::<usize>() +
(0 .. *t)
.map(|n| tail.get::<C>(n.into()))
.filter(|b| !*b)
.count()
},
BitDomain::Spanning(body) => {
body.iter()
.map(T::count_zeros)
.sum::<usize>()
},
}
}
pub fn set_all(&mut self, value: bool) {
match self.bitptr().domain_mut() {
BitDomainMut::Empty => {},
BitDomainMut::Minor(head, elt, tail) => {
for n in *head .. *tail {
elt.set::<C>(n.into(), value);
}
},
BitDomainMut::Major(h, head, body, tail, t) => {
for n in *h .. T::BITS {
head.set::<C>(n.into(), value);
}
for elt in body {
*elt = T::bits(value);
}
for n in 0 .. *t {
tail.set::<C>(n.into(), value);
}
},
BitDomainMut::PartialHead(h, head, body) => {
for n in *h .. T::BITS {
head.set::<C>(n.into(), value);
}
for elt in body {
*elt = T::bits(value);
}
},
BitDomainMut::PartialTail(body, tail, t) => {
for elt in body {
*elt = T::bits(value);
}
for n in 0 .. *t {
tail.set::<C>(n.into(), value);
}
},
BitDomainMut::Spanning(body) => {
for elt in body {
*elt = T::bits(value);
}
},
}
}
pub fn for_each<F>(&mut self, func: F)
where F: Fn(usize, bool) -> bool {
for idx in 0 .. self.len() {
let tmp = self[idx];
self.set(idx, func(idx, tmp));
}
}
pub fn as_slice(&self) -> &[T] {
let bp = self.bitptr();
let (ptr, len) = (bp.pointer(), bp.elements());
unsafe { slice::from_raw_parts(ptr, len) }
}
pub fn as_mut_slice(&mut self) -> &mut [T] {
let bp = self.bitptr();
let (ptr, len) = (bp.pointer() as *mut T, bp.elements());
unsafe { slice::from_raw_parts_mut(ptr, len) }
}
pub fn change_cursor<D>(&self) -> &BitSlice<D, T>
where D: Cursor {
self.bitptr().into_bitslice()
}
pub fn change_cursor_mut<D>(&mut self) -> &mut BitSlice<D, T>
where D: Cursor {
self.bitptr().into_bitslice_mut()
}
pub fn bitptr(&self) -> BitPtr<T> {
BitPtr::from_bitslice(self)
}
}
#[cfg(any(feature = "alloc", feature = "std"))]
impl<C, T> ToOwned for BitSlice<C, T>
where C: Cursor, T: Bits {
type Owned = BitVec<C, T>;
fn to_owned(&self) -> Self::Owned {
Self::Owned::from_bitslice(self)
}
}
impl<C, T> Eq for BitSlice<C, T>
where C: Cursor, T: Bits {}
impl<C, T> Ord for BitSlice<C, T>
where C: Cursor, T: Bits {
fn cmp(&self, rhs: &Self) -> Ordering {
self.partial_cmp(rhs)
.unwrap_or_else(|| unreachable!("`BitSlice` has a total ordering"))
}
}
impl<A, B, C, D> PartialEq<BitSlice<C, D>> for BitSlice<A, B>
where A: Cursor, B: Bits, C: Cursor, D: Bits {
fn eq(&self, rhs: &BitSlice<C, D>) -> bool {
if self.len() != rhs.len() {
return false;
}
self.iter().zip(rhs.iter()).all(|(l, r)| l == r)
}
}
#[cfg(any(feature = "alloc", feature = "std"))]
impl<A, B, C, D> PartialEq<BitVec<C, D>> for BitSlice<A, B>
where A: Cursor, B: Bits, C: Cursor, D: Bits {
fn eq(&self, rhs: &BitVec<C, D>) -> bool {
<Self as PartialEq<BitSlice<C, D>>>::eq(self, &*rhs)
}
}
#[cfg(any(feature = "alloc", feature = "std"))]
impl<A, B, C, D> PartialEq<BitVec<C, D>> for &BitSlice<A, B>
where A: Cursor, B: Bits, C: Cursor, D: Bits {
fn eq(&self, rhs: &BitVec<C, D>) -> bool {
<BitSlice<A, B> as PartialEq<BitSlice<C, D>>>::eq(self, &*rhs)
}
}
impl<A, B, C, D> PartialOrd<BitSlice<C, D>> for BitSlice<A, B>
where A: Cursor, B: Bits, C: Cursor, D: Bits {
fn partial_cmp(&self, rhs: &BitSlice<C, D>) -> Option<Ordering> {
for (l, r) in self.iter().zip(rhs.iter()) {
match (l, r) {
(true, false) => return Some(Ordering::Greater),
(false, true) => return Some(Ordering::Less),
_ => continue,
}
}
self.len().partial_cmp(&rhs.len())
}
}
#[cfg(any(feature = "alloc", feature = "std"))]
impl<A, B, C, D> PartialOrd<BitVec<C, D>> for BitSlice<A, B>
where A: Cursor, B: Bits, C: Cursor, D: Bits {
fn partial_cmp(&self, rhs: &BitVec<C, D>) -> Option<Ordering> {
self.partial_cmp(&**rhs)
}
}
#[cfg(any(feature = "alloc", feature = "std"))]
impl<A, B, C, D> PartialOrd<BitVec<C, D>> for &BitSlice<A, B>
where A: Cursor, B: Bits, C: Cursor, D: Bits {
fn partial_cmp(&self, rhs: &BitVec<C, D>) -> Option<Ordering> {
(*self).partial_cmp(&**rhs)
}
}
impl<C, T> AsMut<[T]> for BitSlice<C, T>
where C: Cursor, T: Bits {
fn as_mut(&mut self) -> &mut [T] {
self.as_mut_slice()
}
}
impl<C, T> AsRef<[T]> for BitSlice<C, T>
where C: Cursor, T: Bits {
fn as_ref(&self) -> &[T] {
self.as_slice()
}
}
impl<'a, C, T> From<&'a T> for &'a BitSlice<C, T>
where C: Cursor, T: 'a + Bits {
fn from(src: &'a T) -> Self {
BitSlice::<C, T>::from_element(src)
}
}
impl<'a, C, T> From<&'a [T]> for &'a BitSlice<C, T>
where C: Cursor, T: 'a + Bits {
fn from(src: &'a [T]) -> Self {
BitSlice::<C, T>::from_slice(src)
}
}
impl<'a, C, T> From<&'a mut T> for &'a mut BitSlice<C, T>
where C: Cursor, T: 'a + Bits {
fn from(src: &'a mut T) -> Self {
BitSlice::<C, T>::from_element_mut(src)
}
}
impl<'a, C, T> From<&'a mut [T]> for &'a mut BitSlice<C, T>
where C: Cursor, T: 'a + Bits {
fn from(src: &'a mut [T]) -> Self {
BitSlice::<C, T>::from_slice_mut(src)
}
}
impl<'a, C, T> From<BitPtr<T>> for &'a BitSlice<C, T>
where C: Cursor, T: 'a + Bits {
fn from(src: BitPtr<T>) -> Self {
src.into_bitslice()
}
}
impl<C, T> From<BitPtr<T>> for &mut BitSlice<C, T>
where C: Cursor, T: Bits {
fn from(src: BitPtr<T>) -> Self {
src.into_bitslice_mut()
}
}
impl<C, T> Debug for BitSlice<C, T>
where C: Cursor, T: Bits {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.write_str("BitSlice<")?;
f.write_str(C::TYPENAME)?;
f.write_str(", ")?;
f.write_str(T::TYPENAME)?;
f.write_str("> ")?;
Display::fmt(self, f)
}
}
impl<C, T> Display for BitSlice<C, T>
where C: Cursor, T: Bits {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
struct Part<'a>(&'a str);
impl<'a> Debug for Part<'a> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.write_str(&self.0)
}
}
let mut dbg = f.debug_list();
if !self.is_empty() {
let mut w: [u8; 64] = [0; 64];
let writer =
|l: &mut DebugList, w: &mut [u8; 64], e: &T, from: u8, to: u8| {
let (from, to) = (from as usize, to as usize);
for (n, byte) in w.iter_mut().enumerate().take(to).skip(from) {
*byte = if e.get::<C>((n as u8).into()) { b'1' }
else { b'0' };
}
l.entry(&Part(unsafe {
str::from_utf8_unchecked(&w[from .. to])
}));
};
match self.bitptr().domain() {
BitDomain::Empty => {},
BitDomain::Minor(head, elt, tail) => {
writer(&mut dbg, &mut w, elt, *head, *tail)
},
BitDomain::Major(h, head, body, tail, t) => {
writer(&mut dbg, &mut w, head, *h, T::BITS);
for elt in body {
writer(&mut dbg, &mut w, elt, 0, T::BITS);
}
writer(&mut dbg, &mut w, tail, 0, *t);
},
BitDomain::PartialHead(h, head, body) => {
writer(&mut dbg, &mut w, head, *h, T::BITS);
for elt in body {
writer(&mut dbg, &mut w, elt, 0, T::BITS);
}
},
BitDomain::PartialTail(body, tail, t) => {
for elt in body {
writer(&mut dbg, &mut w, elt, 0, T::BITS);
}
writer(&mut dbg, &mut w, tail, 0, *t);
},
BitDomain::Spanning(body) => {
for elt in body {
writer(&mut dbg, &mut w, elt, 0, T::BITS);
}
},
}
}
dbg.finish()
}
}
impl<C, T> Hash for BitSlice<C, T>
where C: Cursor, T: Bits {
fn hash<H>(&self, hasher: &mut H)
where H: Hasher {
for bit in self {
hasher.write_u8(bit as u8);
}
}
}
impl<'a, C, T> IntoIterator for &'a BitSlice<C, T>
where C: Cursor, T: 'a + Bits {
type Item = bool;
type IntoIter = Iter<'a, C, T>;
fn into_iter(self) -> Self::IntoIter {
Iter {
inner: self
}
}
}
unsafe impl<C, T> Send for BitSlice<C, T>
where C: Cursor, T: Bits {}
unsafe impl<C, T> Sync for BitSlice<C, T>
where C: Cursor, T: Bits {}
impl<C, T, I> AddAssign<I> for BitSlice<C, T>
where C: Cursor, T: Bits,
I: IntoIterator<Item=bool>, I::IntoIter: DoubleEndedIterator {
#[allow(clippy::many_single_char_names)]
fn add_assign(&mut self, addend: I) {
use core::iter::repeat;
let mut addend_iter = addend.into_iter().rev().chain(repeat(false));
let mut c = false;
for place in (0 .. self.len()).rev() {
static JUMP: [u8; 8] = [0, 2, 2, 1, 2, 1, 1, 3];
let a = self[place];
let b = addend_iter.next().unwrap(); let idx = ((c as u8) << 2) | ((a as u8) << 1) | (b as u8);
let yz = JUMP[idx as usize];
let (y, z) = (yz & 2 != 0, yz & 1 != 0);
self.set(place, y);
c = z;
}
}
}
impl<C, T, I> BitAndAssign<I> for BitSlice<C, T>
where C: Cursor, T: Bits, I: IntoIterator<Item=bool> {
fn bitand_assign(&mut self, rhs: I) {
use core::iter;
rhs.into_iter()
.chain(iter::repeat(false))
.enumerate()
.take(self.len())
.for_each(|(idx, bit)| {
let val = self[idx] & bit;
self.set(idx, val);
});
}
}
impl<C, T, I> BitOrAssign<I> for BitSlice<C, T>
where C: Cursor, T: Bits, I: IntoIterator<Item=bool> {
fn bitor_assign(&mut self, rhs: I) {
for (idx, bit) in rhs.into_iter().enumerate().take(self.len()) {
let val = self[idx] | bit;
self.set(idx, val);
}
}
}
impl<C, T, I> BitXorAssign<I> for BitSlice<C, T>
where C: Cursor, T: Bits, I: IntoIterator<Item=bool> {
fn bitxor_assign(&mut self, rhs: I) {
rhs.into_iter()
.enumerate()
.take(self.len())
.for_each(|(idx, bit)| {
let val = self[idx] ^ bit;
self.set(idx, val);
})
}
}
impl<C, T> Index<usize> for BitSlice<C, T>
where C: Cursor, T: Bits {
type Output = bool;
fn index(&self, index: usize) -> &Self::Output {
let len = self.len();
assert!(index < len, "Index out of range: {} >= {}", index, len);
let h = self.bitptr().head();
let (elt, bit) = h.offset::<T>(index as isize);
if self.as_ref()[elt as usize].get::<C>(bit) { &true } else { &false }
}
}
impl<C, T> Index<Range<usize>> for BitSlice<C, T>
where C: Cursor, T: Bits {
type Output = Self;
fn index(&self, Range { start, end }: Range<usize>) -> &Self::Output {
let len = self.len();
assert!(
start <= len,
"Index {} out of range: {}",
start,
len,
);
assert!(end <= len, "Index {} out of range: {}", end, len);
assert!(end >= start, "Ranges can only run from low to high");
let (data, _, head, _) = self.bitptr().raw_parts();
let (skip, new_head) = head.offset::<T>(start as isize);
let (new_elts, new_tail) = new_head.span::<T>(end - start);
unsafe { BitPtr::new_unchecked(
data.offset(skip),
new_elts,
new_head,
new_tail,
) }.into()
}
}
impl<C, T> IndexMut<Range<usize>> for BitSlice<C, T>
where C: Cursor, T: Bits {
fn index_mut(
&mut self,
Range { start, end }: Range<usize>,
) -> &mut Self::Output {
(&self[start .. end]).bitptr().into_bitslice_mut()
}
}
impl<C, T> Index<RangeInclusive<usize>> for BitSlice<C, T>
where C: Cursor, T: Bits {
type Output = Self;
fn index(&self, index: RangeInclusive<usize>) -> &Self::Output {
let start = *index.start();
if let Some(end) = index.end().checked_add(1) {
&self[start .. end]
}
else {
&self[start ..]
}
}
}
impl<C, T> IndexMut<RangeInclusive<usize>> for BitSlice<C, T>
where C: Cursor, T: Bits {
fn index_mut(&mut self, index: RangeInclusive<usize>) -> &mut Self::Output {
let start = *index.start();
if let Some(end) = index.end().checked_add(1) {
&mut self[start .. end]
}
else {
&mut self[start ..]
}
}
}
impl<C, T> Index<RangeFrom<usize>> for BitSlice<C, T>
where C: Cursor, T: Bits {
type Output = Self;
fn index(&self, RangeFrom { start }: RangeFrom<usize>) -> &Self::Output {
&self[start .. self.len()]
}
}
impl<C, T> IndexMut<RangeFrom<usize>> for BitSlice<C, T>
where C: Cursor, T: Bits {
fn index_mut(
&mut self,
RangeFrom { start }: RangeFrom<usize>,
) -> &mut Self::Output {
let len = self.len();
&mut self[start .. len]
}
}
impl<C, T> Index<RangeFull> for BitSlice<C, T>
where C: Cursor, T: Bits {
type Output = Self;
fn index(&self, _: RangeFull) -> &Self::Output {
self
}
}
impl<C, T> IndexMut<RangeFull> for BitSlice<C, T>
where C: Cursor, T: Bits {
fn index_mut(&mut self, _: RangeFull) -> &mut Self::Output {
self
}
}
impl<C, T> Index<RangeTo<usize>> for BitSlice<C, T>
where C: Cursor, T: Bits {
type Output = Self;
fn index(&self, RangeTo { end }: RangeTo<usize>) -> &Self::Output {
&self[0 .. end]
}
}
impl<C, T> IndexMut<RangeTo<usize>> for BitSlice<C, T>
where C: Cursor, T: Bits {
fn index_mut(
&mut self,
RangeTo { end }: RangeTo<usize>,
) -> &mut Self::Output {
&mut self[0 .. end]
}
}
impl<C, T> Index<RangeToInclusive<usize>> for BitSlice<C, T>
where C: Cursor, T: Bits {
type Output = Self;
fn index(
&self,
RangeToInclusive { end }: RangeToInclusive<usize>,
) -> &Self::Output {
&self[0 ..= end]
}
}
impl<C, T> IndexMut<RangeToInclusive<usize>> for BitSlice<C, T>
where C: Cursor, T: Bits {
fn index_mut(
&mut self,
RangeToInclusive { end }: RangeToInclusive<usize>,
) -> &mut Self::Output {
&mut self[0 ..= end]
}
}
impl<'a, C, T> Neg for &'a mut BitSlice<C, T>
where C: Cursor, T: 'a + Bits {
type Output = Self;
fn neg(self) -> Self::Output {
if self.is_empty() || self.not_any() {
return self;
}
if self[0] {
self.set(0, false);
if self.not_any() {
return self;
}
self.set(0, true);
}
let _ = Not::not(&mut *self);
let one: &[T] = &[T::bits(true)];
let one_bs: &BitSlice<C, T> = one.into();
AddAssign::add_assign(&mut *self, &one_bs[.. 1]);
self
}
}
impl<'a, C, T> Not for &'a mut BitSlice<C, T>
where C: Cursor, T: 'a + Bits {
type Output = Self;
fn not(self) -> Self::Output {
match self.bitptr().domain_mut() {
BitDomainMut::Empty => {},
BitDomainMut::Minor(head, elt, tail) => {
for n in *head .. *tail {
let tmp = elt.get::<C>(n.into());
elt.set::<C>(n.into(), !tmp);
}
},
BitDomainMut::Major(h, head, body, tail, t) => {
for n in *h .. T::BITS {
let tmp = head.get::<C>(n.into());
head.set::<C>(n.into(), !tmp);
}
for elt in body {
*elt = !*elt;
}
for n in 0 .. *t {
let tmp = tail.get::<C>(n.into());
tail.set::<C>(n.into(), !tmp);
}
},
BitDomainMut::PartialHead(h, head, body) => {
for n in *h .. T::BITS {
let tmp = head.get::<C>(n.into());
head.set::<C>(n.into(), !tmp);
}
for elt in body {
*elt = !*elt;
}
},
BitDomainMut::PartialTail(body, tail, t) => {
for elt in body {
*elt = !*elt;
}
for n in 0 .. *t {
let tmp = tail.get::<C>(n.into());
tail.set::<C>(n.into(), !tmp);
}
},
BitDomainMut::Spanning(body) => {
for elt in body {
*elt = !*elt;
}
},
}
self
}
}
__bitslice_shift!(u8, u16, u32, u64, i8, i16, i32, i64);
impl<C, T> ShlAssign<usize> for BitSlice<C, T>
where C: Cursor, T: Bits {
fn shl_assign(&mut self, shamt: usize) {
use core::ops::Shr;
if shamt == 0 {
return;
}
let len = self.len();
if shamt >= len {
self.set_all(false);
return;
}
if shamt & T::MASK as usize == 0 {
let offset = shamt.shr(T::INDX);
let rem = self.as_ref().len().saturating_sub(offset);
for n in *self.bitptr().tail() .. T::BITS {
self.as_mut()[len.saturating_sub(1)].set::<C>(n.into(), false);
}
let head: *mut T = self.as_mut_ptr();
let body: *const T = &self.as_ref()[offset];
let tail: *mut T = &mut self.as_mut()[rem];
unsafe {
ptr::copy(body, head, rem);
ptr::write_bytes(tail, 0, offset);
}
return;
}
for (to, from) in (shamt .. len).enumerate() {
let val = self[from];
self.set(to, val);
}
for bit in (len.saturating_sub(shamt)) .. len {
self.set(bit, false);
}
}
}
impl<C, T> ShrAssign<usize> for BitSlice<C, T>
where C: Cursor, T: Bits {
fn shr_assign(&mut self, shamt: usize) {
if shamt == 0 {
return;
}
let len = self.len();
if shamt >= len {
self.set_all(false);
return;
}
if shamt & T::MASK as usize == 0 {
let offset = shamt >> T::INDX;
let rem = self.as_ref().len().saturating_sub(offset);
for n in 0 .. *self.bitptr().head() {
self.as_mut()[0].set::<C>(n.into(), false);
}
let head: *mut T = self.as_mut_ptr();
let body: *mut T = &mut self.as_mut()[offset];
unsafe {
ptr::copy(head, body, rem);
ptr::write_bytes(head, 0, offset);
}
return;
}
for (from, to) in (shamt .. len).enumerate().rev() {
let val = self[from];
self.set(to, val);
}
for bit in 0 .. shamt {
self.set(bit, false);
}
}
}
#[derive(Clone, Debug)]
pub struct Chunks<'a, C, T>
where C: Cursor, T: 'a + Bits {
inner: &'a BitSlice<C, T>,
width: usize,
}
impl<'a, C, T> DoubleEndedIterator for Chunks<'a, C, T>
where C: Cursor, T: 'a + Bits {
fn next_back(&mut self) -> Option<Self::Item> {
if self.inner.is_empty() {
return None;
}
let len = self.inner.len();
let rem = len % self.width;
let size = if rem == 0 { self.width } else { rem };
let (head, tail) = self.inner.split_at(len - size);
self.inner = head;
Some(tail)
}
}
impl<'a, C, T> ExactSizeIterator for Chunks<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> FusedIterator for Chunks<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> Iterator for Chunks<'a, C, T>
where C: Cursor, T: 'a + Bits {
type Item = &'a BitSlice<C, T>;
fn next(&mut self) -> Option<Self::Item> {
use core::cmp::min;
if self.inner.is_empty() {
return None;
}
let size = min(self.inner.len(), self.width);
let (head, tail) = self.inner.split_at(size);
self.inner = tail;
Some(head)
}
fn size_hint(&self) -> (usize, Option<usize>) {
if self.inner.is_empty() {
return (0, Some(0));
}
let len = self.inner.len();
let (n, r) = (len / self.width, len % self.width);
let len = n + (r > 0) as usize;
(len, Some(len))
}
fn count(self) -> usize {
self.len()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
use core::cmp::min;
let (start, ovf) = n.overflowing_mul(self.width);
let len = self.inner.len();
if start >= len || ovf {
self.inner = BitSlice::empty();
return None;
}
let end = start.checked_add(self.width)
.map(|s| min(s, len))
.unwrap_or(len);
let out = &self.inner[start .. end];
self.inner = &self.inner[end ..];
Some(out)
}
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
}
#[derive(Debug)]
pub struct ChunksMut<'a, C, T>
where C: Cursor, T: 'a + Bits {
inner: &'a mut BitSlice<C, T>,
width: usize,
}
impl<'a, C, T> DoubleEndedIterator for ChunksMut<'a, C, T>
where C: Cursor, T: 'a + Bits {
fn next_back(&mut self) -> Option<Self::Item> {
if self.inner.is_empty() {
return None;
}
let len = self.inner.len();
let rem = len % self.width;
let size = if rem == 0 { self.width } else { rem };
let tmp = mem::replace(&mut self.inner, BitSlice::empty_mut());
let (head, tail) = tmp.split_at_mut(len - size);
self.inner = head;
Some(tail)
}
}
impl<'a, C, T> ExactSizeIterator for ChunksMut<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> FusedIterator for ChunksMut<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> Iterator for ChunksMut<'a, C, T>
where C: Cursor, T: 'a + Bits {
type Item = &'a mut BitSlice<C, T>;
fn next(&mut self) -> Option<Self::Item> {
use core::cmp::min;
if self.inner.is_empty() {
return None;
}
let size = min(self.inner.len(), self.width);
let tmp = mem::replace(&mut self.inner, BitSlice::empty_mut());
let (head, tail) = tmp.split_at_mut(size);
self.inner = tail;
Some(head)
}
fn size_hint(&self) -> (usize, Option<usize>) {
if self.inner.is_empty() {
return (0, Some(0));
}
let len = self.inner.len();
let (n, r) = (len / self.width, len % self.width);
let len = n + (r > 0) as usize;
(len, Some(len))
}
fn count(self) -> usize {
self.len()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
use core::cmp::min;
let (start, ovf) = n.overflowing_mul(self.width);
let len = self.inner.len();
if start >= len || ovf {
self.inner = BitSlice::empty_mut();
return None;
}
let end = start.checked_add(self.width)
.map(|s| min(s, len))
.unwrap_or(len);
let tmp = mem::replace(&mut self.inner, BitSlice::empty_mut());
let (head, tail) = tmp.split_at_mut(start);
let (_, nth) = head.split_at_mut(end - start);
self.inner = tail;
Some(nth)
}
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
}
#[derive(Clone, Debug)]
pub struct ChunksExact<'a, C, T>
where C: Cursor, T: 'a + Bits {
inner: &'a BitSlice<C, T>,
extra: &'a BitSlice<C, T>,
width: usize,
}
impl<'a, C, T> ChunksExact<'a, C, T>
where C: Cursor, T: 'a + Bits {
pub fn remainder(&self) -> &'a BitSlice<C, T> {
self.extra
}
}
impl<'a, C, T> DoubleEndedIterator for ChunksExact<'a, C, T>
where C: Cursor, T: 'a + Bits {
fn next_back(&mut self) -> Option<Self::Item> {
if self.inner.len() < self.width {
self.inner = BitSlice::empty();
return None;
}
let (head, tail) = self.inner.split_at(self.inner.len() - self.width);
self.inner = head;
Some(tail)
}
}
impl<'a, C, T> ExactSizeIterator for ChunksExact<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> FusedIterator for ChunksExact<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> Iterator for ChunksExact<'a, C, T>
where C: Cursor, T: 'a + Bits {
type Item = &'a BitSlice<C, T>;
fn next(&mut self) -> Option<Self::Item> {
if self.inner.len() < self.width {
self.inner = BitSlice::empty();
return None;
}
let (head, tail) = self.inner.split_at(self.width);
self.inner = tail;
Some(head)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.inner.len() / self.width;
(len, Some(len))
}
fn count(self) -> usize {
self.len()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (start, ovf) = n.overflowing_mul(self.width);
if start >= self.inner.len() || ovf {
self.inner = BitSlice::empty();
return None;
}
let (_, tail) = self.inner.split_at(start);
self.inner = tail;
self.next()
}
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
}
#[derive(Debug)]
pub struct ChunksExactMut<'a, C, T>
where C: Cursor, T: 'a + Bits {
inner: &'a mut BitSlice<C, T>,
extra: &'a mut BitSlice<C, T>,
width: usize,
}
impl<'a, C, T> ChunksExactMut<'a, C, T>
where C: Cursor, T: 'a + Bits {
pub fn into_remainder(self) -> &'a mut BitSlice<C, T> {
self.extra
}
}
impl<'a, C, T> DoubleEndedIterator for ChunksExactMut<'a, C, T>
where C: Cursor, T: 'a + Bits {
fn next_back(&mut self) -> Option<Self::Item> {
unimplemented!()
}
}
impl<'a, C, T> ExactSizeIterator for ChunksExactMut<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> FusedIterator for ChunksExactMut<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> Iterator for ChunksExactMut<'a, C, T>
where C: Cursor, T: 'a + Bits {
type Item = &'a mut BitSlice<C, T>;
fn next(&mut self) -> Option<Self::Item> {
if self.inner.len() < self.width {
self.inner = BitSlice::empty_mut();
return None;
}
let tmp = mem::replace(&mut self.inner, BitSlice::empty_mut());
let (head, tail) = tmp.split_at_mut(self.width);
self.inner = tail;
Some(head)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.inner.len() / self.width;
(len, Some(len))
}
fn count(self) -> usize {
self.len()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (start, ovf) = n.overflowing_mul(self.width);
if start >= self.inner.len() || ovf {
self.inner = BitSlice::empty_mut();
return None;
}
let tmp = mem::replace(&mut self.inner, BitSlice::empty_mut());
let (_, tail) = tmp.split_at_mut(start);
self.inner = tail;
self.next()
}
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
}
#[derive(Clone, Debug)]
pub struct Iter<'a, C, T>
where C: Cursor, T: 'a + Bits {
inner: &'a BitSlice<C, T>,
}
impl<'a, C, T> Iter<'a, C, T>
where C: Cursor, T: 'a + Bits {
#[allow(dead_code)]
pub(crate) fn bitptr(&self) -> BitPtr<T> {
self.inner.bitptr()
}
}
impl<'a, C, T> DoubleEndedIterator for Iter<'a, C, T>
where C: Cursor, T: 'a + Bits {
fn next_back(&mut self) -> Option<Self::Item> {
if self.inner.is_empty() {
return None;
}
let len = self.inner.len();
let out = self.inner[len - 1];
self.inner = &self.inner[.. len - 1];
Some(out)
}
}
impl<'a, C, T> ExactSizeIterator for Iter<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> FusedIterator for Iter<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> Iterator for Iter<'a, C, T>
where C: Cursor, T: 'a + Bits {
type Item = bool;
fn next(&mut self) -> Option<Self::Item> {
if self.inner.is_empty() {
return None;
}
let out = self.inner[0];
self.inner = &self.inner[1 ..];
Some(out)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.inner.len();
(len, Some(len))
}
fn count(self) -> usize {
self.len()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
if n >= self.len() {
self.inner = BitSlice::empty();
return None;
}
self.inner = &self.inner[n ..];
self.next()
}
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
}
#[derive(Clone, Debug)]
pub struct RChunks<'a, C, T>
where C: Cursor, T: 'a + Bits {
inner: &'a BitSlice<C, T>,
width: usize,
}
impl<'a, C, T> DoubleEndedIterator for RChunks<'a, C, T>
where C: Cursor, T: 'a + Bits {
fn next_back(&mut self) -> Option<Self::Item> {
if self.inner.is_empty() {
return None;
}
let len = self.inner.len();
let rem = len % self.width;
let size = if rem == 0 { self.width } else { rem };
let (head, tail) = self.inner.split_at(size);
self.inner = tail;
Some(head)
}
}
impl<'a, C, T> ExactSizeIterator for RChunks<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> FusedIterator for RChunks<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> Iterator for RChunks<'a, C, T>
where C: Cursor, T: 'a + Bits {
type Item = &'a BitSlice<C, T>;
fn next(&mut self) -> Option<Self::Item> {
use core::cmp::min;
if self.inner.is_empty() {
return None;
}
let len = self.inner.len();
let size = min(len, self.width);
let (head, tail) = self.inner.split_at(len - size);
self.inner = head;
Some(tail)
}
fn size_hint(&self) -> (usize, Option<usize>) {
if self.inner.is_empty() {
return (0, Some(0));
}
let len = self.inner.len();
let (len, rem) = (len / self.width, len % self.width);
let len = len + (rem > 0) as usize;
(len, Some(len))
}
fn count(self) -> usize {
self.len()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, ovf) = n.overflowing_mul(self.width);
if end >= self.inner.len() || ovf {
self.inner = BitSlice::empty();
return None;
}
let end = self.inner.len() - end;
let start = end.checked_sub(self.width).unwrap_or(0);
let nth = &self.inner[start .. end];
self.inner = &self.inner[.. start];
Some(nth)
}
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
}
#[derive(Debug)]
pub struct RChunksMut<'a, C, T>
where C: Cursor, T: 'a + Bits {
inner: &'a mut BitSlice<C, T>,
width: usize,
}
impl<'a, C, T> DoubleEndedIterator for RChunksMut<'a, C, T>
where C: Cursor, T: 'a + Bits {
fn next_back(&mut self) -> Option<Self::Item> {
if self.inner.is_empty() {
return None;
}
let rem = self.inner.len() % self.width;
let size = if rem == 0 { self.width } else { rem };
let tmp = mem::replace(&mut self.inner, BitSlice::empty_mut());
let (head, tail) = tmp.split_at_mut(size);
self.inner = tail;
Some(head)
}
}
impl<'a, C, T> ExactSizeIterator for RChunksMut<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> FusedIterator for RChunksMut<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> Iterator for RChunksMut<'a, C, T>
where C: Cursor, T: 'a + Bits {
type Item = &'a mut BitSlice<C, T>;
fn next(&mut self) -> Option<Self::Item> {
use core::cmp::min;
if self.inner.is_empty() {
return None;
}
let size = min(self.inner.len(), self.width);
let tmp = mem::replace(&mut self.inner, BitSlice::empty_mut());
let tlen = tmp.len();
let (head, tail) = tmp.split_at_mut(tlen - size);
self.inner = head;
Some(tail)
}
fn size_hint(&self) -> (usize, Option<usize>) {
if self.inner.is_empty() {
return (0, Some(0));
}
let len = self.inner.len();
let (len, rem) = (len / self.width, len % self.width);
let len = len + (rem > 0) as usize;
(len, Some(len))
}
fn count(self) -> usize {
self.len()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, ovf) = n.overflowing_mul(self.width);
if end >= self.inner.len() || ovf {
self.inner = BitSlice::empty_mut();
return None;
}
let end = self.inner.len() - end;
let start = end.checked_sub(self.width).unwrap_or(0);
let tmp = mem::replace(&mut self.inner, BitSlice::empty_mut());
let (head, tail) = tmp.split_at_mut(start);
let (nth, _) = tail.split_at_mut(end - start);
self.inner = head;
Some(nth)
}
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
}
#[derive(Clone, Debug)]
pub struct RChunksExact<'a, C, T>
where C: Cursor, T: 'a + Bits {
inner: &'a BitSlice<C, T>,
extra: &'a BitSlice<C, T>,
width: usize,
}
impl<'a, C, T> RChunksExact<'a, C, T>
where C: Cursor, T: 'a + Bits {
pub fn remainder(&self) -> &'a BitSlice<C, T> {
self.extra
}
}
impl<'a, C, T> DoubleEndedIterator for RChunksExact<'a, C, T>
where C: Cursor, T: 'a + Bits {
fn next_back(&mut self) -> Option<Self::Item> {
if self.inner.len() < self.width {
self.inner = BitSlice::empty();
return None;
}
let (head, tail) = self.inner.split_at(self.width);
self.inner = tail;
Some(head)
}
}
impl<'a, C, T> ExactSizeIterator for RChunksExact<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> FusedIterator for RChunksExact<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> Iterator for RChunksExact<'a, C, T>
where C: Cursor, T: 'a + Bits {
type Item = &'a BitSlice<C, T>;
fn next(&mut self) -> Option<Self::Item> {
if self.inner.len() < self.width {
self.inner = BitSlice::empty();
return None;
}
let (head, tail) = self.inner.split_at(self.inner.len() - self.width);
self.inner = head;
Some(tail)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let n = self.inner.len() / self.width;
(n, Some(n))
}
fn count(self) -> usize {
self.len()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, ovf) = n.overflowing_mul(self.width);
if end >= self.inner.len() || ovf {
self.inner = BitSlice::empty();
return None;
}
let (head, _) = self.inner.split_at(self.inner.len() - end);
self.inner = head;
self.next()
}
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
}
#[derive(Debug)]
pub struct RChunksExactMut<'a, C, T>
where C: Cursor, T: 'a + Bits {
inner: &'a mut BitSlice<C, T>,
extra: &'a mut BitSlice<C, T>,
width: usize,
}
impl<'a, C, T> RChunksExactMut<'a, C, T>
where C: Cursor, T: 'a + Bits {
pub fn into_remainder(self) -> &'a mut BitSlice<C, T> {
self.extra
}
}
impl<'a, C, T> DoubleEndedIterator for RChunksExactMut<'a, C, T>
where C: Cursor, T: 'a + Bits {
fn next_back(&mut self) -> Option<Self::Item> {
if self.inner.len() < self.width {
self.inner = BitSlice::empty_mut();
return None;
}
let tmp = mem::replace(&mut self.inner, BitSlice::empty_mut());
let (head, tail) = tmp.split_at_mut(self.width);;
self.inner = tail;
Some(head)
}
}
impl<'a, C, T> ExactSizeIterator for RChunksExactMut<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> FusedIterator for RChunksExactMut<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> Iterator for RChunksExactMut<'a, C, T>
where C: Cursor, T: 'a + Bits {
type Item = &'a mut BitSlice<C, T>;
fn next(&mut self) -> Option<Self::Item> {
if self.inner.len() < self.width {
self.inner = BitSlice::empty_mut();
return None;
}
let tmp = mem::replace(&mut self.inner, BitSlice::empty_mut());
let tlen = tmp.len();
let (head, tail) = tmp.split_at_mut(tlen - self.width);
self.inner = head;
Some(tail)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let n = self.inner.len() / self.width;
(n, Some(n))
}
fn count(self) -> usize {
self.len()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, ovf) = n.overflowing_mul(self.width);
if end >= self.inner.len() || ovf {
self.inner = BitSlice::empty_mut();
return None;
}
let tmp = mem::replace(&mut self.inner, BitSlice::empty_mut());
let tlen = tmp.len();
let (head, _) = tmp.split_at_mut(tlen - end);
self.inner = head;
self.next()
}
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
}
#[derive(Clone, Debug)]
pub struct Windows<'a, C, T>
where C: Cursor, T: 'a + Bits {
inner: &'a BitSlice<C, T>,
width: usize,
}
impl<'a, C, T> DoubleEndedIterator for Windows<'a, C, T>
where C: Cursor, T: 'a + Bits {
fn next_back(&mut self) -> Option<Self::Item> {
if self.inner.is_empty() || self.width > self.inner.len() {
self.inner = BitSlice::empty();
return None;
}
let len = self.inner.len();
let out = &self.inner[len - self.width ..];
self.inner = &self.inner[.. len - 1];
Some(out)
}
}
impl<'a, C, T> ExactSizeIterator for Windows<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> FusedIterator for Windows<'a, C, T>
where C: Cursor, T: 'a + Bits {}
impl<'a, C, T> Iterator for Windows<'a, C, T>
where C: Cursor, T: 'a + Bits {
type Item = &'a BitSlice<C, T>;
fn next(&mut self) -> Option<Self::Item> {
if self.width > self.inner.len() {
self.inner = BitSlice::empty();
None
}
else {
let out = &self.inner[.. self.width];
self.inner = &self.inner[1 ..];
Some(out)
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.inner.len();
if self.width > len {
(0, Some(0))
}
else {
let len = len - self.width + 1;
(len, Some(len))
}
}
fn count(self) -> usize {
self.len()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, ovf) = n.overflowing_add(self.width);
if end > self.inner.len() || ovf {
self.inner = BitSlice::empty();
return None;
}
let out = &self.inner[n .. end];
self.inner = &self.inner[n + 1 ..];
Some(out)
}
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
}