Struct bitvec::BitVec[][src]

pub struct BitVec<E: Endian = BigEndian, T: Bits = u8> { /* fields omitted */ }

A Vec of bits, whose cursor and storage type can be customized.

BitVec is a newtype wrapper over Vec, and as such is exactly three words in size on the stack.

IMPORTANT NOTE: It is wildly unsafe to use mem::transmute between Vec<T> and BitVec<_, T>, because BitVec achieves its size by using the length field of the underlying Vec to count bits, rather than elements. This means that it has a fixed maximum bit width regardless of element type, and the length field will always be horrifically wrong to be treated as a Vec. Safe methods exist to move between Vec and BitVec – USE THEM.

BitVec takes two type parameters.

  • E: Endian must be an implementor of the Endian trait. BitVec takes a PhantomData marker for access to the associated functions, and will never make use of an instance of the trait. The default implementations, LittleEndian and BigEndian, are zero-sized, and any further implementations should be as well, as the invoked functions will never receive state.
  • T: Bits must be a primitive type. Rust decided long ago to not provide a unifying trait over the primitives, so Bits provides access to just enough properties of the primitives for BitVec to use. This trait is sealed against downstream implementation, and can only be implemented in this crate.

Methods

impl<E: Endian, T: Bits> BitVec<E, T>
[src]

Constructs a new, empty, BitVec<E, T>.

The vector will not allocate until bits are pushed onto it.

Constructs a new, empty BitVec<T> with the specified capacity.

The vector will be able to hold exactly capacity elements without reallocating. If capacity is 0, the vector will not allocate.

Returns the number of bits the vector can hold without reallocating.

Returns the number of bits stored in the vector.

Counts how many bits are used in the tail storage element.

This has no relation to how many elements are filled. To see the total number of bits stored, use .len().

The return value of this function must be passed into E::curr::<T> in order to index the tail element directly. It is a semantic count, not a bit index.

Counts how many storage elements are filled.

This is one fewer than the number of elements in use, because the tail element is always partially filled or empty. It will be zero when the storage Vec is empty, or when the BitVec has begun filling but is not yet greater than T::MASK bits in size.

Incidentally, this means that this is a valid index into the underlying store in order to reach the tail element.

Appends a bit to the collection.

Removes the last bit from the collection.

Returns None if the collection is empty.

Gets a bit at the given position.

Sets a bit at the given position to the given value.

Empty out the BitVec, resetting it to length zero.

This will not affect the allocated capacity.

Returns true if the vector contains no bits.

Provides read-only iteration across the collection.

The iterator returned from this method implements ExactSizeIterator and DoubleEndedIterator just as the consuming .into_iter() method’s iterator does.

Reserve capacity for additional bits.

Shrink the capacity to fit at least as much as is needed, but with as little excess as the allocator chooses.

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

This will not affect the allocated capacity.

Convert the BitVec into a boxed slice of storage elements. This drops all BitVec management semantics, including partial fill status of the trailing element or endianness, and gives ownership the raw storage.

Trait Implementations

impl<E: Endian, T: Bits> AsMut<[T]> for BitVec<E, T>
[src]

Gives write access to all live elements in the underlying storage, including the partially-filled tail.

Examples

use bitvec::*;
let src: &[u8] = &[5, 10, 15, 20, 25];
let mut bv: BitVec = src.into();
for elt in bv.as_mut() {
  *elt += 2;
}
assert_eq!(&[7, 12, 17, 22, 27], bv.as_ref());

Performs the conversion.

impl<E: Endian, T: Bits> AsRef<[T]> for BitVec<E, T>
[src]

Gives read access to all live elements in the underlying storage, including the partially-filled tail.

Examples

use bitvec::*;
let src: &[u8] = &[5, 10, 15, 20, 25];
let bv: BitVec = src.into();
assert_eq!(&[5, 10, 15, 20, 25], bv.as_ref());

Performs the conversion.

impl<E: Endian, T: Bits, I: IntoIterator<Item = bool>> BitAnd<I> for BitVec<E, T>
[src]

Performs 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.

Examples

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));

The resulting type after applying the & operator.

Performs the & operation.

impl<E: Endian, T: Bits, I: IntoIterator<Item = bool>> BitAndAssign<I> for BitVec<E, T>
[src]

Performs 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.

Examples

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));

Performs the &= operation.

impl<E: Endian, T: Bits, I: IntoIterator<Item = bool>> BitOr<I> for BitVec<E, T>
[src]

Performs 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.

Examples

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));

The resulting type after applying the | operator.

Performs the | operation.

impl<E: Endian, T: Bits, I: IntoIterator<Item = bool>> BitOrAssign<I> for BitVec<E, T>
[src]

Performs 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.

Examples

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));

Performs the |= operation.

impl<E: Endian, T: Bits, I: IntoIterator<Item = bool>> BitXor<I> for BitVec<E, T>
[src]

Performs 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.

Examples

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));

The resulting type after applying the ^ operator.

Performs the ^ operation.

impl<E: Endian, T: Bits, I: IntoIterator<Item = bool>> BitXorAssign<I> for BitVec<E, T>
[src]

Performs 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.

Examples

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));

Performs the ^= operation.

impl<E: Endian, T: Bits> Clone for BitVec<E, T>
[src]

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

impl<E: Endian, T: Bits> Debug for BitVec<E, T>
[src]

Prints 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.

Examples

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));

Formats the value using the given formatter. Read more

impl<E: Endian, T: Bits> Display for BitVec<E, T>
[src]

Prints 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.

Examples

use bitvec::*;
let bv = bitvec![BigEndian, u8, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1];
assert_eq!("01001011 01", &format!("{}", bv));

Formats the value using the given formatter. Read more

impl<E: Endian, T: Bits> Drop for BitVec<E, T>
[src]

Readies the underlying storage for Drop.

Executes the destructor for this type. Read more

impl<'a, E: Endian, T: Bits> From<&'a [bool]> for BitVec<E, T>
[src]

Performs the conversion.

impl<'a, E: Endian, T: Bits> From<&'a [T]> for BitVec<E, T>
[src]

Build a BitVec out of a borrowed slice of elements.

This copies the memory as-is from the source buffer into the new BitVec. The source buffer will be unchanged by this operation, so you don't need to worry about using the correct cursor type.

This operation does a copy from the source buffer into a new allocation, as it can only borrow the source and not take ownership.

Examples

use bitvec::*;
let src: &[u8] = &[5, 10];
let bv: BitVec = src.into();
assert_eq!("00000101 00001010", &format!("{}", bv));

Performs the conversion.

impl<E: Endian, T: Bits> From<Box<[T]>> for BitVec<E, T>
[src]

Build a BitVec out of an owned slice of elements.

This moves the memory as-is from the source buffer into the new BitVec. The source buffer will be unchanged by this operation, so you don't need to worry about using the correct cursor type.

Examples

use bitvec::*;
let src: Box<[u8]> = Box::new([3, 6, 9, 12, 15]);
let bv: BitVec = src.into();
assert_eq!("00000011 00000110 00001001 00001100 00001111", &format!("{}", bv));

Performs the conversion.

impl<E: Endian, T: Bits> From<Vec<T>> for BitVec<E, T>
[src]

Build a BitVec out of a Vec of elements.

This moves the memory as-is from the source buffer into the new BitVec. The source buffer will be unchanged by this operation, so you don't need to worry about using the correct cursor type.

Examples

use bitvec::*;
let src: Vec<u8> = vec![1, 2, 4, 8];
let bv: BitVec = src.into();
assert_eq!("00000001 00000010 00000100 00001000", &format!("{}", bv));

Performs the conversion.

impl<T: Bits> From<BitVec<LittleEndian, T>> for BitVec<BigEndian, T>
[src]

Change cursors on a BitVec without mutating the underlying data.

I don't know why this would be useful at the time of writing, as the From implementations on collections crawl the collection elements in the order requested and so the source and destination storage collections will be bitwise identical, but here's the option anyway.

If the tail element is partially filled, then this operation will shift the tail element so that the edge of the filled section is on the correct edge of the tail element.

Performs the conversion.

impl<T: Bits> From<BitVec<BigEndian, T>> for BitVec<LittleEndian, T>
[src]

Change cursors on a BitVec without mutating the underlying data.

I don't know why this would be useful at the time of writing, as the From implementations on collections crawl the collection elements in the order requested and so the source and destination storage collections will be bitwise identical, but here's the option anyway.

If the tail element is partially filled, then this operation will shift the tail element so that the edge of the filled section is on the correct edge of the tail element.

Performs the conversion.

impl<E: Endian, T: Bits> FromIterator<bool> for BitVec<E, T>
[src]

Permits the construction of a BitVec by using .collect() on an iterator of bool

Examples

use bitvec::*;
use std::iter::repeat;
let bv: BitVec = repeat(true).take(4).chain(repeat(false).take(4)).collect();
assert_eq!("11110000", &format!("{}", bv));

Creates a value from an iterator. Read more

impl<E: Endian, T: Bits> Index<usize> for BitVec<E, T>
[src]

Get the bit at a specific index. The index must be less than the length of the BitVec.

Examples

use bitvec::*;
let bv = bitvec![BigEndian, u8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0];
assert!(!bv[7]); // ---------------------------------^  |  |
assert!( bv[8]); //-------------------------------------^  |
assert!(!bv[9]); // ---------------------------------------^

If the index is greater than or equal to the length, indexing will panic.

The below test will panic when accessing index 1, as only index 0 is valid.

use bitvec::*;
let mut bv: BitVec = BitVec::new();
bv.push(true);
bv[1];

The returned type after indexing.

Performs the indexing (container[index]) operation.

impl<E: Endian, T: Bits> Index<(usize, u8)> for BitVec<E, T>
[src]

Get the bit in a specific element. The element index must be less than or equal to the value returned by elts(), and the bit index must be less than the width of the storage type.

If the BitVec has a partially-filled tail, then the value returned by elts() is a valid index.

The element and bit indices are combined using Bits::join for the storage type.

Examples

use bitvec::*;
let bv = bitvec![BigEndian, u8, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1];
assert!(bv[(1, 1)]); // -----------------------------------^

The returned type after indexing.

Index into a BitVec using a known element index and a count into that element. The count must not be converted for endianness outside the call

impl<E: Endian, T: Bits> IntoIterator for BitVec<E, T>
[src]

Produces an iterator over all the bits in the vector.

This iterator follows the ordering in the vector type, and implements ExactSizeIterator, since BitVecs always know exactly how large they are, and DoubleEndedIterator, since they have known ends.

Examples

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);

The type of the elements being iterated over.

Creates an iterator from a value. Read more

Which kind of iterator are we turning this into?

impl<E: Endian, T: Bits> Not for BitVec<E, T>
[src]

Flips all bits in the vector.

Examples

use bitvec::*;
let bv: BitVec<BigEndian, u32> = BitVec::from(&[0u32] as &[u32]);
let flip = !bv;
assert_eq!(!0u32, flip.as_ref()[0]);

The resulting type after applying the ! operator.

Performs the unary ! operation.

impl<E: Endian, T: Bits> Shl<usize> for BitVec<E, T>
[src]

Shifts all bits in the vector to the left – DOWN AND TOWARDS THE FRONT.

On primitives, the left-shift operator << moves bits away from origin and towards the ceiling. This is because we label the bits in a primitive with the minimum on the right and the maximum on the left, which is big-endian bit order. This increases the value of the primitive being shifted.

THAT IS NOT HOW BITVEC WORKS!

BitVec defines its layout with the minimum on the left and the maximum on the right! Thus, left-shifting moves bits towards the minimum.

In BigEndian order, the effect in memory will be what you expect the << operator to do.

In LittleEndian order, the effect will be equivalent to using >> on the primitives in memory!

Notes

In order to preserve the effects in memory that this operator traditionally expects, the bits that are emptied by this operation are zeroed rather than being left to their old value.

The length of the vector is decreased by the shift amount.

If the shift amount is greater than the length, the vector calls clear() and zeroes its memory. This is not an error.

Examples

use bitvec::*;
let bv = bitvec![BigEndian, u8, 0, 0, 0, 1, 1, 1];
assert_eq!("000111", &format!("{}", bv));
assert_eq!(0b0001_1100, bv.as_ref()[0]);
assert_eq!(bv.len(), 6);
let ls = bv << 2;
assert_eq!("0111", &format!("{}", ls));
assert_eq!(0b0111_0000, ls.as_ref()[0]);
assert_eq!(ls.len(), 4);

The resulting type after applying the << operator.

Performs the << operation.

impl<'a, E: Endian, T: Bits> ShlAssign<usize> for BitVec<E, T>
[src]

Shifts all bits in the vector to the left – DOWN AND TOWARDS THE FRONT.

On primitives, the left-shift operator << moves bits away from origin and towards the ceiling. This is because we label the bits in a primitive with the minimum on the right and the maximum on the left, which is big-endian bit order. This increases the value of the primitive being shifted.

THAT IS NOT HOW BITVEC WORKS!

BitVec defines its layout with the minimum on the left and the maximum on the right! Thus, left-shifting moves bits towards the minimum.

In BigEndian order, the effect in memory will be what you expect the << operator to do.

In LittleEndian order, the effect will be equivalent to using >> on the primitives in memory!

Notes

In order to preserve the effects in memory that this operator traditionally expects, the bits that are emptied by this operation are zeroed rather than being left to their old value.

The length of the vector is decreased by the shift amount.

If the shift amount is greater than the length, the vector calls clear() and zeroes its memory. This is not an error.

Examples

use bitvec::*;
let mut bv = bitvec![LittleEndian, u8, 0, 0, 0, 1, 1, 1];
assert_eq!("000111", &format!("{}", bv));
assert_eq!(0b0011_1000, bv.as_ref()[0]);
assert_eq!(bv.len(), 6);
bv <<= 2;
assert_eq!("0111", &format!("{}", bv));
assert_eq!(0b0000_1110, bv.as_ref()[0]);
assert_eq!(bv.len(), 4);

Performs the <<= operation.

impl<E: Endian, T: Bits> Shr<usize> for BitVec<E, T>
[src]

Shifts all bits in the vector to the right – UP AND TOWARDS THE RIGHT.

On primitives, the right-shift operator >> moves bits towards the origin and away from the ceiling. This is because we label the bits in a primitive with the minimum on the right and the maximum on the left, which is big-endian bit order. This decreases the value of the primitive being shifted.

THAT IS NOT HOW BITVEC WORKS!

BitVec defines its layout with the minimum on the left and the maximum on the right! Thus, rightt-shifting moves bits towards the maximum.

In BigEndian order, the effect in memory will be what you expect the >> operator to do.

In LittleEndian order, the effect will be equivalent to using << on the primitives in memory!

Notes

In order to preserve the effects in memory that this operator traditionally expects, the bits that are emptied by this operation are zeroed rather than being left to their old value.

The length of the vector is increased by the shift amount.

If the new length of the vector would overflow, a panic occurs. This is an error.

Examples

use bitvec::*;
let bv = bitvec![BigEndian, u8, 0, 0, 0, 1, 1, 1];
assert_eq!("000111", &format!("{}", bv));
assert_eq!(0b0001_1100, bv.as_ref()[0]);
assert_eq!(bv.len(), 6);
let rs = bv >> 2;
assert_eq!("00000111", &format!("{}", rs));
assert_eq!(0b0000_0111, rs.as_ref()[0]);
assert_eq!(rs.len(), 8);

The resulting type after applying the >> operator.

Performs the >> operation.

impl<'a, E: Endian, T: Bits> ShrAssign<usize> for BitVec<E, T>
[src]

Shifts all bits in the vector to the right – UP AND TOWARDS THE RIGHT.

On primitives, the right-shift operator >> moves bits towards the origin and away from the ceiling. This is because we label the bits in a primitive with the minimum on the right and the maximum on the left, which is big-endian bit order. This decreases the value of the primitive being shifted.

THAT IS NOT HOW BITVEC WORKS!

BitVec defines its layout with the minimum on the left and the maximum on the right! Thus, rightt-shifting moves bits towards the maximum.

In BigEndian order, the effect in memory will be what you expect the >> operator to do.

In LittleEndian order, the effect will be equivalent to using << on the primitives in memory!

Notes

In order to preserve the effects in memory that this operator traditionally expects, the bits that are emptied by this operation are zeroed rather than being left to their old value.

The length of the vector is increased by the shift amount.

If the new length of the vector would overflow, a panic occurs. This is an error.

Examples

use bitvec::*;
let mut bv = bitvec![LittleEndian, u8, 0, 0, 0, 1, 1, 1];
assert_eq!("000111", &format!("{}", bv));
assert_eq!(0b0011_1000, bv.as_ref()[0]);
assert_eq!(bv.len(), 6);
bv >>= 2;
assert_eq!("00000111", &format!("{}", bv));
assert_eq!(0b1110_0000, bv.as_ref()[0]);
assert_eq!(bv.len(), 8);

Performs the >>= operation.

impl<'a, E: Endian, T: Bits> IntoIterator for &'a BitVec<E, T>
[src]

Permits iteration over a borrowed BitVec.

The type of the elements being iterated over.

Creates an iterator from a value. Read more

Which kind of iterator are we turning this into?

Auto Trait Implementations

impl<E, T> Send for BitVec<E, T> where
    E: Send,
    T: Send

impl<E, T> Sync for BitVec<E, T> where
    E: Sync,
    T: Sync