#![cfg(feature = "alloc")]
use core::{
borrow::{
Borrow,
BorrowMut,
},
clone::Clone,
cmp::{
Eq,
Ord,
Ordering,
PartialEq,
PartialOrd,
},
convert::{
AsMut,
AsRef,
From,
},
default::Default,
fmt::{
self,
Debug,
Display,
Formatter,
},
hash::{
Hash,
Hasher,
},
iter::{
DoubleEndedIterator,
ExactSizeIterator,
Extend,
FromIterator,
Iterator,
IntoIterator,
},
marker::PhantomData,
mem,
ops::{
Add,
AddAssign,
BitAnd,
BitAndAssign,
BitOr,
BitOrAssign,
BitXor,
BitXorAssign,
Deref,
DerefMut,
Drop,
Index,
Neg,
Not,
Shl,
ShlAssign,
Shr,
ShrAssign,
Sub,
SubAssign,
},
ptr,
};
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::{
borrow::ToOwned,
boxed::Box,
vec::Vec,
};
#[cfg(feature = "std")]
use std::borrow::ToOwned;
#[cfg_attr(nightly, repr(transparent))]
pub struct BitVec<E = crate::BigEndian, T = u8>
where E: crate::Endian, T: crate::Bits {
_endian: PhantomData<E>,
inner: Vec<T>,
}
impl<E, T> BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
pub fn new() -> Self {
Self {
_endian: PhantomData,
inner: Vec::new(),
}
}
pub fn with_capacity(capacity: usize) -> Self {
let (elts, bits) = T::split(capacity);
let cap = elts + if bits > 0 { 1 } else { 0 };
Self {
inner: Vec::with_capacity(cap),
_endian: PhantomData,
}
}
pub fn capacity(&self) -> usize {
assert!(self.inner.capacity() <= T::MAX_ELT, "Capacity overflow");
self.inner.capacity() << T::BITS
}
pub fn push(&mut self, value: bool) {
assert!(self.len() < core::usize::MAX, "Vector will overflow!");
let bit = self.bits();
let cursor = E::curr::<T>(bit);
self.do_with_tail(|elt| elt.set(cursor, value));
if bit == T::MASK {
let elts = self.elts();
assert!(elts <= T::MAX_ELT, "Elements will overflow");
unsafe { self.set_elts(elts + 1) };
}
unsafe { self.set_bits((bit + 1) & T::MASK); }
}
pub fn pop(&mut self) -> Option<bool> {
if self.inner.is_empty() {
return None;
}
let cur = self.len() - 1;
let ret = self.get(cur);
unsafe { self.inner.set_len(cur); }
Some(ret)
}
pub fn clear(&mut self) {
self.do_with_vec(Vec::<T>::clear);
}
pub fn reserve(&mut self, additional: usize) {
let (cur_elts, cur_bits) = T::split(self.raw_len());
let (new_elts, new_bits) = T::split(additional);
let (elts, bits) = (cur_elts + new_elts, cur_bits + new_bits);
let extra = elts + if bits > 0 { 1 } else { 0 };
assert!(self.raw_len() + extra <= T::MAX_ELT, "Capacity would overflow");
self.do_with_vec(|v| v.reserve(extra));
}
pub fn shrink_to_fit(&mut self) {
self.do_with_vec(Vec::<T>::shrink_to_fit);
}
pub fn truncate(&mut self, len: usize) {
let (elts, bits) = T::split(len);
let trunc = elts + if bits > 0 { 1 } else { 0 };
self.do_with_vec(|v| v.truncate(trunc));
unsafe { self.set_len(len); }
}
pub fn into_boxed_slice(self) -> Box<[T]> {
let raw = self.raw_len();
let buf = unsafe {
let mut buf = ptr::read(&self.inner);
mem::forget(self);
buf.set_len(raw);
buf
};
buf.into_boxed_slice()
}
pub fn set_store(&mut self, element: T) {
self.do_with_vec(|v| {
let len = v.len();
let cap = v.capacity();
unsafe { v.set_len(cap); }
for elt in v.iter_mut() {
*elt = element;
}
unsafe { v.set_len(len); }
});
}
unsafe fn set_bits(&mut self, count: u8) {
assert!(count <= T::MASK, "Index out of range");
let elt = self.len() & !(T::MASK as usize);
self.inner.set_len(elt | count as usize);
}
unsafe fn set_elts(&mut self, count: usize) {
assert!(count <= T::MAX_ELT, "Length out of range");
let bit = self.len() & (T::MASK as usize);
self.inner.set_len(T::join(count, bit as u8));
}
pub unsafe fn set_len(&mut self, len: usize) {
assert!(len <= self.capacity(), "Length cannot exceed capacity");
self.inner.set_len(len);
}
fn do_with_vec<F: Fn(&mut Vec<T>) -> R, R>(&mut self, op: F) -> R {
let len = self.len();
let old = self.raw_len();
unsafe { self.inner.set_len(old); }
let ret = op(&mut self.inner);
let new = self.inner.len();
assert!(new <= T::MAX_ELT, "Length out of range!");
if new == old {
unsafe {
self.inner.set_len(len);
}
}
else {
unsafe {
self.set_bits(0);
self.set_elts(new);
}
}
ret
}
fn do_with_tail<F: Fn(&mut T) -> R, R>(&mut self, op: F) -> R {
if self.bits() == 0 {
self.push_elt();
}
let old_len = self.inner.len();
let elts = self.elts();
unsafe {
self.inner.set_len(elts + 1);
let ret = op(&mut self.inner[elts]);
self.inner.set_len(old_len);
ret
}
}
fn push_elt(&mut self) {
let len = self.len();
self.do_with_vec(|v| v.push(Default::default()));
unsafe {
self.inner.set_len(len);
}
}
fn fmt_header(&self, fmt: &mut Formatter) -> fmt::Result {
write!(fmt, "BitVec<{}, {}>", E::TY, T::TY)
}
}
impl<E, T> Borrow<crate::BitSlice<E, T>> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn borrow(&self) -> &crate::BitSlice<E, T> {
&*self
}
}
impl<E, T> BorrowMut<crate::BitSlice<E, T>> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn borrow_mut(&mut self) -> &mut crate::BitSlice<E, T> {
&mut *self
}
}
impl<E, T> Clone for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn clone(&self) -> Self {
let mut out = Self::from(self.as_ref());
unsafe {
out.inner.set_len(self.len());
}
out
}
fn clone_from(&mut self, other: &Self) {
self.clear();
self.reserve(other.len());
unsafe {
let src = other.as_ptr();
let dst = self.as_mut_ptr();
let len = other.raw_len();
ptr::copy_nonoverlapping(src, dst, len);
}
}
}
impl<E, T> Eq for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {}
impl<E, T> Ord for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn cmp(&self, rhs: &Self) -> Ordering {
crate::BitSlice::cmp(&self, &rhs)
}
}
impl<A, B, C, D> PartialEq<BitVec<C, D>> for BitVec<A, B>
where A: crate::Endian, B: crate::Bits, C: crate::Endian, D: crate::Bits {
fn eq(&self, rhs: &BitVec<C, D>) -> bool {
crate::BitSlice::eq(&self, &rhs)
}
}
impl<A, B, C, D> PartialOrd<BitVec<C, D>> for BitVec<A, B>
where A: crate::Endian, B: crate::Bits, C: crate::Endian, D: crate::Bits {
fn partial_cmp(&self, rhs: &BitVec<C, D>) -> Option<Ordering> {
crate::BitSlice::partial_cmp(&self, &rhs)
}
}
impl<E, T> AsMut<[T]> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn as_mut(&mut self) -> &mut [T] {
crate::BitSlice::as_mut(self)
}
}
impl<E, T> AsRef<[T]> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn as_ref(&self) -> &[T] {
crate::BitSlice::as_ref(self)
}
}
impl<'a, E, T> From<&'a crate::BitSlice<E, T>> for BitVec<E, T>
where E: crate::Endian, T: 'a + crate::Bits {
fn from(src: &'a crate::BitSlice<E, T>) -> Self {
src.to_owned()
}
}
impl<'a, E, T> From<&'a [bool]> for BitVec<E, T>
where E: crate::Endian, T: 'a + crate::Bits {
fn from(src: &'a [bool]) -> Self {
let mut out = Self::with_capacity(src.len());
for bit in src {
out.push(*bit);
}
out
}
}
impl<'a, E, T> From<&'a [T]> for BitVec<E, T>
where E: crate::Endian, T: 'a + crate::Bits {
fn from(src: &'a [T]) -> Self {
<&crate::BitSlice<E, T>>::from(src).to_owned()
}
}
impl<E, T> From<Box<[T]>> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn from(src: Box<[T]>) -> Self {
assert!(src.len() <= T::MAX_ELT, "Source slice too long!");
Self::from(Vec::from(src))
}
}
impl<E, T> From<Vec<T>> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn from(src: Vec<T>) -> Self {
let elts = src.len();
assert!(elts <= T::MAX_ELT, "Source vector too long!");
let mut out = Self {
inner: src,
_endian: PhantomData::<E>,
};
unsafe {
out.set_bits(0);
out.set_elts(elts);
}
out
}
}
impl<T: crate::Bits> From<BitVec<crate::LittleEndian, T>>
for BitVec<crate::BigEndian, T> {
fn from(mut src: BitVec<crate::LittleEndian, T>) -> Self {
let bits = src.bits();
if bits > 0 {
let shamt = T::WIDTH - bits;
src.do_with_tail(|elt| *elt <<= shamt);
}
unsafe { mem::transmute(src) }
}
}
impl<T: crate::Bits> From<BitVec<crate::BigEndian, T>>
for BitVec<crate::LittleEndian, T> {
fn from(mut src: BitVec<crate::BigEndian, T>) -> Self {
let bits = src.bits();
if bits > 0 {
let shamt = T::WIDTH - bits;
src.do_with_tail(|elt| *elt >>= shamt);
}
unsafe { mem::transmute(src) }
}
}
impl<E, T> Default for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn default() -> Self {
Self {
inner: Default::default(),
_endian: Default::default(),
}
}
}
impl<E, T> Debug for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
let alt = fmt.alternate();
self.fmt_header(fmt)?;
fmt.write_str(" [")?;
if alt { writeln!(fmt)?; fmt.write_str(" ")?; }
self.fmt_body(fmt, true)?;
if alt { writeln!(fmt)?; }
fmt.write_str("]")
}
}
impl<E, T> Display for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
self.fmt_body(fmt, false)
}
}
impl<E, T> Hash for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn hash<H>(&self, hasher: &mut H)
where H: Hasher {
<crate::BitSlice<E, T> as Hash>::hash(&self, hasher)
}
}
impl<E, T> Extend<bool> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn extend<I>(&mut self, src: I)
where I: IntoIterator<Item=bool> {
let iter = src.into_iter();
match iter.size_hint() {
(_, Some(hi)) => self.reserve(hi),
(lo, None) => self.reserve(lo),
}
for bit in iter {
self.push(bit);
}
self.shrink_to_fit();
}
}
impl<E, T> FromIterator<bool> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn from_iter<I: IntoIterator<Item=bool>>(src: I) -> Self {
let iter = src.into_iter();
let mut out = match iter.size_hint() {
(_, Some(len)) |
(len, _) if len > 0 => Self::with_capacity(len),
_ => Self::new(),
};
for bit in iter {
out.push(bit);
}
out
}
}
impl<E, T> IntoIterator for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
type Item = bool;
#[doc(hidden)]
type IntoIter = IntoIter<E, T>;
fn into_iter(self) -> Self::IntoIter {
Self::IntoIter::from(self)
}
}
impl<E, T> Add for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
type Output = Self;
fn add(mut self, addend: Self) -> Self::Output {
self += addend;
self
}
}
impl<E, T> AddAssign for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn add_assign(&mut self, mut addend: Self) {
use core::iter::repeat;
if addend.len() > self.len() {
mem::swap(self, &mut addend);
return *self += addend;
}
let mut c = false;
let mut stack = BitVec::<E, T>::with_capacity(self.len());
for (a, b) in self.iter().rev().zip(addend.into_iter().rev().chain(repeat(false))) {
static JUMP: [u8; 8] = [
0, 2, 2, 1, 2, 1, 1, 3, ];
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);
stack.push(y);
c = z;
}
if c {
stack.push(true);
}
self.clear();
while let Some(bit) = stack.pop() {
self.push(bit);
}
}
}
impl<E, T, I> BitAnd<I> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> {
type Output = Self;
fn bitand(mut self, rhs: I) -> Self::Output {
self &= rhs;
self
}
}
impl<E, T, I> BitAndAssign<I> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> {
fn bitand_assign(&mut self, rhs: I) {
let mut len = 0;
for (idx, other) in (0 .. self.len()).zip(rhs.into_iter()) {
let val = self.get(idx) & other;
self.set(idx, val);
len += 1;
}
self.truncate(len);
}
}
impl<E, T, I> BitOr<I> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> {
type Output = Self;
fn bitor(mut self, rhs: I) -> Self::Output {
self |= rhs;
self
}
}
impl<E, T, I> BitOrAssign<I> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> {
fn bitor_assign(&mut self, rhs: I) {
let mut len = 0;
for (idx, other) in (0 .. self.len()).zip(rhs.into_iter()) {
let val = self.get(idx) | other;
self.set(idx, val);
len += 1;
}
self.truncate(len);
}
}
impl<E, T, I> BitXor<I> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> {
type Output = Self;
fn bitxor(mut self, rhs: I) -> Self::Output {
self ^= rhs;
self
}
}
impl<E, T, I> BitXorAssign<I> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> {
fn bitxor_assign(&mut self, rhs: I) {
let mut len = 0;
for (idx, other) in (0 .. self.len()).zip(rhs.into_iter()) {
let val = self.get(idx) ^ other;
self.set(idx, val);
len += 1;
}
self.truncate(len);
}
}
impl<E, T> Deref for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
type Target = crate::BitSlice<E, T>;
fn deref(&self) -> &Self::Target {
#[allow(clippy::transmute_ptr_to_ptr)]
unsafe { mem::transmute(&self.inner as &[T]) }
}
}
impl<E, T> DerefMut for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn deref_mut(&mut self) -> &mut Self::Target {
#[allow(clippy::transmute_ptr_to_ptr)]
unsafe { mem::transmute(&mut self.inner as &mut [T]) }
}
}
impl<E, T> Drop for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn drop(&mut self) {
let raw = self.raw_len();
unsafe { self.inner.set_len(raw); }
}
}
impl<E, T> Index<usize> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
type Output = bool;
fn index(&self, cursor: usize) -> &Self::Output {
assert!(cursor < self.len(), "Index out of range!");
let (elt, bit) = T::split(cursor);
if (self.inner[elt]).get(E::curr::<T>(bit)) { &true } else { &false }
}
}
impl<E, T> Index<(usize, u8)> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
type Output = bool;
fn index(&self, (elt, bit): (usize, u8)) -> &Self::Output {
assert!(T::join(elt, bit) < self.len(), "Index out of range!");
if (self.inner[elt]).get(E::curr::<T>(bit)) { &true } else { &false }
}
}
impl<E, T> Neg for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
type Output = Self;
fn neg(mut self) -> Self::Output {
if self.is_empty() || self.not_any() {
return self;
}
self = !self;
self += BitVec::<E, T>::from(&[true] as &[bool]);
self
}
}
impl<E, T> Not for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
type Output = Self;
fn not(mut self) -> Self::Output {
let _ = !(&mut *self);
self
}
}
__bitvec_shift!(u8, u16, u32, u64, i8, i16, i32, i64);
impl<E, T> Shl<usize> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
type Output = Self;
fn shl(mut self, shamt: usize) -> Self::Output {
self <<= shamt;
self
}
}
impl<E, T> ShlAssign<usize> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
#[allow(clippy::suspicious_op_assign_impl)]
fn shl_assign(&mut self, shamt: usize) {
let len = self.len();
if shamt >= len {
self.clear();
let buf = self.as_mut();
let ptr = buf.as_mut_ptr();
let len = buf.len();
unsafe { core::ptr::write_bytes(ptr, 0, len); }
return;
}
for idx in shamt .. len {
let val = self.get(idx);
self.set(idx - shamt, val);
}
let trunc = len - shamt;
for idx in trunc .. len {
self.set(idx, false);
}
self.truncate(trunc);
}
}
impl<E, T> Shr<usize> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
type Output = Self;
fn shr(mut self, shamt: usize) -> Self::Output {
self >>= shamt;
self
}
}
impl<E, T> ShrAssign<usize> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn shr_assign(&mut self, shamt: usize) {
let old_len = self.len();
for _ in 0 .. shamt {
self.push(false);
}
for idx in (0 .. old_len).rev() {
let val = self.get(idx);
#[allow(clippy::suspicious_op_assign_impl)]
self.set(idx + shamt, val);
}
for idx in 0 .. shamt {
self.set(idx, false);
}
}
}
impl<E, T> Sub for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
type Output = Self;
fn sub(mut self, subtrahend: Self) -> Self::Output {
self -= subtrahend;
self
}
}
impl<E, T> SubAssign for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
fn sub_assign(&mut self, mut subtrahend: Self) {
if subtrahend.not_any() {
return;
}
subtrahend = -subtrahend;
let (llen, rlen) = (self.len(), subtrahend.len());
if rlen > llen {
let diff = rlen - llen;
*self >>= diff;
*self += subtrahend;
}
else {
if llen > rlen {
let diff = llen - rlen;
let sign = subtrahend.get(0);
subtrahend >>= diff;
for idx in 0 .. diff {
subtrahend.set(idx, sign);
}
}
let old = self.len();
*self += subtrahend;
if self.len() > old {
*self <<= 1;
}
}
}
}
#[doc(hidden)]
pub struct IntoIter<E, T>
where E: crate::Endian, T: crate::Bits {
bv: BitVec<E, T>,
head: usize,
tail: usize,
}
impl<E, T> IntoIter<E, T>
where E: crate::Endian, T: crate::Bits {
fn new(bv: BitVec<E, T>) -> Self {
let tail = bv.len();
Self {
bv,
head: 0,
tail,
}
}
fn reset(&mut self) {
self.head = 0;
self.tail = self.bv.len();
}
}
impl<E, T> DoubleEndedIterator for IntoIter<E, T>
where E: crate::Endian, T: crate::Bits {
fn next_back(&mut self) -> Option<Self::Item> {
if self.tail > self.head && self.tail <= self.bv.len() {
self.tail -= 1;
Some(self.bv[self.tail])
}
else {
self.reset();
None
}
}
}
impl<E, T> ExactSizeIterator for IntoIter<E, T>
where E: crate::Endian, T: crate::Bits {
fn len(&self) -> usize {
self.tail - self.head
}
}
impl<E, T> From<BitVec<E, T>> for IntoIter<E, T>
where E: crate::Endian, T: crate::Bits {
fn from(bv: BitVec<E, T>) -> Self {
Self::new(bv)
}
}
impl<E, T> Iterator for IntoIter<E, T>
where E: crate::Endian, T: crate::Bits {
type Item = bool;
fn next(&mut self) -> Option<Self::Item> {
if self.head < self.tail {
let ret = self.bv[self.head];
self.head += 1;
Some(ret)
}
else {
self.reset();
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let rem = ExactSizeIterator::len(self);
(rem, Some(rem))
}
fn count(self) -> usize {
ExactSizeIterator::len(&self)
}
fn nth(&mut self, n: usize) -> Option<bool> {
self.head = self.head.saturating_add(n);
self.next()
}
fn last(mut self) -> Option<bool> {
self.next_back()
}
}