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

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

A slice of individual bits, anywhere in memory.

BitSlice<O, T> is an unsized region type; you interact with it through &BitSlice<O, T> and &mut BitSlice<O, T> references, which work exactly like all other Rust references. As with the standard slice’s relationship to arrays and vectors, this is bitvec’s primary working type, but you will probably hold it through one of the provided BitArray, BitBox, or BitVec containers.

BitSlice is conceptually a [bool] slice, and provides a nearly complete mirror of [bool]’s API.

Every bit-vector crate can give you an opaque type that hides shift/mask calculations 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 you 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().by_ref().position(stop).unwrap_or(0);
  let back = bits.iter().by_ref().rposition(stop).map_or(0, |p| p + 1);
  &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 BitRef<Mut, 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 behaves 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

BitStore 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 an alias-safed wrapper over them (see the access module) in order to permit bit-slices to share underlying memory without interfering with each other.

BitSlice references can only be constructed over the integers, not over their aliasing wrappers. BitSlice will only use aliasing types in its T slots when you invoke APIs that produce them, such as .split_at_mut().

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

BitOrder 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 for signed integers on most machines).

For example, this is the ordering used 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 for most signed integers) and the final index at the least significant bit (numeric value 1).

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 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: BitStore 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 the local scope. The macro expands to a borrowed BitArray temporary; currently, it cannot be assigned to a static binding.

use bitvec::prelude::*;

let immut = bits![Lsb0, u8; 0, 1, 0, 0, 1, 0, 0, 1];
let mutable: &mut BitSlice<_, _> = bits![mut Msb0, u8; 0; 8];

assert_ne!(immut, mutable);
mutable.clone_from_bitslice(immut);
assert_eq!(immut, mutable);

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 64 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::<Lsb0>();

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

impl<O, T> BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

Port of the [T] inherent API.

pub fn len(&self) -> usize[src]

Returns the number of bits in the slice.

Original

slice::len

Examples

use bitvec::prelude::*;

let a = bits![0, 0, 1];
assert_eq!(a.len(), 3);

pub fn is_empty(&self) -> bool[src]

Returns true if the slice has a length of 0.

Original

slice::is_empty

Examples

use bitvec::prelude::*;

let a = bits![0, 0, 1];
assert!(!a.is_empty());

pub fn first(&self) -> Option<BitRef<'_, Const, O, T>>[src]

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

Original

Examples

use bitvec::prelude::*;

let v = bits![1, 0, 0];
assert_eq!(Some(&true), v.first().as_deref());

let w = bits![];
assert_eq!(None, w.first());

pub fn first_mut(&mut self) -> Option<BitRef<'_, Mut, O, T>>[src]

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 BitRef 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 x = bits![mut 0, 1, 0];

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

pub fn split_first(&self) -> Option<(BitRef<'_, Const, O, T>, &Self)>[src]

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::*;

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

if let Some((first, rest)) = x.split_first() {
  assert_eq!(first, &true);
  assert_eq!(rest, bits![0; 2]);
}

pub fn split_first_mut(
    &mut self
) -> Option<(BitRef<'_, Mut, O, T::Alias>, &mut BitSlice<O, T::Alias>)>
[src]

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 BitRef 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 x = bits![mut 0, 0, 1];

if let Some((mut first, rest)) = x.split_first_mut() {
  *first = true;
  rest.set(0, true);
  rest.set(1, false);
}
assert_eq!(x, bits![1, 1, 0]);

pub fn split_last(&self) -> Option<(BitRef<'_, Const, O, T>, &Self)>[src]

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 x = bits![0, 0, 1];

if let Some((last, rest)) = x.split_last() {
  assert_eq!(last, &true);
  assert_eq!(rest, bits![0; 2]);
}

pub fn split_last_mut(
    &mut self
) -> Option<(BitRef<'_, Mut, O, T::Alias>, &mut BitSlice<O, T::Alias>)>
[src]

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 BitRef 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 x = bits![mut 1, 0, 0];

if let Some((mut last, rest)) = x.split_last_mut() {
  *last = true;
  rest.set(0, false);
  rest.set(1, true);
}
assert_eq!(x, bits![0, 1, 1]);

pub fn last(&self) -> Option<BitRef<'_, Const, O, T>>[src]

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

Original

slice::last

Examples

use bitvec::prelude::*;

let v = bits![0, 0, 1];
assert_eq!(Some(&true), v.last().as_deref());

let w = bits![];
assert_eq!(None, w.last());

pub fn last_mut(&mut self) -> Option<BitRef<'_, Mut, O, T>>[src]

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

Original

slice::last_mut

API Differences

This crate cannot manifest &mut bool references, and must use the BitRef 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 x = bits![mut 0, 1, 0];

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

pub fn get<'a, I>(&'a self, index: I) -> Option<I::Immut> where
    I: BitSliceIndex<'a, O, T>, 
[src]

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

  • If given a position, returns a reference to the bit at that position or None if out of bounds.
  • If given a range, returns the subslice corresponding to that range, or None if out of bounds.

Original

slice::get

Examples

use bitvec::prelude::*;

let v = bits![0, 1, 0];
assert_eq!(Some(&true), v.get(1).as_deref());
assert_eq!(Some(bits![0, 1]), v.get(0 .. 2));
assert_eq!(None, v.get(3));
assert_eq!(None, v.get(0 .. 4));

pub fn get_mut<'a, I>(&'a mut self, index: I) -> Option<I::Mut> where
    I: BitSliceIndex<'a, O, T>, 
[src]

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

Original

slice::get_mut

API Differences

This crate cannot manifest &mut bool references, and must use the BitRef 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 x = bits![mut 0, 0, 1];

if let Some(mut bit) = x.get_mut(1) {
  *bit = true;
}
assert_eq!(x, bits![0, 1, 1]);

pub unsafe fn get_unchecked<'a, I>(&'a self, index: I) -> I::Immut where
    I: BitSliceIndex<'a, O, T>, 
[src]

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

This is generally not recommended; use with caution! Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used. For a safe alternative, see .get().

Original

slice::get_unchecked

Examples

use bitvec::prelude::*;

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

unsafe {
  assert_eq!(x.get_unchecked(1), &true);
}

pub unsafe fn get_unchecked_mut<'a, I>(&'a mut self, index: I) -> I::Mut where
    I: BitSliceIndex<'a, O, T>, 
[src]

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

This is generally not recommended; use with caution! Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used. For a safe alternative, see [.get_mut()].

Original

slice::get_unchecked_mut

API Differences

This crate cannot manifest &mut bool references, and must use the BitRef 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 x = bits![mut 0; 3];
unsafe {
  let mut bit = x.get_unchecked_mut(1);
  *bit = true;
}
assert_eq!(x, bits![0, 1, 0]);

pub fn swap(&mut self, a: usize, b: usize)[src]

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 v = bits![mut 0, 1, 1, 0];
v.swap(1, 3);
assert_eq!(v, bits![0, 0, 1, 1]);

pub fn reverse(&mut self)[src]

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

Original

slice::reverse

Examples

use bitvec::prelude::*;

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

pub fn iter(&self) -> Iter<'_, O, T>

Notable traits for Iter<'a, O, T>

impl<'a, O, T> Iterator for Iter<'a, O, T> where
    O: BitOrder,
    T: BitStore
type Item = <usize as BitSliceIndex<'a, O, T>>::Immut;
[src]

Returns an iterator over the slice.

Original

slice::iter

API Differences

This iterator yields BitRef proxy references, rather than &bool ordinary references. It does so in order to promote consistency in the crate, and make switching between immutable and mutable single-bit access easier.

The produced iterator has a by_ref adapter that yields &bool references, and a by_val adapter that yields bool values. Use these methods to fit this iterator into APIs that expect ordinary bool inputs.

Examples

use bitvec::prelude::*;

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

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

pub fn iter_mut(&mut self) -> IterMut<'_, O, T>

Notable traits for IterMut<'a, O, T>

impl<'a, O, T> Iterator for IterMut<'a, O, T> where
    O: BitOrder,
    T: BitStore
type Item = <usize as BitSliceIndex<'a, O, T::Alias>>::Mut;
[src]

Returns an iterator that allows modifying each bit.

Original

slice::iter_mut

API Differences

This crate cannot manifest &mut bool references, and must use the BitRef 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.

This iterator marks each yielded item as aliased, as iterators can be used to yield multiple items into the same scope. If you are using the iterator in a manner that ensures that all yielded items have disjoint lifetimes, you can use the .remove_alias() adapter on it to remove the alias marker from the yielded subslices.

Examples

use bitvec::prelude::*;

let x = bits![mut 0, 0, 1];
for mut bit in x.iter_mut() {
  *bit = !*bit;
}
assert_eq!(x, bits![1, 1, 0]);

pub fn windows(&self, size: usize) -> Windows<'_, O, T>

Notable traits for Windows<'a, O, T>

impl<'a, O, T> Iterator for Windows<'a, O, T> where
    O: BitOrder,
    T: BitStore
type Item = &'a BitSlice<O, T>;
[src]

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 slice = bits![0, 0, 1, 1];
let mut iter = slice.windows(2);
assert_eq!(iter.next().unwrap(), bits![0; 2]);
assert_eq!(iter.next().unwrap(), bits![0, 1]);
assert_eq!(iter.next().unwrap(), bits![1; 2]);
assert!(iter.next().is_none());

If the slice is shorter than size:

use bitvec::prelude::*;

let slice = bits![0; 3];
let mut iter = slice.windows(4);
assert!(iter.next().is_none());

pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, O, T>

Notable traits for Chunks<'a, O, T>

impl<'a, O, T> Iterator for Chunks<'a, O, T> where
    O: BitOrder,
    T: BitStore
type Item = &'a BitSlice<O, T>;
[src]

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 slice = bits![0, 1, 0, 0, 1];
let mut iter = slice.chunks(2);
assert_eq!(iter.next().unwrap(), bits![0, 1]);
assert_eq!(iter.next().unwrap(), bits![0, 0]);
assert_eq!(iter.next().unwrap(), bits![1]);
assert!(iter.next().is_none());

pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, O, T>

Notable traits for ChunksMut<'a, O, T>

impl<'a, O, T> Iterator for ChunksMut<'a, O, T> where
    O: BitOrder,
    T: BitStore
type Item = &'a mut BitSlice<O, T::Alias>;
[src]

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

API Differences

This iterator marks each yielded item as aliased, as iterators can be used to yield multiple items into the same scope. If you are using the iterator in a manner that ensures that all yielded items have disjoint lifetimes, you can use the .remove_alias() adapter on it to remove the alias marker from the yielded subslices.

Panics

Panics if chunk_size is 0.

Examples

use bitvec::prelude::*;

let v = bits![mut 0; 5];
let mut count = 1;

for chunk in v.chunks_mut(2) {
  for mut bit in chunk.iter_mut() {
    *bit = count % 2 == 0;
  }
  count += 1;
}
assert_eq!(v, bits![0, 0, 1, 1, 0]);

pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, O, T>

Notable traits for ChunksExact<'a, O, T>

impl<'a, O, T> Iterator for ChunksExact<'a, O, T> where
    O: BitOrder,
    T: BitStore
type Item = &'a BitSlice<O, T>;
[src]

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() method of the iterator.

Due to each chunk having exactly chunk_size bits, the compiler may be able to 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 slice = bits![0, 1, 1, 0, 0];
let mut iter = slice.chunks_exact(2);
assert_eq!(iter.next().unwrap(), bits![0, 1]);
assert_eq!(iter.next().unwrap(), bits![1, 0]);
assert!(iter.next().is_none());
assert_eq!(iter.remainder(), bits![0]);

pub fn chunks_exact_mut(
    &mut self,
    chunk_size: usize
) -> ChunksExactMut<'_, O, T>

Notable traits for ChunksExactMut<'a, O, T>

impl<'a, O, T> Iterator for ChunksExactMut<'a, O, T> where
    O: BitOrder,
    T: BitStore
type Item = &'a mut BitSlice<O, T::Alias>;
[src]

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 up to chunk_size-1 bits will be omitted and can be retrieved from the .into_remainder() method of the iterator.

Due to each chunk having exactly chunk_size bits, the compiler may be able to 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

API Differences

This iterator marks each yielded item as aliased, as iterators can be used to yield multiple items into the same scope. If you are using the iterator in a manner that ensures that all yielded items have disjoint lifetimes, you can use the .remove_alias() adapter on it to remove the alias marker from the yielded subslices.

Panics

Panics if chunk_size is 0.

Examples

use bitvec::prelude::*;

let v = bits![mut 0; 5];

for chunk in v.chunks_exact_mut(2) {
  chunk.set_all(true);
}
assert_eq!(v, bits![1, 1, 1, 1, 0]);

pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, O, T>

Notable traits for RChunks<'a, O, T>

impl<'a, O, T> Iterator for RChunks<'a, O, T> where
    O: BitOrder,
    T: BitStore
type Item = &'a BitSlice<O, T>;
[src]

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 slice = bits![0, 1, 0, 0, 1];
let mut iter = slice.rchunks(2);
assert_eq!(iter.next().unwrap(), bits![0, 1]);
assert_eq!(iter.next().unwrap(), bits![1, 0]);
assert_eq!(iter.next().unwrap(), bits![0]);
assert!(iter.next().is_none());

pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, O, T>

Notable traits for RChunksMut<'a, O, T>

impl<'a, O, T> Iterator for RChunksMut<'a, O, T> where
    O: BitOrder,
    T: BitStore
type Item = &'a mut BitSlice<O, T::Alias>;
[src]

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

API Differences

This iterator marks each yielded item as aliased, as iterators can be used to yield multiple items into the same scope. If you are using the iterator in a manner that ensures that all yielded items have disjoint lifetimes, you can use the .remove_alias() adapter on it to remove the alias marker from the yielded subslices.

Panics

Panics if chunk_size is 0.

Examples

use bitvec::prelude::*;

let v = bits![mut 0; 5];
let mut count = 1;

for chunk in v.rchunks_mut(2) {
  for mut bit in chunk.iter_mut() {
    *bit = count % 2 == 0;
  }
  count += 1;
}
assert_eq!(v, bits![0, 1, 1, 0, 0]);

pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, O, T>

Notable traits for RChunksExact<'a, O, T>

impl<'a, O, T> Iterator for RChunksExact<'a, O, T> where
    O: BitOrder,
    T: BitStore
type Item = &'a BitSlice<O, T>;
[src]

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() method of the iterator.

Due to each chunk having exactly chunk_size bits, the compiler may be able to optimize the resulting code better than in the case of .rchunks().

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 slice = bits![0, 0, 1, 1, 0];
let mut iter = slice.rchunks_exact(2);
assert_eq!(iter.next().unwrap(), bits![1, 0]);
assert_eq!(iter.next().unwrap(), bits![0, 1]);
assert!(iter.next().is_none());
assert_eq!(iter.remainder(), bits![0]);

pub fn rchunks_exact_mut(
    &mut self,
    chunk_size: usize
) -> RChunksExactMut<'_, O, T>

Notable traits for RChunksExactMut<'a, O, T>

impl<'a, O, T> Iterator for RChunksExactMut<'a, O, T> where
    O: BitOrder,
    T: BitStore
type Item = &'a mut BitSlice<O, T::Alias>;
[src]

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() method of the iterator.

Due to each chunk having exactly chunk_size bits, the compiler may be able to optimize the resulting code better than in the case of .rchunks_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.

Original

slice::rchunks_exact_mut

API Differences

This iterator marks each yielded item as aliased, as iterators can be used to yield multiple items into the same scope. If you are using the iterator in a manner that ensures that all yielded items have disjoint lifetimes, you can use the .remove_alias() adapter on it to remove the alias marker from the yielded subslices.

Panics

Panics if chunk_size is 0.

Examples

use bitvec::prelude::*;

let v = bits![mut 0; 5];

for chunk in v.rchunks_exact_mut(2) {
  chunk.set_all(true);
}
assert_eq!(v, bits![0, 1, 1, 1, 1]);

pub fn split_at(&self, mid: usize) -> (&Self, &Self)[src]

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 v = bits![0, 0, 0, 1, 1, 1];

{
  let (left, right) = v.split_at(0);
  assert_eq!(left, bits![]);
  assert_eq!(right, v);
}

{
  let (left, right) = v.split_at(2);
  assert_eq!(left, bits![0, 0]);
  assert_eq!(right, bits![0, 1, 1, 1]);
}

{
  let (left, right) = v.split_at(6);
  assert_eq!(left, v);
  assert_eq!(right, bits![]);
}

pub fn split_at_mut(
    &mut self,
    mid: usize
) -> (&mut BitSlice<O, T::Alias>, &mut BitSlice<O, T::Alias>)
[src]

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

The partition index mid may occur anywhere in the slice, and as a result the two returned slices may both have write access to the memory address containing mid. As such, the returned slices must be marked with T::Alias in order to correctly manage memory access going forward.

This marking is applied to all memory accesses in both slices, regardless of whether any future accesses actually require it. To limit the alias marking to only the addresses that need it, use [.bit_domain()] or [.bit_domain_mut()] to split either slice into its aliased and unaliased subslices.

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 v = bits![mut 0, 0, 0, 1, 1, 1];
// scoped to restrict the lifetime of the borrows
{
  let (left, right) = v.split_at_mut(2);
  assert_eq!(left, bits![0, 0]);
  assert_eq!(right, bits![0, 1, 1, 1]);

  left.set(1, true);
  right.set(1, false);
}
{
  let mut v = bits![mut 0; 0];
  let (left, right) = v.split_at_mut(0);
  assert!(left.is_empty());
  assert!(right.is_empty());
}
assert_eq!(v, bits![0, 1, 0, 0, 1, 1]);

pub fn split<F>(&self, pred: F) -> Split<'_, O, T, F>

Notable traits for Split<'a, O, T, P>

impl<'a, O, T, P> Iterator for Split<'a, O, T, P> where
    O: BitOrder,
    T: BitStore,
    P: FnMut(usize, &bool) -> bool
type Item = &'a BitSlice<O, T>;
where
    F: FnMut(usize, &bool) -> bool
[src]

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 slice = bits![0, 1, 1, 0];
let mut iter = slice.split(|pos, _bit| pos % 3 == 2);

assert_eq!(iter.next().unwrap(), bits![0, 1]);
assert_eq!(iter.next().unwrap(), bits![0]);
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 bit in the slice is matched, an empty slice will be the last item returned by the iterator:

use bitvec::prelude::*;

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

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

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

use bitvec::prelude::*;

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

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

pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, O, T, F>

Notable traits for SplitMut<'a, O, T, P>

impl<'a, O, T, P> Iterator for SplitMut<'a, O, T, P> where
    O: BitOrder,
    T: BitStore,
    P: FnMut(usize, &bool) -> bool
type Item = &'a mut BitSlice<O, T::Alias>;
where
    F: FnMut(usize, &bool) -> bool
[src]

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.

This iterator marks each yielded item as aliased, as iterators can be used to yield multiple items into the same scope. If you are using the iterator in a manner that ensures that all yielded items have disjoint lifetimes, you can use the .remove_alias() adapter on it to remove the alias marker from the yielded subslices.

Examples

use bitvec::prelude::*;

let v = bits![mut 0, 0, 1, 0, 1, 0];
for group in v.split_mut(|_pos, bit| *bit) {
  group.set(0, true);
}
assert_eq!(v, bits![1, 0, 1, 1, 1, 1]);

pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, O, T, F>

Notable traits for RSplit<'a, O, T, P>

impl<'a, O, T, P> Iterator for RSplit<'a, O, T, P> where
    O: BitOrder,
    T: BitStore,
    P: FnMut(usize, &bool) -> bool
type Item = &'a BitSlice<O, T>;
where
    F: FnMut(usize, &bool) -> bool
[src]

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 slice = bits![1, 1, 1, 0, 1, 1];
let mut iter = slice.rsplit(|_pos, bit| !*bit);

assert_eq!(iter.next().unwrap(), bits![1; 2]);
assert_eq!(iter.next().unwrap(), bits![1; 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 v = bits![1, 0, 0, 1, 0, 0, 1];
let mut it = v.rsplit(|_pos, bit| *bit);
assert_eq!(it.next().unwrap(), bits![]);
assert_eq!(it.next().unwrap(), bits![0; 2]);
assert_eq!(it.next().unwrap(), bits![0; 2]);
assert_eq!(it.next().unwrap(), bits![]);
assert!(it.next().is_none());

pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, O, T, F>

Notable traits for RSplitMut<'a, O, T, P>

impl<'a, O, T, P> Iterator for RSplitMut<'a, O, T, P> where
    O: BitOrder,
    T: BitStore,
    P: FnMut(usize, &bool) -> bool
type Item = &'a mut BitSlice<O, T::Alias>;
where
    F: FnMut(usize, &bool) -> bool
[src]

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.

This iterator marks each yielded item as aliased, as iterators can be used to yield multiple items into the same scope. If you are using the iterator in a manner that ensures that all yielded items have disjoint lifetimes, you can use the .remove_alias() adapter on it to remove the alias marker from the yielded subslices.

Examples

use bitvec::prelude::*;

let v = bits![mut 0, 0, 1, 0, 1, 0];
for group in v.rsplit_mut(|_pos, bit| *bit) {
  group.set(0, true);
}
assert_eq!(v, bits![1, 0, 1, 1, 1, 1]);

pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, O, T, F>

Notable traits for SplitN<'a, O, T, P>

impl<'a, O, T, P> Iterator for SplitN<'a, O, T, P> where
    O: BitOrder,
    T: BitStore,
    P: FnMut(usize, &bool) -> bool
type Item = <Split<'a, O, T, P> as Iterator>::Item;
where
    F: FnMut(usize, &bool) -> bool
[src]

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

Print the slice split once by set bits (i.e., [0, 0,], [0, 1, 0]):

use bitvec::prelude::*;

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

for group in v.splitn(2, |_pos, bit| *bit) {
  println!("{:b}", group);
}

pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, O, T, F>

Notable traits for SplitNMut<'a, O, T, P>

impl<'a, O, T, P> Iterator for SplitNMut<'a, O, T, P> where
    O: BitOrder,
    T: BitStore,
    P: FnMut(usize, &bool) -> bool
type Item = <SplitMut<'a, O, T, P> as Iterator>::Item;
where
    F: FnMut(usize, &bool) -> bool
[src]

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

This iterator marks each yielded item as aliased, as iterators can be used to yield multiple items into the same scope. If you are using the iterator in a manner that ensures that all yielded items have disjoint lifetimes, you can use the .remove_alias() adapter on it to remove the alias marker from the yielded subslices.

Examples

use bitvec::prelude::*;

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

for group in v.splitn_mut(2, |_pos, bit| *bit) {
  group.set(0, true);
}
assert_eq!(v, bits![1, 0, 1, 1, 1, 0]);

pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, O, T, F>

Notable traits for RSplitN<'a, O, T, P>

impl<'a, O, T, P> Iterator for RSplitN<'a, O, T, P> where
    O: BitOrder,
    T: BitStore,
    P: FnMut(usize, &bool) -> bool
type Item = <RSplit<'a, O, T, P> as Iterator>::Item;
where
    F: FnMut(usize, &bool) -> bool
[src]

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

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

Print the slice split once, starting from the end, by set bits (i.e., [0], [0, 0, 1, 0]):

use bitvec::prelude::*;

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

for group in v.rsplitn(2, |_pos, bit| *bit) {
  println!("{:b}", group);
}

pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, O, T, F>

Notable traits for RSplitNMut<'a, O, T, P>

impl<'a, O, T, P> Iterator for RSplitNMut<'a, O, T, P> where
    O: BitOrder,
    T: BitStore,
    P: FnMut(usize, &bool) -> bool
type Item = <RSplitMut<'a, O, T, P> as Iterator>::Item;
where
    F: FnMut(usize, &bool) -> bool
[src]

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.

This iterator marks each yielded item as aliased, as iterators can be used to yield multiple items into the same scope. If you are using the iterator in a manner that ensures that all yielded items have disjoint lifetimes, you can use the .remove_alias() adapter on it to remove the alias marker from the yielded subslices.

Examples

use bitvec::prelude::*;

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

for group in v.rsplitn_mut(2, |_pos, bit| *bit) {
  group.set(0, true);
}
assert_eq!(v, bits![1, 0, 1, 0, 1, 1]);

pub fn contains<O2, T2>(&self, x: &BitSlice<O2, T2>) -> bool where
    O2: BitOrder,
    T2: BitStore
[src]

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.

pub fn starts_with<O2, T2>(&self, needle: &BitSlice<O2, T2>) -> bool where
    O2: BitOrder,
    T2: BitStore
[src]

Returns true if needle is a prefix of the slice.

Original

slice::starts_with

Examples

use bitvec::prelude::*;

let v = bits![0, 1, 0, 0];
assert!(v.starts_with(bits![0]));
assert!(v.starts_with(bits![0, 1]));
assert!(!v.starts_with(bits![1]));
assert!(!v.starts_with(bits![1, 0]));

Always returns true if needle is an empty slice:

use bitvec::prelude::*;

let v = bits![0, 1, 0];
assert!(v.starts_with(bits![]));
let v = bits![];
assert!(v.starts_with(bits![]));

pub fn ends_with<O2, T2>(&self, needle: &BitSlice<O2, T2>) -> bool where
    O2: BitOrder,
    T2: BitStore
[src]

Returns true if needle is a suffix of the slice.

Original

slice::ends_with

Examples

use bitvec::prelude::*;

let v = bits![0, 1, 0, 0];
assert!(v.ends_with(bits![0]));
assert!(v.ends_with(bits![0; 2]));
assert!(!v.ends_with(bits![1]));
assert!(!v.ends_with(bits![1, 0]));

Always returns true if needle is an empty slice:

use bitvec::prelude::*;

let v = bits![0, 1, 0];
assert!(v.ends_with(bits![]));
let v = bits![];
assert!(v.ends_with(bits![]));

pub fn rotate_left(&mut self, by: usize)[src]

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

Complexity

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

Examples

use bitvec::prelude::*;

let a = bits![mut 0, 0, 1, 0, 1, 0];
a.rotate_left(2);
assert_eq!(a, bits![1, 0, 1, 0, 0, 0]);

Rotating a subslice:

use bitvec::prelude::*;

let a = bits![mut 0, 0, 1, 0, 1, 1];
a[1 .. 5].rotate_left(1);
assert_eq!(a, bits![0, 1, 0, 1, 0, 1]);

pub fn rotate_right(&mut self, by: usize)[src]

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

Complexity

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

Examples

use bitvec::prelude::*;

let a = bits![mut 0, 0, 1, 1, 1, 0];
a.rotate_right(2);
assert_eq!(a, bits![1, 0, 0, 0, 1, 1]);

Rotating a subslice:

use bitvec::prelude::*;

let a = bits![mut 0, 0, 1, 0, 1, 1];
a[1 .. 5].rotate_right(1);
assert_eq!(a, bits![0, 1, 0, 1, 0, 1]);

pub fn copy_within<R>(&mut self, src: R, dest: usize) where
    R: RangeBounds<usize>, 
[src]

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 bits within a slice:

use bitvec::prelude::*;

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

bits.copy_within(1 .. 5, 8);

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

pub unsafe fn align_to<U>(&self) -> (&Self, &BitSlice<O, U>, &Self) where
    U: BitStore
[src]

Transmute the bit-slice to a bit-slice of another type, ensuring alignment of the types is maintained.

Original

slice::align_to

API Differences

Type U is required to have the same BitStore type family as type T. If T is a fundamental integer, so must U be; if T is an ::Alias type, then so must U. Changing the type family with this method is unsound and strictly forbidden. Unfortunately, this cannot be encoded in the type system, so you are required to abide by this limitation yourself.

Implementation

The algorithm used to implement this function attempts to create the widest possible span for the middle slice. However, the slice divisions must abide by the Domain restrictions: the left and right slices produced by this function will include the head and tail elements of the domain (if present), as well as the left and right subslices (if any) produced by calling slice::align_to on the domain body (if present).

The standard library implementation currently maximizes the width of the center slice, but its API does not guarantee this property, and retains the right to produce pessimal slices. As such, this function cannot guarantee maximal center slice width either, and you cannot rely on this behavior for correctness of your work; it is only a possible performance improvement.

Safety

This method is essentially a mem::transmute with respect to the memory region in the returned middle slice, so all of the usual caveats pertaining to mem::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")
  }
}

pub unsafe fn align_to_mut<U>(
    &mut self
) -> (&mut Self, &mut BitSlice<O, U>, &mut Self) where
    U: BitStore
[src]

Transmute the bit-slice to a bit-slice of another type, ensuring alignment of the types is maintained.

Original

slice::align_to_mut

API Differences

Type U is required to have the same BitStore type family as type T. If T is a fundamental integer, so must U be; if T is an ::Alias type, then so must U. Changing the type family with this method is unsound and strictly forbidden. Unfortunately, this cannot be encoded in the type system, so you are required to abide by this limitation yourself.

Implementation

The algorithm used to implement this function attempts to create the widest possible span for the middle slice. However, the slice divisions must abide by the DomainMut restrictions: the left and right slices produced by this function will include the head and tail elements of the domain (if present), as well as the left and right subslices (if any) produced by calling slice::align_to_mut on the domain body (if present).

The standard library implementation currently maximizes the width of the center slice, but its API does not guarantee this property, and retains the right to produce pessimal slices. As such, this function cannot guarantee maximal center slice width either, and you cannot rely on this behavior for correctness of your work; it is only a possible performance improvement.

Safety

This method is essentially a mem::transmute with respect to the memory region in the returned middle slice, so all of the usual caveats pertaining to mem::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`
}

impl<O, T> BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

These functions only exist when BitVec does.

pub fn repeat(&self, n: usize) -> BitVec<O, T::Unalias>

Notable traits for BitVec<O, T>

impl<O, T> Write for BitVec<O, T> where
    O: BitOrder,
    T: BitStore,
    BitSlice<O, T>: BitField
[src]

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

impl<O, T> BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

General-purpose functions not present on [T].

pub fn from_element(elem: &T) -> &Self[src]

Constructs a shared &BitSlice reference over a shared element.

The BitView trait, implemented on all BitStore implementors, 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::<Lsb0, _>::from_element(&elem);
assert_eq!(bits.len(), 8);

pub fn from_element_mut(elem: &mut T) -> &mut Self[src]

Constructs an exclusive &mut BitSlice reference over an element.

The BitView trait, implemented on all BitStore implementors, 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);

pub fn from_slice(slice: &[T]) -> Result<&Self, BitSpanError<T>>[src]

Constructs a shared &BitSlice reference over a slice.

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

Parameters

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

Returns

A &BitSlice view of the provided slice. The error condition is only encountered if the source slice is too long to be encoded in a &BitSlice handle, but such a slice is likely impossible to produce without causing errors long before calling this function.

Conditions

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

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.

pub fn from_slice_mut(slice: &mut [T]) -> Result<&mut Self, BitSpanError<T>>[src]

Constructs an exclusive &mut BitSlice reference over a slice.

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

Parameters

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

Returns

A &mut BitSlice view of the provided slice. The error condition is only encountered if the source slice is too long to be encoded in a &mut BitSlice handle, but such a slice is likely impossible to produce without causing errors long before calling this function.

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

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::<Lsb0, usize>::MAX_ELTS];
let bits = BitSlice::<Lsb0, _>::from_slice_mut(&mut data[..]).unwrap();

pub unsafe fn from_slice_unchecked(slice: &[T]) -> &Self[src]

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

Safety

If the slice length is longer than MAX_ELTS, then the returned BitSlice will have its length severely truncated. This is not a safety violation, but it is behavior that callers must avoid to remain correct.

Prefer ::from_slice().

pub unsafe fn from_slice_unchecked_mut(slice: &mut [T]) -> &mut Self[src]

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

Safety

If the slice length is longer than MAX_ELTS, then the returned BitSlice will have its length severely truncated. This is not a safety violation, but it is behavior that callers must avoid to remain correct.

Prefer ::from_slice_mut().

pub fn empty<'a>() -> &'a Self[src]

Produces the empty slice reference.

This is equivalent to &[] for ordinary slices.

Examples

use bitvec::prelude::*;

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

pub fn empty_mut<'a>() -> &'a mut Self[src]

Produces the empty mutable slice reference.

This is equivalent to &mut [] for ordinary slices.

Examples

use bitvec::prelude::*;

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

pub fn set(&mut self, index: usize, value: bool)[src]

Writes a new bit at a given index.

Parameters

  • &mut self
  • index: The bit index at which to write. It must be in the range 0 .. self.len().
  • value: The value to be written; true for 1 or 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 not less than self.len().

Examples

use bitvec::prelude::*;

let bits = bits![mut 0];

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

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

pub fn any(&self) -> bool[src]

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

pub fn all(&self) -> bool[src]

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

pub fn not_any(&self) -> bool[src]

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

pub fn not_all(&self) -> bool[src]

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

pub fn some(&self) -> bool[src]

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

pub fn count_ones(&self) -> usize[src]

Counts the number of bits set to 1 in the slice contents.

Parameters

  • &self

Returns

The number of bits in the slice domain that are set to 1.

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

pub fn count_zeros(&self) -> usize[src]

Counts the number of bits cleared to 0 in the slice contents.

Parameters

  • &self

Returns

The number of bits in the slice domain that are cleared to 0.

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

pub fn iter_ones(&self) -> IterOnes<'_, O, T>

Notable traits for IterOnes<'_, O, T>

impl<O, T> Iterator for IterOnes<'_, O, T> where
    O: BitOrder,
    T: BitStore
type Item = usize;
[src]

Enumerates all bits in a BitSlice that are set to 1.

Examples

use bitvec::prelude::*;

let bits = bits![0, 1, 0, 0, 1, 0, 0, 0, 1];
let mut indices = [1, 4, 8].iter().copied();

let mut iter_ones = bits.iter_ones();
let mut compose = bits.iter()
  .copied()
  .enumerate()
  .filter_map(|(idx, bit)| if bit { Some(idx) } else { None });

for ((a, b), c) in iter_ones.zip(compose).zip(indices) {
  assert_eq!(a, b);
  assert_eq!(b, c);
}

pub fn iter_zeros(&self) -> IterZeros<'_, O, T>

Notable traits for IterZeros<'_, O, T>

impl<O, T> Iterator for IterZeros<'_, O, T> where
    O: BitOrder,
    T: BitStore
type Item = usize;
[src]

Enumerates all bits in a BitSlice that are cleared to 0.

Examples

use bitvec::prelude::*;

let bits = bits![1, 0, 1, 1, 0, 1, 1, 1, 0];
let mut indices = [1, 4, 8].iter().copied();

let mut iter_zeros = bits.iter_zeros();
let mut compose = bits.iter()
  .copied()
  .enumerate()
  .filter_map(|(idx, bit)| if !bit { Some(idx) } else { None });

for ((a, b), c) in iter_zeros.zip(compose).zip(indices) {
  assert_eq!(a, b);
  assert_eq!(b, c);
}

pub fn first_one(&self) -> Option<usize>[src]

Gets the index of the first bit in the bit-slice set to 1.

Examples

use bitvec::prelude::*;

assert!(bits![].first_one().is_none());
assert_eq!(bits![0, 0, 1].first_one().unwrap(), 2);

pub fn first_zero(&self) -> Option<usize>[src]

Gets the index of the first bit in the bit-slice set to 0.

Examples

use bitvec::prelude::*;

assert!(bits![].first_zero().is_none());
assert_eq!(bits![1, 1, 0].first_zero().unwrap(), 2);

pub fn last_one(&self) -> Option<usize>[src]

Gets the index of the last bit in the bit-slice set to 1.

Examples

use bitvec::prelude::*;

assert!(bits![].last_one().is_none());
assert_eq!(bits![1, 0, 0, 1].last_one().unwrap(), 3);

pub fn last_zero(&self) -> Option<usize>[src]

Gets the index of the last bit in the bit-slice set to 0.

Examples

use bitvec::prelude::*;

assert!(bits![].last_zero().is_none());
assert_eq!(bits![0, 1, 1, 0].last_zero().unwrap(), 3);

pub fn leading_ones(&self) -> usize[src]

Counts the number of bits from the start of the bit-slice to the first bit set to 0.

This returns 0 if the bit-slice is empty.

Examples

use bitvec::prelude::*;

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

pub fn leading_zeros(&self) -> usize[src]

Counts the number of bits from the start of the bit-slice to the first bit set to 1.

This returns 0 if the bit-slice is empty.

Examples

use bitvec::prelude::*;

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

pub fn trailing_ones(&self) -> usize[src]

Counts the number of bits from the end of the bit-slice to the last bit set to 0.

This returns 0 if the bit-slice is empty.

Examples

use bitvec::prelude::*;

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

pub fn trailing_zeros(&self) -> usize[src]

Counts the number of bits from the end of the bit-slice to the last bit set to 1.

This returns 0 if the bit-slice is empty.

Examples

use bitvec::prelude::*;

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

pub fn clone_from_bitslice<O2, T2>(&mut self, src: &BitSlice<O2, T2>) where
    O2: BitOrder,
    T2: BitStore
[src]

Copies the bits from src into self.

The length of src must be the same as `self.

If src has the same type arguments as self, it can be more performant to use .copy_from_bitslice().

Original

slice::clone_from_bitslice

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 src = bits![Msb0, u16; 1; 4];
let dst = bits![mut Lsb0, u8; 0; 2];

dst.clone_from_bitslice(&src[2 ..]);
assert_eq!(dst, bits![1; 2]);

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

use bitvec::prelude::*;

let slice = bits![mut 0, 0, 0, 1, 1];
slice[.. 2].clone_from_bitslice(&slice[3 ..]); // compile fail!

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

use bitvec::prelude::*;

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

{
  let (left, right) = slice.split_at_mut(2);
  left.clone_from_bitslice(&right[1 ..]);
}

assert_eq!(slice, bits![1, 1, 0, 1, 1]);

Performance

If self and src use the same type arguments, this specializes to .copy_from_bitslice(); if you know statically that this is the case, prefer to call that method directly and avoid the cost of detection at runtime. Otherwise, this is a bit-by-bit crawl across both slices, which is a slow process.

pub fn copy_from_bitslice(&mut self, src: &Self)[src]

Copies all bits from src into self, using a memcpy wherever possible.

The length of src must be same as self.

If src does not use the same type arguments as self, use .clone_from_bitslice().

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 src = bits![1; 4];
let dst = bits![mut 0; 2];

// Because the slices have to be the same length,
// we slice the source slice from four bits to
// two. It will panic if we don't do this.
dst.clone_from_bitslice(&src[2..]);

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

use bitvec::prelude::*;

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

slice[.. 2].copy_from_bitslice(&bits[3 ..]); // compile fail!

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

use bitvec::prelude::*;

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

{
  let (left, right) = slice.split_at_mut(2);
  left.copy_from_bitslice(&right[1 ..]);
}

assert_eq!(slice, bits![1, 1, 0, 1, 1]);

pub fn swap_with_bitslice<O2, T2>(&mut self, other: &mut BitSlice<O2, T2>) where
    O2: BitOrder,
    T2: BitStore
[src]

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

pub fn shift_left(&mut self, by: usize)[src]

Shifts the contents of a bit-slice left (towards index 0).

This moves the contents of the slice from by .. down to 0 .. len - by, and erases len - by .. to 0. As this is a destructive (and linearly expensive) operation, you may prefer instead to use range subslicing.

Parameters

  • &mut self
  • by: The distance by which to shift the slice contents.

Panics

This panics if by is not less than self.len().

Examples

use bitvec::prelude::*;

let bits = bits![mut 1; 6];
bits.shift_left(2);
assert_eq!(bits, bits![1, 1, 1, 1, 0, 0]);

pub fn shift_right(&mut self, by: usize)[src]

Shifts the contents of a bit-slice right (towards index self.len()).

This moves the contents of the slice from .. len - by up to by .., and erases .. by to 0. As this is a destructive (and linearly expensive) operation, you may prefer instead to use range subslicing.

Parameters

  • &mut self
  • by: The distance by which to shift the slice contents.

Panics

This panics if by is not less than self.len().

Examples

use bitvec::prelude::*;

let bits = bits![mut 1; 6];
bits.shift_right(2);
assert_eq!(bits, bits![0, 0, 1, 1, 1, 1]);

pub fn set_all(&mut self, value: bool)[src]

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_raw_slice(), &[0b0011_1100]);
bits[3 .. 5].set_all(false);
assert_eq!(bits.as_raw_slice(), &[0b0010_0100]);
bits[.. 1].set_all(true);
assert_eq!(bits.as_raw_slice(), &[0b1010_0100]);

pub fn for_each<F>(&mut self, func: F) where
    F: FnMut(usize, bool) -> bool
[src]

Applies a function to each bit in the slice.

BitSlice cannot implement IndexMut, as it cannot manifest &mut bool references, and the BitRef 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. Benchmarks indicate that this method is about 2–4 times faster than the .iter_mut().enumerate() equivalent.

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

pub fn offset_from(&self, other: &Self) -> isize[src]

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.

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

impl<O, T> BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

Unchecked variants of checked accessors.

pub unsafe fn set_unchecked(&mut self, index: usize, value: bool)[src]

Writes a new bit at a given index, without doing bounds checking.

This is generally not recommended; use with caution! Calling this method with an out-of-bounds index is undefined behavior. For a safe alternative, see .set().

Parameters

  • &mut self
  • index: The bit index at which to write. It must be in the range 0 .. self.len().
  • value: The value to be written; true for 1 or false for 0.

Effects

The bit at index is set to value. If index is out of bounds, then the memory access is incorrect, and its behavior is unspecified.

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 bits = bits![mut 0; 2];
let (first, _) = bits.split_at_mut(1);

unsafe {
  first.set_unchecked(1, true);
}

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

pub unsafe fn swap_unchecked(&mut self, a: usize, b: usize)[src]

Swaps two bits in the slice.

See .swap().

Safety

a and b must both be less than self.len().

pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&Self, &Self)[src]

Divides one slice into two at an index, without performing any bounds checking.

See .split_at().

Safety

mid must not be greater than self.len(). If this condition is violated, the function behavior is unspecified.

Examples

use bitvec::prelude::*;

let bits = bits![0, 0, 0, 1, 1, 1];
let (l, r) = unsafe { bits.split_at_unchecked(3) };
assert!(l.not_any());
assert!(r.all());

let (l, r) = unsafe { bits.split_at_unchecked(6) };
assert_eq!(l, bits);
assert!(r.is_empty());

pub unsafe fn split_at_unchecked_mut(
    &mut self,
    mid: usize
) -> (&mut BitSlice<O, T::Alias>, &mut BitSlice<O, T::Alias>)
[src]

Divides one mutable slice into two at an index.

See .split_at_mut().

Safety

mid must not be greater than self.len().

pub unsafe fn copy_within_unchecked<R>(&mut self, src: R, dest: usize) where
    R: RangeBounds<usize>, 
[src]

Copies bits from one part of the slice to another part of itself, without doing bounds checks.

The ranges are allowed to overlap.

Parameters

  • &mut self
  • src: The range within self from which to copy.
  • dst: The starting index within self at which to paste.

Effects

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

Safety

src and dest .. dest + src.len() must be entirely within self.len().

impl<O, T> BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

View conversions.

pub fn as_bitptr(&self) -> BitPtr<Const, O, T>[src]

Returns a raw bit-pointer to the base of the bit-slice’s region.

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

The caller must also ensure that the memory the bit-pointer (non-transitively) points to is never written to using this bit-pointer or any bit-pointer derived from it. If you need to mutate the contents of the slice, use .as_mut_bitptr().

Modifying the container referenced by this bit-slice may cause its buffer to be reällocated, which would also make any bit-pointers to it invalid.

Original

slice::as_ptr

API Differences

This returns a structure, BitPtr, rather than an actual raw pointer *Bit. The information required to address a bit within a memory element cannot be encoded into a single pointer.

This structure can be converted back into a &BitSlice with the function from_raw_parts.

Examples

use bitvec::prelude::*;

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

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

pub fn as_mut_bitptr(&mut self) -> BitPtr<Mut, O, T>[src]

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

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

Modifying the container referenced by this bit-slice may cause its buffer to be reällocated, which would also make any bit-pointers to it invalid.

Original

slice::as_mut_ptr

API Differences

This returns *mut BitSlice, which is the equivalent 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.

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 {
    bits_ptr.add(i).write(i % 3 == 0);
  }
}
assert_eq!(bits.as_raw_slice()[0], 0b0100_1001);

pub fn as_bitptr_range(&self) -> BitPtrRange<Const, O, T>

Notable traits for BitPtrRange<M, O, T>

impl<M, O, T> Iterator for BitPtrRange<M, O, T> where
    M: Mutability,
    O: BitOrder,
    T: BitStore
type Item = BitPtr<M, O, T>;
[src]

Returns the two raw bit-pointers spanning the bit-slice.

The returned range is half-open, which means that the end bit-pointer points one past the last bit of the bit-slice. This way, an empty bit-slice is represented by two equal bit-pointers, and the difference between the two bit-pointers represents the size of the bit-slice.

See as_bitptr for warnings on using these bit-pointers. The end bit-pointer requires extra caution, as it does not point to a valid bit in the bit-slice.

This function allows a more direct access to bit-pointers, without paying the cost of encoding into a *BitSlice, at the cost of no longer fitting into ordinary Rust interfaces.

Original

slice::as_ptr_range

API Differences

This returns a dedicated structure, rather than a range of BitPtrs, because the traits needed for non-core types to correctly operate in ranges are still unstable. The structure can be converted into a range, but that range will not be an iterator.

Examples

use bitvec::prelude::*;

let bits = bits![0, 1, 0, 0, 1];
let mid_ptr = bits.get(2).unwrap().into_bitptr();
let mut range = bits.as_bitptr_range();
assert!(range.contains(&mid_ptr));
unsafe {
  assert!(!range.next().unwrap().read());
  assert!(range.next_back().unwrap().read())
}

pub fn as_mut_bitptr_range(&mut self) -> BitPtrRange<Mut, O, T>

Notable traits for BitPtrRange<M, O, T>

impl<M, O, T> Iterator for BitPtrRange<M, O, T> where
    M: Mutability,
    O: BitOrder,
    T: BitStore
type Item = BitPtr<M, O, T>;
[src]

Returns the two unsafe mutable bit-pointers spanning the bit-slice.

The returned range is half-open, which means that the end bit-pointer points one past the last bitt of the bit-slice. This way, an empty bit-slice is represented by two equal bit-pointers, and the difference between the two bit-pointers represents the size of the bit-slice.

See as_mut_bitptr for warnings on using these bit-pointers. The end bit-pointer requires extra caution, as it does not point to a valid bit in the bit-slice.

Original

slice::as_mut_ptr_range

API Differences

This returns a dedicated structure, rather than a range of BitPtrs, because the traits needed for non-core types to correctly operate in ranges are still unstable. The structure can be converted into a range, but that range will not be an iterator.

Examples

use bitvec::prelude::*;
use bitvec::ptr as bv_ptr;

let mut data = 0u8;
let bits = data.view_bits_mut::<Msb0>();
for mut bitptr in bits.as_mut_bitptr_range() {
  unsafe { bv_ptr::write(bitptr, true); }
}
assert_eq!(data, !0);

pub fn bit_domain(&self) -> BitDomain<'_, O, T>[src]

Splits the slice into subslices at alias boundaries.

This splits self into the memory locations that it partially fills and the memory locations that it completely fills. The locations that are completely filled may be accessed without any bitvec-imposed alias conditions, while the locations that are only partially filled are left unchanged.

You can read more about the BitDomain splitting in its documentation.

Examples

use bitvec::prelude::*;

let mut data = [0u16; 3];
let all = data.view_bits_mut::<Msb0>();
let (_, rest) = all.split_at_mut(8);
let bits: &BitSlice<Msb0, <u16 as BitStore>::Alias> = &rest[.. 32];

let (head, body, tail) = bits
  .bit_domain()
  .region()
  .unwrap();
assert_eq!(head.len(), 8);
assert_eq!(tail.len(), 8);
let _: &BitSlice<Msb0, <u16 as BitStore>::Alias> = head;
let _: &BitSlice<Msb0, <u16 as BitStore>::Alias> = tail;
let _: &BitSlice<Msb0, u16> = body;

pub fn bit_domain_mut(&mut self) -> BitDomainMut<'_, O, T>[src]

Splits the slice into subslices at alias boundaries.

This splits self into the memory locations that it partially fills and the memory locations that it completely fills. The locations that are completely filled may be accessed without any bitvec-imposed alias conditions, while the locations that are only partially filled are left unchanged.

You can read more about the BitDomainMut splitting in its documentation.

Examples

use bitvec::prelude::*;

let mut data = [0u16; 3];
let all = data.view_bits_mut::<Msb0>();
let (_, rest) = all.split_at_mut(8);
let bits: &mut BitSlice<Msb0, <u16 as BitStore>::Alias>
  = &mut rest[.. 32];

let (head, body, tail) = bits
  .bit_domain_mut()
  .region()
  .unwrap();
assert_eq!(head.len(), 8);
assert_eq!(tail.len(), 8);
let _: &mut BitSlice<Msb0, <u16 as BitStore>::Alias> = head;
let _: &mut BitSlice<Msb0, <u16 as BitStore>::Alias> = tail;
let _: &mut BitSlice<Msb0, u16> = body;

pub fn domain(&self) -> Domain<'_, T>

Notable traits for Domain<'a, T>

impl<'a, T> Iterator for Domain<'a, T> where
    T: BitStore
type Item = T::Mem;
[src]

Views the underlying memory containing the slice, split at alias boundaries.

This splits self into the memory locations that it partially fills and the memory locations that it completely fills. The locations that are completely filled may be accessed without any bitvec-imposed alias conditions, while the locations that are only partially filled are left unchanged.

You can read more about the Domain splitting in its documentation.

Examples

use bitvec::prelude::*;

let mut data = [0u16; 3];
let all = data.view_bits_mut::<Msb0>();
let (_, rest) = all.split_at_mut(8);
let bits: &BitSlice<Msb0, <u16 as BitStore>::Alias> = &rest[.. 32];

let (head, body, tail) = bits
  .domain()
  .region()
  .unwrap();
assert_eq!(body.len(), 1);

let _: &<u16 as BitStore>::Alias = head.unwrap().1;
let _: &<u16 as BitStore>::Alias = tail.unwrap().0;
let _: &[u16] = body;

pub fn domain_mut(&mut self) -> DomainMut<'_, T>[src]

Views the underlying memory containing the slice, split at alias boundaries.

This splits self into the memory locations that it partially fills and the memory locations that it completely fills. The locations that are completely filled may be accessed without any bitvec-imposed alias conditions, while the locations that are only partially filled are left unchanged.

You can read more about the DomainMut splitting in its documentation.

Examples

use bitvec::prelude::*;

let mut data = [0u16; 3];
let all = data.view_bits_mut::<Msb0>();
let (_, rest) = all.split_at_mut(8);
let bits: &mut BitSlice<Msb0, <u16 as BitStore>::Alias> = &mut rest[.. 32];

let (head, body, tail) = bits
  .domain_mut()
  .region()
  .unwrap();
assert_eq!(body.len(), 1);

let _: &<<u16 as BitStore>::Alias as BitStore>::Access = head.unwrap().1;
let _: &<<u16 as BitStore>::Alias as BitStore>::Access = tail.unwrap().0;
let _: &mut [u16] = body;

pub fn as_raw_slice(&self) -> &[T][src]

Views the underlying memory containing the slice.

The returned slice handle views all elements touched by self, and marks them all with self’s current aliasing state. For a more precise view, or one that permits mutation, use .domain() or .domain_mut().

impl<O, T> BitSlice<O, T> where
    O: BitOrder,
    T: BitStore + Radium
[src]

Methods available only when T allows shared mutability.

pub fn set_aliased(&self, index: usize, value: bool)[src]

Writes a new bit at a given index.

This method supports writing through a shared reference to a bit that may be observed by other BitSlice handles. It is only present when the T type parameter supports such shared mutation (measured by the Radium trait).

Parameters

  • &self
  • index: The bit index at which to write. It must be in the range 0 .. self.len().
  • value: The value to be written; true for 1 or false for 0.

Effects

If index is valid, then the bit to which it refers is set to value. If T is an atomic, this will lock the memory bus for the referent address, and may cause stalls.

Panics

This method panics if index is not less than self.len().

Examples

use bitvec::prelude::*;
use core::cell::Cell;

let byte = Cell::new(0u8);
let bits = byte.view_bits::<Msb0>();
let bits_2 = bits;

bits.set_aliased(1, true);
assert!(bits_2[1]);

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

use bitvec::prelude::*;
use core::cell::Cell;

let byte = Cell::new(0u8);
let bits = byte.view_bits::<Lsb0>();
bits.set_aliased(8, false);

pub unsafe fn set_aliased_unchecked(&self, index: usize, value: bool)[src]

Writes a new bit at a given index, without doing bounds checking.

This method supports writing through a shared reference to a bit that may be observed by other BitSlice handles. It is only present when the T type parameter supports such shared mutation (measured by the Radium trait).

Effects

The bit at index is set to value. If index is out of bounds, then the memory access is incorrect, and its behavior is unspecified. If T is an atomic, this will lock the memory bus for the referent address, and may cause stalls.

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

use bitvec::prelude::*;
use core::cell::Cell;

let byte = Cell::new(0u8);
let bits = byte.view_bits::<Msb0>();
let bits_2 = bits;

let (first, _) = bits.split_at(1);
assert_eq!(first.len(), 1);
unsafe { first.set_aliased_unchecked(2, true); }

assert!(bits_2[2]);

pub fn split_at_aliased_mut(&mut self, mid: usize) -> (&mut Self, &mut Self)[src]

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.

impl<O, T> BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

Miscellaneous information.

pub const MAX_BITS: usize[src]

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

pub const MAX_ELTS: usize[src]

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

impl<O, T> BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

pub fn to_bitvec(&self) -> BitVec<O, T::Unalias>

Notable traits for BitVec<O, T>

impl<O, T> Write for BitVec<O, T> where
    O: BitOrder,
    T: BitStore,
    BitSlice<O, T>: BitField
[src]

Copies self into a new BitVec.

This resets any alias markings from self, since the returned buffer is known to be newly allocated and thus unaliased.

Examples

use bitvec::prelude::*;

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

Trait Implementations

impl<O, V> AsMut<BitSlice<O, <V as BitView>::Store>> for BitArray<O, V> where
    O: BitOrder,
    V: BitViewSized
[src]

impl<O, T> AsMut<BitSlice<O, T>> for BitBox<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, T> AsMut<BitSlice<O, T>> for BitVec<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, V> AsRef<BitSlice<O, <V as BitView>::Store>> for BitArray<O, V> where
    O: BitOrder,
    V: BitViewSized
[src]

impl<O, T> AsRef<BitSlice<O, T>> for Iter<'_, O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, T> AsRef<BitSlice<O, T>> for BitBox<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, T> AsRef<BitSlice<O, T>> for Drain<'_, O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, T> AsRef<BitSlice<O, T>> for BitVec<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, T> Binary for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

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.

impl<O, T, Rhs> BitAndAssign<Rhs> for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore,
    Rhs: IntoIterator<Item = bool>, 
[src]

impl<T> BitField for BitSlice<Lsb0, T> where
    T: BitStore
[src]

fn load_le<M>(&self) -> M where
    M: BitMemory
[src]

Loads from self, using little-endian element ordering if self spans more than one T element.

If self.domain() produces a Domain::Region, then:

  • its head element contains the least significant segment of the returned value, in the bits at the most significant edge of the element,
  • its body slice contains successively more-significant segments, and
  • its tail element contains the most significant segment of the returned value, in the bits at the least significant edge of the element.

If the domain is an Enclave, then the referent element is merely loaded, shifted, and masked; no recombination of segments is necessary.

Examples

use bitvec::prelude::*;

let mut data = [0u8; 3];
data.view_bits_mut::<Lsb0>()[5 .. 21].store_le::<u16>(
  0b1_1011_0100_1100_011
//  K LMNO PQRS TUVW XYZ
);
assert_eq!(data, [
  0b011_00000, 0b0100_1100, 0b000_1_1011
//  XYZ          PQRS TUVW        K LMNO
]);
let val = data.view_bits::<Lsb0>()[5 .. 21].load_le::<u16>();
assert_eq!(
  val,
  0b1_1011_0100_1100_011,
//  K LMNO PQRS TUVW XYZ
);

fn load_be<M>(&self) -> M where
    M: BitMemory
[src]

Loads from self, using big-endian element ordering if self spans more than one T element.

If self.domain() produces a Domain::Region, then:

  • its head element contains the most significant segment of the returned value, in the bits at the most significant edge of the element,
  • its body slice contains successively less-significant segments, and
  • its tail element contains the least significant segment of the returned value, in the bits at the least significant edge of the element.

If the domain is an Enclave, then the referent element is merely loaded, shifted, and masked; no recombination of segments is necessary.

Examples

use bitvec::prelude::*;

let mut data = [0u8; 3];
data.view_bits_mut::<Lsb0>()[5 .. 21].store_be::<u16>(
  0b011_1100_0100_1011_1,
//  KLM NOPQ RSTU VWXY Z
);
assert_eq!(data, [
  0b011_00000, 0b1100_0100, 0b000_1011_1
//  KLM          NOPQ RSTU        VWXY Z
]);
let val = data.view_bits::<Lsb0>()[5 .. 21].load_be::<u16>();
assert_eq!(
  val,
  0b011_1100_0100_1011_1,
//  KLM NOPQ RSTU VWXY Z
);

fn store_le<M>(&mut self, value: M) where
    M: BitMemory
[src]

Stores into self, using little-endian element ordering if self spans more than one T element.

If self.domain() produces a Domain::Region, then:

  • its head element receives the least significant segment of value, in the bits at the most significant edge of the element,
  • its body slice receives successively more-significant segments of value, and
  • its tail element receives the most significant segment of value, in the bits at the least significant edge of the element.

If the domain is an Enclave, then value is shifted into place and written without any segmentation.

Examples

See the documentation for <BitSlice<Lsb0, u8> as BitField>::load_le.

fn store_be<M>(&mut self, value: M) where
    M: BitMemory
[src]

Stores into self, using big-endian element ordering if self spans more than one T element.

If self.domain() produces a Domain::Region, then:

  • its head element receives the most significant segment of value, in the bits at the most significant edge of the element,
  • its body slice receives successively less-significant segments of value, and
  • its tail element receives the least significant segment of value, in the bits at the least significant edge of the element.

If the domain is an Enclave, then value is shifted into place and written without any segmentation.

Examples

See the documentation for <BitSlice<Lsb0, u8> as BitField>::load_be.

impl<T> BitField for BitSlice<Msb0, T> where
    T: BitStore
[src]

fn load_le<M>(&self) -> M where
    M: BitMemory
[src]

Loads from self, using little-endian element ordering if self spans more than one T element.

If self.domain() produces a Domain::Region, then:

  • its head element contains the least significant segment of the returned value, in the bits at the least significant edge of the element,
  • its body slice contains successively more-significant segments, and
  • its tail element contains the most significant segment of the returned value, in the bits at the most significant edge of the element.

If the domain is an Enclave, then the referent element is merely loaded, shifted, and masked; no recombination of segments is necessary.

Examples

use bitvec::prelude::*;

let mut data = [0u8; 3];
data.view_bits_mut::<Msb0>()[5 .. 21].store_le::<u16>(
  0b1_1011_0100_1100_110
//  K LMNO PQRS TUVW XYZ
);
assert_eq!(data, [
  0b00000_110, 0b0100_1100, 0b1_1011_000
//        XYZ    PQRS TUVW    K LMNO
]);
let val = data.view_bits::<Msb0>()[5 .. 21].load_le::<u16>();
assert_eq!(
  val,
  0b1_1011_0100_1100_110,
//  K LMNO PQRS TUVW XYZ
);

fn load_be<M>(&self) -> M where
    M: BitMemory
[src]

Loads from self, using big-endian element ordering if self spans more than one element T.

If self.domain() produces a Domain::Region, then:

  • its head element contains the most significant segment of the returned value, in the bits at the least significant edge of the element,
  • its body slice contains successively less-significant segments, and
  • its tail element contains the least significant segment of the returned value, in the bits at the most significant edge of the element.

If the domain is an Enclave, then the referent element is merely loaded, shifted, and masked; no recombination of segments is necessary.

Examples

use bitvec::prelude::*;

let mut data = [0u8; 3];
data.view_bits_mut::<Msb0>()[5 .. 21].store_be::<u16>(
  0b110_1011_1100_0100_1
//  KLM NOPQ RSTU VWXY Z
);
assert_eq!(data, [
  0b00000_110, 0b1011_1100, 0b0100_1_000
//        KLM    NOPQ RSTU    VWXY Z
]);
let val = data.view_bits::<Msb0>()[5 .. 21].load_be::<u16>();
assert_eq!(
  val,
  0b110_1011_1100_0100_1,
//  KLM NOPQ RSTU VWXY Z
);

fn store_le<M>(&mut self, value: M) where
    M: BitMemory
[src]

Stores into self, using little-endian element ordering if self spans more than one T element.

If self.domain() produces a Domain::Region, then:

  • its head element receives the least significant segment of value, in the bits at the least significant edge of the element,
  • its body slice receives successively more-significant segments of value, and
  • its tail element receives the most significant segment of value, in the bits at the most significant edge of the element.

If the domain is an Enclave, then value is shifted into place and written without any segmentation.

Examples

See the documentation for <BitSlice<Msb0, u8> as BitField>::load_le.

fn store_be<M>(&mut self, value: M) where
    M: BitMemory
[src]

Stores into self, using big-endian element ordering if self spans more than one T element.

If self.domain() produces a Domain::Region, then:

  • its head element receives the most significant segment of value, in the bits at the least significant edge of the element,
  • its body slice receives successively less-significant segments of value, and
  • its tail element receives the least significant segment of value, in the bits at the most significant edge of the element.

If the domain is an Enclave, then value is shifted into place and written without any segmentation.

Examples

See the documentation for <BitSlice<Lsb0, u8> as BitField>::load_be.

impl<O, T, Rhs> BitOrAssign<Rhs> for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore,
    Rhs: IntoIterator<Item = bool>, 
[src]

impl<O, T, Rhs> BitXorAssign<Rhs> for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore,
    Rhs: IntoIterator<Item = bool>, 
[src]

impl<O, V> Borrow<BitSlice<O, <V as BitView>::Store>> for BitArray<O, V> where
    O: BitOrder,
    V: BitViewSized
[src]

impl<O, T> Borrow<BitSlice<O, T>> for BitBox<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, T> Borrow<BitSlice<O, T>> for BitVec<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, V> BorrowMut<BitSlice<O, <V as BitView>::Store>> for BitArray<O, V> where
    O: BitOrder,
    V: BitViewSized
[src]

impl<O, T> BorrowMut<BitSlice<O, T>> for BitBox<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, T> BorrowMut<BitSlice<O, T>> for BitVec<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, T> Debug for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, T> Default for &BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, T> Default for &mut BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, T> Display for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, T> Eq for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<'a, O, T> From<&'a BitSlice<O, T>> for BitBox<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<'a, O, T> From<&'a BitSlice<O, T>> for BitVec<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<'a, O, T> From<&'a mut BitSlice<O, T>> for BitVec<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, T> Hash for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

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

impl<O, T> Index<Range<usize>> for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

type Output = Self

The returned type after indexing.

impl<O, T> Index<RangeFrom<usize>> for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

type Output = Self

The returned type after indexing.

impl<O, T> Index<RangeFull> for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

type Output = Self

The returned type after indexing.

impl<O, T> Index<RangeInclusive<usize>> for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

type Output = Self

The returned type after indexing.

impl<O, T> Index<RangeTo<usize>> for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

type Output = Self

The returned type after indexing.

impl<O, T> Index<RangeToInclusive<usize>> for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

type Output = Self

The returned type after indexing.

impl<O, T> Index<usize> for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

type Output = bool

The returned type after indexing.

fn index(&self, index: usize) -> &Self::Output[src]

Looks up a single bit by semantic index.

Examples

use bitvec::prelude::*;

let bits = bits![Msb0, u8; 0, 1, 0];
assert!(!bits[0]); // -----^  |  |
assert!( bits[1]); // --------^  |
assert!(!bits[2]); // -----------^

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]; // --------^

impl<O, T> IndexMut<Range<usize>> for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, T> IndexMut<RangeFrom<usize>> for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, T> IndexMut<RangeFull> for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, T> IndexMut<RangeInclusive<usize>> for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, T> IndexMut<RangeTo<usize>> for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O, T> IndexMut<RangeToInclusive<usize>> for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<'a, O, T> IntoIterator for &'a BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

type IntoIter = Iter<'a, O, T>

Which kind of iterator are we turning this into?

type Item = <Self::IntoIter as Iterator>::Item

The type of the elements being iterated over.

impl<'a, O, T> IntoIterator for &'a mut BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

type IntoIter = IterMut<'a, O, T>

Which kind of iterator are we turning this into?

type Item = <Self::IntoIter as Iterator>::Item

The type of the elements being iterated over.

impl<O, T> LowerHex for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

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.

impl<'a, O, T> Not for &'a mut BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

type Output = Self

The resulting type after applying the ! operator.

impl<O, T> Octal for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

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.

impl<O, T> Ord for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

impl<O1, O2, T1, T2> PartialEq<&'_ BitSlice<O2, T2>> for BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<O1, O2, T1, T2> PartialEq<&'_ mut BitSlice<O2, T2>> for BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<O1, O2, V, T> PartialEq<BitArray<O2, V>> for BitSlice<O1, T> where
    O1: BitOrder,
    O2: BitOrder,
    V: BitViewSized,
    T: BitStore
[src]

impl<O1, O2, T1, T2> PartialEq<BitBox<O2, T2>> for BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<O1, O2, T1, T2> PartialEq<BitBox<O2, T2>> for &BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<O1, O2, T1, T2> PartialEq<BitBox<O2, T2>> for &mut BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<O1, O2, T1, T2> PartialEq<BitSlice<O2, T2>> for BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

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.

impl<O1, O2, T1, T2> PartialEq<BitSlice<O2, T2>> for &BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<O1, O2, T1, T2> PartialEq<BitSlice<O2, T2>> for &mut BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<O1, O2, T1, T2> PartialEq<BitVec<O2, T2>> for BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<O1, O2, T1, T2> PartialEq<BitVec<O2, T2>> for &BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<O1, O2, T1, T2> PartialEq<BitVec<O2, T2>> for &mut BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<O1, O2, T1, T2> PartialOrd<&'_ BitSlice<O2, T2>> for BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<O1, O2, T1, T2> PartialOrd<&'_ BitSlice<O2, T2>> for &mut BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<O1, O2, T1, T2> PartialOrd<&'_ mut BitSlice<O2, T2>> for BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<O1, O2, T1, T2> PartialOrd<&'_ mut BitSlice<O2, T2>> for &BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<O, V, T> PartialOrd<BitArray<O, V>> for BitSlice<O, T> where
    O: BitOrder,
    V: BitViewSized,
    T: BitStore
[src]

impl<O1, O2, T1, T2> PartialOrd<BitBox<O2, T2>> for BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<'a, O1, O2, T1, T2> PartialOrd<BitBox<O2, T2>> for &'a BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<'a, O1, O2, T1, T2> PartialOrd<BitBox<O2, T2>> for &'a mut BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<O1, O2, T1, T2> PartialOrd<BitSlice<O2, T2>> for BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

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.

impl<O1, O2, T1, T2> PartialOrd<BitSlice<O2, T2>> for &BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<O1, O2, T1, T2> PartialOrd<BitSlice<O2, T2>> for &mut BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<O1, O2, T1, T2> PartialOrd<BitVec<O2, T2>> for BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<'a, O1, O2, T1, T2> PartialOrd<BitVec<O2, T2>> for &'a BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<'a, O1, O2, T1, T2> PartialOrd<BitVec<O2, T2>> for &'a mut BitSlice<O1, T1> where
    O1: BitOrder,
    O2: BitOrder,
    T1: BitStore,
    T2: BitStore
[src]

impl<'a, O, T> Read for &'a BitSlice<O, T> where
    O: BitOrder,
    T: BitStore,
    BitSlice<O, T>: BitField
[src]

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.

The implementation uses BitField::load_be.

impl<O, T> Send for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore + Sync
[src]

Conditionally mark BitSlice as Send based on its T type argument.

In order for BitSlice to be Send (that is, &mut BitSlice can be moved across thread boundaries), it must be capable of writing to memory without invalidating any other &BitSlice handles that alias the same memory address.

This is true when T is one of the fundamental integers, because no other &BitSlice handle is able to observe mutations, or when T is a BitSafe type that implements atomic read-modify-write instructions, because other &BitSlice types will be protected from data races by the hardware.

When T is a non-atomic BitSafe type, BitSlice cannot be Send, because one &mut BitSlice moved across a thread boundary may cause mutation that another &BitSlice may observe, but the instructions used to access memory do not guard against data races.

A &mut BitSlice over aliased memory addresses is equivalent to either a &Cell or &AtomicT, depending on what the radium crate makes available for the register width.

impl<O, T> Serialize for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore,
    T::Mem: Serialize
[src]

impl<O, T> Sync for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore + Sync
[src]

Conditionally mark BitSlice as Sync based on its T type argument.

In order for BitSlice to be Sync (that is, &BitSlice can be copied across thread boundaries), it must be capable of reading from memory without being invalidated by any other &mut BitSlice handles that alias the same memory address.

This is true when T is one of the fundamental integers, because no other &mut BitSlice handle can exist to effect mutations, or when T is a BitSafe type that implements atomic read-modify-write instructions, because it will guard against other &mut BitSlice modifications in hardware.

When T is a non-atomic BitSafe type, BitSlice cannot be Sync, because one &BitSlice moved across a thread boundary may read from memory that is modified by the originally-owning thread, but the instructions used to access memory do not guard against such data races.

A &BitSlice over aliased memory addresses is equivalent to either a &Cell or &AtomicT, depending on what the radium crate makes available for the register width.

impl<O, T> ToOwned for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

type Owned = BitVec<O, T>

The resulting type after obtaining ownership.

impl<'a, O, T> TryFrom<&'a [T]> for &'a BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

type Error = &'a [T]

The type returned in the event of a conversion error.

impl<'a, O, T> TryFrom<&'a BitSlice<O, T>> for BitArray<O, T> where
    O: BitOrder,
    T: BitStore
[src]

type Error = TryFromBitSliceError<'a, O, T>

The type returned in the event of a conversion error.

impl<'a, O, T, const N: usize> TryFrom<&'a BitSlice<O, T>> for BitArray<O, [T; N]> where
    O: BitOrder,
    T: BitStore
[src]

type Error = TryFromBitSliceError<'a, O, T>

The type returned in the event of a conversion error.

impl<'a, O, T> TryFrom<&'a BitSlice<O, T>> for &'a BitArray<O, T> where
    O: BitOrder,
    T: BitStore
[src]

type Error = TryFromBitSliceError<'a, O, T>

The type returned in the event of a conversion error.

impl<'a, O, T, const N: usize> TryFrom<&'a BitSlice<O, T>> for &'a BitArray<O, [T; N]> where
    O: BitOrder,
    T: BitStore
[src]

type Error = TryFromBitSliceError<'a, O, T>

The type returned in the event of a conversion error.

impl<'a, O, T> TryFrom<&'a mut [T]> for &'a mut BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

type Error = &'a mut [T]

The type returned in the event of a conversion error.

impl<'a, O, T> TryFrom<&'a mut BitSlice<O, T>> for &'a mut BitArray<O, T> where
    O: BitOrder,
    T: BitStore
[src]

type Error = TryFromBitSliceError<'a, O, T>

The type returned in the event of a conversion error.

impl<'a, O, T, const N: usize> TryFrom<&'a mut BitSlice<O, T>> for &'a mut BitArray<O, [T; N]> where
    O: BitOrder,
    T: BitStore
[src]

type Error = TryFromBitSliceError<'a, O, T>

The type returned in the event of a conversion error.

impl<O, T> UpperHex for BitSlice<O, T> where
    O: BitOrder,
    T: BitStore
[src]

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.

impl<'a, O, T> Write for &'a mut BitSlice<O, T> where
    O: BitOrder,
    T: BitStore,
    BitSlice<O, T>: BitField
[src]

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.

The implementation uses BitField::store_be.

Auto Trait Implementations

impl<O, T> RefUnwindSafe for BitSlice<O, T> where
    O: RefUnwindSafe,
    T: RefUnwindSafe

impl<O = Lsb0, T = usize> !Sized for BitSlice<O, T>

impl<O, T> Unpin for BitSlice<O, T> where
    O: Unpin,
    T: Unpin

impl<O, T> UnwindSafe for BitSlice<O, T> where
    O: UnwindSafe,
    T: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Conv for T[src]

impl<T> FmtForward for T[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Pipe for T where
    T: ?Sized
[src]

impl<T> Tap for T[src]

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T> TryConv for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.