#[repr(C)]
pub struct BitVec<O = Local, T = usize> where
    O: BitOrder,
    T: BitStore
{ /* private fields */ }
Expand description

A compact Vec of bits, whose order 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.

Examples

use bitvec::prelude::*;

let mut bv: BitVec = BitVec::new();
bv.push(false);
bv.push(true);

assert_eq!(bv.len(), 2);
assert_eq!(bv[0], false);

assert_eq!(bv.pop(), Some(true));
assert_eq!(bv.len(), 1);

bv.set(0, true);
assert_eq!(bv[0], true);

bv.extend([0u8, 1, 0].iter().map(|n| *n != 0u8));
for bit in &*bv {
  println!("{}", bit);
}
assert_eq!(bv, bitvec![1, 0, 1, 0]);

The bitvec! macro is provided to make initialization more convenient.

use bitvec::prelude::*;

let mut bv = bitvec![0, 1, 2, 3];
bv.push(false);
assert_eq!(bv, bitvec![0, 1, 1, 1, 0]);

It can also initialize each element of a BitVec<_, T> with a given value. This may be more efficient than performing allocation and initialization in separate steps, especially when initializing a vector of zeros:

use bitvec::prelude::*;

let bv = bitvec![0; 15];
assert_eq!(bv, bitvec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);

// The following is equivalent, but potentially slower:
let mut bv1: BitVec = BitVec::with_capacity(15);
bv1.resize(15, false);

Use a BitVec<T> as an efficient stack:

use bitvec::prelude::*;
let mut stack: BitVec = BitVec::new();

stack.push(false);
stack.push(true);
stack.push(true);

while let Some(top) = stack.pop() {
  //  Prints true, true, false
  println!("{}", top);
}

Indexing

The BitVec type allows you to access values by index, because it implements the Index trait. An example will be more explicit:

use bitvec::prelude::*;

let bv = bitvec![0, 0, 1, 1];
println!("{}", bv[1]); // it will display 'false'

However, be careful: if you try to access an index which isn’t in the BitVec, your software will panic! You cannot do this:

use bitvec::prelude::*;

let bv = bitvec![0, 1, 0, 1];
println!("{}", bv[6]); // it will panic!

In conclusion: always check if the index you want to get really exists before doing it.

Slicing

A BitVec is growable. A BitSlice, on the other hand, is fixed size. To get a bit slice, use &. Example:

use bitvec::prelude::*;
fn read_bitslice(slice: &BitSlice) {
    // use slice
}

let bv = bitvec![0, 1];
read_bitslice(&bv);

// … and that’s all!
// you can also do it like this:
let bs: &BitSlice = &bv;

In Rust, it’s more common to pass slices as arguments rather than vectors when you do not want to grow or shrink it. The same goes for Vec and [&[]], and String and &str.

Capacity and reallocation

The capacity of a bit vector is the amount of space allocated for any future bits that will be added onto the vector. This is not to be confused with the length of a vector, which specifies the number of live, useful bits within the vector. If a vector’s length exceeds its capacity, its capacity will automatically be increased, but its storage elements will have to be reallocated.

For example, a bit vector with capacity 10 and length 0 would be an allocated, but uninhabited, vector, with space for ten more bits. Pushing ten or fewer bits onto the vector will not change its capacity or cause reallocation to occur. However, if the vector’s length is increased to eleven, it will have to reallocate, which can be slow. For this reason, it is recommended to use BitVec::with_capacity whenever possible to specify how big the bit vector is expected to get.

Guarantees

Due to its incredibly fundamental nature, BitVec makes a lot of guarantees about its design. This ensures that it is as low-overhead as possible in the general case, and can be correctly manipulated in fundamental ways by unsafe code.

Most fundamentally, BitVec is and always will be a ([BitPtr], capacity) doublet. No more, no less. The order of these fields is unspecified, and you should only interact with the members through the provided APIs. Note that BitPtr is not directly manipulable, and must never be written or interpreted as anything but opaque binary data by user code.

When a BitVec has allocated memory, then the memory to which it points is on the heap (as defined by the allocator Rust is configured to use by default), and its pointer points to len initialized bits in order of the BitOrder type parameter, followed by capacity - len logically uninitialized bits.

BitVec will never perform a “small optimization” where elements are stored in its handle representation, for two reasons:

  • It would make it more difficult for user code to correctly manipulate a BitVec. The contents of the BitVec would not have a stable address if the handle were moved, and it would be more difficult to determine if a BitVec had allocated memory.

  • It would penalize the general, heap-allocated, case by incurring a branch on every access.

BitVec will never automatically shrink itself, even if it is emptied. This ensures that no unnecessary allocations or deallocations occur. Emptying a BitVec and then refilling it to the same length will incur no calls to the allocator. If you wish to free up unused memory, use shrink_to_fit.

Erasure

BitVec will not specifically overwrite any data that is removed from it, nor will it specifically preserve it. Its uninitialized memory is scratch space that may be used however the implementation desires, and must not be relied upon as stable. Do not rely on removed data to be erased for security purposes. Even if you drop a BitVec, its buffer may simply be reused for other data structures in your program. Even if you zero a BitVec’s memory first, that may not actually occur if the optimizer does not consider this an observable side effect. There is one case that will never break, however: using unsafe to construct a [T] slice over the BitVec’s capacity, and writing to the excess space, then increasing the length to match, is always valid.

Type Parameters

  • O: BitOrder: An implementor of the BitOrder trait. This type is used to convert semantic indices into concrete bit positions in elements, and store or retrieve bit values from the storage type.
  • T: BitStore: An implementor of the BitStore trait: u8, u16, u32, or u64 (64-bit systems only). This is the actual type in memory that the vector will use to store data.

Safety

The BitVec handle has the same size as standard Rust Vec handles, but it is extremely binary incompatible with them. Attempting to treat BitVec<_, T> as Vec<T> in any manner except through the provided APIs is catastrophically unsafe and unsound.

[&[]]: https://doc.rust-lang.org/stable/std/primitive.slice.html

Implementations

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

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

let mut bv: BitVec<Local, usize> = BitVec::new();

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

The vector will be able to hold at least capacity bits without reallocating. If capacity is 0, the vector will not allocate.

It is important to note that although the returned vector has the capacity specified, the vector will have a zero length. For an explanation of the difference between length and capacity, see Capacity and reallocation.

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

Examples
let bv: BitVec<Local, usize> = BitVec::with_capacity(100);
assert!(bv.capacity() >= 100);

Reserves capacity for at least additional more bits to be inserted in the given BitVec<C, T>. The collection may reserve more space to avoid frequent reallocations. After calling reserve, the capacity will be greater than or equal to self.len() + additional. Does nothing if the capacity is already sufficient.

Panics

Panics if the new capacity overflows BitPtr::<T>::MAX_BITS.

Examples
let mut bv = bitvec![1];
bv.reserve(10);
assert!(bv.capacity() >= 11);

Reserves the minimum capacity for exactly additional more bits to be inserted in the given BitVec<C, T>. After calling reserve_exact, capacity will be greater than or equal to self.len() + additional. Does nothing if the capacity is already sufficient.

Note that the allocator may give the collection more space than it requests. Therefore, capacity can not be relied upon to be precisely minimal. Prefer reserve if future insertions are expected.

Panics

Panics if the new capacity overflows BitPtr::<T>::MAX_BITS.

Examples
let mut bv = bitvec![1];
bv.reserve_exact(10);
assert!(bv.capacity() >= 11);

Shrinks the capacity of the vector as much as possible.

It will drop down as close as possible to the length but the allocator may still inform the vector that there is space for a few more elements.

Examples
let mut bv: BitVec<Local, usize> = BitVec::with_capacity(10);
bv.extend([true, false, true].iter().copied());
assert!(bv.capacity() >= 10);
bv.shrink_to_fit();
assert!(bv.capacity() >= 3);

Converts the bit-vector into [Box<[T]>].

Note that this will drop any excess capacity.

For the vec-to-box equivalent that produces a BitBox<C, T>, see [into_boxed_bitslice].

Examples
let bv = bitvec![1, 0, 1];

let slice = bv.into_boxed_slice();

Any excess capacity is removed:

let mut bv = BitVec::<Local, usize>::with_capacity(100);
bv.extend([true, false, true].iter().copied());

assert!(bv.capacity() >= 100);
let slice = bv.into_boxed_slice();
let boxed_bitslice = BitBox::<Local, usize>::from_boxed_slice(slice);
let bv = BitVec::from_boxed_bitslice(boxed_bitslice);
assert!(bv.capacity() >= 3);

[Box<[T]>]: https://doc.rust-lang.org/std/boxed/struct.Box.html [into_boxed_bitslice]: #method.into_boxed_bitslice

Shortens the vector, keeping the first len bits and dropping the rest.

If len is greater than the vector’s current length, this has no effect.

The [drain] method can emulate truncate, but causes the excess bits to be returned instead of dropped.

Note that this method has no effect on the allocated capacity of the vector.

Examples

Truncating a five-bit vector to two bits:

let mut bv = bitvec![1, 0, 1, 0, 1];
bv.truncate(2);
assert_eq!(bv, bitvec![1, 0]);

No truncation occurs when len is greater than the vector’s current length:

let mut bv = bitvec![1; 5];
bv.truncate(10);
assert_eq!(bv, bitvec![1; 5]);

Truncating to zero is equivalent to calling the [clear] method.

let mut bv = bitvec![0; 5];
bv.truncate(0);
assert!(bv.is_empty());

Extracts an element slice containing the entire vector.

Unlike BitSlice::as_slice, this will produce partial edge elements, as they are known to not be aliased by any other slice handles.

Examples
use std::io::{self, Write};
let buffer = bitvec![Local, u8; 1, 0, 1, 0, 1];
io::sink().write(buffer.as_slice()).unwrap();

Extracts a mutable slice of the entire vector.

Unlike BitSlice::as_mut_slice, this will produce partial edge elements, as they are known to not be aliased by any other slice handles.

Examples
use std::io::{self, Read};
let mut buffer = bitvec![Local, u8; 0; 24];
io::repeat(0xA5u8).read_exact(buffer.as_mut_slice()).unwrap();

Forces the length of the vector to new_len.

This is a low-level operation that maintains none of the normal invariants of the type. Normally changing the length of a vector is done using one of the safe operations instead, such as [truncate], [resize], [extend], or [clear].

Safety
  • new_len must be less than or equal to [capacity()].
  • The underlying elements at old_len ..new_len must be initialized.
Examples

This method can be useful for situations in which the vector is serving as a buffer for other code, particularly over FFI.

let mut bv = BitVec::<Local, usize>::with_capacity(17);
assert!(bv.is_empty());
unsafe { bv.set_len(23) };
assert_eq!(bv.len(), 23);

This example executes correctly, because the allocator can only reserve even multiples of bytes, and so rounds up from the with_capacity argument.

Removes a bit from the vector and returns it.

The removed bit is replaced by the last bit of the vector.

This does not preserve ordering, but is O(1).

Panics

Panics if index is out of bounds.

Examples
let mut bv = bitvec![1, 0, 1, 0, 1];

assert!(!bv.swap_remove(1));
assert_eq!(bv, bitvec![1, 1, 1, 0]);

assert!(bv.swap_remove(0));
assert_eq!(bv, bitvec![0, 1, 1]);

Inserts a bit at position index within the vector, shifting all bits after it to the right.

Panics

Panics if index > len.

Examples
let mut bv = bitvec![1, 0, 1, 0, 1];
bv.insert(1, false);
assert_eq!(bv, bitvec![1, 0, 0, 1, 0, 1]);
bv.insert(4, true);
assert_eq!(bv, bitvec![1, 0, 0, 1, 1, 0, 1]);

Removes and returns the bit at position index within the vector, shifting all bits after it to the left.

Panics

Panics if index is out of bounds.

Examples
let mut bv = bitvec![1, 0, 1, 0, 1];
assert!(!bv.remove(1));
assert_eq!(bv, bitvec![1, 1, 0, 1]);

Retains only the bits that pass the predicate.

This removes all bits b where f(e) returns false. This method operates in place and preserves the order of the retained bits. Because it is in-place, it operates in O(n²) time.

API Differences

The Vec::retain method takes a predicate function with signature (&T) -> bool, whereas this method’s predicate function has signature (usize, &T) -> bool. This difference is in place because BitSlice by definition has only one bit of information per slice item, and including the index allows the callback function to make more informed choices.

Examples
let mut bv = bitvec![0, 1, 0, 1, 0, 1];
bv.retain(|_, b| b);
assert_eq!(bv, bitvec![1, 1, 1]);

Appends a bit to the back of the vector.

If the vector is at capacity, this may cause a reallocation.

Panics

This will panic if the push will cause the vector to allocate above BitPtr<T>::MAX_ELTS or machine capacity.

Examples
let mut bv: BitVec = BitVec::new();
assert!(bv.is_empty());
bv.push(true);
assert_eq!(bv.len(), 1);
assert!(bv[0]);

Removes the last element from a vector and returns it, or None if it is empty.

Examples
let mut bv: BitVec = BitVec::new();
assert!(bv.is_empty());
bv.push(true);
assert_eq!(bv.len(), 1);
assert!(bv[0]);

assert!(bv.pop().unwrap());
assert!(bv.is_empty());
assert!(bv.pop().is_none());

Moves all the elements of other into self, leaving other empty.

Panics

Panics if the number of bits in the vector overflows BitPtr::<T>::MAX_ELTS.

Examples
let mut bv1 = bitvec![0; 10];
let mut bv2 = bitvec![1; 10];
bv1.append(&mut bv2);
assert_eq!(bv1.len(), 20);
assert!(bv1[10]);
assert!(bv2.is_empty());

Creates a draining iterator that removes the specified range from the vector and yields the removed bits.

Notes
  1. The element range is removed even if the iterator is only partially consumed or not consumed at all.
  2. It is unspecified how many bits are removed from the vector if the Drain value is leaked.
Panics

Panics if the starting point is greater than the end point or if the end point is greater than the length of the vector.

Examples
let mut bv = bitvec![0, 0, 1, 1, 1, 0, 0];
assert_eq!(bv.len(), 7);
for bit in bv.drain(2 .. 5) {
  assert!(bit);
}
assert!(bv.not_any());
assert_eq!(bv.len(), 4);

Clears the vector, removing all values.

Note that this method has no effect on the allocated capacity of the vector.

Examples
let mut bv = bitvec![1; 30];
assert_eq!(bv.len(), 30);
assert!(bv.iter().all(|b| *b));
bv.clear();
assert!(bv.is_empty());

After calling clear(), bv will no longer show raw memory, so the above test cannot show that the underlying memory is not altered. This is also an implementation detail on which you should not rely.

Splits the collection into two at the given index.

Returns a newly allocated Self. self contains elements [0, at), and the returned Self contains elements [at, len).

Note that the capacity of self does not change.

Panics

Panics if at > len.

Examples
let mut bv1 = bitvec![0, 0, 0, 1, 1, 1];
let bv2 = bv1.split_off(3);
assert_eq!(bv1, bitvec![0, 0, 0]);
assert_eq!(bv2, bitvec![1, 1, 1]);

Resizes the BitVec in-place so that len is equal to new_len.

If new_len is greater than len, the BitVec is extended by the difference, with each additional slot filled with the result of calling the closure f. The return values from f will end up in the BitVec in the order they have been generated.

If new_len is less than len, the BitVec is simply truncated.

This method uses a closure to create new values on every push. If you’d rather Clone a given value, use resize. If you want to use the Default trait to generate values, you can pass Default::default() as the second argument.

Examples
let mut bv = bitvec![1, 0, 1];
bv.resize_with(5, Default::default);
assert_eq!(bv, bitvec![1, 0, 1, 0, 0]);

let mut bv = bitvec![];
let mut p = 1;
bv.resize_with(4, || { p += 1; p % 2 == 0});
assert_eq!(bv, bitvec![1, 0, 1, 0]);

Resizes the BitVec in place so that len is equal to new_len.

If new_len is greater than len, the BitVec is extended by the difference, with each additional slot filled with value. If new_len is less than len, the BitVec is simply truncated.

Examples
let mut bv = bitvec![0; 4];
bv.resize(8, true);
assert_eq!(bv, bitvec![0, 0, 0, 0, 1, 1, 1, 1]);
bv.resize(5, false);
assert_eq!(bv, bitvec![0, 0, 0, 0, 1]);

Clones and appends all bits in a bit-slice to the BitVec.

Iterates over the bit-slice other, clones each bit, and then appends it to this BitVec. The other slice is traversed in-order.

Note that this function is the same as extend except that it is specialized to work with bit-slices instead. If and when Rust gets specialization this function will likely be deprecated (but still available).

Examples
let mut bv = bitvec![1];
bv.extend_from_slice(0xA5u8.bits::<Lsb0>());
assert_eq!(bv, bitvec![1, 1, 0, 1, 0, 0, 1, 0, 1]);

Creates a splicing iterator that replaces the specified range in the vector with the given replace_with iterator and yields the removed bits. replace_with does not need to be the same length as range.

Notes
  1. The element range is removed and replaced even if the iterator produced by this method is not consumed until the end.

  2. It is unspecified how many bits are removed from the vector if the Splice value is leaked.

  3. The input iterator replace_with is only consumed when the Splice value is dropped.

  4. This is optimal if:

    • the tail (elements in the vector after range) is empty,
    • or replace_with yields fewer bits than range’s length,
    • the lower bound of its size_hint() is exact.

    Otherwise, a temporary vector is allocated and the tail is moved twice.

Panics

Panics if the starting point is greater than the end point or if the end point is greater than the length of the vector.

Examples

This example starts with six bits of zero, and then splices out bits 2 and 3 and replaces them with four bits of one.

let mut bv = bitvec![0; 6];
let bv2 = bitvec![1; 4];

let s = bv.splice(2 .. 4, bv2).collect::<BitVec>();
assert_eq!(s.len(), 2);
assert!(!s[0]);
assert_eq!(bv, bitvec![0, 0, 1, 1, 1, 1, 0, 0]);

Constructs a BitVec from a value repeated many times.

This function is equivalent to the bitvec![O, T; bit; len] macro call, and is in fact the implementation of that macro syntax.

Parameters
  • bit: The bit value to which all len allocated bits will be set.
  • len: The number of live bits in the constructed BitVec.
Returns

A BitVec with len live bits, all set to bit.

Constructs a BitVec from a single element.

The produced BitVec will span the element, and include all bits in it.

Parameters
  • elt: The source element.
Returns

A BitVec over the provided element.

Examples
use bitvec::prelude::*;

let bv = BitVec::<Msb0, u8>::from_element(5);
assert_eq!(bv.count_ones(), 2);

Constructs a BitVec from a slice of elements.

The produced BitVec will span the provided slice.

Parameters
  • slice: The source elements to copy into the new BitVec.
Returns

A BitVec set to the provided slice values.

Examples
use bitvec::prelude::*;

let src = [5, 10];
let bv = BitVec::<Msb0, u8>::from_slice(&src[..]);
assert!(bv[5]);
assert!(bv[7]);
assert!(bv[12]);
assert!(bv[14]);

Consumes a Vec<T> and creates a BitVec<C, T> from it.

Parameters
  • vec: The source vector whose memory will be used.
Returns

A new BitVec using the vec Vec’s memory.

Panics

Panics if the source vector would cause the BitVec to overflow capacity.

Examples
use bitvec::prelude::*;

let bv = BitVec::<Msb0, u8>::from_vec(vec![1, 2, 4, 8]);
assert_eq!(
  "[00000001, 00000010, 00000100, 00001000]",
  &format!("{}", bv),
);

Clones a &BitSlice into a BitVec.

This is the only method by which a BitVec can be created whose first live bit is not at the 0 position. This behavior, though unconventional for common uses of BitVec, allows for a more efficient clone of any BitSlice region without shifting each bit in the region down to fit the 0 starting position.

Misaligned BitVecs do not have any adverse effect on usage other than the in-memory representation.

Whenever a BitVec is emptied, its head index is always set to 0, and will begin from the aligned position on future refills.

The ::force_align method will shift the BitVec’s data to begin at the 0 index, if you require this property.

Parameters
  • slice: The source BitSlice region. This may have any head index, and its memory will be copied element-wise into the new buffer.
Returns

A BitVec containing the same bits as the source slice.

Examples
use bitvec::prelude::*;

let bs = [0u8, !0].bits::<Msb0>();
let bv = BitVec::from_bitslice(bs);
assert_eq!(bv.len(), 16);
assert!(bv.some());

Converts a frozen BitBox allocation into a growable BitVec.

This does not copy or reallocate.

Parameters
  • slice: A BitBox to be thawed.
Returns

A growable collection over the original memory of the slice.

Examples
use bitvec::prelude::*;

let bv = BitVec::from_boxed_bitslice(bitbox![0, 1]);
assert_eq!(bv.len(), 2);
assert!(bv.some());

Creates a new BitVec<C, T> directly from the raw parts of another.

Parameters
  • pointer: The BitPtr<T> to use.
  • capacity: The number of T elements allocated in that slab.
Returns

A BitVec over the given slab of memory.

Safety

This is highly unsafe, due to the number of invariants that aren’t checked:

  • pointer needs to have been previously allocated by some allocating type.
  • pointer’s T needs to have the same size and alignment as it was initially allocated.
  • pointer’s element count needs to be less than or equal to the original allocation capacity.
  • capacity needs to be the original allocation capacity for the vector. This is not the value produced by .capacity().

Violating these will cause problems, like corrupting the handle’s concept of memory, the allocator’s internal data structures, and the sanity of your program. It is absolutely not safe to construct a BitVec whose T differs from the type used for the initial allocation.

The ownership of pointer is effectively transferred to the BitVec<C, T> which may then deallocate, reallocate, or modify the contents of the referent slice at will. Ensure that nothing else uses the pointer after calling this function.

Produces a BitSlice containing the entire vector.

Equivalent to &s[..].

Parameters
  • &self
Returns

A BitSlice over the vector.

Examples
use bitvec::prelude::*;

let bv = bitvec![0, 1, 1, 0];
let bs = bv.as_bitslice();

Produces a mutable BitSlice containing the entire vector.

Equivalent to &mut s[..].

Parameters
  • &mut self
Returns

A mutable BitSlice over the vector.

Examples
use bitvec::prelude::*;

let mut bv = bitvec![0, 1, 1, 0];
let bs = bv.as_mut_bitslice();

Sets the backing storage to the provided element.

This unconditionally sets each live element in the backing buffer to the provided value, without altering the BitVec length or capacity. It operates on the underlying Vec’s memory buffer directly, and ignores the BitVec’s cursors.

It is an implementation detail as to whether this affects the value of allocated, but not currently used, elements in the buffer. Behavior of this method on elements not visible through self.as_slice() is not specified.

Parameters
  • &mut self
  • element: The value to which each live element in the backing store will be set.
Examples
use bitvec::prelude::*;

let mut bv = bitvec![Local, u8; 0; 10];
//  note: the second element is not required to be zero, only to have
//  bits `0` and `1` according to `Local` be `0`.
assert_eq!(bv.as_slice()[0], 0);
bv.set_elements(0xA5);
assert_eq!(bv.as_slice(), &[0xA5, 0xA5]);

Performs “reverse” addition (left to right instead of right to left).

This addition traverses the addends from left to right, performing the addition at each index and writing the sum into self.

If addend expires before self does, addend is zero-extended and the carry propagates through the rest of self. If self expires before addend, then self is zero-extended and the carry propagates through the rest of addend, growing self until addend expires.

An infinite addend will cause unbounded memory growth until the vector overflows and panics.

Parameters
  • self
  • addend: impl IntoIterator<Item=bool>: A stream of bits to add into self, from left to right.
Returns

The sum vector of self and addend.

Examples
use bitvec::prelude::*;

let a = bitvec![0, 1, 0, 1];
let b = bitvec![0, 0, 1, 1];
let c = a.add_reverse(b);
assert_eq!(c, bitvec![0, 1, 1, 0, 1]);

Performs “reverse” addition (left to right instead of right to left).

This addition traverses the addends from left to right, performing the addition at each index and writing the sum into self.

If addend expires before self does, addend is zero-extended and the carry propagates through the rest of self. If self expires before addend, then self is zero-extended and the carry propagates through the rest of addend, growing self until addend expires.

An infinite addend will cause unbounded memory growth until the vector overflows and panics.

Parameters
  • &mut self
  • addend: impl IntoIterator<Item=bool>: A stream of bits to add into self, from left to right.
Effects

self may grow as a result of the final carry-out bit being 1 and pushed onto the right end.

Examples
use bitvec::prelude::*;

let mut a = bitvec![0, 1, 0, 1];
let     b = bitvec![0, 0, 1, 1];
a.add_assign_reverse(b.iter().copied());
assert_eq!(a, bitvec![0, 1, 1, 0, 1]);

Changes the order type on the vector handle, without changing its contents.

Parameters
  • self
Returns

An equivalent vector handle with a new order type. The contents of the backing storage are unchanged.

To reorder the bits in memory, drain this vector into a new handle with the desired order type.

Degrades a BitVec to a BitBox, freezing its size.

Parameters
  • self
Returns

Itself, with its size frozen and ungrowable.

Degrades a BitVec to a standard Vec.

Parameters
  • self
Returns

The plain vector underlying the BitVec.

Ensures that the live region of the underlying memory begins at the 0 bit position.

Notes

This method is currently implemented as a linear traversal that moves each bit individually from its original index to its final position. This is O(n) in the bit length of the vector.

It is possible to create an optimized rotation behavior that only moves a few bits individually, then moves elements in a gallop. The speed difference is proportional to the width of the element type.

When this behavior is implemented, force_align will be rewritten to take advantage of it. For now, it remains slow.

Examples
use bitvec::prelude::*;

let src = &bits![Msb0, u8; 1, 0, 1, 1, 0, 1, 1, 0][1 .. 7];
assert_eq!(src.len(), 6);
let mut bv = src.to_owned();
assert_eq!(bv.len(), 6);
assert_eq!(bv.as_slice()[0], 0xB6);
bv.force_align();
assert_eq!(bv.as_slice()[0], 0x6E);

Methods from Deref<Target = BitSlice<O, T>>

Returns the number of bits in the slice.

Original

slice::len

Examples
let bits = 0u8.bits::<Local>();
assert_eq!(bits.len(), 8);

Returns true if the slice has a length of 0.

Original

slice::is_empty

Examples
let bits = 0u8.bits::<Local>();
assert!(!bits.is_empty());

assert!(BitSlice::<Local, usize>::empty().is_empty())

Returns the first bit of the slice, or None if it is empty.

Original

slice::first

Examples
let bits = 1u8.bits::<Lsb0>();
assert_eq!(bits.first(), Some(&true));

assert!(BitSlice::<Local, usize>::empty().first().is_none());

Returns a mutable pointer to the first bit of the slice, or None if it is empty.

Original

slice::first_mut

Examples
let mut data = 0u8;
let bits = data.bits_mut::<Lsb0>();
if let Some(mut first) = bits.first_mut() {
    *first = true;
}
assert_eq!(data, 1u8);

Returns the first and all the rest of the bits of the slice, or None if it is empty.

Examples
let bits = 1u8.bits::<Lsb0>();
if let Some((first, rest)) = bits.split_first() {
    assert_eq!(first, &true);
    assert_eq!(rest, &bits[1 ..]);
}

Returns the first and all the rest of the bits of the slice, or None if it is empty.

Examples
let mut data = 0u8;
let bits = data.bits_mut::<Lsb0>();
if let Some((mut first, rest)) = bits.split_first_mut() {
    *first = true;
    *rest.at(0) = true;
    *rest.at(1) = true;
}
assert_eq!(data, 7);

Returns the last and all the rest of the bits of the slice, or None if it is empty.

Examples
let bits = 1u8.bits::<Msb0>();
if let Some((last, rest)) = bits.split_last() {
    assert_eq!(last, &true);
    assert_eq!(rest, &bits[.. 7]);
}

Returns the last and all the rest of the bits of the slice, or None if it is empty.

Examples
let mut data = 0u8;
let bits = data.bits_mut::<Msb0>();
if let Some((mut last, rest)) = bits.split_last_mut() {
    *last = true;
    *rest.at(0) = true;
    *rest.at(1) = true;
}
assert_eq!(data, 128 | 64 | 1);

Returns the last bit of the slice, or None if it is empty.

Examples
let bits = 1u8.bits::<Msb0>();
assert_eq!(Some(&true), bits.last());
assert!(BitSlice::<Local, usize>::empty().last().is_none());

Returns a mutable pointer to the last bit in the slice.

Examples
let mut data = 0u8;
let bits = data.bits_mut::<Msb0>();
if let Some(mut last) = bits.last_mut() {
    *last = true;
}
assert!(bits[7]);

Returns a reference to a bit or subslice depending on the type of index.

  • If given a position, returns a reference to the bit at that position or None if out of bounds.
  • If given a range, returns the subslice corresponding to that range, or None if out of bounds.
Examples
let data = 1u8;
let bits = data.bits::<Lsb0>();
assert_eq!(Some(&true), bits.get(0));
assert!(bits.get(8).is_none());
assert!(bits.get(1 ..).expect("in bounds").not_any());
assert!(bits.get(.. 12).is_none());

Returns a mutable reference to a bit or subslice depending on the type of index (see get) or None if the index is out of bounds.

Examples
let mut data = 0u8;
let bits = data.bits_mut::<Lsb0>();
if let Some(mut bit) = bits.get_mut(1) {
    *bit = true;
}
if let Some(bits) = bits.get_mut(5 .. 7) {
    bits.set_all(true);
}
assert_eq!(data, 64 | 32 | 2);

Returns a reference to a bit or subslice, without doing bounds checking.

This is generally not recommended; use with caution! For a safe alternative, see get.

Safety

As this function does not perform boundary checking, the caller must ensure that self is an index within the boundaries of slice before calling in order to avoid boundary escapes and ensuing safety violations.

Examples
let data = 4u8;
let bits = data.bits::<Lsb0>();
unsafe {
    assert!(bits.get_unchecked(2));
    assert!(!bits.get_unchecked(1));
}

Returns a mutable reference to a bit or subslice, without doing bounds checking.

This is generally not recommended; use with caution! For a safe alternative, see get_mut.

Safety

As this function does not perform boundary checking, the caller must ensure that self is an index within the boundaries of slice before calling in order to avoid boundary escapes and ensuing safety violations.

Examples
let mut data = 0u8;
let bits = data.bits_mut::<Msb0>();
unsafe {
    let mut bit = bits.get_unchecked_mut(0);
    *bit = true;
    drop(bit); // release the borrow immediately
    let bits = bits.get_unchecked_mut(6 ..);
    bits.set_all(true);
}
assert_eq!(data, 1 | 2 | 128);

Returns a raw pointer to the slice’s buffer.

The caller must ensure that the slice outlives the pointer this function returns, or else it will end up pointing to garbage.

The caller must also ensure that the memory the pointer (non-transitively) points to is never written to (except inside an UnsafeCell) using this pointer or any pointer derived from it. If you need to mutate the contents of the buffer, use as_mut_ptr.

Modifying the container referenced by this slice may cause its buffer to be reallocated, which would also make any pointers to it invalid.

Notes

This pointer is always to the first T element in the backing storage, even if that element is only partially used by the self slice. Multiple separate BitSlice handles may produce the same pointer with this method.

Examples
let data = [0u8; 2];
let bits = data.bits::<Msb0>();
let (head, rest) = bits.split_at(4);
assert_eq!(head.as_ptr(), rest.as_ptr());

Returns an unsafe mutable pointer to the slice’s buffer.

The caller must ensure thath the slice outlives the pointer this function returns, or else it will end up pointing to garbage.

Modifying the container referenced by this slice may couse its buffer to be reallocated, which would also make any pointers to it invalid.

Notes

This pointer is always to the first T element in the backing storage, even if that element is only partially used by the self slice. Multiple separate BitSlice handles may produce the same pointer with this method.

Examples
let mut data = [0u8; 2];
let bits = data.bits_mut::<Msb0>();
let (head, rest) = bits.split_at_mut(4);
assert_eq!(head.as_mut_ptr(), rest.as_mut_ptr());
unsafe { *head.as_mut_ptr() = 2; }
assert!(rest[2]);

Swaps two bits in the slice.

Arguments
  • a: The index of the first bit
  • b: The index of the second bit
Panics

Panics if a or b are out of bounds.

Examples
let mut data = 2u8;
let bits = data.bits_mut::<Lsb0>();
bits.swap(0, 1);
assert_eq!(data, 1);

Reverses the order of bits in the slice, in place.

Examples
use bitvec::prelude::*;
let mut data = 0b1_1001100u8;
let bits = data.bits_mut::<Msb0>();
bits[1 ..].reverse();
assert_eq!(data, 0b1_0011001);

Returns an iterator over the slice.

Examples
let data = 3u8;
let bits = data.bits::<Lsb0>();
let mut iter = bits[.. 4].iter();
assert_eq!(iter.next(), Some(&true));
assert_eq!(iter.next(), Some(&true));
assert_eq!(iter.next(), Some(&false));
assert_eq!(iter.next(), Some(&false));
assert!(iter.next().is_none());

Returns an iterator that allows modifying each bit.

Examples
let mut data = 0u8;
let bits = &mut data.bits_mut::<Lsb0>()[.. 2];
for mut bit in bits.iter_mut() {
    *bit = true;
}
assert_eq!(data, 3);

Returns an iterator over all contiguous windows of width width.

The windows overlap. If the slice is shorter than width, the iterator returns no values.

Panics

Panics if width is 0.

Examples
let data = 0b100_010_01u8;
let bits = data.bits::<Msb0>();
let mut iter = bits[.. 5].windows(3);
assert_eq!(iter.next().unwrap(), &bits[0 .. 3]);
assert_eq!(iter.next().unwrap(), &bits[1 .. 4]);
assert_eq!(iter.next().unwrap(), &bits[2 .. 5]);
assert!(iter.next().is_none());

If the slice is shorter than width:

let data = 0u8;
let bits = data.bits::<Local>();
let mut iter = bits[.. 3].windows(4);
assert!(iter.next().is_none());

Returns an iterator over chunk_size bits of the slice at a time, starting at the beginning of the slice.

The chunks are slices and do not overlap. If chunk_size does not divide the length of the slice, then the last chunk will not have length chunk_size.

See chunks_exact for a variant of this iterator that returns chunks of always exactly chunk_size elements, and rchunks for the same iterator but starting at the end of the slice.

Panics

Panics if chunk_size is 0.

Examples
let data = 0b001_010_10u8;
let bits = data.bits::<Msb0>();
let mut iter = bits.chunks(3);
assert_eq!(iter.next().unwrap(), &bits[0 .. 3]);
assert_eq!(iter.next().unwrap(), &bits[3 .. 6]);
assert_eq!(iter.next().unwrap(), &bits[6 .. 8]);
assert!(iter.next().is_none());

Returns an iterator over chunk_size bits of the slice at a time, starting at the beginning of the slice.

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the length of the slice, then the last chunk will not have length chunk_size.

See chunks_exact_mut for a variant of this iterator that returns chunks of always exactly chunk_size bits, and rchunks_mut for the same iterator but starting at the end of the slice.

Panics

Panics if chunk_size is 0.

Examples
let mut data = 0u8;
let bits = data.bits_mut::<Msb0>();
let mut count = 0;

for chunk in bits.chunks_mut(3) {
    chunk.store(4u8 >> count);
    count += 1;
}
assert_eq!(count, 3);
assert_eq!(data, 0b100_010_01);

Returns an iterator over chunk_size elements of the slice at a time, starting at the beginning of the slice.

The chunks are slices and do not overlap. If chunk_size does not divide the length of the slice, then the last up to chunk_size - 1 elements will be omitted and can be retrieved from the remainder function of the iterator.

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the resulting code better than in the case of chunks.

See chunks for a variant of this iterator that also returns the remainder as a smaller chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

Panics

Panics if chunk_size is 0.

Examples
let data = 0b100_010_01u8;
let bits = data.bits::<Msb0>();
let mut iter = bits.chunks_exact(3);
assert_eq!(iter.next().unwrap(), &bits[0 .. 3]);
assert_eq!(iter.next().unwrap(), &bits[3 .. 6]);
assert!(iter.next().is_none());
assert_eq!(iter.remainder(), &bits[6 .. 8]);

Returns an iterator over chunk_size elements of the slice at a time, starting at the beginning of the slice.

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the length of the slice, then the last up to chunk_size - 1 elements will be omitted and can be retrieved from the into_remainder function of the iterator.

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the resulting code better than in the case of chunks_mut.

See chunks_mut for a variant of this iterator that also returns the remainder as a smaller chunk, and rchunks_exact_mut for the same iterator but starting at the end of the slice of the slice.

Panics

Panics if chunk_size is 0.

Examples
let mut data = 0u8;
let bits = data.bits_mut::<Msb0>();
let mut count = 0u8;

let mut iter = bits.chunks_exact_mut(3);
for chunk in &mut iter {
    chunk.store(4u8 >> count);
    count += 1;
}
iter.into_remainder().store(1u8);
assert_eq!(count, 2);
assert_eq!(data, 0b100_010_01);

Returns an iterator over chunk_size bits of the slice at a time, starting at the end of the slice.

The chunks are slices and do not overlap. If chunk_size does not divide the length of the slice, then the last chunk will not have length of the slice, then the last chunk will not have length chunk_size.

See rchunks_exact for a variant of this iterator that returns chunks of always exactly chunk_size bits, and chunks for the same iterator but starting at the beginning of the slice.

Panics

Panics if chunk_size is 0.

Examples
let data = 0b01_010_100u8;
let bits = data.bits::<Msb0>();
let mut iter = bits.rchunks(3);
assert_eq!(iter.next().unwrap(), &bits[5 .. 8]);
assert_eq!(iter.next().unwrap(), &bits[2 .. 5]);
assert_eq!(iter.next().unwrap(), &bits[0 .. 2]);
assert!(iter.next().is_none());

Returns an iterator over chunk_size bits of the slice at a time, starting at the end of the slice.

The chunks are mutable slices and do not overlap. If chunk_size does not divide the length of the slice, then the last chunk will not have length of the slice, then the last chunk will not have length chunk_size.

See rchunks_exact_mut for a variant of this iterator that returns chunks of always exactly chunk_size bits, and chunks_mut for the same iterator but starting at the beginning of the slice.

Panics

Panics if chunk_size is 0.

Examples
let mut data = 0u8;
let bits = data.bits_mut::<Lsb0>();
let mut count = 0;

for chunk in bits.rchunks_mut(3) {
    chunk.store(4u8 >> count);
    count += 1;
}
assert_eq!(count, 3);
assert_eq!(data, 0b100_010_01);

Returns an iterator over chunk_size bits of the slice at a time, starting at the end of the slice.

The chunks are slices and do not overlap. If chunk_size does not divide the length of the slice, then the last up to chunk_size - 1 bits will be omitted and can be retrieved from the remainder function of the iterator.

Due to each chunk having exactly chunk_size bits, the compiler can often optimize the resulting code better than in the case of chunks.

See rchunks for a variant of this iterator that also returns the remainder as a smaller chunk, and chunks_exact for the same iterator but starting at the beginning of the slice.

Panics

Panics if chunk_size is 0.

Examples
let data = 0b100_010_01u8;
let bits = data.bits::<Lsb0>();
let mut iter = bits.rchunks_exact(3);
assert_eq!(iter.next().unwrap(), &bits[5 .. 8]);
assert_eq!(iter.next().unwrap(), &bits[2 .. 5]);
assert!(iter.next().is_none());
assert_eq!(iter.remainder(), &bits[0 ..2]);

Returns an iterator over chunk_size bits of the slice at a time, starting at the end of the slice.

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the length of the slice, then the last up to chunk_size - 1 bits will be omitted and can be retrieved from the into_remainder function of the iterator.

Due to each chunk having exactly chunk_size bits, the compiler can often optimize the resulting code better than in the case of chunks_mut.

See rchunks_mut for a variant of this iterator that also returns the remainder as a smaller chunk, and chunks_exact_mut for the same iterator but starting at the beginning of the slice.

Panics

Panics if chunk_size is 0.

Examples
let mut data = 0u8;
let bits = data.bits_mut::<Lsb0>();
let mut count = 0;
let mut iter = bits.rchunks_exact_mut(3);

for chunk in &mut iter {
    chunk.store(4u8 >> count);
    count += 1;
}
iter.into_remainder().store(1u8);
assert_eq!(data, 0b100_010_01);
assert_eq!(count, 2);

Divides one slice into two at an index.

The first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

Panics

Panics if mid > len.

Examples
let data = 0x0Fu8;
let bits = data.bits::<Msb0>();

{
    let (left, right) = bits.split_at(0);
    assert!(left.is_empty());
    assert_eq!(right, bits);
}

{
    let (left, right) = bits.split_at(4);
    assert!(left.not_any());
    assert!(right.all());
}

{
    let (left, right) = bits.split_at(8);
    assert_eq!(left, bits);
    assert!(right.is_empty());
}

Divides one mutable slice into two at an index.

The first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

Panics

Panics if mid > len.

Examples
let mut data = 0x0Fu8;
let bits = data.bits_mut::<Msb0>();

let (left, right) = bits.split_at_mut(4);
assert!(left.not_any());
assert!(right.all());
*left.at(1) = true;
*right.at(2) = false;

assert_eq!(data, 0b0100_1101);

Returns an iterator over subslices separated by indexed bits that satisfy the predicate function. The matched position is not contained in the subslices.

API Differences

The slice::split method takes a predicate function with signature (&T) -> bool, whereas this method’s predicate function has signature (usize, &T) -> bool. This difference is in place because BitSlice by definition has only one bit of information per slice item, and including the index allows the callback function to make more informed choices.

Examples
let data = 0b01_001_000u8;
let bits = data.bits::<Msb0>();
let mut iter = bits.split(|pos, bit| *bit);

assert_eq!(iter.next().unwrap(), &bits[0 .. 1]);
assert_eq!(iter.next().unwrap(), &bits[2 .. 4]);
assert_eq!(iter.next().unwrap(), &bits[5 .. 8]);
assert!(iter.next().is_none());

If the first position is matched, an empty slice will be the first item returned by the iterator. Similarly, if the last position in the slice is matched, an empty slice will be the last item returned by the iterator:

let data = 1u8;
let bits = data.bits::<Msb0>();
let mut iter = bits.split(|pos, bit| *bit);

assert_eq!(iter.next().unwrap(), &bits[0 .. 7]);
assert_eq!(iter.next().unwrap(), BitSlice::<Local, usize>::empty());
assert!(iter.next().is_none());

If two matched positions are directly adjacent, an empty slice will be present between them.

let data = 0b001_100_00u8;
let bits = data.bits::<Msb0>();
let mut iter = bits.split(|pos, bit| *bit);

assert_eq!(iter.next().unwrap(), &bits[0 .. 2]);
assert_eq!(iter.next().unwrap(), BitSlice::<Local, usize>::empty());
assert_eq!(iter.next().unwrap(), &bits[4 .. 8]);
assert!(iter.next().is_none());

Returns an iterator over mutable subslices separated by indexed bits that satisfy the predicate function. The matched position is not contained in the subslices.

API Differences

The slice::split_mut method takes a predicate function with signature (&T) -> bool, whereas this method’s predicate function has signature (usize, &T) -> bool. This difference is in place because BitSlice by definition has only one bit of information per slice item, and including the index allows the callback function to make more informed choices.

Examples
let mut data = 0b001_000_10u8;
let bits = data.bits_mut::<Msb0>();

for group in bits.split_mut(|pos, bit| *bit) {
    *group.at(0) = true;
}
assert_eq!(data, 0b101_1001_1u8);

Returns an iterator over subslices separated by indexed bits that satisfy a predicate function, starting at the end of the slice and working backwards. The matched position is not contained in the subslices.

API Differences

The slice::rsplit method takes a predicate function with signature (&T) -> bool, whereas this method’s predicate function has signature (usize, &T) -> bool. This difference is in place because BitSlice by definition has only one bit of information per slice item, and including the index allows the callback function to make more informed choices.

Examples
let data = 0b0001_0000u8;
let bits = data.bits::<Msb0>();
let mut iter = bits.rsplit(|pos, bit| *bit);

assert_eq!(iter.next().unwrap(), &bits[4 .. 8]);
assert_eq!(iter.next().unwrap(), &bits[0 .. 3]);
assert!(iter.next().is_none());

As with split(), if the first or last position is matched, an empty slice will be the first (or last) item returned by the iterator.

let data = 0b1001_0001u8;
let bits = data.bits::<Msb0>();
let mut iter = bits.rsplit(|pos, bit| *bit);
assert!(iter.next().unwrap().is_empty());
assert_eq!(iter.next().unwrap(), &bits[4 .. 7]);
assert_eq!(iter.next().unwrap(), &bits[1 .. 3]);
assert!(iter.next().unwrap().is_empty());
assert!(iter.next().is_none());

Returns an iterator over mutable subslices separated by indexed bits that satisfy a predicate function, starting at the end of the slice and working backwards. The matched position is not contained in the subslices.

API Differences

The slice::rsplit_mut method takes a predicate function with signature (&T) -> bool, whereas this method’s predicate function has signature (usize, &T) -> bool. This difference is in place because BitSlice by definition has only one bit of information per slice item, and including the index allows the callback function to make more informed choices.

Examples
let mut data = 0u8;
let bits = data.bits_mut::<Msb0>();

let mut count = 0u8;
for group in bits.rsplit_mut(|pos, bit| pos % 3 == 2) {
    count += 1;
    group.store(count);
}
assert_eq!(data, 0b11_0_10_0_01);

Returns an iterator over subslices separated by indexed bits that satisfy the predicate function, limited to returning at most n items. The matched position is not contained in the subslices.

The last element returned, if any, will contain the remainder of the slice.

API Differences

The slice::splitn method takes a predicate function with signature (&T) -> bool, whereas this method’s predicate function has signature (usize, &T) -> bool. This difference is in place because BitSlice by definition has only one bit of information per slice item, and including the index allows the callback function to make more informed choices.

Examples

Print the slice split once by indices divisible by 3:

let data = 0xA5u8;
let bits = data.bits::<Msb0>();

for group in bits.splitn(2, |pos, bit| pos % 3 == 2) {
    println!("{}", group);
}
//  [10]
//  [00101]

Returns an iterator over mutable subslices separated by indexed bits that satisfy the predicate function, limited to returning at most n items. The matched position is not contained in the subslices.

The last element returned, if any, will contain the remainder of the slice.

API Differences

The slice::splitn_mut method takes a predicate function with signature (&T) -> bool, whereas this method’s predicate function has signature (usize, &T) -> bool. This difference is in place because BitSlice by definition has only one bit of information per slice item, and including the index allows the callback function to make more informed choices.

Examples
let mut data = 0u8;
let bits = data.bits_mut::<Msb0>();
let mut counter = 0u8;

for group in bits.splitn_mut(2, |pos, bit| pos % 4 == 3) {
    counter += 1;
    group.store(counter);
}
assert_eq!(data, 0b001_0_0010);

Returns an iterator over subslices separated by indexed bits that satisfy a predicate function, limited to returning at most n items. This starts at the end of the slice and works backwards. The matched position is not contained in the subslices.

The last element returned, if any, will contain the remainder of the slice.

API Differences

The slice::rsplitn method takes a predicate function with signature (&T) -> bool, whereas this method’s predicate function has signature (usize, &T) -> bool. This difference is in place because BitSlice by definition has only one bit of information per slice item, and including the index allows the callback function to make more informed choices.

Examples

Print the slice split once, starting from the end, by indices divisible by 3:

let data = 0xA5u8;
let bits = data.bits::<Msb0>();

for group in bits.rsplitn(2, |pos, bit| pos % 3 == 2) {
    println!("{}", group);
}
//  [01]
//  [10100]

Returns an iterator over mutable subslices separated by indexed bits that satisfy a predicate function, limited to returning at most n items. This starts at the end of the slice and works backwards. The matched position is not contained in the subslices.

The last element returned, if any, will contain the remainder of the slice.

API Differences

The slice::rsplitn_mut method takes a predicate function with signature (&T) -> bool, whereas this method’s predicate function has signature (usize, &T) -> bool. This difference is in place because BitSlice by definition has only one bit of information per slice item, and including the index allows the callback function to make more informed choices.

Examples
let mut data = 0u8;
let bits = data.bits_mut::<Msb0>();
let mut counter = 0u8;

for group in bits.rsplitn_mut(2, |pos, bit| pos % 3 == 2) {
    counter += 1;
    group.store(counter);
}
assert_eq!(data, 0b00010_0_01);

Returns true if the slice contains a region that matches the given span.

API Differences

The slice::contains method tests for a single slice element. Because this is a slice of single bits, testing for the presence of one bool value is not very informative. This instead searches for a subslice, which may be one or more bits.

Examples
let data = 0b0101_1010u8;
let bits_be = data.bits::<Msb0>();
let bits_le = data.bits::<Lsb0>();
assert!(bits_be.contains(&bits_le[1 .. 5]));

This example uses a palindrome pattern to demonstrate that the query does not need to have the same type parameters as the searched slice.

Returns true if prefix is a prefix of the slice.

Examples
let data = 0b0110_1110u8;
let bits = data.bits::<Msb0>();
assert!(bits.starts_with(&data.bits::<Lsb0>()[.. 2]));

Returns true if suffix is a suffix of the slice.

Examples
let data = 0b0111_1010u8;
let bits = data.bits::<Msb0>();
assert!(bits.ends_with(&data.bits::<Lsb0>()[6 ..]));

Rotates the slice in-place such that the first by bits of the slice move to the end while the last self.len() - by bits move to the front. After calling rotate_left, the bit previously at index by will become the first bit in the slice.

Panics

This function will panic if by is greater than the length of the slice. Note that by == self.len() does not panic and is a noöp rotation.

Complexity

Takes linear (in self.len()) time.

Examples
let mut data = 0xF0u8;
let bits = data.bits_mut::<Msb0>();
bits.rotate_left(2);
assert_eq!(data, 0xC3);

Rotating a subslice:

let mut data = 0xF0u8;
let bits = data.bits_mut::<Msb0>();
bits[1 .. 5].rotate_left(1);
assert_eq!(data, 0b1_1101_000);

Rotates the slice in-place such that the first self.len() - by bits of the slice move to the end while the last by bits move to the front. After calling rotate_right, the bit previously at index self.len() - by will become the first bit in the slice.

Panics

This function will panic if by is greater than the length of the slice. Note that by == self.len() does not panic and is a noöp rotation.

Complexity

Takes linear (in self.len()) time.

Examples
let mut data = 0xF0u8;
let bits = data.bits_mut::<Msb0>();
bits.rotate_right(2);
assert_eq!(data, 0x3C);

Rotate a subslice:

let mut data = 0xF0u8;
let bits = data.bits_mut::<Msb0>();
bits[1 .. 5].rotate_right(1);
assert_eq!(data, 0b1_0111_000);

Copies the elements from src into self.

The length of src must be the same as self.

This is equivalent to copy_from_slice; this function is only included for API surface equivalence.

Panics

This function will panic if the two slices have different lengths.

Examples
let mut data = 0u8;
let bits = data.bits_mut::<Msb0>();
let src = 0x0Fu16.bits::<Lsb0>();
bits.clone_from_slice(&src[.. 8]);
assert_eq!(data, 0xF0);

Rust enforces that there can only be one mutable reference with no immutable references to a particular piece of data in a particular scope. Because of this, attempting to use clone_from_slice on a single slice will result in a compile failure:

let mut data = 3u8;
let bits = data.bits_mut::<Msb0>();
bits[.. 2].clone_from_slice(&bits[6 ..]);

To work around this, we can use [split_at_mut] to create two distinct sub-slices from a slice:

let mut data = 3u8;
let bits = data.bits_mut::<Msb0>();
let (head, tail) = bits.split_at_mut(4);
head.clone_from_slice(tail);
assert_eq!(data, 0x33);

Copies the elements from src into self.

The length of src must be the same as self.

This is restricted to take exactly the same type of bit slice as the source slice, so that the implementation has the chace to use faster memcpy if possible.

Panics

This function will panic if the two slices have different lengths.

Examples
let mut data = 0u8;
let bits = data.bits_mut::<Msb0>();
let src = 0x0Fu8.bits::<Msb0>();
bits.copy_from_slice(src);
assert_eq!(data, 0x0F);

Rust enforces that there can only be one mutable reference with no immutable references to a particular piece of data in a particular scope. Because of this, attempting to use copy_from_slice on a single slice will result in a compile failure:

let mut data = 3u8;
let bits = data.bits_mut::<Msb0>();
bits[.. 2].copy_from_slice(&bits[6 ..]);

To work around this, we can use [split_at_mut] to create two distinct sub-slices from a slice:

let mut data = 3u8;
let bits = data.bits_mut::<Msb0>();
let (head, tail) = bits.split_at_mut(4);
head.copy_from_slice(tail);
assert_eq!(data, 0x33);

Swaps all bits in self with those in other.

The length of other must be the same as self.

Panics

This function will panic if the two slices hav different lengths.

Example

Swapping two elements across slices:

let mut a = 0u8;
let mut b = 0x96A5u16;
let bits_a = a.bits_mut::<Lsb0>();
let bits_b = b.bits_mut::<Msb0>();

bits_a.swap_with_slice(&mut bits_b[4 .. 12]);

assert_eq!(a, 0x56);
assert_eq!(b, 0x9005);

Rust enforces that there can only be one mutable reference to a particular piece of data in a particular scope. Because of this, attempting to use swap_with_slice on a single slice will result in a compile failure:

let mut data = 15u8;
let bits = data.bits_mut::<Msb0>();
bits[.. 3].swap_with_slice(&mut bits[5 ..]);

To work around this, we can use [split_at_mut] to create two distinct mutable sub-slices from a slice:

let mut data = 15u8;
let bits = data.bits_mut::<Msb0>();

{
    let (left, right) = bits.split_at_mut(4);
    left[.. 2].swap_with_slice(&mut right[2 ..]);
}

assert_eq!(data, 0xCC);

Transmute the slice to a slice with a different backing store, ensuring alignment of the types is maintained.

This method splits the slice into three distinct slices: prefix, correctly aligned middle slice of a new backing type, and the suffix slice. The method does a best effort to make the middle slice the greatest length possible for a given type and input slice, but only your algorithm’s performance should depend on that, not its correctness.

Safety

This method is essentially a transmute with respect to the elements in the returned middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

Examples

Basic usage:

unsafe {
    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
    let bits = bytes.bits::<Local>();
    let (prefix, shorts, suffix) = bits.align_to::<u16>();
    match prefix.len() {
        0 => {
            assert_eq!(shorts, bits[.. 48]);
            assert_eq!(suffix, bits[48 ..]);
        },
        8 => {
            assert_eq!(prefix, bits[.. 8]);
            assert_eq!(shorts, bits[8 ..]);
        },
        _ => unreachable!("This case will not occur")
    }
}

Transmute the slice to a slice with a different backing store, ensuring alignment of the types is maintained.

This method splits the slice into three distinct slices: prefix, correctly aligned middle slice of a new backing type, and the suffix slice. The method does a best effort to make the middle slice the greatest length possible for a given type and input slice, but only your algorithm’s performance should depend on that, not its correctness.

Safety

This method is essentially a transmute with respect to the elements in the returned middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

Examples

Basic usage:

unsafe {
    let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
    let bits = bytes.bits_mut::<Local>();
    let (prefix, shorts, suffix) = bits.align_to_mut::<u16>();
    //  same access and behavior as in `align_to`
}

Copies self into a new BitVec.

Examples
let data = [0u8, !0u8];
let bits = data.bits::<Local>();
let vec = bits.to_vec();
assert_eq!(bits, vec);

Sets the bit value at the given position.

Parameters
  • &mut self
  • index: The bit index to set. It must be in the domain 0 .. self.len().
  • value: The value to be set, true for 1 and false for 0.
Panics

This method panics if index is outside the slice domain.

Examples
use bitvec::prelude::*;

let mut store = 8u8;
let bits = store.bits_mut::<Msb0>();
assert!(!bits[3]);
bits.set(3, true);
assert!(bits[3]);

Sets a bit at an index, without doing bounds checking.

This is generally not recommended; use with caution! For a safe alternative, see set.

Parameters
  • &mut self
  • index: The bit index to retrieve. This index is not checked against the length of self.
Effects

The bit at index is set to value.

Safety

This method is not safe. It performs raw pointer arithmetic to seek from the start of the slice to the requested index, and set the bit there. It does not inspect the length of self, and it is free to perform out-of-bounds memory write access.

Use this method only when you have already performed the bounds check, and can guarantee that the call occurs with a safely in-bounds index.

Examples

This example uses a bit slice of length 2, and demonstrates out-of-bounds access to the last bit in the element.

use bitvec::prelude::*;

let mut src = 0u8;
{
 let bits = &mut src.bits_mut::<Msb0>()[2 .. 4];
 assert_eq!(bits.len(), 2);
 unsafe { bits.set_unchecked(5, true); }
}
assert_eq!(src, 1);
👎 Deprecated since 0.18.0:

Use .get_mut() instead

Produces a write reference to a region of the slice.

This method corresponds to [Index::index], except that it produces a writable reference rather than a read-only reference. See BitSliceIndex for the possible types of the produced reference.

Use of this method locks the &mut BitSlice for the duration of the produced reference’s lifetime. If you need multiple non-overlapping write references into a single source &mut BitSlice, see the ::split_at_mut method.

Lifetimes
  • 'a: Propagates the lifetime of the referent slice to the interior reference produced.
Parameters
  • &mut self
  • index: Some value whose type can be used to index BitSlices.
Returns

A writable reference into self, whose exact type is determined by index’s implementation of BitSliceIndex. This may be either a smaller &mut BitSlice when index is a range, or a BitMut proxy type when index is a usize. See the BitMut documentation for information on how to use it.

Panics

This panics if index is out of bounds of self.

Examples
use bitvec::prelude::*;

let mut src = 0u8;
let bits = src.bits_mut::<Msb0>();

assert!(!bits[0]);
*bits.at(0) = true;
//  note the leading dereference.
assert!(bits[0]);

This example shows multiple usage by using split_at_mut.

use bitvec::prelude::*;

let mut src = 0u8;
let bits = src.bits_mut::<Msb0>();

{
 let (mut a, rest) = bits.split_at_mut(2);
 let (mut b, rest) = rest.split_at_mut(3);
 *a.at(0) = true;
 *b.at(0) = true;
 *rest.at(0) = true;
}

assert_eq!(bits.as_slice()[0], 0b1010_0100);
//                               a b   rest

The above example splits the slice into three (the first, the second, and the rest) in order to hold multiple write references into the slice.

👎 Deprecated since 0.18.0:

Use .get_unchecked_mut() instead

Version of at that does not perform boundary checking.

Safety

If index is outside the boundaries of self, then this function will induce safety violations. The caller must ensure that index is within the boundaries of self before calling.

Version of split_at that does not perform boundary checking.

Safety

If mid is outside the boundaries of self, then this function will induce safety violations. The caller must ensure that mid is within the boundaries of self before calling.

Version of split_at_mut that does not perform boundary checking.

Safety

If mid is outside the boundaries of self, then this function will induce safety violations. The caller must ensure that mid is within the boundaries of self before calling.

Version of swap that does not perform boundary checks.

Safety

a and b must be within the bounds of self, otherwise, the memory access is unsound and may induce undefined behavior.

Tests if all bits in the slice domain are set (logical ).

Truth Table
0 0 => 0
0 1 => 0
1 0 => 0
1 1 => 1
Parameters
  • &self
Returns

Whether all bits in the slice domain are set. The empty slice returns true.

Examples
use bitvec::prelude::*;

let bits = 0xFDu8.bits::<Msb0>();
assert!(bits[.. 4].all());
assert!(!bits[4 ..].all());

Tests if any bit in the slice is set (logical ).

Truth Table
0 0 => 0
0 1 => 1
1 0 => 1
1 1 => 1
Parameters
  • &self
Returns

Whether any bit in the slice domain is set. The empty slice returns false.

Examples
use bitvec::prelude::*;

let bits = 0x40u8.bits::<Msb0>();
assert!(bits[.. 4].any());
assert!(!bits[4 ..].any());

Tests if any bit in the slice is unset (logical ¬∧).

Truth Table
0 0 => 1
0 1 => 1
1 0 => 1
1 1 => 0
Parameters
  • `&self
Returns

Whether any bit in the slice domain is unset.

Examples
use bitvec::prelude::*;

let bits = 0xFDu8.bits::<Msb0>();
assert!(!bits[.. 4].not_all());
assert!(bits[4 ..].not_all());

Tests if all bits in the slice are unset (logical ¬∨).

Truth Table
0 0 => 1
0 1 => 0
1 0 => 0
1 1 => 0
Parameters
  • &self
Returns

Whether all bits in the slice domain are unset.

Examples
use bitvec::prelude::*;

let bits = 0x40u8.bits::<Msb0>();
assert!(!bits[.. 4].not_any());
assert!(bits[4 ..].not_any());

Tests whether the slice has some, but not all, bits set and some, but not all, bits unset.

This is false if either all() or not_any() are true.

Truth Table
0 0 => 0
0 1 => 1
1 0 => 1
1 1 => 0
Parameters
  • &self
Returns

Whether the slice domain has mixed content. The empty slice returns false.

Examples
use bitvec::prelude::*;

let bits = 0b111_000_10u8.bits::<Msb0>();
assert!(!bits[0 .. 3].some());
assert!(!bits[3 .. 6].some());
assert!(bits[6 ..].some());

Counts how many bits are set high.

Parameters
  • &self
Returns

The number of high bits in the slice domain.

Examples
use bitvec::prelude::*;

let bits = [0xFDu8, 0x25].bits::<Msb0>();
assert_eq!(bits.count_ones(), 10);

Counts how many bits are set low.

Parameters
  • &self
Returns

The number of low bits in the slice domain.

Examples
use bitvec::prelude::*;

let bits = [0xFDu8, 0x25].bits::<Msb0>();
assert_eq!(bits.count_zeros(), 6);

Set all bits in the slice to a value.

Parameters
  • &mut self
  • value: The bit value to which all bits in the slice will be set.
Examples
use bitvec::prelude::*;

let mut src = 0u8;
let bits = src.bits_mut::<Msb0>();
bits[2 .. 6].set_all(true);
assert_eq!(bits.as_ref(), &[0b0011_1100]);
bits[3 .. 5].set_all(false);
assert_eq!(bits.as_ref(), &[0b0010_0100]);
bits[.. 1].set_all(true);
assert_eq!(bits.as_ref(), &[0b1010_0100]);

Provides mutable traversal of the collection.

It is impossible to implement IndexMut on BitSlice, because bits do not have addresses, so there can be no &mut u1. This method allows the client to receive an enumerated bit, and provide a new bit to set at each index.

Parameters
  • &mut self
  • func: A function which receives a (usize, bool) pair of index and value, and returns a bool. It receives the bit at each position, and the return value is written back at that position.
Examples
use bitvec::prelude::*;

let mut src = 0u8;
{
 let bits = src.bits_mut::<Msb0>();
 bits.for_each(|idx, _bit| idx % 3 == 0);
}
assert_eq!(src, 0b1001_0010);

Performs “reverse” addition (left to right instead of right to left).

This addition interprets the slice, and the other addend, as having its least significant bits first in the order and its most significant bits last. This is most likely to be numerically useful under a Lsb0 BitOrder type.

Parameters
  • &mut self: The addition uses self as one addend, and writes the sum back into self.
  • addend: impl IntoIterator<Item=bool>: A stream of bits. When this is another BitSlice, iteration proceeds from left to right.
Return

The final carry bit is returned

Effects

Starting from index 0 and proceeding upwards until either self or addend expires, the carry-propagated addition of self[i] and addend[i] is written to self[i].

  101111
+ 0010__ (the two missing bits are logically zero)
--------
  100000 1 (the carry-out is returned)
Examples
use bitvec::prelude::*;

let mut a = 0b0000_1010u8;
let     b = 0b0000_1100u8;
//      s =      1 0110
let ab = &mut a.bits_mut::<Lsb0>()[.. 4];
let bb = &    b.bits::<Lsb0>()[.. 4];
let c = ab.add_assign_reverse(bb.iter().copied());
assert!(c);
assert_eq!(a, 0b0000_0110u8);
Performance Notes

When using Lsb0 BitOrder types, this can be accelerated by delegating the addition to the underlying types. This is a software implementation of the ripple-carry adder, which has O(n) runtime in the number of bits. The CPU is much faster, as it has access to element-wise or vectorized addition operations.

If your use case sincerely needs binary-integer arithmetic operations on bit sets, please file an issue.

Accesses the backing storage of the BitSlice as a slice of its elements.

This will not include partially-owned edge elements, as they may be contended by other slice handles.

Parameters
  • &self
Returns

A slice of all the elements that the BitSlice uses for storage.

Examples
use bitvec::prelude::*;

let src = [1u8, 66];
let bits = src.bits::<Msb0>();

let accum = bits.as_slice()
  .iter()
  .map(|elt| elt.count_ones())
  .sum::<u32>();
assert_eq!(accum, 3);

Accesses the underlying store.

This will not include partially-owned edge elements, as they may be contended by other slice handles.

Examples
use bitvec::prelude::*;

let mut src = [1u8, 64];
let bits = src.bits_mut::<Msb0>();
for elt in bits.as_mut_slice() {
  *elt |= 2;
}
assert_eq!(&[3, 66], bits.as_slice());

Accesses the underlying store, including contended partial elements.

This produces a slice of element wrappers that permit shared mutation, rather than a slice of the bare T fundamentals.

Parameters
  • &self
Returns

A slice of all elements under the bit span, including any partially-owned edge elements, wrapped in safe shared-mutation types.

Trait Implementations

Adds two BitVecs 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. BitVecs are not intended for arithmetic, and bitvec makes no guarantees about sustained correctness in arithmetic at this time.

Adds two BitVecs.

Examples
use bitvec::prelude::*;

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 BitVecs, and will overflow.

use bitvec::prelude::*;

let a = bitvec![1; 4];
let b = bitvec![1; 1];
let s = b + a;
assert_eq!(bitvec![1, 0, 0, 0, 0], s);

The resulting type after applying the + operator.

Adds 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. BitVecs are not intended for arithmetic, and bitvec makes no guarantees about sustained correctness in arithmetic at this time.

Adds another BitVec into self.

Examples
use bitvec::prelude::*;

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

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

Performs the conversion.

Performs the conversion.

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

Accesses the underlying store.

Examples
use bitvec::prelude::*;

let bv = bitvec![Msb0, u8; 0, 0, 0, 0, 0, 0, 0, 0, 1];
assert_eq!(&[0, 0b1000_0000], bv.as_slice());

Performs the conversion.

Formats the value using the given formatter.

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.

ANDs a vector and a bitstream, producing a new vector.

Examples
use bitvec::prelude::*;

let lhs = bitvec![Msb0, u8; 0, 1, 0, 1];
let rhs = bitvec![Msb0, u8; 0, 0, 1, 1];
let and = lhs & rhs;
assert_eq!("[0001]", &format!("{}", and));

The resulting type after applying the & operator.

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.

ANDs another bitstream into a vector.

Examples
use bitvec::prelude::*;

let mut src  = bitvec![Msb0, u8; 0, 1, 0, 1];
        src &= bitvec![Msb0, u8; 0, 0, 1, 1];
assert_eq!("[0001]", &format!("{}", src));

Load from self, using little-endian element ordering. Read more

Load from self, using big-endian element ordering. Read more

Store into self, using little-endian element ordering. Read more

Store into self, using big-endian element ordering. Read more

Load the sequence of bits from self into the least-significant bits of an element. Read more

Stores a sequence of bits from the user into the domain of self. Read more

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.

ORs a vector and a bitstream, producing a new vector.

Examples
use bitvec::prelude::*;

let lhs = bitvec![0, 1, 0, 1];
let rhs = bitvec![0, 0, 1, 1];
let or  = lhs | rhs;
assert_eq!("[0111]", &format!("{}", or));

The resulting type after applying the | operator.

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.

ORs another bitstream into a vector.

Examples
use bitvec::prelude::*;

let mut src  = bitvec![0, 1, 0, 1];
        src |= bitvec![0, 0, 1, 1];
assert_eq!("[0111]", &format!("{}", 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.

XORs a vector and a bitstream, producing a new vector.

Examples
use bitvec::prelude::*;

let lhs = bitvec![0, 1, 0, 1];
let rhs = bitvec![0, 0, 1, 1];
let xor = lhs ^ rhs;
assert_eq!("[0110]", &format!("{}", xor));

The resulting type after applying the ^ operator.

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.

XORs another bitstream into a vector.

Examples
use bitvec::prelude::*;

let mut src  = bitvec![0, 1, 0, 1];
        src ^= bitvec![0, 0, 1, 1];
assert_eq!("[0110]", &format!("{}", src));

Signifies that BitSlice is the borrowed form of BitVec.

Borrows the BitVec as a BitSlice.

Parameters
  • &self
Returns

A borrowed BitSlice of the vector.

Examples
use bitvec::prelude::*;
use std::borrow::Borrow;

let bv = bitvec![0; 13];
let bs: &BitSlice = bv.borrow();
assert!(!bs[10]);

Signifies that BitSlice is the borrowed form of BitVec.

Mutably borrows the BitVec as a BitSlice.

Parameters
  • &mut self
Returns

A mutably borrowed BitSlice of the vector.

Examples
use bitvec::prelude::*;
use std::borrow::BorrowMut;

let mut bv = bitvec![0; 13];
let bs: &mut BitSlice = bv.borrow_mut();
assert!(!bs[10]);
bs.set(10, true);
assert!(bs[10]);

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Prints the BitVec for debugging.

The output is of the form BitVec<O, T> [ELT, *], where <O, T> is the order 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_slice()); instead.

The alternate character {:#?} prints each element on its own line, rather than separated by a space.

Renders the BitVec type header and contents for debug.

Examples
use bitvec::prelude::*;

let bv = bitvec![Lsb0, u16;
  0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1
];
assert_eq!(
  "BitVec<Lsb0, u16> [0101000011110101]",
  &format!("{:?}", bv)
);

Returns the “default value” for a type. Read more

Reborrows the BitVec as a BitSlice.

This mimics the separation between Vec<T> and [T].

Dereferences &BitVec down to &BitSlice.

Examples
use bitvec::prelude::*;

let bv: BitVec = bitvec![1; 4];
let bref: &BitSlice = &bv;
assert!(bref[2]);

The resulting type after dereferencing.

Mutably reborrows the BitVec as a BitSlice.

This mimics the separation between Vec<T> and [T].

Dereferences &mut BitVec down to &mut BitSlice.

Examples
use bitvec::prelude::*;

let mut bv: BitVec = bitvec![0; 6];
let bref: &mut BitSlice = &mut bv;
assert!(!bref[5]);
bref.set(5, true);
assert!(bref[5]);

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.

Renders the BitVec contents for display.

Examples
use bitvec::prelude::*;

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

Readies the underlying storage for Drop.

Rebuild the interior Vec and let it run the deallocator.

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

Extends a BitVec from another bitstream.

Parameters
  • &mut self
  • src: A source bitstream.
Type Parameters
  • I: IntoIterator<Item=bool>: The source bitstream with which to extend self.
Examples
use bitvec::prelude::*;

let mut bv = bitvec![Msb0, u8; 0; 4];
bv.extend(bitvec![1; 4]);
assert_eq!(0x0F, bv.as_slice()[0]);
🔬 This is a nightly-only experimental API. (extend_one)

Extends a collection with exactly one element.

🔬 This is a nightly-only experimental API. (extend_one)

Reserves capacity in a collection for the given number of additional elements. Read more

Performs the conversion.

Builds a BitVec out of a slice of bool.

This is primarily for the bitvec! macro; it is not recommended for general use.

Performs the conversion.

Performs the conversion.

Performs the conversion.

Performs the conversion.

Performs the conversion.

Builds 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 order type.

Performs the conversion.

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

Collects an iterator of bool into a vector.

Examples
use bitvec::prelude::*;

use std::iter::repeat;
let bv: BitVec<Msb0, u8> = repeat(true)
  .take(4)
  .chain(repeat(false).take(4))
  .collect();
assert_eq!(bv.as_slice()[0], 0xF0);

Writes the contents of the BitVec, in semantic bit order, into a hasher.

Writes each bit of the BitVec, as a full bool, into the hasher.

Parameters
  • &self
  • hasher: The hashing pool into which the vector is written.

Feeds a slice of this type into the given Hasher. Read more

The returned type after indexing.

Performs the indexing (container[index]) operation. Read more

The returned type after indexing.

Performs the indexing (container[index]) operation. Read more

The returned type after indexing.

Performs the indexing (container[index]) operation. Read more

The returned type after indexing.

Performs the indexing (container[index]) operation. Read more

The returned type after indexing.

Performs the indexing (container[index]) operation. Read more

The returned type after indexing.

Performs the indexing (container[index]) operation. Read more

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

Looks up a single bit by semantic count.

Examples
use bitvec::prelude::*;

let bv = bitvec![Msb0, 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::prelude::*;

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

The returned type after indexing.

Performs the mutable indexing (container[index]) operation. Read more

Performs the mutable indexing (container[index]) operation. Read more

Performs the mutable indexing (container[index]) operation. Read more

Performs the mutable indexing (container[index]) operation. Read more

Performs the mutable indexing (container[index]) operation. Read more

Performs the mutable indexing (container[index]) operation. Read more

Performs the conversion.

Performs the conversion.

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.

Iterates over the vector.

Examples
use bitvec::prelude::*;

let bv = bitvec![Msb0, 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.

Which kind of iterator are we turning this into?

The type of the elements being iterated over.

Which kind of iterator are we turning this into?

Creates an iterator from a value. Read more

Formats the value using the given formatter.

2’s-complement negation of a BitVec.

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. BitVecs are not intended for arithmetic, and bitvec makes no guarantees about sustained correctness in arithmetic at this time.

Numerically negates a BitVec using 2’s-complement arithmetic.

Examples
use bitvec::prelude::*;

let bv = bitvec![0, 1, 1];
let ne = -bv;
assert_eq!(ne, bitvec![1, 0, 1]);

The resulting type after applying the - operator.

Flips all bits in the vector.

Inverts all bits in the vector.

Examples
use bitvec::prelude::*;

let bv: BitVec<Msb0, u32> = BitVec::from(&[0u32] as &[u32]);
let flip = !bv;
assert_eq!(!0u32, flip.as_slice()[0]);

The resulting type after applying the ! operator.

Formats the value using the given formatter.

This method returns an Ordering between self and other. Read more

Compares and returns the maximum of two values. Read more

Compares and returns the minimum of two values. Read more

Restrict a value to a certain interval. Read more

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

Tests if two BitVecs are semantically — not bitwise — equal.

It is valid to compare two vectors of different order 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.

Performs a comparison by ==.

Parameters
  • &self
  • rhs: The other vector to compare.
Returns

Whether the vectors compare equal.

Examples
use bitvec::prelude::*;

let l: BitVec<Lsb0, u16> = bitvec![Lsb0, u16; 0, 1, 0, 1];
let r: BitVec<Msb0, u32> = bitvec![Msb0, u32; 0, 1, 0, 1];
assert!(l == r);

This example uses the same types to prove that raw, bitwise, values are not used for equality comparison.

use bitvec::prelude::*;

let l: BitVec<Msb0, u8> = bitvec![Msb0, u8; 0, 1, 0, 1];
let r: BitVec<Lsb0, u8> = bitvec![Lsb0, u8; 0, 1, 0, 1];

assert_eq!(l, r);
assert_ne!(l.as_slice(), r.as_slice());

This method tests for !=.

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

This method returns an ordering between self and other values if one exists. Read more

This method tests less than (for self and other) and is used by the < operator. Read more

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more

This method tests greater than (for self and other) and is used by the > operator. Read more

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more

This method returns an ordering between self and other values if one exists. Read more

This method tests less than (for self and other) and is used by the < operator. Read more

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more

This method tests greater than (for self and other) and is used by the > operator. Read more

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more

Compares two BitVecs 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.

Performs a comparison by < or >.

Parameters
  • &self
  • rhs: The other vector to compare.
Returns

The relative ordering of the two vectors.

Examples
use bitvec::prelude::*;

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

This method tests less than (for self and other) and is used by the < operator. Read more

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more

This method tests greater than (for self and other) and is used by the > operator. Read more

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more

This method returns an ordering between self and other values if one exists. Read more

This method tests less than (for self and other) and is used by the < operator. Read more

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more

This method tests greater than (for self and other) and is used by the > operator. Read more

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more

This method returns an ordering between self and other values if one exists. Read more

This method tests less than (for self and other) and is used by the < operator. Read more

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more

This method tests greater than (for self and other) and is used by the > operator. Read more

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more

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

On fundamentals, 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 Msb0 order, the effect in memory will be what you expect the << operator to do.

In Lsb0 order, the effect will be equivalent to using >> on the fundamentals 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 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.

Shifts a BitVec to the left, shortening it.

Examples
use bitvec::prelude::*;

let bv = bitvec![Msb0, u8; 0, 0, 0, 1, 1, 1];
assert_eq!("[000111]", &format!("{}", bv));
assert_eq!(0b0001_1100, bv.as_slice()[0]);
assert_eq!(bv.len(), 6);
let ls = bv << 2usize;
assert_eq!("[0111]", &format!("{}", ls));
assert_eq!(0b0111_0000, ls.as_slice()[0]);
assert_eq!(ls.len(), 4);

The resulting type after applying the << operator.

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

On fundamentals, 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 Msb0 order, the effect in memory will be what you expect the << operator to do.

In Lsb0 order, the effect will be equivalent to using >> on the fundamentals 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 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.

Shifts a BitVec to the left in place, shortening it.

Examples
use bitvec::prelude::*;

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

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

On fundamentals, 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, right-shifting moves bits towards the maximum.

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

In Lsb0 order, the effect will be equivalent to using << on the fundamentals 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 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.

Shifts a BitVec to the right, lengthening it and filling the front with 0.

Examples
use bitvec::prelude::*;

let bv = bitvec![Msb0, u8; 0, 0, 0, 1, 1, 1];
assert_eq!("[000111]", &format!("{}", bv));
assert_eq!(0b0001_1100, bv.as_slice()[0]);
assert_eq!(bv.len(), 6);
let rs = bv >> 2usize;
assert_eq!("[00000111]", &format!("{}", rs));
assert_eq!(0b0000_0111, rs.as_slice()[0]);
assert_eq!(rs.len(), 8);

The resulting type after applying the >> operator.

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

On fundamentals, 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, right-shifting moves bits towards the maximum.

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

In Lsb0 order, the effect will be equivalent to using << on the fundamentals 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 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.

Shifts a BitVec to the right in place, lengthening it and filling the front with 0.

Examples
use bitvec::prelude::*;

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

Subtracts 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. BitVecs are not intended for arithmetic, and bitvec makes no guarantees about sustained correctness in arithmetic at this time.

Subtracts one BitVec from another.

Examples

Minuend larger than subtrahend, positive difference.

use bitvec::prelude::*;

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.

use bitvec::prelude::*;

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.

use bitvec::prelude::*;

let a = bitvec![0, 1, 1, 0];
let b = a.clone();
let c = a - b;
assert!(c.not_any(), "{:?}", c);

The resulting type after applying the - operator.

Subtracts 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. BitVecs are not intended for arithmetic, and bitvec makes no guarantees about sustained correctness in arithmetic at this time.

Subtracts another BitVec from self.

Examples
use bitvec::prelude::*;

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

Formats the value using the given formatter.

BitVec is safe to move across thread boundaries, as is &mut BitVec.

&BitVec is safe to move across thread boundaries.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The resulting type after obtaining ownership.

Creates owned data from borrowed data, usually by cloning. Read more

🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

Converts the given value to a String. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.