Struct bitvec::slice::BitSlice[][src]

#[repr(transparent)]
pub struct BitSlice<O = Lsb0, T = usize> where
    O: BitOrder,
    T: BitStore
{ /* fields omitted */ }
Expand description

A slice of individual bits, anywhere in memory.

This is the main working type of the crate. It is analagous to [bool], and is written to be as close as possible to drop-in replacable for it. This type contains most of the methods used to operate on memory, but it will rarely be named directly in your code. You should generally prefer to use BitArray for fixed-size arrays or BitVec for dynamic vectors, and use &BitSlice references only where you would directly use &[bool] or &[u8] references before using this crate.

As it is a slice wrapper, you are intended to work with this through references (&BitSlice<O, T> and &mut BitSlice<O, T>) or through the other data structures provided by bitvec that are implemented atop it. Once created, references to BitSlice are guaranteed to work just like references to [bool] to the fullest extent possible in the Rust language.

Every bit-vector crate can give you an opaque type that hides shift/mask operations from you. BitSlice does far more than this: it offers you the full Rust guarantees about reference behavior, including lifetime tracking, mutability and aliasing awareness, and explicit memory control, as well as the full set of tools and APIs available to the standard [bool] slice type. BitSlice can arbitrarily split and subslice, just like [bool]. You can write a linear consuming function and keep the patterns already know.

For example, to trim all the bits off either edge that match a condition, you could write

use bitvec::prelude::*;

fn trim<O: BitOrder, T: BitStore>(
  bits: &BitSlice<O, T>,
  to_trim: bool,
) -> &BitSlice<O, T> {
  let stop = |b: &bool| *b != to_trim;
  let front = bits.iter().position(stop).unwrap_or(0);
  let back = bits.iter().rposition(stop).unwrap_or(0);
  &bits[front ..= back]
}

to get behavior something like trim(&BitSlice[0, 0, 1, 1, 0, 1, 0], false) == &BitSlice[1, 1, 0, 1].

Documentation

All APIs that mirror something in the standard library will have an Original section linking to the corresponding item. All APIs that have a different signature or behavior than the original will have an API Differences section explaining what has changed, and how to adapt your existing code to the change.

These sections look like this:

Original

slice

API Differences

The slice type [bool] has no type parameters. BitSlice<O, T> has two: one for the memory type used as backing storage, and one for the order of bits within that memory type.

&BitSlice<O, T> is capable of producing &bool references to read bits out of its memory, but is not capable of producing &mut bool references to write bits into its memory. Any [bool] API that would produce a &mut bool will instead produce a BitMut<O, T> proxy reference.

Behavior

BitSlice is a wrapper over [T]. It describes a region of memory, and must be handled indirectly. This is most commonly through the reference types &BitSlice and &mut BitSlice, which borrow memory owned by some other value in the program. These buffers can be directly owned by the sibling types BitBox, which behavios like Box<[T]>, and BitVec, which behaves like Vec<T>. It cannot be used as the type parameter to a standard-library-provided handle type.

The BitSlice region provides access to each individual bit in the region, as if each bit had a memory address that you could use to dereference it. It packs each logical bit into exactly one bit of storage memory, just like std::bitset and std::vector<bool> in C++.

Type Parameters

BitSlice has two type parameters which propagate through nearly every public API in the crate. These are very important to its operation, and your choice of type arguments informs nearly every part of this library’s behavior.

T: BitStore

This is the simpler of the two parameters. It refers to the integer type used to hold bits. It must be one of the Rust unsigned integer fundamentals: u8, u16, u32, usize, and on 64-bit systems only, u64. In addition, it can also be the Cell<N> wrapper over any of those, or their equivalent types in core::sync::atomic. Unless you know you need to have Cell or atomic properties, though, you should use a plain integer.

The default type argument is usize.

The argument you choose is used as the basis of a [T] slice, over which the BitSlice view type is placed. BitSlice<_, T> is subject to all of the rules about alignment that [T] is. If you are working with in-memory representation formats, chances are that you already have a T type with which you’ve been working, and should use it here.

If you are only using this crate to discard the seven wasted bits per bool of a collection of bools, and are not too concerned about the in-memory representation, then you should use the default type argument of usize. This is because most processors work best when moving an entire usize between memory and the processor itself, and using a smaller type may cause it to slow down.

O: BitOrder

This is the more complex parameter. It has a default argument which, like usize, is the good-enough choice when you do not explicitly need to control the representation of bits in memory.

This parameter determines how to index the bits within a single memory element T. Computers all agree that in a slice of elements T, the element with the lower index has a lower memory address than the element with the higher index. But the individual bits within an element do not have addresses, and so there is no uniform standard of which bit is the zeroth, which is the first, which is the penultimate, and which is the last.

To make matters even more confusing, there are two predominant ideas of in-element ordering that often correlate with the in-element byte ordering of integer types, but are in fact wholly unrelated! bitvec provides these two main orders as types for you, and if you need a different one, it also provides the tools you need to make your own.

Least Significant Bit Comes First

This ordering, named the Lsb0 type, indexes bits within an element by placing the 0 index at the least significant bit (numeric value 1) and the final index at the most significant bit (numeric value T::min_value(), for signed integers on most machines).

For example, this is the ordering used by the TCP wire format, and by most C compilers to lay out bit-field struct members on little-endian byte-ordered machines.

Most Significant Bit Comes First

This ordering, named the Msb0 type, indexes bits within an element by placing the 0 index at the most significant bit (numeric value T::min_value() for most signed integers) and the final index at the least significant bit (numeric value 1).

This is the ordering used by most C compilers to lay out bit-field struct members on big-endian byte-ordered machines.

Default Ordering

The default ordering is Lsb0, as it typically produces shorter object code than Msb0 does. If you are implementing a collection, then Lsb0 is likely the more performant ordering; if you are implementing a buffer protocol, then your choice of ordering is dictated by the protocol definition.

Safety

BitSlice is designed to never introduce new memory unsafety that you did not provide yourself, either before or during the use of this crate. Bugs do, and have, occured, and you are encouraged to submit any discovered flaw as a defect report.

The &BitSlice reference type uses a private encoding scheme to hold all the information needed in its stack value. This encoding is not part of the public API of the library, and is not binary-compatible with &[T]. Furthermore, in order to satisfy Rust’s requirements about alias conditions, BitSlice performs type transformations on the T parameter to ensure that it never creates the potential for undefined behavior.

You must never attempt to type-cast a reference to BitSlice in any way. You must not use mem::transmute with BitSlice anywhere in its type arguments. You must not use as-casting to convert between *BitSlice and any other type. You must not attempt to modify the binary representation of a &BitSlice reference value. These actions will all lead to runtime memory unsafety, are (hopefully) likely to induce a program crash, and may possibly cause undefined behavior at compile-time.

Everything in the BitSlice public API, even the unsafe parts, are guaranteed to have no more unsafety than their equivalent parts in the standard library. All unsafe APIs will have documentation explicitly detailing what the API requires you to uphold in order for it to function safely and correctly. All safe APIs will do so themselves.

Performance

Like the standard library’s [T] slice, BitSlice is designed to be very easy to use safely, while supporting unsafe when necessary. Rust has a powerful optimizing engine, and BitSlice will frequently be compiled to have zero runtime cost. Where it is slower, it will not be significantly slower than a manual replacement.

As the machine instructions operate on registers rather than bits, your choice of T: BitOrder type parameter can influence your slice’s performance. Using larger register types means that slices can gallop over completely-filled interior elements faster, while narrower register types permit more graceful handling of subslicing and aliased splits.

Construction

BitSlice views of memory can be constructed over borrowed data in a number of ways. As this is a reference-only type, it can only ever be built by borrowing an existing memory buffer and taking temporary control of your program’s view of the region.

Macro Constructor

BitSlice buffers can be constructed at compile-time through the bits! macro. This macro accepts a superset of the vec! arguments, and creates an appropriate buffer in your program’s static memory.

use bitvec::prelude::*;

let static_borrow = bits![0, 1, 0, 0, 1, 0, 0, 1];
let mutable_static: &mut BitSlice<_, _> = bits![mut 0; 8];

assert_ne!(static_borrow, mutable_static);
mutable_static.clone_from_bitslice(static_borrow);
assert_eq!(static_borrow, mutable_static);

Note that, despite constructing a static mut binding, the bits![mut …] call is not unsafe, as the constructed symbol is hidden and only accessible by the sole &mut reference returned by the macro call.

Borrowing Constructors

The functions [from_element], [from_element_mut], [from_slice], and [from_slice_mut] take references to existing memory, and construct BitSlice references over them. These are the most basic ways to borrow memory and view it as bits.

use bitvec::prelude::*;

let data = [0u16; 3];
let local_borrow = BitSlice::<Lsb0, _>::from_slice(&data);

let mut data = [0u8; 5];
let local_mut = BitSlice::<Lsb0, _>::from_slice_mut(&mut data);

Trait Method Constructors

The BitView trait implements .view_bits::<O>() and .view_bits_mut::<O>() methods on elements, arrays not larger than 32 elements, and slices. This trait, imported in the crate prelude, is probably the easiest way for you to borrow memory.

use bitvec::prelude::*;

let data = [0u32; 5];
let trait_view = data.view_bits::<Msb0>();

let mut data = 0usize;
let trait_mut = data.view_bits_mut::<Msb0>();

Owned Bit Slices

If you wish to take ownership of a memory region and enforce that it is always viewed as a BitSlice by default, you can use one of the BitArray, BitBox, or BitVec types, rather than pairing ordinary buffer types with the borrowing constructors.

use bitvec::prelude::*;

let slice = bits![0; 27];
let array = bitarr![LocalBits, u8; 0; 10];
let boxed = bitbox![0; 10];
let vec = bitvec![0; 20];

// arrays always round up
assert_eq!(array.as_bitslice(), slice[.. 16]);
assert_eq!(boxed.as_bitslice(), slice[.. 10]);
assert_eq!(vec.as_bitslice(), slice[.. 20]);

Implementations

Port of the [T] inherent API.

Returns the number of bits in the slice.

Original

slice::len

Examples
use bitvec::prelude::*;

assert_eq!(bits![0].len(), 1);

Returns true if the slice has a length of 0.

Original

slice::is_empty

Examples
use bitvec::prelude::*;

assert!(bits![].is_empty());
assert!(!bits![0].is_empty());

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

Original

slice::first

Examples
use bitvec::prelude::*;

assert_eq!(Some(&true), bits![1, 0].first());
assert!(bits![].first().is_none());

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

Original

slice::first_mut

API Differences

This crate cannot manifest &mut bool references, and must use the BitMut proxy type where &mut bool exists in the standard library API. The proxy value must be bound as mut in order to write through it.

Examples
use bitvec::prelude::*;

let bits = bits![mut 0];
assert!(!bits[0]);
if let Some(mut first) = bits.first_mut() {
  *first = true;
}
assert!(bits[0]);

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

Original

slice::split_first

Examples
use bitvec::prelude::*;

if let Some((first, rest)) = bits![1].split_first() {
  assert!(*first);
  assert!(rest.is_empty());
}

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

Original

slice::split_first_mut

API Differences

This crate cannot manifest &mut bool references, and must use the BitMut proxy type where &mut bool exists in the standard library API. The proxy value must be bound as mut in order to write through it.

Because the references are permitted to use the same memory address, they are marked as aliasing in order to satisfy Rust’s requirements about freedom from data races.

Examples
use bitvec::prelude::*;

let bits = bits![mut 0; 3];
if let Some((mut first, rest)) = bits.split_first_mut() {
  *first = true;
  *rest.get_mut(1).unwrap() = true;
}
assert_eq!(bits.count_ones(), 2);
assert!(bits![mut].split_first_mut().is_none());

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

Original

slice::split_last

Examples
use bitvec::prelude::*;

let bits = bits![1];
if let Some((last, rest)) = bits.split_last() {
  assert!(*last);
  assert!(rest.is_empty());
}

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

Original

slice::split_last_mut

API Differences

This crate cannot manifest &mut bool references, and must use the BitMut proxy type where &mut bool exists in the standard library API. The proxy value must be bound as mut in order to write through it.

Because the references are permitted to use the same memory address, they are marked as aliasing in order to satisfy Rust’s requirements about freedom from data races.

Examples
use bitvec::prelude::*;

let bits = bits![mut 0; 3];

if let Some((mut last, rest)) = bits.split_last_mut() {
  *last = true;
  *rest.get_mut(1).unwrap() = true;
}
assert_eq!(bits.count_ones(), 2);
assert!(bits![mut].split_last_mut().is_none());

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

Original

slice::last

Examples
use bitvec::prelude::*;

assert_eq!(Some(&true), bits![0, 1].last());
assert!(bits![].last().is_none());

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

Original

slice::last_mut

API Differences

This crate cannot manifest &mut bool references, and must use the BitMut proxy type where &mut bool exists in the standard library API. The proxy value must be bound as mut in order to write through it.

Examples
use bitvec::prelude::*;

let bits = bits![mut 0];
if let Some(mut last) = bits.last_mut() {
  *last = true;
}
assert!(bits[0]);

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

  • If given a position, returns a reference to the element 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.
Original

slice::get

Examples
use bitvec::prelude::*;

let bits = bits![0, 1, 0, 0];

assert_eq!(Some(&true), bits.get(1));
assert_eq!(Some(&bits[1 .. 3]), bits.get(1 .. 3));
assert!(bits.get(9).is_none());
assert!(bits.get(8 .. 10).is_none());

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

Original

slice::get_mut

API Differences

When I is usize, this returns BitMut instead of &mut bool.

Examples
use bitvec::prelude::*;

let bits = bits![mut 0; 2];
assert!(!bits.get(1).unwrap());
*bits.get_mut(1).unwrap() = true;
assert!(bits.get(1).unwrap());

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

This is generally not recommended; use with caution!

Unlike the original slice function, calling this with an out-of-bounds index is not technically compile-time undefined behavior, as the references produced do not actually describe local memory. However, the use of an out-of-bounds index will eventually cause an out-of-bounds memory read, which is a runtime safety violation. For a safe alternative see get.

Original

slice::get_unchecked

Examples
use bitvec::prelude::*;

let bits = bits![0, 1];
unsafe {
  assert!(*bits.get_unchecked(1));
}

Returns a mutable reference to the output at this location, without doing bounds checking.

This is generally not recommended; use with caution!

Unlike the original slice function, calling this with an out-of-bounds index is not technically compile-time undefined behavior, as the references produced do not actually describe local memory. However, the use of an out-of-bounds index will eventually cause an out-of-bounds memory write, which is a runtime safety violation. For a safe alternative see get_mut.

Original

slice::get_unchecked_mut

Examples
use bitvec::prelude::*;

let bits = bits![mut 0; 2];
unsafe {
  let mut bit = bits.get_unchecked_mut(1);
  *bit = true;
}
assert!(bits[1]);

Returns a raw bit-slice pointer to the region.

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 only written to if T allows shared mutation, using this pointer or any pointer derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

Modifying the container (such as BitVec) referenced by this slice may cause its buffer to be reällocated, which would also make any pointers to it invalid.

Original

slice::as_ptr

API Differences

This returns *const BitSlice, which is the equivalent of *const [T] instead of *const T. The pointer encoding used requires more than one CPU word of space to address a single bit, so there is no advantage to removing the length information from the encoded pointer value.

Notes

You cannot use any of the methods in the pointer fundamental type or the core::ptr module on the *_ BitSlice type. This pointer retains the bitvec-specific value encoding, and is incomprehensible by the Rust standard library.

The only thing you can do with this pointer is dereference it.

Examples
use bitvec::prelude::*;

let bits = bits![0, 1, 1, 0];
let bits_ptr = bits.as_ptr();

for i in 0 .. bits.len() {
  assert_eq!(bits[i], unsafe {
    (&*bits_ptr)[i]
  });
}

Returns an unsafe mutable bit-slice pointer to the region.

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

Modifying the container (such as BitVec) referenced by this slice may cause its buffer to be reällocated, which would also make any pointers to it invalid.

Original

slice::as_mut_ptr

API Differences

This returns *mut BitSlice, which is the equivalont of *mut [T] instead of *mut T. The pointer encoding used requires more than one CPU word of space to address a single bit, so there is no advantage to removing the length information from the encoded pointer value.

Notes

You cannot use any of the methods in the pointer fundamental type or the core::ptr module on the *_ BitSlice type. This pointer retains the bitvec-specific value encoding, and is incomprehensible by the Rust standard library.

Examples
use bitvec::prelude::*;

let bits = bits![mut Lsb0, u8; 0; 8];
let bits_ptr = bits.as_mut_ptr();

for i in 0 .. bits.len() {
  unsafe { &mut *bits_ptr }.set(i, i % 3 == 0);
}
assert_eq!(bits.as_slice()[0], 0b0100_1001);

Swaps two bits in the slice.

Original

slice::swap

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
use bitvec::prelude::*;

let bits = bits![mut 0, 1];
bits.swap(0, 1);
assert_eq!(bits, bits![1, 0]);

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

Original

slice::reverse

Examples
use bitvec::prelude::*;

let mut data = 0b1_1001100u8;
let bits = data.view_bits_mut::<Msb0>();
bits[1 ..].reverse();
assert_eq!(data, 0b1_0011001);

Returns an iterator over the slice.

Original

slice::iter

Examples
use bitvec::prelude::*;

let bits = bits![0, 1, 0, 0, 0, 0, 0, 1];
let mut iterator = bits.iter();

assert_eq!(iterator.next(), Some(&false));
assert_eq!(iterator.next(), Some(&true));
assert_eq!(iterator.nth(5), Some(&true));
assert_eq!(iterator.next(), None);

Returns an iterator that allows modifying each bit.

Original

slice::iter_mut

Examples
use bitvec::prelude::*;

let bits = bits![mut Msb0, u8; 0; 8];
for (idx, mut elem) in bits.iter_mut().enumerate() {
  *elem = idx % 3 == 0;
}
assert_eq!(bits.as_slice()[0], 0b100_100_10);

Returns an iterator over all contiguous windows of length size. The windows overlap. If the slice is shorter than size, the iterator returns no values.

Original

slice::windows

Panics

Panics if size is 0.

Examples
use bitvec::prelude::*;

let bits = bits![1, 0, 1, 0, 0, 1, 0, 1];
let mut iter = bits.windows(6);

assert_eq!(iter.next().unwrap(), &bits[.. 6]);
assert_eq!(iter.next().unwrap(), &bits[1 .. 7]);
assert_eq!(iter.next().unwrap(), &bits[2 ..]);
assert!(iter.next().is_none());

If the slice is shorter than size:

use bitvec::prelude::*;

let bits = BitSlice::<LocalBits, usize>::empty();
let mut iter = bits.windows(1);
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 bits, and rchunks for the same iterator but starting at the end of the slice.

Original

slice::chunks

Panics

Panics if chunk_size is 0.

Examples
use bitvec::prelude::*;

let bits = bits![0, 0, 1, 1, 1, 1, 0, 0];
let mut iter = bits.chunks(3);

assert_eq!(iter.next().unwrap(), &bits[.. 3]);
assert_eq!(iter.next().unwrap(), &bits[3 .. 6]);
assert_eq!(iter.next().unwrap(), &bits[6 ..]);
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.

Original

slice::chunks_mut

Panics

Panics if chunk_size is 0.

Examples
use bitvec::prelude::*;

let bits = bits![mut Lsb0, u8; 0; 8];
for (idx, chunk) in bits.chunks_mut(3).enumerate() {
  chunk.set(2 - idx, true);
}
assert_eq!(bits.as_slice()[0], 0b01_010_100);

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

Original

slice::chunks_exact

Panics

Panics if chunk_size is 0.

Examples
use bitvec::prelude::*;

let bits = bits![1, 1, 0, 0, 1, 0, 1, 1];
let mut iter = bits.chunks_exact(3);

assert_eq!(iter.next().unwrap(), &bits[.. 3]);
assert_eq!(iter.next().unwrap(), &bits[3 .. 6]);
assert!(iter.next().is_none());
assert_eq!(iter.remainder(), &bits[6 ..]);

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 beginning 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 may 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.

Original

slice::chunks_exact_mut

Panics

Panics if chunk_size is 0.

Examples
use bitvec::prelude::*;

let bits = bits![mut Lsb0, u8; 0; 8];
for (idx, chunk) in bits.chunks_exact_mut(3).enumerate() {
  chunk.set(idx, true);
}
assert_eq!(bits.as_slice()[0], 0b00_010_001);

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

Original

slice::rchunks

Panics

Panics if chunk_size is 0.

Examples
use bitvec::prelude::*;

let bits = bits![0, 0, 1, 1, 0, 1, 1, 0];
let mut iter = bits.rchunks(3);

assert_eq!(iter.next().unwrap(), &bits[5 ..]);
assert_eq!(iter.next().unwrap(), &bits[2 .. 5]);
assert_eq!(iter.next().unwrap(), &bits[.. 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 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.

Original

slice::rchunks_mut

Panics

Panics if chunk_size is 0.

Examples
use bitvec::prelude::*;

let bits = bits![mut Lsb0, u8; 0; 8];
for (idx, chunk) in bits.rchunks_mut(3).enumerate() {
  chunk.set(2 - idx, true);
}
assert_eq!(bits.as_slice()[0], 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.

Original

slice::rchunks_exact

Panics

Panics if chunk_size is 0.

Examples
use bitvec::prelude::*;

let bits = bits![mut 0, 1, 1, 1, 0, 0, 1, 0];
let mut iter = bits.rchunks_exact(3);

assert_eq!(iter.next().unwrap(), &bits[5 ..]);
assert_eq!(iter.next().unwrap(), &bits[2 .. 5]);
assert!(iter.next().is_none());
assert_eq!(iter.remainder(), &bits[.. 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
use bitvec::prelude::*;

let bits = bits![mut Lsb0, u8; 0; 8];
for (idx, chunk) in bits.rchunks_exact_mut(3).enumerate() {
  chunk.set(idx, true);
}
assert_eq!(bits.as_slice()[0], 0b001_010_00);

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

Original

slice::split_at

Panics

Panics if mid > len.

Behavior

When mid is 0 or self.len(), then the left or right return values, respectively, are empty slices. Empty slice references produced by this method are specified to have the address information you would expect: a left empty slice has the same base address and start bit as self, and a right empty slice will have its address raised by self.len().

Examples
use bitvec::prelude::*;

let bits = bits![1, 1, 0, 0, 0, 0, 1, 1];

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

let (left, right) = bits.split_at(2);
assert_eq!(left, &bits[.. 2]);
assert_eq!(right, &bits[2 ..]);

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

Original

slice::split_at_mut

API Differences

Because the partition point mid is permitted to occur in the interior of a memory element T, this method is required to mark the returned slices as being to aliased memory. This marking ensures that writes to the covered memory use the appropriate synchronization behavior of your build to avoid data races – by default, this makes all writes atomic; on builds with the atomic feature disabled, this uses Cells and forbids the produced subslices from leaving the current thread.

See the BitStore documentation for more information.

Panics

Panics if mid > len.

Behavior

When mid is 0 or self.len(), then the left or right return values, respectively, are empty slices. Empty slice references produced by this method are specified to have the address information you would expect: a left empty slice has the same base address and start bit as self, and a right empty slice will have its address raised by self.len().

Examples
use bitvec::prelude::*;

let bits = bits![mut Msb0, u8; 0; 8];
// scoped to restrict the lifetime of the borrows
{
  let (left, right) = bits.split_at_mut(3);
  *left.get_mut(1).unwrap() = true;
  *right.get_mut(2).unwrap() = true;
}
assert_eq!(bits.as_slice()[0], 0b010_00100);

Returns an iterator over subslices separated by bits that match pred. The matched bit is not contained in the subslices.

Original

slice::split

API Differences

In order to allow more than one bit of information for the split decision, the predicate receives the index of each bit, as well as its value.

Examples
use bitvec::prelude::*;

let bits = bits![0, 1, 0, 0, 1, 0, 0, 0];
let mut iter = bits.split(|_pos, bit| *bit);

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

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

use bitvec::prelude::*;

let bits = bits![0, 0, 0, 1];
let mut iter = bits.split(|_pos, bit| *bit);

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

If two matched bits are directly adjacent, an empty slice will be present between them:

use bitvec::prelude::*;

let bits = bits![0, 0, 1, 1, 0, 0, 0, 0,];
let mut iter = bits.split(|pos, bit| *bit);

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

Returns an iterator over mutable subslices separated by bits that match pred. The matched bit is not contained in the subslices.

Original

slice::split_mut

API Differences

In order to allow more than one bit of information for the split decision, the predicate receives the index of each bit, as well as its value.

Examples
use bitvec::prelude::*;

let bits = bits![mut Msb0, u8; 0, 0, 1, 0, 0, 0, 1, 0];
for group in bits.split_mut(|_pos, bit| *bit) {
  *group.get_mut(0).unwrap() = true;
}
assert_eq!(bits.as_slice()[0], 0b101_100_11);

Returns an iterator over subslices separated by bits that match pred, starting at the end of the slice and working backwards. The matched bit is not contained in the subslices.

Original

slice::rsplit

API Differences

In order to allow more than one bit of information for the split decision, the predicate receives the index of each bit, as well as its value.

Examples
use bitvec::prelude::*;

let bits = bits![mut Msb0, u8; 0, 0, 0, 1, 0, 0, 0, 0];
let mut iter = bits.rsplit(|_pos, bit| *bit);

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

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

use bitvec::prelude::*;

let bits = bits![mut Msb0, u8; 1, 0, 0, 1, 0, 0, 0, 1];
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 bits that match pred, starting at the end of the slice and working backwards. The matched bit is not contained in the subslices.

Original

slice::rsplit_mut

API Differences

In order to allow more than one bit of information for the split decision, the predicate receives the index of each bit, as well as its value.

Examples
use bitvec::prelude::*;

let bits = bits![mut Msb0, u8; 0, 0, 1, 0, 0, 0, 1, 0];
for group in bits.rsplit_mut(|_pos, bit| *bit) {
  *group.get_mut(0).unwrap() = true;
}
assert_eq!(bits.as_slice()[0], 0b101_100_11);

Returns an iterator over subslices separated by bits that match pred, limited to returning at most n items. The matched bit is not contained in the subslices.

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

Original

slice::splitn

API Differences

In order to allow more than one bit of information for the split decision, the predicate receives the index of each bit, as well as its value.

Examples
use bitvec::prelude::*;

let bits = bits![1, 0, 1, 0, 0, 1, 0, 1];
for group in bits.splitn(2, |pos, _bit| pos % 3 == 2) {
  println!("{}", group.len());
}
//  2
//  5

Returns an iterator over subslices separated by bits that match pred, limited to returning at most n items. The matched element is not contained in the subslices.

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

Original

slice::splitn_mut

API Differences

In order to allow more than one bit of information for the split decision, the predicate receives the index of each bit, as well as its value.

Examples
use bitvec::prelude::*;

let bits = bits![mut Msb0, u8; 0, 0, 1, 0, 0, 0, 1, 0];
for group in bits.splitn_mut(2, |_pos, bit| *bit) {
  *group.get_mut(0).unwrap() = true;
}
assert_eq!(bits.as_slice()[0], 0b101_100_10);

Returns an iterator over subslices separated by bits that match pred limited to returining at most n items. This starts at the end of the slice and works backwards. The matched bit is not contained in the subslices.

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

Original

slice::rsplitn

API Differences

In order to allow more than one bit of information for the split decision, the predicate receives the index of each bit, as well as its value.

Examples
use bitvec::prelude::*;

let bits = bits![Msb0, u8; 1, 0, 1, 0, 0, 1, 0, 1];
for group in bits.rsplitn(2, |pos, _bit| pos % 3 == 2) {
  println!("{}", group.len());
}
//  2
//  5

Returns an iterator over subslices separated by bits that match pred limited to returning at most n items. This starts at the end of the slice and works backwards. The matched bit is not contained in the subslices.

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

Original

slice::rsplitn_mut

API Differences

In order to allow more than one bit of information for the split decision, the predicate receives the index of each bit, as well as its value.

Examples
use bitvec::prelude::*;

let bits = bits![mut Msb0, u8; 0, 0, 1, 0, 0, 0, 1, 0];
for group in bits.rsplitn_mut(2, |_pos, bit| *bit) {
  *group.get_mut(0).unwrap() = true;
}
assert_eq!(bits.as_slice()[0], 0b101_000_11);

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

Original

slice::contains

API Differences

This searches for a matching subslice (allowing different type parameters) rather than for a specific bit. Searching for a contained element with a given value is not as useful on a collection of bool.

Furthermore, BitSlice defines any and not_all, which are optimized searchers for any true or false bit, respectively, in a sequence.

Examples
use bitvec::prelude::*;

let data = 0b0101_1010u8;
let bits_msb = data.view_bits::<Msb0>();
let bits_lsb = data.view_bits::<Lsb0>();
assert!(bits_msb.contains(&bits_lsb[1 .. 5]));

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

Returns true if needle is a prefix of the slice.

Original

slice::starts_with

Examples
use bitvec::prelude::*;

let data = 0b0100_1011u8;
let haystack = data.view_bits::<Msb0>();
let needle = &data.view_bits::<Lsb0>()[2 .. 5];

assert!(haystack.starts_with(&needle[.. 2]));
assert!(haystack.starts_with(needle));
assert!(!haystack.starts_with(&haystack[2 .. 4]));

Always returns true if needle is an empty slice:

use bitvec::prelude::*;

let empty = BitSlice::<LocalBits, usize>::empty();
assert!(0u8.view_bits::<LocalBits>().starts_with(empty));
assert!(empty.starts_with(empty));

Returns true if needle is a suffix of the slice.

Original

slice::ends_with

Examples
use bitvec::prelude::*;

let data = 0b0100_1011u8;
let haystack = data.view_bits::<Lsb0>();
let needle = &data.view_bits::<Msb0>()[3 .. 6];

assert!(haystack.ends_with(&needle[1 ..]));
assert!(haystack.ends_with(needle));
assert!(!haystack.ends_with(&haystack[2 .. 4]));

Always returns true if needle is an empty slice:

use bitvec::prelude::*;

let empty = BitSlice::<LocalBits, usize>::empty();
assert!(0u8.view_bits::<LocalBits>().ends_with(empty));
assert!(empty.ends_with(empty));

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.

Original

slice::rotate_left

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-op rotation.

Complexity

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

Examples
use bitvec::prelude::*;

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

Rotating a subslice:

use bitvec::prelude::*;

let mut data = 0xF0u8;
let bits = data.view_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.

Original

slice::rotate_right

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-op rotation.

Complexity

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

Examples
use bitvec::prelude::*;

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

Rotate a subslice:

use bitvec::prelude::*;

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

Copies the bits from src into self.

The length of src must be the same as self.

If you are attempting to write an integer value into a BitSlice, see the BitField::store trait function.

Implementation

This method is by necessity a bit-by-bit individual walk across both slices. Benchmarks indicate that where the slices share type parameters, this is very close in performance to an element-wise memcpy. You should use this method as the default transfer behavior, and only switch to [.copy_from_bitslice()] where you know that your performance is an issue and you can demonstrate that .copy_from_bitslice() is meaningfully better.

Where self and src are not of the same type parameters, crate benchmarks show a roughly halved runtime performance.

Original

slice::clone_from_slice

API Differences

This method is renamed, as it takes a bit slice rather than an element slice.

Panics

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

Examples

Cloning two bits from a slice into another:

use bitvec::prelude::*;

let mut data = 0u8;
let bits = data.view_bits_mut::<Msb0>();
let src = 0x0Fu16.view_bits::<Lsb0>();
bits[.. 2].clone_from_bitslice(&src[2 .. 4]);
assert_eq!(data, 0xC0);

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_bitslice on a single slice will result in a compile failure:

use bitvec::prelude::*;

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

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

use bitvec::prelude::*;

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

Copies all bits from src into self.

The length of src must be the same as self.

If you are attempting to write an integer value into a BitSlice, see the BitField::store trait function.

Implementation

This method attempts to use memcpy element-wise copy acceleration where possible. This will only occur when both src and self are exactly similar: in addition to having the same type parameters and length, they must begin at the same offset in an element.

Benchmarks do not indicate that memcpy element-wise copy is significantly faster than .clone_from_bitslice()’s bit-wise crawl. This implementation is retained so that you have the ability to observe performance characteristics on your own targets and choose as appropriate.

Original

slice::copy_from_slice

API Differences

This method is renamed, as it takes a bit slice rather than an element slice.

Panics

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

Examples

Copying two bits from a slice into another:

use bitvec::prelude::*;

let mut dst = bits![mut 0; 200];
let src = bits![1; 200];

assert!(dst.not_any());
dst.copy_from_bitslice(src);
assert!(dst.all());

Copies bits from one part of the slice to another part of itself.

src is the range within self to copy from. dest is the starting index of the range within self to copy to, which will have the same length as src. The two ranges may overlap. The ends of the two ranges must be less than or equal to self.len().

Original

slice::copy_within

Panics

This function will panic if either range exceeds the end of the slice, or if the end of src is before the start.

Examples

Copying four bytes within a slice:

use bitvec::prelude::*;

let mut data = 0x07u8;
let bits = data.view_bits_mut::<Msb0>();
bits.copy_within(5 .., 0);
assert_eq!(data, 0xE7);

Swaps all bits in self with those in other.

The length of other must be the same as self.

Original

slice::swap_with_slice

API Differences

This method is renamed, as it takes a bit slice rather than an element slice.

Panics

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

Examples
use bitvec::prelude::*;

let mut one = [0xA5u8, 0x69];
let mut two = 0x1234u16;
let one_bits = one.view_bits_mut::<Msb0>();
let two_bits = two.view_bits_mut::<Lsb0>();

one_bits.swap_with_bitslice(two_bits);

assert_eq!(one, [0x2C, 0x48]);
assert_eq!(two, 0x96A5);

Transmute the bitslice to a bitslice of another type, ensuring alignment of the types is maintained.

This method splits the bitslice into three distinct bitslices: prefix, correctly aligned middle bitslice of a new type, and the suffix bitslice. The method may make the middle bitslice the greatest length possible for a given type and input bitslice, but only your algorithm’s performance should depend on that, not its correctness. It is permissible for all of the input data to be returned as the prefix or suffix bitslice.

Original

slice::align_to

API Differences

Type U is required to have the same type family as type T. Whatever T is of the fundamental integers, atomics, or Cell wrappers, U must be a different width in the same family. Changing the type family with this method is unsound and strictly forbidden. Unfortunately, it cannot be guaranteed by this function, so you are required to abide by this limitation.

Safety

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

Examples

Basic usage:

use bitvec::prelude::*;

unsafe {
  let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
  let bits = bytes.view_bits::<LocalBits>();
  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 bitslice to a bitslice of another type, ensuring alignment of the types is maintained.

This method splits the bitslice into three distinct bitslices: prefix, correctly aligned middle bitslice of a new type, and the suffix bitslice. The method may make the middle bitslice the greatest length possible for a given type and input bitslice, but only your algorithm’s performance should depend on that, not its correctness. It is permissible for all of the input data to be returned as the prefix or suffix bitslice.

Original

slice::align_to

API Differences

Type U is required to have the same type family as type T. Whatever T is of the fundamental integers, atomics, or Cell wrappers, U must be a different width in the same family. Changing the type family with this method is unsound and strictly forbidden. Unfortunately, it cannot be guaranteed by this function, so you are required to abide by this limitation.

Safety

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

Examples

Basic usage:

use bitvec::prelude::*;

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

These functions only exist when BitVec does.

Copies self into a new BitVec.

Original

slice::to_vec

Examples
use bitvec::prelude::*;

let bits = bits![0, 1, 0, 1];
let bv = bits.to_bitvec();
assert_eq!(bits, bv);

Creates a vector by repeating a slice n times.

Original

slice::repeat

Panics

This function will panic if the capacity would overflow.

Examples

Basic usage:

use bitvec::prelude::*;

assert_eq!(bits![0, 1].repeat(3), bits![0, 1, 0, 1, 0, 1]);

A panic upon overflow:

use bitvec::prelude::*;

// this will panic at runtime
bits![0, 1].repeat(BitSlice::<LocalBits, usize>::MAX_BITS);

Constructors are limited to integers only, and not their Cells or atomics.

Constructs a shared &BitSlice reference over a shared element.

The BitView trait, implemented on all T elements, provides a method .view_bits::<O>() which delegates to this function and may be more convenient for you to write.

Parameters
  • elem: A shared reference to a memory element.
Returns

A shared &BitSlice over the elem element.

Examples
use bitvec::prelude::*;

let elem = 0u8;
let bits = BitSlice::<LocalBits, _>::from_element(&elem);
assert_eq!(bits.len(), 8);

Constructs an exclusive &mut BitSlice reference over an element.

The BitView trait, implemented on all T elements, provides a method .view_bits_mut::<O>() which delegates to this function and may be more convenient for you to write.

Parameters
  • elem: An exclusive reference to a memory element.
Returns

An exclusive &mut BitSlice over the elem element.

Note that the original elem reference will be inaccessible for the duration of the returned slice handle’s lifetime.

Examples
use bitvec::prelude::*;

let mut elem = 0u16;
let bits = BitSlice::<Msb0, _>::from_element_mut(&mut elem);
bits.set(15, true);
assert!(bits.get(15).unwrap());
assert_eq!(elem, 1);

Constructs a shared &BitSlice reference over a shared element slice.

The BitView trait, implemented on all [T] slices, provides a method .view_bits::<O>() that is equivalent to this function and may be more convenient for you to write.

Parameters
  • slice: A shared reference over a sequence of memory elements.
Returns

If slice does not have fewer than MAX_ELTS elements, this returns None. Otherwise, it returns a shared &BitSlice over the slice elements.

Conditions

The produced &BitSlice handle always begins at the zeroth bit.

Examples
use bitvec::prelude::*;

let slice = &[0u8, 1];
let bits = BitSlice::<Msb0, _>::from_slice(slice).unwrap();
assert!(bits[15]);

An example showing this function failing would require a slice exceeding !0usize >> 3 bytes in size, which is infeasible to produce.

Converts a slice reference into a BitSlice reference without checking that its size can be safely used.

Safety

If the slice length is too long, then it will be capped at MAX_BITS. You are responsible for ensuring that the input slice is not unduly truncated.

Prefer from_slice.

Constructs an exclusive &mut BitSlice reference over a slice.

The BitView trait, implemented on all [T] slices, provides a method .view_bits_mut::<O>() that is equivalent to this function and may be more convenient for you to write.

Parameters
  • slice: An exclusive reference over a sequence of memory elements.
Returns

An exclusive &mut BitSlice over the slice elements.

Note that the original slice reference will be inaccessible for the duration of the returned slice handle’s lifetime.

Panics

This panics if slice does not have fewer than MAX_ELTS elements.

Conditions

The produced &mut BitSlice handle always begins at the zeroth bit of the zeroth element in slice.

Examples
use bitvec::prelude::*;

let mut slice = [0u8; 2];
let bits = BitSlice::<Lsb0, _>::from_slice_mut(&mut slice).unwrap();

assert!(!bits[0]);
bits.set(0, true);
assert!(bits[0]);
assert_eq!(slice[0], 1);

This example attempts to construct a &mut BitSlice handle from a slice that is too large to index. Either the vec! allocation will fail, or the bit-slice constructor will fail.

use bitvec::prelude::*;

let mut data = vec![0usize; BitSlice::<LocalBits, usize>::MAX_ELTS];
let bits = BitSlice::<LocalBits, _>::from_slice_mut(&mut data[..]).unwrap();

Converts a slice reference into a BitSlice reference without checking that its size can be safely used.

Safety

If the slice length is too long, then it will be capped at MAX_BITS. You are responsible for ensuring that the input slice is not unduly truncated.

Prefer from_slice_mut.

Methods specific to BitSlice<_, T>, and not present on [T].

Produces the empty slice. This is equivalent to &[] for ordinary slices.

Examples
use bitvec::prelude::*;

let bits: &BitSlice = BitSlice::empty();
assert!(bits.is_empty());

Produces the empty mutable slice. This is equivalent to &mut [] for ordinary slices.

Examples
use bitvec::prelude::*;

let bits: &mut BitSlice = BitSlice::empty_mut();
assert!(bits.is_empty());

Sets the bit value at the given position.

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

If index is valid, then the bit to which it refers is set to value.

Panics

This method panics if index is outside the slice domain.

Examples
use bitvec::prelude::*;

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

assert!(!bits.get(7).unwrap());
bits.set(7, true);
assert!(bits.get(7).unwrap());
assert_eq!(data, 1);

This example panics when it attempts to set a bit that is out of bounds.

use bitvec::prelude::*;

let bits = bits![mut 0];
bits.set(1, false);

Sets a bit at an index, without checking boundary conditions.

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

Parameters
  • &mut self
  • index: The bit index to set. It must be in the range 0 .. self.len(). It will not be checked.
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 data = 0u8;
let bits = &mut data.view_bits_mut::<Msb0>()[2 .. 4];

assert_eq!(bits.len(), 2);
unsafe {
  bits.set_unchecked(5, true);
}
assert_eq!(data, 1);

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 = bits![1, 1, 0, 1];
assert!(bits[.. 2].all());
assert!(!bits[2 ..].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 = bits![0, 1, 0, 0];
assert!(bits[.. 2].any());
assert!(!bits[2 ..].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 = bits![1, 1, 0, 1];
assert!(!bits[.. 2].not_all());
assert!(bits[2 ..].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 = bits![0, 1, 0, 0];
assert!(!bits[.. 2].not_any());
assert!(bits[2 ..].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 data = 0b111_000_10u8;
let bits = bits![1, 1, 0, 0, 1, 0];

assert!(!bits[.. 2].some());
assert!(!bits[2 .. 4].some());
assert!(bits.some());

Returns the number of ones in the memory region backing self.

Parameters
  • &self
Returns

The number of high bits in the slice domain.

Examples

Basic usage:

use bitvec::prelude::*;

let bits = bits![1, 1, 0, 0];
assert_eq!(bits[.. 2].count_ones(), 2);
assert_eq!(bits[2 ..].count_ones(), 0);

Returns the number of zeros in the memory region backing self.

Parameters
  • &self
Returns

The number of low bits in the slice domain.

Examples

Basic usage:

use bitvec::prelude::*;

let bits = bits![1, 1, 0, 0];
assert_eq!(bits[.. 2].count_zeros(), 0);
assert_eq!(bits[2 ..].count_zeros(), 2);

Sets 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.view_bits_mut::<Msb0>();
bits[2 .. 6].set_all(true);
assert_eq!(bits.as_slice(), &[0b0011_1100]);
bits[3 .. 5].set_all(false);
assert_eq!(bits.as_slice(), &[0b0010_0100]);
bits[.. 1].set_all(true);
assert_eq!(bits.as_slice(), &[0b1010_0100]);

Applies a function to each bit in the slice.

BitSlice cannot implement IndexMut, as it cannot manifest &mut bool references, and the BitMut proxy reference has an unavoidable overhead. This method bypasses both problems, by applying a function to each pair of index and value in the slice, without constructing a proxy reference.

Parameters
  • &mut self
  • func: A function which receives two arguments, index: usize and value: bool, and returns a bool.
Effects

For each index in the slice, the result of invoking func with the index number and current bit value is written into the slice.

Examples
use bitvec::prelude::*;

let mut data = 0u8;
let bits = data.view_bits_mut::<Msb0>();
bits.for_each(|idx, _bit| idx % 3 == 0);
assert_eq!(data, 0b100_100_10);

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

This method produces a slice over all the memory elements it touches, using the current storage parameter. This is safe to do, as any events that would create an aliasing view into the elements covered by the returned slice will also have caused the slice to use its alias-aware type.

Parameters
  • &self
Returns

A view of the entire memory region this slice covers, including the edge elements.

Examples
use bitvec::prelude::*;

let data = 0x3Cu8;
let bits = &data.view_bits::<LocalBits>()[2 .. 6];

assert!(bits.all());
assert_eq!(bits.len(), 4);
assert_eq!(bits.as_slice(), &[0x3Cu8]);

Views the wholly-filled elements of the BitSlice.

This will not include partially-owned edge elements, as they may be aliased by other handles. To gain access to all elements that the BitSlice region covers, use one of the following:

  • .as_slice produces a shared slice over all elements, marked aliased as appropriate.
  • .domain produces a view describing each component of the region, marking only the contended edges as aliased and the uncontended interior as unaliased.
Parameters
  • &self
Returns

A slice of all the wholly-filled elements in the BitSlice backing storage.

Examples
use bitvec::prelude::*;

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

let accum = bits
  .as_raw_slice()
  .iter()
  .copied()
  .map(u8::count_ones)
  .sum::<u32>();
assert_eq!(accum, 3);

Views the wholly-filled elements of the BitSlice.

This will not include partially-owned edge elements, as they may be aliased by other handles. To gain access to all elements that the BitSlice region covers, use one of the following:

  • .as_aliased_slice produces a shared slice over all elements, marked as aliased to allow for the possibliity of mutation.
  • .domain_mut produces a view describing each component of the region, marking only the contended edges as aliased and the uncontended interior as unaliased.
Parameters
  • &mut self
Returns

A mutable slice of all the wholly-filled elements in the BitSlice backing storage.

Examples
use bitvec::prelude::*;

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

Splits the slice into the logical components of its memory domain.

This produces a set of read-only subslices, marking as much as possible as affirmatively lacking any write-capable view (T::NoAlias). The unaliased view is able to safely perform unsynchronized reads from memory without causing undefined behavior, as the type system is able to statically prove that no other write-capable views exist.

Parameters
  • &self
Returns

A BitDomain structure representing the logical components of the memory region.

Safety Exception

The following snippet describes a means of constructing a T::NoAlias view into memory that is, in fact, aliased:

use bitvec::prelude::*;
use core::sync::atomic::AtomicU8;
type Bs<T> = BitSlice<LocalBits, T>;

let data = [AtomicU8::new(0), AtomicU8::new(0), AtomicU8::new(0)];
let bits: &Bs<AtomicU8> = data.view_bits::<LocalBits>();
let subslice: &Bs<AtomicU8> = &bits[4 .. 20];

let (_, noalias, _): (_, &Bs<u8>, _) =
  subslice.bit_domain().region().unwrap();

The noalias reference, which has memory type u8, assumes that it can act as an &u8 reference: unsynchronized loads are permitted, as no handle exists which is capable of modifying the middle bit of data. This means that LLVM is permitted to issue loads from memory wherever it wants in the block during which noalias is live, as all loads are equivalent.

Use of the bits or subslice handles, which are still live for the lifetime of noalias, to issue .set_aliased calls into the middle element introduce undefined behavior. bitvec permits safe code to introduce this undefined behavior solely because it requires deliberate opt-in – you must start from atomic data; this cannot occur when data is non-atomic – and use of the shared-mutation facility simultaneously with the unaliasing view.

The .set_aliased method is speculative, and will be marked as unsafe or removed at any suspicion that its presence in the library has any costs.

Examples

This method can be used to accelerate reads from a slice that is marked as aliased.

use bitvec::prelude::*;
type Bs<T> = BitSlice<LocalBits, T>;

let bits = bits![mut LocalBits, u8; 0; 24];
let (a, b): (
  &mut Bs<<u8 as BitStore>::Alias>,
  &mut Bs<<u8 as BitStore>::Alias>,
) = bits.split_at_mut(4);
let (partial, full, _): (
  &Bs<<u8 as BitStore>::Alias>,
  &Bs<<u8 as BitStore>::Mem>,
  _,
) = b.bit_domain().region().unwrap();
read_from(partial); // uses alias-aware reads
read_from(full); // uses ordinary reads

Splits the slice into the logical components of its memory domain.

This produces a set of mutable subslices, marking as much as possible as affirmatively lacking any other view (T::Mem). The bare view is able to safely perform unsynchronized reads from and writes to memory without causing undefined behavior, as the type system is able to statically prove that no other views exist.

Why This Is More Sound Than .bit_domain

The &mut exclusion rule makes it impossible to construct two references over the same memory where one of them is marked &mut. This makes it impossible to hold a live reference to memory separately from any references produced from this method. For the duration of all references produced by this method, all ancestor references used to reach this method call are either suspended or dead, and the compiler will not allow you to use them.

As such, this method cannot introduce undefined behavior where a reference incorrectly believes that the referent memory region is immutable.

Splits the slice into immutable references to its underlying memory components.

Unlike .bit_domain and .bit_domain_mut, this does not return smaller BitSlice handles but rather appropriately-marked references to the underlying memory elements.

The aliased references allow mutation of these elements. You are required to not use mutating methods on these references at all. This function is not marked unsafe, but this is a contract you must uphold. Use .domain_mut to modify the underlying elements.

It is not currently possible to forbid mutation through these references. This may change in the future.

Safety Exception

As with .bit_domain, this produces unsynchronized immutable references over the fully-populated interior elements. If this view is constructed from a BitSlice handle over atomic memory, then it will remove the atomic access behavior for the interior elements. This by itself is safe, as long as no contemporaneous atomic writes to that memory can occur. You must not retain and use an atomic reference to the memory region marked as NoAlias for the duration of this view’s existence.

Parameters
  • &self
Returns

A read-only descriptor of the memory elements backing *self.

Splits the slice into mutable references to its underlying memory elements.

Like .domain, this returns appropriately-marked references to the underlying memory elements. These references are all writable.

The aliased edge references permit modifying memory beyond their bit marker. You are required to only mutate the region of these edge elements that you currently govern. This function is not marked unsafe, but this is a contract you must uphold.

It is not currently possible to forbid out-of-bounds mutation through these references. This may change in the future.

Parameters
  • &mut self
Returns

A descriptor of the memory elements underneath *self, permitting mutation.

Splits a slice at some mid-point, without checking boundary conditions.

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

Parameters
  • &self
  • mid: The index at which to split the slice. This must be in the range 0 .. self.len().
Returns
  • .0: &self[.. mid]
  • .1: &self[mid ..]
Safety

This function is not safe. It performs raw pointer arithmetic to construct two new references. If mid is out of bounds, then the first slice will be too large, and the second will be catastrophically incorrect. As both are references to invalid memory, they are undefined to construct, and may not ever be used.

Examples
use bitvec::prelude::*;

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

let (one, two) = unsafe { bits.split_at_unchecked(8) };
assert!(one[7]);
assert!(two[0]);

Splits a mutable slice at some mid-point, without checking boundary conditions.

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

Parameters
  • &mut self
  • mid: The index at which to split the slice. This must be in the range 0 .. self.len().
Returns
  • .0: &mut self[.. mid]
  • .1: &mut self[mid ..]
Safety

This function is not safe. It performs raw pointer arithmetic to construct two new references. If mid is out of bounds, then the first slice will be too large, and the second will be catastrophically incorrect. As both are references to invalid memory, they are undefined to construct, and may not ever be used.

Examples
use bitvec::prelude::*;

let mut data = 0u16;
let bits = data.view_bits_mut::<Msb0>();

let (one, two) = unsafe { bits.split_at_unchecked_mut(8) };
one.set(7, true);
two.set(0, true);
assert_eq!(data, 0x0180u16);

Swaps the bits at two indices without checking boundary conditions.

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

Parameters
  • &mut self
  • a: One index to swap.
  • b: The other index to swap.
Effects

The bit at index a is written into index b, and the bit at index b is written into a.

Safety

Both a and b must be less than self.len(). Indices greater than the length will cause out-of-bounds memory access, which can lead to memory unsafety and a program crash.

Examples
use bitvec::prelude::*;

let mut data = 8u8;
let bits = data.view_bits_mut::<Msb0>();

unsafe { bits.swap_unchecked(0, 4); }

assert_eq!(data, 128);

Copies a bit from one index to another without checking boundary conditions.

Parameters
  • &mut self
  • from: The index whose bit is to be copied
  • to: The index into which the copied bit is written.
Effects

The bit at from is written into to.

Safety

Both from and to must be less than self.len(), in order for self to legally read from and write to them, respectively.

If self had been split from a larger slice, reading from from or writing to to may not necessarily cause a memory-safety violation in the Rust model, due to the aliasing system bitvec employs. However, writing outside the bounds of a slice reference is always a logical error, as it causes changes observable by another reference handle.

Examples
use bitvec::prelude::*;

let mut data = 1u8;
let bits = data.view_bits_mut::<Lsb0>();

unsafe { bits.copy_unchecked(0, 2) };

assert_eq!(data, 5);

Copies bits from one part of the slice to another part of itself.

src is the range within self to copy from. dest is the starting index of the range within self to copy to, which will have the same length as src. The two ranges may overlap. The ends of the two ranges must be less than or equal to self.len().

Effects

self[src] is copied to self[dest .. dest + src.end() - src.start()].

Panics

This function will panic if either range exceeds the end of the slice, or if the end of src is before the start.

Safety

Both the src range and the target range dest .. dest + src.len() must not exceed the self.len() slice range.

Examples
use bitvec::prelude::*;

let mut data = 0x07u8;
let bits = data.view_bits_mut::<Msb0>();

unsafe { bits.copy_within_unchecked(5 .., 0); }

assert_eq!(data, 0xE7);

Produces the absolute offset in bits between two slice heads.

While this method is sound for any two arbitrary bit slices, the answer it produces is meaningful only when one argument is a strict subslice of the other. If the two slices are created from different buffers entirely, a comparison is undefined; if the two slices are disjoint regions of the same buffer, then the semantically correct distance is between the tail of the lower and the head of the upper, which this does not measure.

Visual Description

Consider the following sequence of bits:

[ 0 1 2 3 4 5 6 7 8 9 a b ]
  |       ^^^^^^^       |
  ^^^^^^^^^^^^^^^^^^^^^^^

It does not matter whether there are bits between the tail of the smaller and the larger slices. The offset is computed from the bit distance between the two heads.

Behavior

This function computes the semantic distance between the heads, rather than the *electrical. It does not take into account the BitOrder implementation of the slice. See the [::electrical_distance] method for that comparison.

Safety and Soundness

One of self or other must contain the other for this comparison to be meaningful.

Parameters
  • &self
  • other: Another bit slice. This must be either a strict subregion or a strict superregion of self.
Returns

The distance in (semantic) bits betwen the heads of each region. The value is positive when other is higher in the address space than self, and negative when other is lower in the address space than self.

[::electrical_distance]: #method.electrical_comparison

Computes the electrical distance between the heads of two slices.

This method uses the slices’ BitOrder implementation to compute the bit position of their heads, then computes the shift distance, in bits, between them.

This computation presumes that the bits are counted in the same direction as are bytes in the abstract memory map.

Parameters
  • &self
  • other: Another bit slice. This must be either a strict subregion or a strict superregion of self.
Returns

The electrical bit distance between the heads of self and other.

Methods available only when T allows shared mutability.

Splits a mutable slice at some mid-point.

This method has the same behavior as split_at_mut, except that it does not apply an aliasing marker to the partitioned subslices.

Safety

Because this method is defined only on BitSlices whose T type is alias-safe, the subslices do not need to be additionally marked.

Miscellaneous information.

The inclusive maximum length of a BitSlice<_, T>.

As BitSlice is zero-indexed, the largest possible index is one less than this value.

CPU word widthValue
32 bits0x1fff_ffff
64 bits0x1fff_ffff_ffff_ffff

The inclusive maximum length that a slice [T] can be for BitSlice<_, T> to cover it.

A BitSlice<_, T> that begins in the interior of an element and contains the maximum number of bits will extend one element past the cutoff that would occur if the slice began at the zeroth bit. Such a slice must be manually constructed, but will not otherwise fail.

Type BitsMax Elements (32-bit)Max Elements (64-bit)
80x0400_00010x0400_0000_0000_0001
160x0200_00010x0200_0000_0000_0001
320x0100_00010x0100_0000_0000_0001
640x0080_00010x0080_0000_0000_0001

Trait Implementations

Performs the conversion.

Performs the conversion.

Performs the conversion.

Performs the conversion.

Performs the conversion.

Performs the conversion.

Performs the conversion.

Performs the conversion.

Render the contents of a BitSlice in a numeric format.

These implementations render the bits of memory contained in a BitSlice as one of the three numeric bases that the Rust format system supports:

  • Binary renders each bit individually as 0 or 1,
  • Octal renders clusters of three bits as the numbers 0 through 7,
  • and UpperHex and LowerHex render clusters of four bits as the numbers 0 through 9 and A through F.

The formatters produce a “word” for each element T of memory. The chunked formats (octal and hexadecimal) operate somewhat peculiarly: they show the semantic value of the memory, as interpreted by the ordering parameter’s implementation rather than the raw value of memory you might observe with a debugger. In order to ease the process of expanding numbers back into bits, each digit is grouped to the right edge of the memory element. So, for example, the byte 0xFF would be rendered in as 0o377 rather than 0o773.

Rendered words are chunked by memory elements, rather than by as clean as possible a number of digits, in order to aid visualization of the slice’s place in memory.

Formats the value using the given formatter.

Performs the &= operation. Read more

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

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

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

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

Loads the bits in the self region into a local value. Read more

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

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

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

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

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

Loads the bits in the self region into a local value. Read more

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

Performs the |= operation. Read more

Performs the ^= operation. Read more

Immutably borrows from an owned value. Read more

Immutably borrows from an owned value. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Formats the value using the given formatter. Read more

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

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

Formats the value using the given formatter. Read more

Performs the conversion.

Performs the conversion.

Performs the conversion.

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

Feeds this value into the given Hasher. Read more

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

Looks up a single bit by semantic index.

Examples
use bitvec::prelude::*;

let bits = bits![Msb0, u8; 0, 0, 0, 0, 0, 0, 0, 0, 1, 0];
assert!(!bits[7]); // --------------------------^  |  |
assert!( bits[8]); // -----------------------------^  |
assert!(!bits[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 bits = bits![0,  ];
bits[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

Which kind of iterator are we turning this into?

The type of the elements being iterated over.

Creates an iterator from a value. Read more

Which kind of iterator are we turning this into?

The type of the elements being iterated over.

Creates an iterator from a value. Read more

Render the contents of a BitSlice in a numeric format.

These implementations render the bits of memory contained in a BitSlice as one of the three numeric bases that the Rust format system supports:

  • Binary renders each bit individually as 0 or 1,
  • Octal renders clusters of three bits as the numbers 0 through 7,
  • and UpperHex and LowerHex render clusters of four bits as the numbers 0 through 9 and A through F.

The formatters produce a “word” for each element T of memory. The chunked formats (octal and hexadecimal) operate somewhat peculiarly: they show the semantic value of the memory, as interpreted by the ordering parameter’s implementation rather than the raw value of memory you might observe with a debugger. In order to ease the process of expanding numbers back into bits, each digit is grouped to the right edge of the memory element. So, for example, the byte 0xFF would be rendered in as 0o377 rather than 0o773.

Rendered words are chunked by memory elements, rather than by as clean as possible a number of digits, in order to aid visualization of the slice’s place in memory.

Formats the value using the given formatter.

The resulting type after applying the ! operator.

Performs the unary ! operation. Read more

Render the contents of a BitSlice in a numeric format.

These implementations render the bits of memory contained in a BitSlice as one of the three numeric bases that the Rust format system supports:

  • Binary renders each bit individually as 0 or 1,
  • Octal renders clusters of three bits as the numbers 0 through 7,
  • and UpperHex and LowerHex render clusters of four bits as the numbers 0 through 9 and A through F.

The formatters produce a “word” for each element T of memory. The chunked formats (octal and hexadecimal) operate somewhat peculiarly: they show the semantic value of the memory, as interpreted by the ordering parameter’s implementation rather than the raw value of memory you might observe with a debugger. In order to ease the process of expanding numbers back into bits, each digit is grouped to the right edge of the memory element. So, for example, the byte 0xFF would be rendered in as 0o377 rather than 0o773.

Rendered words are chunked by memory elements, rather than by as clean as possible a number of digits, in order to aid visualization of the slice’s place in memory.

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 !=.

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 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 BitSlices are semantically — not bitwise — equal.

It is valid to compare slices of different ordering or memory types.

The equality condition requires that they have the same length and that at each index, the two slices have the same bit value.

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

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

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 BitSlices by semantic — not bitwise — ordering.

The comparison sorts by testing at each index if one slice has a high bit where the other has a low. At the first index where the slices differ, the slice with the high bit is greater. If the slices are equal until at least one terminates, then they are compared by length.

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

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

Renders a BitSlice handle as its pointer representation.

This does not enable {:p} in a format string, as there is a blanket Pointer implementation for all references, and unsized types cannot format by themselves. It is only reachable by forwarding from another format marker, such as Debug.

Formats the value using the given formatter.

Mirrors the implementation on [u8] (found here).

The implementation loads bytes out of the &BitSlice reference until exhaustion of either the source BitSlice or destination [u8]. When .read() returns, self will have been updated to no longer include the leading segment copied out as bytes of buf.

Pull some bytes from this source into the specified buffer, returning how many bytes were read. Read more

Like read, except that it reads into a slice of buffers. Read more

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

Determines if this Reader has an efficient read_vectored implementation. Read more

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

Determines if this Reader can work with buffers of uninitialized memory. Read more

Read all bytes until EOF in this source, placing them into buf. Read more

Read all bytes until EOF in this source, appending them to buf. Read more

Read the exact number of bytes required to fill buf. Read more

Creates a “by reference” adapter for this instance of Read. Read more

Transforms this Read instance to an Iterator over its bytes. Read more

Creates an adapter which will chain this stream with another. Read more

Creates an adapter which will read at most limit bytes from it. Read more

Serialize this value into the given Serde serializer. Read more

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)

recently added

Uses borrowed data to replace owned data, usually by cloning. 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.

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.

Render the contents of a BitSlice in a numeric format.

These implementations render the bits of memory contained in a BitSlice as one of the three numeric bases that the Rust format system supports:

  • Binary renders each bit individually as 0 or 1,
  • Octal renders clusters of three bits as the numbers 0 through 7,
  • and UpperHex and LowerHex render clusters of four bits as the numbers 0 through 9 and A through F.

The formatters produce a “word” for each element T of memory. The chunked formats (octal and hexadecimal) operate somewhat peculiarly: they show the semantic value of the memory, as interpreted by the ordering parameter’s implementation rather than the raw value of memory you might observe with a debugger. In order to ease the process of expanding numbers back into bits, each digit is grouped to the right edge of the memory element. So, for example, the byte 0xFF would be rendered in as 0o377 rather than 0o773.

Rendered words are chunked by memory elements, rather than by as clean as possible a number of digits, in order to aid visualization of the slice’s place in memory.

Formats the value using the given formatter.

Mirrors the implementation on [u8] (found here).

The implementation copies bytes into the &mut BitSlice reference until exhaustion of either the source [u8] or destination BitSlice. When .write() returns, self will have been updated to no longer include the leading segment containing bytes copied in from buf.

Write a buffer into this writer, returning how many bytes were written. Read more

Flush this output stream, ensuring that all intermediately buffered contents reach their destination. Read more

Like write, except that it writes from a slice of buffers. Read more

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

Determines if this Writer has an efficient write_vectored implementation. Read more

Attempts to write an entire buffer into this writer. Read more

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

Attempts to write multiple buffers into this writer. Read more

Writes a formatted string into this writer, returning any error encountered. Read more

Creates a “by reference” adapter for this instance of Write. Read more

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

Converts self into T using Into<T>. Read more

Converts self into a target type. Read more

Causes self to use its Binary implementation when Debug-formatted.

Causes self to use its Display implementation when Debug-formatted. Read more

Causes self to use its LowerExp implementation when Debug-formatted. Read more

Causes self to use its LowerHex implementation when Debug-formatted. Read more

Causes self to use its Octal implementation when Debug-formatted.

Causes self to use its Pointer implementation when Debug-formatted. Read more

Causes self to use its UpperExp implementation when Debug-formatted. Read more

Causes self to use its UpperHex implementation when Debug-formatted. Read more

Performs the conversion.

Performs the conversion.

Pipes by value. This is generally the method you want to use. Read more

Borrows self and passes that borrow into the pipe function. Read more

Mutably borrows self and passes that borrow into the pipe function. Read more

Borrows self, then passes self.borrow() into the pipe function. Read more

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more

Borrows self, then passes self.as_ref() into the pipe function.

Mutably borrows self, then passes self.as_mut() into the pipe function. Read more

Borrows self, then passes self.deref() into the pipe function.

Mutably borrows self, then passes self.deref_mut() into the pipe function. Read more

Pipes a value into a function that cannot ordinarily be called in suffix position. Read more

Pipes a trait borrow into a function that cannot normally be called in suffix position. Read more

Pipes a trait mutable borrow into a function that cannot normally be called in suffix position. Read more

Pipes a trait borrow into a function that cannot normally be called in suffix position. Read more

Pipes a trait mutable borrow into a function that cannot normally be called in suffix position. Read more

Pipes a dereference into a function that cannot normally be called in suffix position. Read more

Pipes a mutable dereference into a function that cannot normally be called in suffix position. Read more

Pipes a reference into a function that cannot ordinarily be called in suffix position. Read more

Pipes a mutable reference into a function that cannot ordinarily be called in suffix position. Read more

Immutable access to a value. Read more

Mutable access to a value. Read more

Immutable access to the Borrow<B> of a value. Read more

Mutable access to the BorrowMut<B> of a value. Read more

Immutable access to the AsRef<R> view of a value. Read more

Mutable access to the AsMut<R> view of a value. Read more

Immutable access to the Deref::Target of a value. Read more

Mutable access to the Deref::Target of a value. Read more

Calls .tap() only in debug builds, and is erased in release builds.

Calls .tap_mut() only in debug builds, and is erased in release builds. Read more

Calls .tap_borrow() only in debug builds, and is erased in release builds. Read more

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds. Read more

Calls .tap_ref() only in debug builds, and is erased in release builds. Read more

Calls .tap_ref_mut() only in debug builds, and is erased in release builds. Read more

Calls .tap_deref() only in debug builds, and is erased in release builds. Read more

Calls .tap_deref_mut() only in debug builds, and is erased in release builds. Read more

Provides immutable access for inspection. Read more

Calls tap in debug builds, and does nothing in release builds.

Provides mutable access for modification. Read more

Calls tap_mut in debug builds, and does nothing in release builds.

Provides immutable access to the reference for inspection.

Calls tap_ref in debug builds, and does nothing in release builds.

Provides mutable access to the reference for modification.

Calls tap_ref_mut in debug builds, and does nothing in release builds.

Provides immutable access to the borrow for inspection. Read more

Calls tap_borrow in debug builds, and does nothing in release builds.

Provides mutable access to the borrow for modification.

Calls tap_borrow_mut in debug builds, and does nothing in release builds. Read more

Immutably dereferences self for inspection.

Calls tap_deref in debug builds, and does nothing in release builds.

Mutably dereferences self for modification.

Calls tap_deref_mut in debug builds, and does nothing in release builds. Read more

Converts the given value to a String. Read more

Attempts to convert self into T using TryInto<T>. Read more

Attempts to convert self into a target type. 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.