blob: 37a7cb3a8696ac2aef7a75c887e1a641605aa0d0 [file] [log] [blame] [view]
# Bit-Precision Array Immediate
This type is a wrapper over the [array fundamental][0] `[T; N]` that views its
contents as a [`BitSlice`] region. As an array, it can be held directly by value
and does not require an indirection such as the `&BitSlice` reference.
## Original
[`[T; N]`](https://doc.rust-lang.org/std/primitive.array.html)
## Usage
`BitArray` is a Rust analogue of the C++ [`std::bitset<N>`] container. However,
restrictions in the Rust type system do not allow specifying exact bit lengths
in the array type. Instead, it must specify a storage array that can contain all
the bits you want.
Because `BitArray` is a plain-old-data object, its fields are public and it has
no restrictions on its interior value. You can freely access the interior
storage and move data in or out of the `BitArray` type with no cost.
As a convenience, the [`BitArr!`] type-constructor macro can produce correct
type definitions from an exact bit count and your memory-layout type parameters.
Values of that type can then be built from the [`bitarr!`] *value*-constructor
macro:
```rust
use bitvec::prelude::*;
type Example = BitArr!(for 43, in u32, Msb0);
let example: Example = bitarr!(u32, Msb0; 1; 33);
struct HasBitfield {
inner: Example,
}
let ex2 = HasBitfield {
inner: BitArray::new([1, 2]),
};
```
Note that the actual type of the `Example` alias is `BitArray<[u32; 2], Msb0>`,
as that is `ceil(32, 43)`, so the `bitarr!` macro can accept any number of bits
in `33 .. 65` and will produce a value of the correct type.
## Type Parameters
`BitArray` differs from the other data structures in the crate in that it does
not take a `T: BitStore` parameter, but rather takes `A: BitViewSized`. That
trait is implemented by all `T: BitStore` scalars and all `[T; N]` arrays of
them, and provides the logic to translate the aggregate storage into the memory
sequence that the crate expects.
As with all `BitSlice` regions, the `O: BitOrder` parameter specifies the
ordering of bits within a single `A::Store` element.
## Future API Changes
Exact bit lengths cannot be encoded into the `BitArray` type until the
const-generics system in the compiler can allow type-level computation on type
integers. When this stabilizes, `bitvec` will issue a major upgrade that
replaces the `BitArray<A, O>` definition with `BitArray<T, O, const N: usize>`
and match the C++ `std::bitset<N>` definition.
## Large Bit-Arrays
As with ordinary arrays, large arrays can be expensive to move by value, and
should generally be preferred to have static locations such as actual `static`
bindings, a long lifetime in a low stack frame, or a heap allocation. While you
certainly can `Box<[BitArray<A, O>]>` directly, you may instead prefer the
[`BitBox`] or [`BitVec`] heap-allocated regions. These offer the same storage
behavior and are better optimized than `Box<BitArray>` for working with the
contained `BitSlice` region.
## Examples
```rust
use bitvec::prelude::*;
const WELL_KNOWN: BitArr!(for 16, in u8, Lsb0) = BitArray::<[u8; 2], Lsb0> {
data: *b"bv",
..BitArray::ZERO
};
struct HasBitfields {
inner: BitArr!(for 50, in u8, Lsb0),
}
impl HasBitfields {
fn new() -> Self {
Self {
inner: bitarr!(u8, Lsb0; 0; 50),
}
}
fn some_field(&self) -> &BitSlice<u8, Lsb0> {
&self.inner[2 .. 52]
}
}
```
[0]: https://doc.rust-lang.org/std/primitive.array.html
[`BitArr!`]: macro@crate::BitArr
[`BitBox`]: crate::boxed::BitBox
[`BitSlice`]: crate::slice::BitSlice
[`BitVec`]: crate::vec::BitVec
[`bitarr!`]: macro@crate::bitarr
[`std::bitset<N>`]: https://en.cppreference.com/w/cpp/utility/bitset