New:Socket for Asana Is Now Available.Learn more
Get Started

bitvec

Package Overview
Dependencies
Maintainers
0
Versions
61
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bitvec - cargo Package Compare versions

Package version was removed
This package version has been unpublished, mostly likely due to security reasons
Comparing version
0.4.0
to
0.5.0
+1
-1
Cargo.toml

@@ -15,3 +15,3 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO

name = "bitvec"
version = "0.4.0"
version = "0.5.0"
authors = ["myrrlyn <myrrlyn@outlook.com>"]

@@ -18,0 +18,0 @@ description = "A crate for manipulating memory, bit by bit"

@@ -5,2 +5,29 @@ # Changelog

## 0.5.0
### Added
- `BitVec` and `BitSlice` implement `Hash`.
- `BitVec` fully implements addition, negation, and subtraction.
- `BitSlice` implements in-place addition and negation.
- `impl AddAssign for BitSlice`
- `impl Neg for &mut BitSlice`
This distinction is required in order to match the expectations of the
arithmetic traits and the realities of immovable `BitSlice`.
- `BitSlice` offers `.all()`, `.any()`, `.not_all()`, `.not_any()`, and
`.some()` methods to perform n-ary Boolean logic.
- `.all()` tests if all bits are set high
- `.any()` tests if any bits are set high (includes `.all()`)
- `.not_all()` tests if any bits are set low (includes `.not_all()`)
- `.not_any()` tests if all bits are set low
- `.some()` tests if any bits are high and any are low (excludes `.all()` and
`.not_all()`)
- `BitSlice` can count how many bits are set high or low with `.count_one()` and
`.count_zero()`.
## 0.4.0

@@ -7,0 +34,0 @@

@@ -41,3 +41,3 @@ # `BitVec` – Managing memory bit by bit

[dependencies]
bitvec = "0.4"
bitvec = "0.5"
```

@@ -44,0 +44,0 @@

+591
-231

@@ -55,4 +55,4 @@ /*! `BitSlice` Wide Reference

use std::convert::{
AsMut,
AsRef,
AsMut,
From,

@@ -66,2 +66,6 @@ };

};
use std::hash::{
Hash,
Hasher,
};
use std::iter::{

@@ -76,2 +80,3 @@ DoubleEndedIterator,

use std::ops::{
AddAssign,
BitAndAssign,

@@ -81,2 +86,3 @@ BitOrAssign,

Index,
Neg,
Not,

@@ -117,3 +123,4 @@ ShlAssign,

#[cfg_attr(nightly, repr(transparent))]
pub struct BitSlice<E: Endian = BigEndian, T: Bits = u8> {
pub struct BitSlice<E = BigEndian, T = u8>
where E: Endian, T: Bits {
_endian: PhantomData<E>,

@@ -125,3 +132,3 @@ inner: [T],

where E: Endian, T: Bits {
/// Gets the bit value at the given position.
/// Get the bit value at the given position.
///

@@ -145,3 +152,3 @@ /// The index value is a semantic count, not a bit address. It converts to a

/// Sets the bit value at the given position.
/// Set the bit value at the given position.
///

@@ -166,4 +173,13 @@ /// The index value is a semantic count, not a bit address. It converts to a

/// Returns the number of bits contained in the `BitSlice`.
/// Return true if *all* bits in the slice are set (logical `∧`).
///
/// # Truth Table
///
/// ```text
/// 0 0 => 0
/// 0 1 => 0
/// 1 0 => 0
/// 1 1 => 1
/// ```
///
/// # Examples

@@ -173,2 +189,197 @@ ///

/// use bitvec::*;
/// let all = bitvec![1; 10];
/// let any = bitvec![0, 0, 1, 0, 0];
/// let some = bitvec![1, 1, 0, 1, 1];
/// let none = bitvec![0; 10];
///
/// assert!(all.all());
/// assert!(!any.all());
/// assert!(!some.all());
/// assert!(!none.all());
/// ```
pub fn all(&self) -> bool {
// Gallop the filled elements
let store = self.as_ref();
for elt in &store[.. self.elts()] {
if *elt != T::from(!0) {
return false;
}
}
// Walk the partial tail
let bits = self.bits();
if bits > 0 {
let tail = store[self.elts()];
for bit in 0 .. bits {
if !tail.get(E::curr::<T>(bit)) {
return false;
}
}
}
return true;
}
/// Return true if *any* bit in the slice is set (logical `∨`).
///
/// # Truth Table
///
/// ```text
/// 0 0 => 0
/// 0 1 => 1
/// 1 0 => 1
/// 1 1 => 1
/// ```
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let all = bitvec![1; 10];
/// let any = bitvec![0, 0, 1, 0, 0];
/// let some = bitvec![1, 1, 0, 1, 1];
/// let none = bitvec![0; 10];
///
/// assert!(all.any());
/// assert!(any.any());
/// assert!(some.any());
/// assert!(!none.any());
/// ```
pub fn any(&self) -> bool {
// Gallop the filled elements
let store = self.as_ref();
for elt in &store[.. self.elts()] {
if *elt != T::from(0) {
return true;
}
}
// Walk the partial tail
let bits = self.bits();
if bits > 0 {
let tail = store[self.elts()];
for bit in 0 .. bits {
if tail.get(E::curr::<T>(bit)) {
return true;
}
}
}
return false;
}
/// Return true if *any* bit in the slice is unset (logical `¬∧`).
///
/// # Truth Table
///
/// ```text
/// 0 0 => 1
/// 0 1 => 1
/// 1 0 => 1
/// 1 1 => 0
/// ```
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let all = bitvec![1; 10];
/// let any = bitvec![0, 0, 1, 0, 0];
/// let some = bitvec![1, 1, 0, 1, 1];
/// let none = bitvec![0; 10];
///
/// assert!(!all.not_all());
/// assert!(any.not_all());
/// assert!(some.not_all());
/// assert!(none.not_all());
/// ```
pub fn not_all(&self) -> bool {
!self.all()
}
/// Return true if *all* bits in the slice are uset (logical `¬∨`).
///
/// # Truth Table
///
/// ```text
/// 0 0 => 1
/// 0 1 => 0
/// 1 0 => 0
/// 1 1 => 0
/// ```
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let all = bitvec![1; 10];
/// let any = bitvec![0, 0, 1, 0, 0];
/// let some = bitvec![1, 1, 0, 1, 1];
/// let none = bitvec![0; 10];
///
/// assert!(!all.not_any());
/// assert!(!any.not_any());
/// assert!(!some.not_any());
/// assert!(none.not_any());
/// ```
pub fn not_any(&self) -> bool {
!self.any()
}
/// Return true if some, but not all, bits are set and some, but not all,
/// are unset.
///
/// # Truth Table
///
/// ```text
/// 0 0 => 0
/// 0 1 => 1
/// 1 0 => 1
/// 1 1 => 0
/// ```
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let all = bitvec![1; 2];
/// let some = bitvec![1, 0];
/// let none = bitvec![0; 2];
///
/// assert!(!all.some());
/// assert!(some.some());
/// assert!(!none.some());
/// ```
pub fn some(&self) -> bool {
self.any() && self.not_all()
}
/// Count how many bits are set high.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let bv = bitvec![1, 0, 1, 0, 1];
/// assert_eq!(bv.count_one(), 3);
/// ```
pub fn count_one(&self) -> usize {
self.into_iter().filter(|b| *b).count()
}
/// Count how many bits are set low.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let bv = bitvec![0, 1, 0, 1, 0];
/// assert_eq!(bv.count_zero(), 3);
/// ```
pub fn count_zero(&self) -> usize {
self.into_iter().filter(|b| !b).count()
}
/// Return the number of bits contained in the `BitSlice`.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let bv = bitvec![1; 10];

@@ -182,3 +393,3 @@ /// let bits: &BitSlice = &bv;

/// Counts how many *whole* storage elements are in the `BitSlice`.
/// Count how many *whole* storage elements are in the `BitSlice`.
///

@@ -208,3 +419,3 @@ /// If the `BitSlice` length is not an even multiple of the width of `T`,

/// Counts how many bits are in the trailing partial storage element.
/// Count how many bits are in the trailing partial storage element.
///

@@ -234,3 +445,3 @@ /// If the `BitSlice` length is an even multiple of the width of `T`, then

/// Returns `true` if the slice contains no bits.
/// Return `true` if the slice contains no bits.
///

@@ -374,2 +585,109 @@ /// # Examples

/// Clone a borrowed `BitSlice` into an owned `BitVec`.
impl<E, T> ToOwned for BitSlice<E, T>
where E: Endian, T: Bits {
type Owned = BitVec<E, T>;
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let src = bitvec![0; 5];
/// let src_ref: &BitSlice = &src;
/// let dst = src_ref.to_owned();
/// assert_eq!(src, dst);
/// ```
fn to_owned(&self) -> Self::Owned {
let mut out = Self::Owned::with_capacity(self.len());
unsafe {
let src = self.as_ptr();
let dst = out.as_mut_ptr();
let len = self.raw_len();
ptr::copy_nonoverlapping(src, dst, len);
out.set_len(self.len());
}
out
}
}
impl<E, T> Eq for BitSlice<E, T>
where E: Endian, T: Bits {}
impl<E, T> Ord for BitSlice<E, T>
where E: Endian, T: Bits {
fn cmp(&self, rhs: &Self) -> Ordering {
match self.partial_cmp(rhs) {
Some(ord) => ord,
None => unreachable!("`BitSlice` has a total ordering"),
}
}
}
/// Test if two `BitSlice`s are semantically — not bitwise — equal.
///
/// It is valid to compare two slices of different endianness or element types.
///
/// The equality condition requires that they have the same number of total bits
/// and that each pair of bits in semantic order are identical.
impl<A, B, C, D> PartialEq<BitSlice<C, D>> for BitSlice<A, B>
where A: Endian, B: Bits, C: Endian, D: Bits {
/// Perform a comparison by `==`.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let l: BitVec<LittleEndian, u16> = bitvec![LittleEndian, u16; 0, 1, 0, 1];
/// let r: BitVec<BigEndian, u32> = bitvec![BigEndian, u32; 0, 1, 0, 1];
///
/// let ls: &BitSlice<_, _> = &l;
/// let rs: &BitSlice<_, _> = &r;
/// assert!(ls == rs);
/// ```
fn eq(&self, rhs: &BitSlice<C, D>) -> bool {
let (l, r) = (self.iter(), rhs.iter());
if l.len() != r.len() {
return false;
}
l.zip(r).all(|(l, r)| l == r)
}
}
/// Compare two `BitSlice`s by semantic — not bitwise — ordering.
///
/// The comparison sorts by testing each index for one slice to have a set bit
/// where the other has an unset bit. If the slices are different, the slice
/// with the set bit sorts greater than the slice with the unset bit.
///
/// If one of the slices is exhausted before they differ, the longer slice is
/// greater.
impl<A, B, C, D> PartialOrd<BitSlice<C, D>> for BitSlice<A, B>
where A: Endian, B: Bits, C: Endian, D: Bits {
/// Perform a comparison by `<` or `>`.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let a = bitvec![0, 1, 0, 0];
/// let b = bitvec![0, 1, 0, 1];
/// let c = bitvec![0, 1, 0, 1, 1];
/// let aref: &BitSlice = &a;
/// let bref: &BitSlice = &b;
/// let cref: &BitSlice = &c;
/// assert!(aref < bref);
/// assert!(bref < cref);
/// ```
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())
}
}
/// Give write access to all elements in the underlying storage, including the

@@ -417,8 +735,8 @@ /// partially-filled tail element (if present).

/// Performs the Boolean AND operation against another bitstream and writes the
/// result into `self`. If the other bitstream ends before `self` does, it is
/// extended with zero, clearing all remaining bits in `self`.
impl<E, T, I> BitAndAssign<I> for BitSlice<E, T>
where E: Endian, T: Bits, I: IntoIterator<Item=bool> {
/// AND a bitstream inta a slice.
/// Build a `BitSlice` from a slice of elements. The resulting `BitSlice` will
/// always completely fill the original slice, and will not have a partial tail.
impl<'a, E, T> From<&'a [T]> for &'a BitSlice<E, T>
where E: Endian, T: 'a + Bits {
/// Wrap an `&[T: Bits]` in an `&BitSlice<E: Endian, T>`. The endianness
/// must be specified by the call site. The element type cannot be changed.
///

@@ -429,12 +747,20 @@ /// # Examples

/// use bitvec::*;
/// let lhs: &mut BitSlice = &mut bitvec![0, 1, 0, 1, 0, 1];
/// let rhs = bitvec![0, 0, 1, 1];
/// *lhs &= rhs;
/// assert_eq!("000100", &format!("{}", lhs));
/// let src = vec![1u8, 2, 3];
/// let borrow: &[u8] = &src;
/// let bits: &BitSlice<BigEndian, _> = borrow.into();
/// assert_eq!(bits.len(), 24);
/// assert_eq!(bits.elts(), 3);
/// assert_eq!(bits.bits(), 0);
/// assert!(bits.get(7)); // src[0] == 0b0000_0001
/// assert!(bits.get(14)); // src[1] == 0b0000_0010
/// assert!(bits.get(22)); // src[2] == 0b0000_0011
/// assert!(bits.get(23));
/// ```
fn bitand_assign(&mut self, rhs: I) {
use std::iter::repeat;
for (idx, other) in (0 .. self.len()).zip(rhs.into_iter().chain(repeat(false))) {
let val = self.get(idx) & other;
self.set(idx, val);
fn from(src: &'a [T]) -> Self {
let (ptr, len): (*const T, usize) = (src.as_ptr(), src.len());
assert!(len <= T::MAX_ELT, "Source slice length out of range!");
unsafe {
mem::transmute(
slice::from_raw_parts(ptr, len << T::BITS)
)
}

@@ -444,8 +770,10 @@ }

/// Performs the Boolear OR operation against another bitstream and writes the
/// result into `self`. If the other bitstream ends before `self` does, it is
/// extended with zero, leaving all remaining bits in `self` as they were.
impl<E, T, I> BitOrAssign<I> for BitSlice<E, T>
where E: Endian, T: Bits, I: IntoIterator<Item=bool> {
/// OR a bitstream into a slice.
/// Build a mutable `BitSlice` from a slice of mutable elements. The resulting
/// `BitSlice` will always completely fill the original slice, and will not have
/// a partial tail.
impl<'a, E, T> From<&'a mut [T]> for &'a mut BitSlice<E, T>
where E: Endian, T: 'a + Bits {
/// Wrap an `&mut [T: Bits]` in an `&mut BitSlice<E: Endian, T>`. The
/// endianness must be specified by the call site. The element type cannot
/// be changed.
///

@@ -456,11 +784,17 @@ /// # Examples

/// use bitvec::*;
/// let lhs: &mut BitSlice = &mut bitvec![0, 1, 0, 1, 0, 1];
/// let rhs = bitvec![0, 0, 1, 1];
/// *lhs |= rhs;
/// assert_eq!("011101", &format!("{}", lhs));
/// let mut src = vec![1u8, 2, 3];
/// let borrow: &mut [u8] = &mut src;
/// let bits: &mut BitSlice<LittleEndian, _> = borrow.into();
/// // The first bit read is the LSb of the first element, which is set.
/// assert!(bits.get(0));
/// bits.set(0, false);
/// assert!(!bits.get(0));
/// ```
fn bitor_assign(&mut self, rhs: I) {
for (idx, other) in (0 .. self.len()).zip(rhs.into_iter()) {
let val = self.get(idx) | other;
self.set(idx, val);
fn from(src: &'a mut [T]) -> Self {
let (ptr, len): (*mut T, usize) = (src.as_mut_ptr(), src.len());
assert!(len <= T::MAX_ELT, "Source slice length out of range!");
unsafe {
mem::transmute(
slice::from_raw_parts_mut(ptr, len << T::BITS)
)
}

@@ -470,27 +804,2 @@ }

/// Perform the Boolean XOR operation against another bitstream and writes the
/// result into `self`. If the other bitstream ends before `self` does, it is
/// extended with zero, leaving all remaining bits in `self` as they were.
impl<E, T, I> BitXorAssign<I> for BitSlice<E, T>
where E: Endian, T: Bits, I: IntoIterator<Item=bool> {
/// XOR a bitstream into a slice.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let lhs: &mut BitSlice = &mut bitvec![0, 1, 0, 1, 0, 1];
/// let rhs = bitvec![0, 0, 1, 1];
/// *lhs ^= rhs;
/// assert_eq!("011001", &format!("{}", lhs));
/// ```
fn bitxor_assign(&mut self, rhs: I) {
use std::iter::repeat;
for (idx, other) in (0 .. self.len()).zip(rhs.into_iter().chain(repeat(false))) {
let val = self.get(idx) ^ other;
self.set(idx, val);
}
}
}
/// Print the `BitSlice` for debugging.

@@ -528,3 +837,3 @@ ///

fmt.write_str(" [")?;
if alt { writeln!(fmt)?; }
if alt { writeln!(fmt)?; fmt.write_str(" ")?; }
self.fmt_body(fmt, true)?;

@@ -562,8 +871,23 @@ if alt { writeln!(fmt)?; }

/// Build a `BitSlice` from a slice of elements. The resulting `BitSlice` will
/// always completely fill the original slice, and will not have a partial tail.
impl<'a, E, T> From<&'a [T]> for &'a BitSlice<E, T>
impl<E, T> Hash for BitSlice<E, T>
where E: Endian, T: Bits {
fn hash<H>(&self, hasher: &mut H)
where H: Hasher {
for bit in self {
hasher.write_u8(bit as u8);
}
}
}
/// Produce a read-only iterator over all the bits in the `BitSlice`.
///
/// This iterator follows the ordering in the `BitSlice` type, and implements
/// `ExactSizeIterator` as `BitSlice` has a known, fixed length, and
/// `DoubleEndedIterator` as it has known ends.
impl<'a, E, T> IntoIterator for &'a BitSlice<E, T>
where E: Endian, T: 'a + Bits {
/// Wrap an `&[T: Bits]` in an `&BitSlice<E: Endian, T>`. The endianness
/// must be specified by the call site. The element type cannot be changed.
type Item = bool;
type IntoIter = Iter<'a, E, T>;
/// Iterate over the slice.
///

@@ -574,20 +898,67 @@ /// # Examples

/// use bitvec::*;
/// let src = vec![1u8, 2, 3];
/// let borrow: &[u8] = &src;
/// let bits: &BitSlice<BigEndian, _> = borrow.into();
/// assert_eq!(bits.len(), 24);
/// assert_eq!(bits.elts(), 3);
/// assert_eq!(bits.bits(), 0);
/// assert!(bits.get(7)); // src[0] == 0b0000_0001
/// assert!(bits.get(14)); // src[1] == 0b0000_0010
/// assert!(bits.get(22)); // src[2] == 0b0000_0011
/// assert!(bits.get(23));
/// let bv = bitvec![1, 0, 1, 0, 1, 1, 0, 0];
/// let bref: &BitSlice = &bv;
/// let mut count = 0;
/// for bit in bref {
/// if bit { count += 1; }
/// }
/// assert_eq!(count, 4);
/// ```
fn from(src: &'a [T]) -> Self {
let (ptr, len): (*const T, usize) = (src.as_ptr(), src.len());
assert!(len <= T::MAX_ELT, "Source slice length out of range!");
unsafe {
mem::transmute(
slice::from_raw_parts(ptr, len << T::BITS)
)
fn into_iter(self) -> Self::IntoIter {
self.into()
}
}
/// Perform unsigned addition in place on a `BitSlice`.
///
/// If the addend `BitSliec` is shorter than `self`, the addend is zero-extended
/// to the right. If the addend is longer, the excess front length is unused.
///
/// Addition proceeds from the right ends of each slice towards the left.
/// Because this trait is forbidden from returning anything, the final carry-out
/// bit is discarded.
///
/// Note that, unlike `BitVec`, there is no subtraction implementation until I
/// find a subtraction algorithm that does not require modifying the subtrahend.
///
/// Subtraction can be implemented by negating the intended subtrahend yourself,
/// then using addition, or by using `BitVec`s instead of `BitSlice`s.
impl<'a, E, T> AddAssign<&'a BitSlice<E, T>> for BitSlice<E, T>
where E: Endian, T: Bits {
/// Perform unsigned wrapping addition in place.
///
/// # Examples
///
/// This example shows addition of a slice wrapping from MAX to zero.
///
/// ```rust
/// use bitvec::*;
/// let nums: [BitVec; 3] = [
/// bitvec![1, 1, 1, 0],
/// bitvec![1, 1, 1, 1],
/// bitvec![0, 0, 0, 0],
/// ];
/// let one = bitvec![0, 1];
/// let mut num = nums[0].clone();
/// let numr: &mut BitSlice = &mut num;
/// *numr += &one;
/// assert_eq!(numr, &nums[1] as &BitSlice);
/// *numr += &one;
/// assert_eq!(numr, &nums[2] as &BitSlice);
/// ```
fn add_assign(&mut self, addend: &'a BitSlice<E, T>) {
use std::iter::repeat;
// zero-extend the addend if it's shorter than self
let mut addend_iter = addend.into_iter().rev().chain(repeat(false));
let mut c = false;
for place in (0 .. self.len()).rev() {
// See BitVec::AddAssign
static JUMP: [u8; 8] = [0, 2, 2, 1, 2, 1, 1, 3];
let a = self.get(place);
let b = addend_iter.next().unwrap(); // addend is an infinite source
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;
}

@@ -597,10 +968,8 @@ }

/// Build a mutable `BitSlice` from a slice of mutable elements. The resulting
/// `BitSlice` will always completely fill the original slice, and will not have
/// a partial tail.
impl<'a, E, T> From<&'a mut [T]> for &'a mut BitSlice<E, T>
where E: Endian, T: 'a + Bits {
/// Wrap an `&mut [T: Bits]` in an `&mut BitSlice<E: Endian, T>`. The
/// endianness must be specified by the call site. The element type cannot
/// be changed.
/// Perform the Boolean AND operation against another bitstream and writes the
/// result into `self`. If the other bitstream ends before `self` does, it is
/// extended with zero, clearing all remaining bits in `self`.
impl<E, T, I> BitAndAssign<I> for BitSlice<E, T>
where E: Endian, T: Bits, I: IntoIterator<Item=bool> {
/// AND a bitstream inta a slice.
///

@@ -611,17 +980,12 @@ /// # Examples

/// use bitvec::*;
/// let mut src = vec![1u8, 2, 3];
/// let borrow: &mut [u8] = &mut src;
/// let bits: &mut BitSlice<LittleEndian, _> = borrow.into();
/// // The first bit read is the LSb of the first element, which is set.
/// assert!(bits.get(0));
/// bits.set(0, false);
/// assert!(!bits.get(0));
/// let lhs: &mut BitSlice = &mut bitvec![0, 1, 0, 1, 0, 1];
/// let rhs = bitvec![0, 0, 1, 1];
/// *lhs &= rhs;
/// assert_eq!("000100", &format!("{}", lhs));
/// ```
fn from(src: &'a mut [T]) -> Self {
let (ptr, len): (*mut T, usize) = (src.as_mut_ptr(), src.len());
assert!(len <= T::MAX_ELT, "Source slice length out of range!");
unsafe {
mem::transmute(
slice::from_raw_parts_mut(ptr, len << T::BITS)
)
fn bitand_assign(&mut self, rhs: I) {
use std::iter::repeat;
for (idx, other) in (0 .. self.len()).zip(rhs.into_iter().chain(repeat(false))) {
let val = self.get(idx) & other;
self.set(idx, val);
}

@@ -631,2 +995,51 @@ }

/// Perform the Boolean OR operation against another bitstream and writes the
/// result into `self`. If the other bitstream ends before `self` does, it is
/// extended with zero, leaving all remaining bits in `self` as they were.
impl<E, T, I> BitOrAssign<I> for BitSlice<E, T>
where E: Endian, T: Bits, I: IntoIterator<Item=bool> {
/// OR a bitstream into a slice.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let lhs: &mut BitSlice = &mut bitvec![0, 1, 0, 1, 0, 1];
/// let rhs = bitvec![0, 0, 1, 1];
/// *lhs |= rhs;
/// assert_eq!("011101", &format!("{}", lhs));
/// ```
fn bitor_assign(&mut self, rhs: I) {
for (idx, other) in (0 .. self.len()).zip(rhs.into_iter()) {
let val = self.get(idx) | other;
self.set(idx, val);
}
}
}
/// Perform the Boolean XOR operation against another bitstream and writes the
/// result into `self`. If the other bitstream ends before `self` does, it is
/// extended with zero, leaving all remaining bits in `self` as they were.
impl<E, T, I> BitXorAssign<I> for BitSlice<E, T>
where E: Endian, T: Bits, I: IntoIterator<Item=bool> {
/// XOR a bitstream into a slice.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let lhs: &mut BitSlice = &mut bitvec![0, 1, 0, 1, 0, 1];
/// let rhs = bitvec![0, 0, 1, 1];
/// *lhs ^= rhs;
/// assert_eq!("011001", &format!("{}", lhs));
/// ```
fn bitxor_assign(&mut self, rhs: I) {
use std::iter::repeat;
for (idx, other) in (0 .. self.len()).zip(rhs.into_iter().chain(repeat(false))) {
let val = self.get(idx) ^ other;
self.set(idx, val);
}
}
}
/// Index a single bit by semantic count. The index must be less than the length

@@ -687,28 +1100,82 @@ /// of the `BitSlice`.

/// Produce a read-only iterator over all the bits in the `BitSlice`.
/// Perform fixed-width 2's-complement negation of a `BitSlice`.
///
/// This iterator follows the ordering in the `BitSlice` type, and implements
/// `ExactSizeIterator` as `BitSlice` has a known, fixed length, and
/// `DoubleEndedIterator` as it has known ends.
impl<'a, E, T> IntoIterator for &'a BitSlice<E, T>
/// Unlike the `!` operator (`Not` trait), the unary `-` operator treats the
/// `BitSlice` as if it represents a signed 2's-complement integer of fixed
/// width. The negation of a number in 2's complement is defined as its
/// inversion (using `!`) plus one, and on fixed-width numbers has the following
/// discontinuities:
///
/// - A slice whose bits are all zero is considered to represent the number zero
/// which negates as itself.
/// - A slice whose bits are all one is considered to represent the most
/// negative number, which has no correpsonding positive number, and thus
/// negates as zero.
///
/// This behavior was chosen so that all possible values would have *some*
/// output, and so that repeated application converges at idempotence. The most
/// negative input can never be reached by negation, but `--MOST_NEG` converges
/// at the least unreasonable fallback value, 0.
///
/// Because `BitSlice` cannot move, the negation is performed in place.
impl<'a, E, T> Neg for &'a mut BitSlice<E, T>
where E: Endian, T: 'a + Bits {
type Item = bool;
type IntoIter = Iter<'a, E, T>;
type Output = Self;
/// Iterate over the slice.
/// Perform 2's-complement fixed-width negation.
///
/// # Examples
///
/// The contortions shown here are a result of this operator applying to a
/// mutable reference, and this example balancing access to the original
/// `BitVec` for comparison with aquiring a mutable borrow *as a slice* to
/// ensure that the `BitSlice` implementation is used, not the `BitVec`.
///
/// Negate an arbitrary positive number (first bit unset).
///
/// ```rust
/// use bitvec::*;
/// let bv = bitvec![1, 0, 1, 0, 1, 1, 0, 0];
/// let bref: &BitSlice = &bv;
/// let mut count = 0;
/// for bit in bref {
/// if bit { count += 1; }
/// }
/// assert_eq!(count, 4);
/// let mut num = bitvec![0, 1, 1, 0];
/// - (&mut num as &mut BitSlice);
/// assert_eq!(num, bitvec![1, 0, 1, 0]);
/// ```
fn into_iter(self) -> Self::IntoIter {
self.into()
///
/// Negate an arbitrary negative number. This example will use the above
/// result to demonstrate round-trip correctness.
///
/// ```rust
/// use bitvec::*;
/// let mut num = bitvec![1, 0, 1, 0];
/// - (&mut num as &mut BitSlice);
/// assert_eq!(num, bitvec![0, 1, 1, 0]);
/// ```
///
/// Negate the most negative number, which will become zero, and show
/// convergence at zero.
///
/// ```rust
/// use bitvec::*;
/// let zero = bitvec![0; 10];
/// let mut num = bitvec![1; 10];
/// - (&mut num as &mut BitSlice);
/// assert_eq!(num, zero);
/// - (&mut num as &mut BitSlice);
/// assert_eq!(num, zero);
/// ```
fn neg(self) -> Self::Output {
if self.is_empty() || self.not_any() {
return self;
}
Not::not(&mut *self);
// Fill an element with all 1 bits
let elt: [T; 1] = [!T::default()];
if self.any() {
// Turn a slice reference [T; 1] into a bit-slice reference [u1; 1]
let addend: &BitSlice<E, T> = {
unsafe { mem::transmute::<&[T], &BitSlice<E, T>>(&elt) }
};
// And add it (if the slice was not all-ones).
AddAssign::add_assign(&mut *self, addend);
}
self
}

@@ -750,82 +1217,2 @@ }

/// Test if two `BitSlice`s are semantically — not bitwise — equal.
///
/// It is valid to compare two slices of different endianness or element types.
///
/// The equality condition requires that they have the same number of total bits
/// and that each pair of bits in semantic order are identical.
impl<A, B, C, D> PartialEq<BitSlice<C, D>> for BitSlice<A, B>
where A: Endian, B: Bits, C: Endian, D: Bits {
/// Perform a comparison by `==`.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let l: BitVec<LittleEndian, u16> = bitvec![LittleEndian, u16; 0, 1, 0, 1];
/// let r: BitVec<BigEndian, u32> = bitvec![BigEndian, u32; 0, 1, 0, 1];
///
/// let ls: &BitSlice<_, _> = &l;
/// let rs: &BitSlice<_, _> = &r;
/// assert!(ls == rs);
/// ```
fn eq(&self, rhs: &BitSlice<C, D>) -> bool {
let (l, r) = (self.iter(), rhs.iter());
if l.len() != r.len() {
return false;
}
l.zip(r).all(|(l, r)| l == r)
}
}
impl<E, T> Eq for BitSlice<E, T>
where E: Endian, T: Bits {}
/// Compare two `BitSlice`s by semantic — not bitwise — ordering.
///
/// The comparison sorts by testing each index for one slice to have a set bit
/// where the other has an unset bit. If the slices are different, the slice
/// with the set bit sorts greater than the slice with the unset bit.
///
/// If one of the slices is exhausted before they differ, the longer slice is
/// greater.
impl<A, B, C, D> PartialOrd<BitSlice<C, D>> for BitSlice<A, B>
where A: Endian, B: Bits, C: Endian, D: Bits {
/// Perform a comparison by `<` or `>`.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let a = bitvec![0, 1, 0, 0];
/// let b = bitvec![0, 1, 0, 1];
/// let c = bitvec![0, 1, 0, 1, 1];
/// let aref: &BitSlice = &a;
/// let bref: &BitSlice = &b;
/// let cref: &BitSlice = &c;
/// assert!(aref < bref);
/// assert!(bref < cref);
/// ```
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())
}
}
impl<E, T> Ord for BitSlice<E, T>
where E: Endian, T: Bits {
fn cmp(&self, rhs: &Self) -> Ordering {
match self.partial_cmp(rhs) {
Some(ord) => ord,
None => unreachable!("`BitSlice` has a total ordering"),
}
}
}
__bitslice_shift!(u8, u16, u32, u64, i8, i16, i32, i64);

@@ -1016,29 +1403,2 @@

/// Clone a borrowed `BitSlice` into an owned `BitVec`.
impl<E, T> ToOwned for BitSlice<E, T>
where E: Endian, T: Bits {
type Owned = BitVec<E, T>;
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let src = bitvec![0; 5];
/// let src_ref: &BitSlice = &src;
/// let dst = src_ref.to_owned();
/// assert_eq!(src, dst);
/// ```
fn to_owned(&self) -> Self::Owned {
let mut out = Self::Owned::with_capacity(self.len());
unsafe {
let src = self.as_ptr();
let dst = out.as_mut_ptr();
let len = self.raw_len();
ptr::copy_nonoverlapping(src, dst, len);
out.set_len(self.len());
}
out
}
}
/// Permit iteration over a `BitSlice`

@@ -1045,0 +1405,0 @@ #[doc(hidden)]

+724
-393

@@ -27,2 +27,3 @@ use super::{

};
use std::default::Default;
use std::fmt::{

@@ -34,2 +35,6 @@ self,

};
use std::hash::{
Hash,
Hasher,
};
use std::iter::{

@@ -46,2 +51,4 @@ DoubleEndedIterator,

use std::ops::{
Add,
AddAssign,
BitAnd,

@@ -55,3 +62,5 @@ BitAndAssign,

DerefMut,
Drop,
Index,
Neg,
Not,

@@ -62,2 +71,4 @@ Shl,

ShrAssign,
Sub,
SubAssign,
};

@@ -268,3 +279,3 @@ use std::ptr;

/// Shrinks the `BitVec` to the given size, dropping all excess storage.
/// Shrink the `BitVec` to the given size, dropping all excess storage.
///

@@ -443,197 +454,2 @@ /// This does not affect the memory store! It will not zero the raw memory

/// Give write access to all live elements in the underlying storage, including
/// the partially-filled tail.
impl<E, T> AsMut<[T]> for BitVec<E, T>
where E: Endian, T: Bits {
/// Access the underlying store.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let mut bv: BitVec = bitvec![0, 0, 0, 0, 0, 0, 0, 0, 1];
/// for elt in bv.as_mut() {
/// *elt += 2;
/// }
/// assert_eq!(&[2, 0b1000_0010], bv.as_ref());
/// ```
fn as_mut(&mut self) -> &mut [T] {
BitSlice::as_mut(self)
}
}
/// Give read access to all live elements in the underlying storage, including
/// the partially-filled tail.
impl<E, T> AsRef<[T]> for BitVec<E, T>
where E: Endian, T: Bits {
/// Access the underlying store.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let bv = bitvec![0, 0, 0, 0, 0, 0, 0, 0, 1];
/// assert_eq!(&[0, 0b1000_0000], bv.as_ref());
/// ```
fn as_ref(&self) -> &[T] {
BitSlice::as_ref(self)
}
}
/// Perform the Boolean AND operation between each element of a `BitVec` and
/// anything that can provide a stream of `bool` values (such as another
/// `BitVec`, or any `bool` generator of your choice). The `BitVec` emitted will
/// have the length of the shorter sequence of bits -- if one is longer than the
/// other, the extra bits will be ignored.
impl<E, T, I> BitAnd<I> for BitVec<E, T>
where E: Endian, T: Bits, I: IntoIterator<Item=bool> {
type Output = Self;
/// AND a vector and a bitstream, producing a new vector.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let lhs = bitvec![BigEndian, u8; 0, 1, 0, 1];
/// let rhs = bitvec![BigEndian, u8; 0, 0, 1, 1];
/// let and = lhs & rhs;
/// assert_eq!("0001", &format!("{}", and));
/// ```
fn bitand(mut self, rhs: I) -> Self::Output {
self &= rhs;
self
}
}
/// Perform the Boolean AND operation in place on a `BitVec`, using a stream of
/// `bool` values as the other bit for each operation. If the other stream is
/// shorter than `self`, `self` will be truncated when the other stream expires.
impl<E, T, I> BitAndAssign<I> for BitVec<E, T>
where E: Endian, T: Bits, I: IntoIterator<Item=bool> {
/// AND another bitstream into a vector.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let mut src = bitvec![BigEndian, u8; 0, 1, 0, 1];
/// src &= bitvec![BigEndian, u8; 0, 0, 1, 1];
/// assert_eq!("0001", &format!("{}", src));
/// ```
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);
}
}
/// Perform the Boolean OR operation between each element of a `BitVec` and
/// anything that can provide a stream of `bool` values (such as another
/// `BitVec`, or any `bool` generator of your choice). The `BitVec` emitted will
/// have the length of the shorter sequence of bits -- if one is longer than the
/// other, the extra bits will be ignored.
impl<E, T, I> BitOr<I> for BitVec<E, T>
where E: Endian, T: Bits, I: IntoIterator<Item=bool> {
type Output = Self;
/// OR a vector and a bitstream, producing a new vector.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let lhs = bitvec![BigEndian, u8; 0, 1, 0, 1];
/// let rhs = bitvec![BigEndian, u8; 0, 0, 1, 1];
/// let or = lhs | rhs;
/// assert_eq!("0111", &format!("{}", or));
/// ```
fn bitor(mut self, rhs: I) -> Self::Output {
self |= rhs;
self
}
}
/// Perform the Boolean OR operation in place on a `BitVec`, using a stream of
/// `bool` values as the other bit for each operation. If the other stream is
/// shorter than `self`, `self` will be truncated when the other stream expires.
impl<E, T, I> BitOrAssign<I> for BitVec<E, T>
where E: Endian, T: Bits, I: IntoIterator<Item=bool> {
/// OR another bitstream into a vector.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let mut src = bitvec![BigEndian, u8; 0, 1, 0, 1];
/// src |= bitvec![BigEndian, u8; 0, 0, 1, 1];
/// assert_eq!("0111", &format!("{}", src));
/// ```
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);
}
}
/// Perform the Boolean XOR operation between each element of a `BitVec` and
/// anything that can provide a stream of `bool` values (such as another
/// `BitVec`, or any `bool` generator of your choice). The `BitVec` emitted will
/// have the length of the shorter sequence of bits -- if one is longer than the
/// other, the extra bits will be ignored.
impl<E, T, I> BitXor<I> for BitVec<E, T>
where E: Endian, T: Bits, I: IntoIterator<Item=bool> {
type Output = Self;
/// XOR a vector and a bitstream, producing a new vector.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let lhs = bitvec![BigEndian, u8; 0, 1, 0, 1];
/// let rhs = bitvec![BigEndian, u8; 0, 0, 1, 1];
/// let xor = lhs ^ rhs;
/// assert_eq!("0110", &format!("{}", xor));
/// ```
fn bitxor(mut self, rhs: I) -> Self::Output {
self ^= rhs;
self
}
}
/// Perform the Boolean XOR operation in place on a `BitVec`, using a stream of
/// `bool` values as the other bit for each operation. If the other stream is
/// shorter than `self`, `self` will be truncated when the other stream expires.
impl<E, T, I> BitXorAssign<I> for BitVec<E, T>
where E: Endian, T: Bits, I: IntoIterator<Item=bool> {
/// XOR another bitstream into a vector.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let mut src = bitvec![BigEndian, u8; 0, 1, 0, 1];
/// src ^= bitvec![BigEndian, u8; 0, 0, 1, 1];
/// assert_eq!("0110", &format!("{}", src));
/// ```
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);
}
}
/// Signify that `BitSlice` is the borrowed form of `BitVec`.

@@ -701,47 +517,21 @@ impl<E, T> Borrow<BitSlice<E, T>> for BitVec<E, T>

/// Print the `BitVec` for debugging.
///
/// The output is of the form `BitVec<E, T> [ELT, *]`, where `<E, T>` is the
/// endianness and element type, with square brackets on each end of the bits
/// and all the live elements in the vector printed in binary. The printout is
/// always in semantic order, and may not reflect the underlying store. To see
/// the underlying store, use `format!("{:?}", self.as_ref());` instead.
///
/// The alternate character `{:#?}` prints each element on its own line, rather
/// than separated by a space.
impl<E, T> Debug for BitVec<E, T>
impl<E, T> Eq for BitVec<E, T>
where E: Endian, T: Bits {}
impl<E, T> Ord for BitVec<E, T>
where E: Endian, T: Bits {
/// Render the `BitVec` type header and contents for debug.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let bv = bitvec![LittleEndian, u16;
/// 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1
/// ];
/// assert_eq!(
/// "BitVec<LittleEndian, u16> [0101000011110101]",
/// &format!("{:?}", bv)
/// );
/// ```
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
let alt = fmt.alternate();
self.fmt_header(fmt)?;
fmt.write_str(" [")?;
if alt { writeln!(fmt)?; }
self.fmt_body(fmt, true)?;
if alt { writeln!(fmt)?; }
fmt.write_str("]")
fn cmp(&self, rhs: &Self) -> Ordering {
BitSlice::cmp(&self, &rhs)
}
}
/// Reborrow the `BitVec` as a `BitSlice`.
/// Test if two `BitVec`s are semantically — not bitwise — equal.
///
/// This mimics the separation between `Vec<T>` and `[T]`.
impl<E, T> Deref for BitVec<E, T>
where E: Endian, T: Bits {
type Target = BitSlice<E, T>;
/// Dereference `&BitVec` down to `&BitSlice`.
/// It is valid to compare two vectors of different endianness or element types.
///
/// The equality condition requires that they have the same number of stored
/// bits and that each pair of bits in semantic order are identical.
impl<A, B, C, D> PartialEq<BitVec<C, D>> for BitVec<A, B>
where A: Endian, B: Bits, C: Endian, D: Bits {
/// Perform a comparison by `==`.
///

@@ -752,19 +542,22 @@ /// # Examples

/// use bitvec::*;
/// let bv: BitVec = bitvec![1; 4];
/// let bref: &BitSlice = &bv;
/// assert!(bref.get(2));
/// let l: BitVec<LittleEndian, u16> = bitvec![LittleEndian, u16; 0, 1, 0, 1];
/// let r: BitVec<BigEndian, u32> = bitvec![BigEndian, u32; 0, 1, 0, 1];
/// assert!(l == r);
/// ```
fn deref(&self) -> &Self::Target {
// `BitVec`'s representation of its inner `Vec` matches exactly the
// invariants of how `BitSlice` references must look. This is fine.
unsafe { mem::transmute(&self.inner as &[T]) }
fn eq(&self, rhs: &BitVec<C, D>) -> bool {
BitSlice::eq(&self, &rhs)
}
}
/// Reborrow the `BitVec` as a `BitSlice`.
/// Compare two `BitVec`s by semantic — not bitwise — ordering.
///
/// This mimics the separation between `Vec<T>` and `[T]`.
impl<E, T> DerefMut for BitVec<E, T>
where E: Endian, T: Bits {
/// Dereference `&mut BitVec` down to `&mut BitSlice`.
/// The comparison sorts by testing each index for one vector to have a set bit
/// where the other vector has an unset bit. If the vectors are different, the
/// vector with the set bit sorts greater than the vector with the unset bit.
///
/// If one of the vectors is exhausted before they differ, the longer vector is
/// greater.
impl<A, B, C, D> PartialOrd<BitVec<C, D>> for BitVec<A, B>
where A: Endian, B: Bits, C: Endian, D: Bits {
/// Perform a comparison by `<` or `>`.
///

@@ -775,26 +568,19 @@ /// # Examples

/// use bitvec::*;
/// let mut bv: BitVec = bitvec![0; 6];
/// let bref: &mut BitSlice = &mut bv;
/// assert!(!bref.get(5));
/// bref.set(5, true);
/// assert!(bref.get(5));
/// use bitvec::*;
/// let a = bitvec![0, 1, 0, 0];
/// let b = bitvec![0, 1, 0, 1];
/// let c = bitvec![0, 1, 0, 1, 1];
/// assert!(a < b);
/// assert!(b < c);
/// ```
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { mem::transmute(&mut self.inner as &mut [T]) }
fn partial_cmp(&self, rhs: &BitVec<C, D>) -> Option<Ordering> {
BitSlice::partial_cmp(&self, &rhs)
}
}
/// Print the `BitVec` for displaying.
///
/// This prints each element in turn, formatted in binary in semantic order (so
/// the first bit seen is printed first and the last bit seen printed last).
/// Each element of storage is separated by a space for ease of reading.
///
/// The alternate character `{:#}` prints each element on its own line.
///
/// To see the in-memory representation, use `AsRef` to get access to the raw
/// elements and print that slice instead.
impl<E, T> Display for BitVec<E, T>
/// Give write access to all live elements in the underlying storage, including
/// the partially-filled tail.
impl<E, T> AsMut<[T]> for BitVec<E, T>
where E: Endian, T: Bits {
/// Render the `BitVec` contents for display.
/// Access the underlying store.
///

@@ -805,34 +591,18 @@ /// # Examples

/// use bitvec::*;
/// let bv = bitvec![BigEndian, u8; 0, 1, 0, 0, 1, 0, 1, 1, 0, 1];
/// assert_eq!("01001011 01", &format!("{}", bv));
/// let mut bv: BitVec = bitvec![0, 0, 0, 0, 0, 0, 0, 0, 1];
/// for elt in bv.as_mut() {
/// *elt += 2;
/// }
/// assert_eq!(&[2, 0b1000_0010], bv.as_ref());
/// ```
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
self.fmt_body(fmt, false)
fn as_mut(&mut self) -> &mut [T] {
BitSlice::as_mut(self)
}
}
/// Ready the underlying storage for Drop.
impl<E, T> Drop for BitVec<E, T>
/// Give read access to all live elements in the underlying storage, including
/// the partially-filled tail.
impl<E, T> AsRef<[T]> for BitVec<E, T>
where E: Endian, T: Bits {
fn drop(&mut self) {
// If the `Vec` is non-empty, set the length to the number of used
// elements as preparation for drop. The bits do not need to be wiped.
//
// If we don't do this, the `Vec` drop will treat the bit total as the
// number of elements and try to loop through all of them, which will
// not take 2 ** T::BITS times as long to run as expected, because
// it'll segfault.
let raw = self.raw_len();
unsafe { self.inner.set_len(raw); }
}
}
/// Extend a `BitVec` with the contents of another bitstream.
///
/// At present, this just calls `.push()` in a loop. When specialization becomes
/// available, it will be able to more intelligently perform bulk moves from the
/// source into `self` when the source is `BitSlice`-compatible.
impl<E, T> Extend<bool> for BitVec<E, T>
where E: Endian, T: Bits {
/// Extend a `BitVec` from another bitstream.
/// Access the underlying store.
///

@@ -843,17 +613,7 @@ /// # Examples

/// use bitvec::*;
/// let mut bv = bitvec![0; 4];
/// bv.extend(bitvec![1; 4]);
/// assert_eq!("00001111", &format!("{}", bv));
/// let bv = bitvec![0, 0, 0, 0, 0, 0, 0, 0, 1];
/// assert_eq!(&[0, 0b1000_0000], bv.as_ref());
/// ```
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();
fn as_ref(&self) -> &[T] {
BitSlice::as_ref(self)
}

@@ -1018,2 +778,114 @@ }

impl<E, T> Default for BitVec<E, T>
where E: Endian, T: Bits {
fn default() -> Self {
Self {
inner: Default::default(),
_endian: Default::default(),
}
}
}
/// Print the `BitVec` for debugging.
///
/// The output is of the form `BitVec<E, T> [ELT, *]`, where `<E, T>` is the
/// endianness and element type, with square brackets on each end of the bits
/// and all the live elements in the vector printed in binary. The printout is
/// always in semantic order, and may not reflect the underlying store. To see
/// the underlying store, use `format!("{:?}", self.as_ref());` instead.
///
/// The alternate character `{:#?}` prints each element on its own line, rather
/// than separated by a space.
impl<E, T> Debug for BitVec<E, T>
where E: Endian, T: Bits {
/// Render the `BitVec` type header and contents for debug.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let bv = bitvec![LittleEndian, u16;
/// 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1
/// ];
/// assert_eq!(
/// "BitVec<LittleEndian, u16> [0101000011110101]",
/// &format!("{:?}", bv)
/// );
/// ```
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
let alt = fmt.alternate();
self.fmt_header(fmt)?;
fmt.write_str(" [")?;
if alt { writeln!(fmt)?; }
self.fmt_body(fmt, true)?;
if alt { writeln!(fmt)?; }
fmt.write_str("]")
}
}
/// Print the `BitVec` for displaying.
///
/// This prints each element in turn, formatted in binary in semantic order (so
/// the first bit seen is printed first and the last bit seen printed last).
/// Each element of storage is separated by a space for ease of reading.
///
/// The alternate character `{:#}` prints each element on its own line.
///
/// To see the in-memory representation, use `AsRef` to get access to the raw
/// elements and print that slice instead.
impl<E, T> Display for BitVec<E, T>
where E: Endian, T: Bits {
/// Render the `BitVec` contents for display.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let bv = bitvec![BigEndian, u8; 0, 1, 0, 0, 1, 0, 1, 1, 0, 1];
/// assert_eq!("01001011 01", &format!("{}", bv));
/// ```
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
self.fmt_body(fmt, false)
}
}
impl<E, T> Hash for BitVec<E, T>
where E: Endian, T: Bits {
fn hash<H>(&self, hasher: &mut H)
where H: Hasher {
BitSlice::<E, T>::hash(&self, hasher)
}
}
/// Extend a `BitVec` with the contents of another bitstream.
///
/// At present, this just calls `.push()` in a loop. When specialization becomes
/// available, it will be able to more intelligently perform bulk moves from the
/// source into `self` when the source is `BitSlice`-compatible.
impl<E, T> Extend<bool> for BitVec<E, T>
where E: Endian, T: Bits {
/// Extend a `BitVec` from another bitstream.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let mut bv = bitvec![0; 4];
/// bv.extend(bitvec![1; 4]);
/// assert_eq!("00001111", &format!("{}", bv));
/// ```
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();
}
}
/// Permit the construction of a `BitVec` by using `.collect()` on an iterator

@@ -1047,2 +919,392 @@ /// of `bool`.

/// Produce an iterator over all the bits in the vector.
///
/// This iterator follows the ordering in the vector type, and implements
/// `ExactSizeIterator`, since `BitVec`s always know exactly how large they are,
/// and `DoubleEndedIterator`, since they have known ends.
impl<E, T> IntoIterator for BitVec<E, T>
where E: Endian, T: Bits {
type Item = bool;
#[doc(hidden)]
type IntoIter = IntoIter<E, T>;
/// Iterate over the vector.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let bv = bitvec![BigEndian, u8; 1, 1, 1, 1, 0, 0, 0, 0];
/// let mut count = 0;
/// for bit in bv {
/// if bit { count += 1; }
/// }
/// assert_eq!(count, 4);
/// ```
fn into_iter(self) -> Self::IntoIter {
Self::IntoIter::from(self)
}
}
/// Add two `BitVec`s together, zero-extending the shorter.
///
/// `BitVec` addition works just like adding numbers longhand on paper. The
/// first bits in the `BitVec` are the highest, so addition works from right to
/// left, and the shorter `BitVec` is assumed to be extended to the left with
/// zero.
///
/// The output `BitVec` may be one bit longer than the longer input, if addition
/// overflowed.
///
/// Numeric arithmetic is provided on `BitVec` as a convenience. Serious numeric
/// computation on variable-length integers should use the `num_bigint` crate
/// instead, which is written specifically for that use case. `BitVec`s are not
/// intended for arithmetic, and `bitvec` makes no guarantees about sustained
/// correctness in arithmetic at this time.
impl<E, T> Add for BitVec<E, T>
where E: Endian, T: Bits {
type Output = Self;
/// Add two `BitVec`s.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let a = bitvec![0, 1, 0, 1];
/// let b = bitvec![0, 0, 1, 1];
/// let s = a + b;
/// assert_eq!(bitvec![1, 0, 0, 0], s);
/// ```
///
/// This example demonstrates the addition of differently-sized `BitVec`s,
/// and will overflow.
///
/// ```rust
/// use bitvec::*;
/// let a = bitvec![1; 4];
/// let b = bitvec![1; 1];
/// let s = b + a;
/// assert_eq!(bitvec![1, 0, 0, 0, 0], s);
/// ```
fn add(mut self, addend: Self) -> Self::Output {
self += addend;
self
}
}
/// Add another `BitVec` into `self`, zero-extending the shorter.
///
/// `BitVec` addition works just like adding numbers longhand on paper. The
/// first bits in the `BitVec` are the highest, so addition works from right to
/// left, and the shorter `BitVec` is assumed to be extended to the left with
/// zero.
///
/// The output `BitVec` may be one bit longer than the longer input, if addition
/// overflowed.
///
/// Numeric arithmetic is provided on `BitVec` as a convenience. Serious numeric
/// computation on variable-length integers should use the `num_bigint` crate
/// instead, which is written specifically for that use case. `BitVec`s are not
/// intended for arithmetic, and `bitvec` makes no guarantees about sustained
/// correctness in arithmetic at this time.
impl<E, T> AddAssign for BitVec<E, T>
where E: Endian, T: Bits {
/// Add another `BitVec` into `self`.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let mut a = bitvec![1, 0, 0, 1];
/// let b = bitvec![0, 1, 1, 1];
/// a += b;
/// assert_eq!(a, bitvec![1, 0, 0, 0, 0]);
/// ```
fn add_assign(&mut self, mut addend: Self) {
use std::iter::repeat;
// If the other vec is longer, swap them and try again.
if addend.len() > self.len() {
mem::swap(self, &mut addend);
return *self += addend;
}
// Now that self.len() >= addend.len(), proceed with addition.
//
// I don't, at this time, want to implement a carry-lookahead adder in
// software, so this is going to be a plain ripple-carry adder with
// O(n) runtime. Furthermore, until I think of an optimization
// strategy, it is going to build up another bitvec to use as a stack.
//
// Computers are fast. Whatever.
let mut c = false;
let mut stack = BitVec::<E, T>::with_capacity(self.len());
// Reverse self, reverse addend and zero-extend, and zip both together.
// This walks both vecs from rightmost to leftmost, and considers an
// early expiration of addend to continue with 0 bits.
//
// 100111
// + 0010
// ^^---- semantically zero
for (a, b) in self.iter().rev().zip(addend.into_iter().rev().chain(repeat(false))) {
// Addition is a finite state machine that can be precomputed into a single
// jump table rather than requiring more complex branching.
// The table is indexed as (carry, a, b) and returns (bit, carry).
static JUMP: [u8; 8] = [
// 0 + 0 + 0 = 0, 0
0,
// 0 + 1 + 0 = 1, 0
2,
// 1 + 0 + 0 = 1, 0
2,
// 1 + 1 + 1 = 0, 1
1,
// 0 + 0 + 1 = 1, 0
2,
// 0 + 1 + 0 = 0, 1
1,
// 1 + 0 + 0 = 0, 1
1,
// 1 + 1 + 1 = 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);
// Note: I checked in Godbolt, and the above comes out to ten
// simple instructions with the JUMP baked in as immediate values.
// The more semantically clear match statement does not optimize
// nearly as well.
stack.push(y);
c = z;
}
// If the carry made it to the end, push it.
if c {
stack.push(true);
}
// Unwind the stack into `self`.
self.clear();
while let Some(bit) = stack.pop() {
self.push(bit);
}
}
}
/// Perform the Boolean AND operation between each element of a `BitVec` and
/// anything that can provide a stream of `bool` values (such as another
/// `BitVec`, or any `bool` generator of your choice). The `BitVec` emitted will
/// have the length of the shorter sequence of bits -- if one is longer than the
/// other, the extra bits will be ignored.
impl<E, T, I> BitAnd<I> for BitVec<E, T>
where E: Endian, T: Bits, I: IntoIterator<Item=bool> {
type Output = Self;
/// AND a vector and a bitstream, producing a new vector.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let lhs = bitvec![BigEndian, u8; 0, 1, 0, 1];
/// let rhs = bitvec![BigEndian, u8; 0, 0, 1, 1];
/// let and = lhs & rhs;
/// assert_eq!("0001", &format!("{}", and));
/// ```
fn bitand(mut self, rhs: I) -> Self::Output {
self &= rhs;
self
}
}
/// Perform the Boolean AND operation in place on a `BitVec`, using a stream of
/// `bool` values as the other bit for each operation. If the other stream is
/// shorter than `self`, `self` will be truncated when the other stream expires.
impl<E, T, I> BitAndAssign<I> for BitVec<E, T>
where E: Endian, T: Bits, I: IntoIterator<Item=bool> {
/// AND another bitstream into a vector.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let mut src = bitvec![BigEndian, u8; 0, 1, 0, 1];
/// src &= bitvec![BigEndian, u8; 0, 0, 1, 1];
/// assert_eq!("0001", &format!("{}", src));
/// ```
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);
}
}
/// Perform the Boolean OR operation between each element of a `BitVec` and
/// anything that can provide a stream of `bool` values (such as another
/// `BitVec`, or any `bool` generator of your choice). The `BitVec` emitted will
/// have the length of the shorter sequence of bits -- if one is longer than the
/// other, the extra bits will be ignored.
impl<E, T, I> BitOr<I> for BitVec<E, T>
where E: Endian, T: Bits, I: IntoIterator<Item=bool> {
type Output = Self;
/// OR a vector and a bitstream, producing a new vector.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let lhs = bitvec![BigEndian, u8; 0, 1, 0, 1];
/// let rhs = bitvec![BigEndian, u8; 0, 0, 1, 1];
/// let or = lhs | rhs;
/// assert_eq!("0111", &format!("{}", or));
/// ```
fn bitor(mut self, rhs: I) -> Self::Output {
self |= rhs;
self
}
}
/// Perform the Boolean OR operation in place on a `BitVec`, using a stream of
/// `bool` values as the other bit for each operation. If the other stream is
/// shorter than `self`, `self` will be truncated when the other stream expires.
impl<E, T, I> BitOrAssign<I> for BitVec<E, T>
where E: Endian, T: Bits, I: IntoIterator<Item=bool> {
/// OR another bitstream into a vector.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let mut src = bitvec![BigEndian, u8; 0, 1, 0, 1];
/// src |= bitvec![BigEndian, u8; 0, 0, 1, 1];
/// assert_eq!("0111", &format!("{}", src));
/// ```
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);
}
}
/// Perform the Boolean XOR operation between each element of a `BitVec` and
/// anything that can provide a stream of `bool` values (such as another
/// `BitVec`, or any `bool` generator of your choice). The `BitVec` emitted will
/// have the length of the shorter sequence of bits -- if one is longer than the
/// other, the extra bits will be ignored.
impl<E, T, I> BitXor<I> for BitVec<E, T>
where E: Endian, T: Bits, I: IntoIterator<Item=bool> {
type Output = Self;
/// XOR a vector and a bitstream, producing a new vector.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let lhs = bitvec![BigEndian, u8; 0, 1, 0, 1];
/// let rhs = bitvec![BigEndian, u8; 0, 0, 1, 1];
/// let xor = lhs ^ rhs;
/// assert_eq!("0110", &format!("{}", xor));
/// ```
fn bitxor(mut self, rhs: I) -> Self::Output {
self ^= rhs;
self
}
}
/// Perform the Boolean XOR operation in place on a `BitVec`, using a stream of
/// `bool` values as the other bit for each operation. If the other stream is
/// shorter than `self`, `self` will be truncated when the other stream expires.
impl<E, T, I> BitXorAssign<I> for BitVec<E, T>
where E: Endian, T: Bits, I: IntoIterator<Item=bool> {
/// XOR another bitstream into a vector.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let mut src = bitvec![BigEndian, u8; 0, 1, 0, 1];
/// src ^= bitvec![BigEndian, u8; 0, 0, 1, 1];
/// assert_eq!("0110", &format!("{}", src));
/// ```
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);
}
}
/// Reborrow the `BitVec` as a `BitSlice`.
///
/// This mimics the separation between `Vec<T>` and `[T]`.
impl<E, T> Deref for BitVec<E, T>
where E: Endian, T: Bits {
type Target = BitSlice<E, T>;
/// Dereference `&BitVec` down to `&BitSlice`.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let bv: BitVec = bitvec![1; 4];
/// let bref: &BitSlice = &bv;
/// assert!(bref.get(2));
/// ```
fn deref(&self) -> &Self::Target {
// `BitVec`'s representation of its inner `Vec` matches exactly the
// invariants of how `BitSlice` references must look. This is fine.
unsafe { mem::transmute(&self.inner as &[T]) }
}
}
/// Reborrow the `BitVec` as a `BitSlice`.
///
/// This mimics the separation between `Vec<T>` and `[T]`.
impl<E, T> DerefMut for BitVec<E, T>
where E: Endian, T: Bits {
/// Dereference `&mut BitVec` down to `&mut BitSlice`.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let mut bv: BitVec = bitvec![0; 6];
/// let bref: &mut BitSlice = &mut bv;
/// assert!(!bref.get(5));
/// bref.set(5, true);
/// assert!(bref.get(5));
/// ```
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { mem::transmute(&mut self.inner as &mut [T]) }
}
}
/// Ready the underlying storage for Drop.
impl<E, T> Drop for BitVec<E, T>
where E: Endian, T: Bits {
fn drop(&mut self) {
// If the `Vec` is non-empty, set the length to the number of used
// elements as preparation for drop. The bits do not need to be wiped.
//
// If we don't do this, the `Vec` drop will treat the bit total as the
// number of elements and try to loop through all of them, which will
// not take 2 ** T::BITS times as long to run as expected, because
// it'll segfault.
let raw = self.raw_len();
unsafe { self.inner.set_len(raw); }
}
}
/// Get the bit at a specific index. The index must be less than the length of

@@ -1117,28 +1379,25 @@ /// the `BitVec`.

/// Produce an iterator over all the bits in the vector.
/// 2's-complement negation of a `BitVec`.
///
/// This iterator follows the ordering in the vector type, and implements
/// `ExactSizeIterator`, since `BitVec`s always know exactly how large they are,
/// and `DoubleEndedIterator`, since they have known ends.
impl<E, T> IntoIterator for BitVec<E, T>
/// In 2's-complement, negation is defined as bit-inversion followed by adding
/// one.
///
/// Numeric arithmetic is provided on `BitVec` as a convenience. Serious numeric
/// computation on variable-length integers should use the `num_bigint` crate
/// instead, which is written specifically for that use case. `BitVec`s are not
/// intended for arithmetic, and `bitvec` makes no guarantees about sustained
/// correctness in arithmetic at this time.
impl<E, T> Neg for BitVec<E, T>
where E: Endian, T: Bits {
type Item = bool;
#[doc(hidden)]
type IntoIter = IntoIter<E, T>;
type Output = Self;
/// Iterate over the vector.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let bv = bitvec![BigEndian, u8; 1, 1, 1, 1, 0, 0, 0, 0];
/// let mut count = 0;
/// for bit in bv {
/// if bit { count += 1; }
/// }
/// assert_eq!(count, 4);
/// ```
fn into_iter(self) -> Self::IntoIter {
Self::IntoIter::from(self)
fn neg(mut self) -> Self::Output {
// An empty vector does nothing.
// Negative zero is zero. Without this check, -[0+] becomes[10+1].
if self.is_empty() || self.not_any() {
return self;
}
self = !self;
self += BitVec::<E, T>::from(&[true] as &[bool]);
self
}

@@ -1177,63 +1436,2 @@ }

/// Test if two `BitVec`s are semantically — not bitwise — equal.
///
/// It is valid to compare two vectors of different endianness or element types.
///
/// The equality condition requires that they have the same number of stored
/// bits and that each pair of bits in semantic order are identical.
impl<A, B, C, D> PartialEq<BitVec<C, D>> for BitVec<A, B>
where A: Endian, B: Bits, C: Endian, D: Bits {
/// Perform a comparison by `==`.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let l: BitVec<LittleEndian, u16> = bitvec![LittleEndian, u16; 0, 1, 0, 1];
/// let r: BitVec<BigEndian, u32> = bitvec![BigEndian, u32; 0, 1, 0, 1];
/// assert!(l == r);
/// ```
fn eq(&self, rhs: &BitVec<C, D>) -> bool {
BitSlice::eq(&self, &rhs)
}
}
impl<E, T> Eq for BitVec<E, T>
where E: Endian, T: Bits {}
/// Compare two `BitVec`s by semantic — not bitwise — ordering.
///
/// The comparison sorts by testing each index for one vector to have a set bit
/// where the other vector has an unset bit. If the vectors are different, the
/// vector with the set bit sorts greater than the vector with the unset bit.
///
/// If one of the vectors is exhausted before they differ, the longer vector is
/// greater.
impl<A, B, C, D> PartialOrd<BitVec<C, D>> for BitVec<A, B>
where A: Endian, B: Bits, C: Endian, D: Bits {
/// Perform a comparison by `<` or `>`.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// use bitvec::*;
/// let a = bitvec![0, 1, 0, 0];
/// let b = bitvec![0, 1, 0, 1];
/// let c = bitvec![0, 1, 0, 1, 1];
/// assert!(a < b);
/// assert!(b < c);
/// ```
fn partial_cmp(&self, rhs: &BitVec<C, D>) -> Option<Ordering> {
BitSlice::partial_cmp(&self, &rhs)
}
}
impl<E, T> Ord for BitVec<E, T>
where E: Endian, T: Bits {
fn cmp(&self, rhs: &Self) -> Ordering {
BitSlice::cmp(&self, &rhs)
}
}
__bitvec_shift!(u8, u16, u32, u64, i8, i16, i32, i64);

@@ -1464,3 +1662,2 @@

let old_len = self.len();
// Implement `Extend` to make this more efficient
for _ in 0 .. shamt {

@@ -1479,2 +1676,136 @@ self.push(false);

/// Subtract one `BitVec` from another assuming 2's-complement encoding.
///
/// Subtraction is a more complex operation than addition. The bit-level work is
/// largely the same, but semantic distinctions must be made. Unlike addition,
/// which is commutative and tolerant of switching the order of the addends,
/// subtraction cannot swap the minuend (LHS) and subtrahend (RHS).
///
/// Because of the properties of 2's-complement arithmetic, M - S is equivalent
/// to M + (!S + 1). Subtraction therefore bitflips the subtrahend and adds one.
/// This may, in a degenerate case, cause the subtrahend to increase in length.
///
/// Once the subtrahend is stable, the minuend zero-extends its left side in
/// order to match the length of the subtrahend if needed (this is provided by
/// the `>>` operator).
///
/// When the minuend is stable, the minuend and subtrahend are added together
/// by the `<BitVec as Add>` implementation. The output will be encoded in
/// 2's-complement, so a leading one means that the output is considered
/// negative.
///
/// Interpreting the contents of a `BitVec` as an integer is beyond the scope of
/// this crate.
///
/// Numeric arithmetic is provided on `BitVec` as a convenience. Serious numeric
/// computation on variable-length integers should use the `num_bigint` crate
/// instead, which is written specifically for that use case. `BitVec`s are not
/// intended for arithmetic, and `bitvec` makes no guarantees about sustained
/// correctness in arithmetic at this time.
impl<E, T> Sub for BitVec<E, T>
where E: Endian, T: Bits {
type Output = Self;
/// Subtract one `BitVec` from another.
///
/// # Examples
///
/// Minuend larger than subtrahend, positive difference.
///
/// ```rust
/// use bitvec::*;
/// let a = bitvec![1, 0];
/// let b = bitvec![ 1];
/// let c = a - b;
/// assert_eq!(bitvec![0, 1], c);
/// ```
///
/// Minuend smaller than subtrahend, negative difference.
///
/// ```rust
/// use bitvec::*;
/// let a = bitvec![ 1];
/// let b = bitvec![1, 0];
/// let c = a - b;
/// assert_eq!(bitvec![1, 1], c);
/// ```
///
/// Subtraction from self is correctly handled.
///
/// ```rust
/// use bitvec::*;
/// let a = bitvec![1; 4];
/// let b = a.clone();
/// let c = a - b;
/// assert!(c.not_any(), "{:?}", c);
/// ```
fn sub(mut self, subtrahend: Self) -> Self::Output {
self -= subtrahend;
self
}
}
/// Subtract another `BitVec` from `self`, assuming 2's-complement encoding.
///
/// The minuend is zero-extended, or the subtrahend sign-extended, as needed to
/// ensure that the vectors are the same width before subtraction occurs.
///
/// The `Sub` trait has more documentation on the subtraction process.
///
/// Numeric arithmetic is provided on `BitVec` as a convenience. Serious numeric
/// computation on variable-length integers should use the `num_bigint` crate
/// instead, which is written specifically for that use case. `BitVec`s are not
/// intended for arithmetic, and `bitvec` makes no guarantees about sustained
/// correctness in arithmetic at this time.
impl<E, T> SubAssign for BitVec<E, T>
where E: Endian, T: Bits {
/// Subtract another `BitVec` from `self`.
///
/// # Examples
///
/// ```rust
/// use bitvec::*;
/// let a = bitvec![0, 0, 0, 1];
/// let b = bitvec![0, 0, 0, 0];
/// let c = a - b;
/// assert_eq!(c, bitvec![0, 0, 0, 1]);
/// ```
fn sub_assign(&mut self, mut subtrahend: Self) {
// Test for a zero subtrahend. Subtraction of zero is the identity
// function, and can exit immediately.
if subtrahend.not_any() {
return;
}
// Invert the subtrahend in preparation for addition
subtrahend = -subtrahend;
let (llen, rlen) = (self.len(), subtrahend.len());
// If the subtrahend is longer than the minuend, 0-extend the minuend.
if rlen > llen {
let diff = rlen - llen;
*self >>= diff;
*self += subtrahend;
}
else {
// If the minuend is longer than the subtrahend, 1-extend the
// subtrahend.
if llen > rlen {
let diff = llen - rlen;
let sign = subtrahend.get(0);
subtrahend >>= diff;
// Implementing BitVec >> (usize, bool) would permit sign
// extension in fewer steps.
for idx in 0 .. diff {
subtrahend.set(idx, sign);
}
}
let old = self.len();
*self += subtrahend;
// If the subtraction emitted a carry, remove it.
if self.len() > old {
*self <<= 1;
}
}
}
}
/// Iterate over an owned `BitVec`.

@@ -1481,0 +1812,0 @@ #[doc(hidden)]

Sorry, the diff of this file is not supported yet