New:Socket for Asana Is Now Available.Learn more
Get Started

bitvec

Package Overview
Dependencies
Maintainers
0
Versions
61
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bitvec - cargo Package Compare versions

Package version was removed
This package version has been unpublished, mostly likely due to security reasons
Comparing version
0.8.0
to
0.9.0-e2018
+5
.cargo_vcs_info.json
{
"git": {
"sha1": "b9bf6ee8b924493adbb1247decda1c02fed217d0"
}
}
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
indent_size = 2
indent_style = space
[*.rs]
indent_size = 4
indent_style = tab
[*.toml]
indent_size = 8
indent_style = tab
[*.yml]
indent_size = 2
indent_style = space
language: rust
sudo: required
rust:
- stable
- beta
- nightly
matrix:
allow_failures:
- rust: nightly
# codecov
addons:
apt:
packages:
- libcurl4-openssl-dev
- libelf-dev
- libdw-dev
- cmake
- gcc
- binutils-dev
- libiberty-dev
# codecov
after_success: |
wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
tar xzf master.tar.gz &&
cd kcov-master &&
mkdir build &&
cd build &&
cmake .. &&
make &&
make install DESTDIR=../../kcov-build &&
cd ../.. &&
rm -rf kcov-master &&
for file in target/debug/bitvec-*[^\.d]; do mkdir -p "target/cov/$(basename $file)"; ./kcov-build/usr/local/bin/kcov --exclude-pattern=/.cargo,/usr/lib --verify "target/cov/$(basename $file)" "$file"; done &&
bash <(curl -s https://codecov.io/bash) &&
echo "Uploaded code coverage"
/*! Bit Cursors
`BitVec` is parametric over any ordering of bits within an element. The `Cursor`
trait maps a cursor position to a bit index within an element, and the order of
traversal over an element.
The only requirement on implementors of `Cursor` is that the transform function
from cursor to index is *total* (every integer in the range `0 .. T::BITS` is
used), *unique* (each cursor maps to one and only one index, and each index is
mapped by one and only one cursor). Contiguity is not required.
!*/
use super::bits::Bits;
/// Travels an element starting at the Most Significant Bit and ending at the
/// Least Significant Bit.
pub struct BigEndian;
/// Travels an element starting at the Least Significant Bit and ending at the
/// Most Significant Bit.
pub struct LittleEndian;
/** A cursor over an element.
# Usage
`BitVec` stores semantic count, not a cursor into an element, as its `bits`
value. The methods on `Cursor` all return a cursor into a storage element.
- `curr` computes the bit index of the count given. In Little-Endian order, this
is the identity function (bit indices count up “left” from LSb), and in
Big-Endian order, this subtracts the count given from `T::MASK` (bit indices
count down “right” from MSb).
- `next` computes the next index forward from the count given. In Little-Endian
order, this increments (moving up from LSb towards MSb); in Big-Endian order,
this decrements (moving down from MSb towards LSb).
- `prev` computes the previous index backward from the count given. In
Little-Endian order, this decrements (moving down towards LSb from MSb); in
Big-Endian order, this increments (moving up towards MSb from LSb).
- `jump` computes a number of whole elements to move, as well as the bit index
within the destination element of the target bit.
You should use `curr` to look up a bit at a known point, such as when indexing a
`BitVec`; you should use `next` or `prev` to implement push, pop, and iteration;
you should use `jump` only to implement striding iterators in a manner faster
than the default (which just repeatedly calls `next` and drops most yielded
values).
# Notes
All functions *take* a semantic count into a storage element, which will always
move upwards from zero, but all functions *return* an actual index to a specific
bit in the element achieved by shifting right and masking off all but the LSb of
the output. The output is *not* a semantic count, and does not need converted to
an index with `curr`. It therefore cannot be stored as the new semantic count
during a mutation. The caller is responsible for maintaining count status.
`next` and `prev` signal when they cross the boundary of a storage element. If
their second return value is true, then the first return value is an index into
the storage element either after (`next`) or before (`prev`) the element for
which the input count referred. The caller is responsible for ensuring that they
use the returned index in the correct storage element by inspecting this flag
and moving their selection accordingly.
`jump` returns the number of storage elements the caller will have to move their
cursor before indexing. `next` and `prev` can only move zero or one elements, so
their flag is a `bool` rather than an `isize`. The order swap for `jump` is
because the number of elements to move is expected to be a more significant part
of its return value than the edge flag is in `next` and `prev`.
**/
pub trait Cursor {
/// Compute the bit index at a given count.
///
/// In Little-Endian, this is a no-op; in Big-Endian, it subtracts the index
/// from `T::MASK` (the maximum value).
fn curr<T: Bits>(count: u8) -> u8;
/// Compute the semantic index that logically follows the given index.
///
/// The first value returned must be passed into `curr` in order to index
/// into an element. The second value indicates whether the increment points
/// into a different element.
fn next<T: Bits>(count: u8) -> (u8, bool) {
let next = count.wrapping_add(1) & T::MASK;
let wrap = next == 0;
(next, wrap)
}
/// Compute the semantic index that logically precedes the given index.
///
/// The first value returned must be passed into `curr` in order to index
/// into an element. The second value indicates whether the decrement points
/// into a different element.
fn prev<T: Bits>(count: u8) -> (u8, bool) {
let (next, wrap) = count.overflowing_sub(1);
(next & T::MASK, wrap)
}
/// Computes the bit index at a given semantic offset from the current
/// cursor.
///
/// Returns a tuple where the first value is the number of whole storage
/// elements to move, and the second is the bit index within the element.
fn jump<T: Bits>(count: u8, offset: isize) -> (isize, u8) {
assert!(count < T::WIDTH, "Bit count out of range for the storage type");
// Add offset to *count*, not to the current bit index, because this
// math doesn't know how to move around in an ordering. The offset is
// signed in count order, not Endian order.
// Subtraction can never fail, because count is always >= 0 and
// `0 - isize::MIN` is `isize::MIN`, which does not overflow.
// In a non-overflowing addition, the result will be the position of
// the target bit
match (count as isize).overflowing_add(offset) {
// If the addition overflows, then the offset is positive. Add as
// unsigned and use that.
// Note that this is guaranteed not to overflow `usize::MAX`
// because converting two positive signed integers to unsigned
// doubles the domain, which will always be enormously wider than
// the domain of count.
(_, true) => {
let far = Self::curr::<T>(count) as usize + offset as usize;
// The number of elements advanced is, conveniently, the number
// of bits advanced integer-divided by the number of bits in
// the elements, which even more conveniently, is equivalent to
// right-shift by the number of bits required to index an
// element. Note that we don't cast until *after* the shift, in
// order to ensure that it is zero-filled at the high bits.
let elements = (far >> T::BITS) as isize;
// The new bit position of the cursor is the new position
// modulo the number of bits in the element (equivalent to
// bit-and of the provided mask).
let pos = (far & (T::MASK as usize)) as u8;
(elements, pos)
},
// If `far` is negative, then the jump leaves the element going
// backward. If `far` is greater than `T::MASK`, then the jump
// leaves the element going forward.
(far, _) if far < 0 || far > T::MASK as isize => {
let elements = far >> T::BITS;
let pos = (far & (T::MASK as isize)) as u8;
(elements, Self::curr::<T>(pos))
},
// Otherwise, `far` is the *bit count* in the current element. It
// must still be converted from count to bit index.
(far, _) => {
(0, Self::curr::<T>(far as u8))
},
}
}
#[doc(hidden)]
const TY: &'static str = "";
}
impl Cursor for BigEndian {
fn curr<T: Bits>(count: u8) -> u8 {
assert!(count < T::WIDTH, "Index out of range of the storage type");
T::MASK - count
}
const TY: &'static str = "BigEndian";
}
impl Cursor for LittleEndian {
fn curr<T: Bits>(count: u8) -> u8 {
assert!(count < T::WIDTH, "Index out of range of the storage type");
count
}
const TY: &'static str = "LittleEndian";
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn incr_edge() {
assert_eq!(LittleEndian::next::<u8>(7), (0, true));
assert_eq!(BigEndian::next::<u8>(7), (0, true));
assert_eq!(LittleEndian::next::<u16>(15), (0, true));
assert_eq!(BigEndian::next::<u16>(15), (0, true));
assert_eq!(LittleEndian::next::<u32>(31), (0, true));
assert_eq!(BigEndian::next::<u32>(31), (0, true));
assert_eq!(LittleEndian::next::<u64>(63), (0, true));
assert_eq!(BigEndian::next::<u64>(63), (0, true));
}
#[test]
fn decr_edge() {
assert_eq!(LittleEndian::prev::<u8>(0), (7, true));
assert_eq!(BigEndian::prev::<u8>(0), (7, true));
assert_eq!(LittleEndian::prev::<u16>(0), (15, true));
assert_eq!(BigEndian::prev::<u16>(0), (15, true));
assert_eq!(LittleEndian::prev::<u32>(0), (31, true));
assert_eq!(BigEndian::prev::<u32>(0), (31, true));
assert_eq!(LittleEndian::prev::<u64>(0), (63, true));
assert_eq!(BigEndian::prev::<u64>(0), (63, true));
}
#[test]
fn jump_inside_elt() {
// TODO(myrrlyn): test the other two types.
let (elt, bit) = LittleEndian::jump::<u8>(5, 2);
assert_eq!(elt, 0);
assert_eq!(bit, 7);
// Counts start from 0, so count 5 is the SIXTH bit
let (elt, bit) = BigEndian::jump::<u8>(5, 2);
assert_eq!(elt, 0);
assert_eq!(bit, 0);
let (elt, bit) = LittleEndian::jump::<u32>(20, 8);
assert_eq!(elt, 0);
assert_eq!(bit, 28);
// In Big-Endian order, count 20 is bit 11, and moving that backward by
// 8 is addition, up to 19.
let (elt, bit) = BigEndian::jump::<u32>(20, -8);
assert_eq!(elt, 0);
assert_eq!(bit, 19);
}
#[test]
fn jump_backwards() {
// TODO(myrrlyn): Test the other three types.
let (elt, bit) = LittleEndian::jump::<u32>(10, -15);
assert_eq!(elt, -1);
// Moving backwards through LE starts at MSb and decrements
// 10 - 10 is 0, 0 - 1 is 31, 31 - 4 is 27
assert_eq!(bit, 27);
let (elt, bit) = BigEndian::jump::<u32>(10, -15);
assert_eq!(elt, -1);
// Moving backwards through BE starts at LSb and increments
// 10 - 10 is count 0 (bit 31), then the cursor crosses the boundary
// and counts 0, 1, 2, 3, 4.
assert_eq!(bit, 4);
}
#[test]
fn jump_forwards() {
// TODO(myrrlyn): Test the other three types.
let (elt, bit) = LittleEndian::jump::<u32>(25, 10);
assert_eq!(elt, 1);
assert_eq!(bit, 3);
let (elt, bit) = BigEndian::jump::<u32>(25, 10);
assert_eq!(elt, 1);
// Moving forwards through BE starts at MSb and decrements. 25 + 6 is
// count 31 (bit 0), then the cursor crosses the boundary and counts
// 31, 30, 29, 28.
assert_eq!(bit, 28);
}
#[test]
fn jump_overflow() {
// TODO(myrrlyn): Test the other three types.
// Force an overflowing stride. We expect the destination bit *count*
// to be one less than the starting point (which on BigEndian will be
// `MASK - start - 1`), and the elements skipped to be
// `isize::MIN >> BITS` (an overflowing isize add will set the high bit
// as the `usize` repr).
let start = 20;
let (elt, bit) = LittleEndian::jump::<u32>(start, core::isize::MAX);
assert_eq!(elt as usize, core::isize::MIN as usize >> u32::BITS);
assert_eq!(bit, start - 1);
let (elt, bit) = BigEndian::jump::<u32>(start, core::isize::MAX);
assert_eq!(elt as usize, core::isize::MIN as usize >> u32::BITS);
assert_eq!(bit, BigEndian::curr::<u32>(start) - 1);
}
#[test]
fn curr_reversible() {
for n in 0 .. 8 {
assert_eq!(n, BigEndian::curr::<u8>(BigEndian::curr::<u8>(n)));
}
for n in 0 .. 16 {
assert_eq!(n, BigEndian::curr::<u16>(BigEndian::curr::<u16>(n)));
}
for n in 0 .. 32 {
assert_eq!(n, BigEndian::curr::<u32>(BigEndian::curr::<u32>(n)));
}
for n in 0 .. 64 {
assert_eq!(n, BigEndian::curr::<u64>(BigEndian::curr::<u64>(n)));
}
for n in 0 .. 8 {
assert_eq!(n, LittleEndian::curr::<u8>(LittleEndian::curr::<u8>(n)));
}
for n in 0 .. 16 {
assert_eq!(n, LittleEndian::curr::<u16>(LittleEndian::curr::<u16>(n)));
}
for n in 0 .. 32 {
assert_eq!(n, LittleEndian::curr::<u32>(LittleEndian::curr::<u32>(n)));
}
for n in 0 .. 64 {
assert_eq!(n, LittleEndian::curr::<u64>(LittleEndian::curr::<u64>(n)));
}
}
}
+20
-2

@@ -14,4 +14,5 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO

[package]
edition = "2018"
name = "bitvec"
version = "0.8.0"
version = "0.9.0-e2018"
authors = ["myrrlyn <myrrlyn@outlook.com>"]

@@ -21,3 +22,6 @@ description = "A crate for manipulating memory, bit by bit"

documentation = "https://docs.rs/bitvec"
license-file = "LICENSE.txt"
readme = "README.md"
keywords = ["bits", "bitvec"]
categories = ["data-structures", "embedded", "no-std", "rust-patterns"]
license = "MIT"
repository = "https://github.com/myrrlyn/bitvec"

@@ -31,1 +35,15 @@

std = ["alloc"]
testing = ["std"]
[badges.codecov]
branch = "master"
repository = "myrrlyn/bitvec"
service = "github"
[badges.is-it-maintained-issue-resolution]
repository = "myrrlyn/bitvec"
[badges.is-it-maintained-open-issues]
repository = "myrrlyn/bitvec"
[badges.maintenance]
status = "actively-developed"

@@ -5,2 +5,11 @@ # Changelog

## 0.9.0
### Changed
- The trait `Endian` has been renamed to `Cursor`, and all type variables
`E: Endian` have been renamed to `C: Cursor`.
- The `Bits` trait is no longer bound by `Default`.
## 0.8.0

@@ -7,0 +16,0 @@

+0
-3

@@ -5,5 +5,2 @@ /*! Prove that the example code in `README.md` executes.

#[cfg(feature = "alloc")]
extern crate bitvec;
#[cfg(feature = "alloc")]
use bitvec::*;

@@ -10,0 +7,0 @@

@@ -26,5 +26,2 @@ /*! Sieve of Eratosthenes

#[cfg(feature = "alloc")]
extern crate bitvec;
#[cfg(feature = "alloc")]
use bitvec::{

@@ -31,0 +28,0 @@ BitVec,

@@ -10,5 +10,2 @@ /*! Demonstrates construction and use of a big-endian, u8, `BitVec`

#[cfg(feature = "alloc")]
extern crate bitvec;
#[cfg(feature = "alloc")]
use bitvec::{

@@ -22,3 +19,3 @@ // `bitvec!` macro

// element-traversal trait (you shouldn’t explicitly need this)
Endian,
Cursor,
// directionality type marker (the default for `BitVec`; you will rarely

@@ -98,3 +95,3 @@ // explicitly need this)

fn render<E: Endian, T: Bits>(bv: &BitVec<E, T>) {
fn render<C: Cursor, T: Bits>(bv: &BitVec<C, T>) {
println!("Memory information: {} {} {}", bv.elts(), bv.bits(), bv.len());

@@ -101,0 +98,0 @@ println!("Print out the semantic contents");

@@ -14,3 +14,3 @@ # `BitVec` – Managing memory bit by bit

`BitVec` is generic over an ordering cursor, using the trait `Endian`, and the
`BitVec` is generic over an ordering cursor, using the trait `Cursor`, and the
primitive type, using the trait `Bits`. This means that `BitVec` structures can

@@ -77,3 +77,3 @@ be built with a great deal of flexibility over how they manage their memory and

- `BitSlice<E: Endian, T: Bits>` – the actual bit-slice reference type It is
- `BitSlice<C: Cursor, T: Bits>` – the actual bit-slice reference type It is
generic over a cursor type (`E`) and storage type (`T`). Note that `BitSlice`

@@ -89,8 +89,8 @@ is unsized, and can never be held directly; it must always be behind a

- `BitVec<E: Endian, T: Bits>` – the actual bit-vector structure type. It is
- `BitVec<C: Cursor, T: Bits>` – the actual bit-vector structure type. It is
generic over a cursor type (`E`) and storage type (`T`).
- `Endian` – an open trait that defines an ordering schema for `BitVec` to use.
- `Cursor` – an open trait that defines an ordering schema for `BitVec` to use.
Little and big endian orderings are provided by default. If you wish to
implement other ordering types, the `Endian` trait requires one function:
implement other ordering types, the `Cursor` trait requires one function:

@@ -111,6 +111,6 @@ - `fn curr<T: Bits>(index: u8) -> u8` takes a semantic index and computes a

- `BigEndian` – a zero-sized struct that implements `Endian` by defining the
- `BigEndian` – a zero-sized struct that implements `Cursor` by defining the
forward direction as towards LSb and the backward direction as towards MSb.
- `LittleEndian` – a zero-sized struct that implements `Endian` by defining the
- `LittleEndian` – a zero-sized struct that implements `Cursor` by defining the
forward direction as towards MSb and the backward direction as towards LSb.

@@ -117,0 +117,0 @@

@@ -11,3 +11,2 @@ /*! Bit Management

convert::From,
default::Default,
fmt::{

@@ -50,5 +49,2 @@ Binary,

+ Debug
// `BitVec` cannot push new elements without this. (Well, it CAN, but
// `mem::uninitialized` is Considered Harmful.)
+ Default
+ Display

@@ -77,5 +73,5 @@ // Permit testing a value against 1 in `get()`.

///
/// Incidentally, this can be computed as `size_of().trailing_zeroes()` once
/// Incidentally, this can be computed as `size_of().trailing_zeros()` once
/// that becomes a valid constexpr.
const BITS: u8; // = size_of::<Self>().trailing_zeros();
const BITS: u8; // = size_of::<Self>().trailing_zeros() as u8;

@@ -106,6 +102,8 @@ /// The bitmask to turn an arbitrary usize into the bit index. Bit indices

/// Counts how many bits are set.
fn ones(&self) -> u32;
#[inline(always)]
fn ones(&self) -> usize;
/// Counts how many bits are unset.
fn zeros(&self) -> u32;
#[inline(always)]
fn zeros(&self) -> usize;

@@ -137,8 +135,10 @@ /// Splits a `usize` cursor into an (element, bit) tuple.

fn ones(&self) -> u32 {
self.count_ones()
#[inline(always)]
fn ones(&self) -> usize {
self.count_ones() as usize
}
fn zeros(&self) -> u32 {
self.count_zeros()
#[inline(always)]
fn zeros(&self) -> usize {
self.count_zeros() as usize
}

@@ -152,8 +152,10 @@

fn ones(&self) -> u32 {
self.count_ones()
#[inline(always)]
fn ones(&self) -> usize {
self.count_ones() as usize
}
fn zeros(&self) -> u32 {
self.count_zeros()
#[inline(always)]
fn zeros(&self) -> usize {
self.count_zeros() as usize
}

@@ -167,8 +169,10 @@

fn ones(&self) -> u32 {
self.count_ones()
#[inline(always)]
fn ones(&self) -> usize {
self.count_ones() as usize
}
fn zeros(&self) -> u32 {
self.count_zeros()
#[inline(always)]
fn zeros(&self) -> usize {
self.count_zeros() as usize
}

@@ -184,8 +188,10 @@

fn ones(&self) -> u32 {
self.count_ones()
#[inline(always)]
fn ones(&self) -> usize {
self.count_ones() as usize
}
fn zeros(&self) -> u32 {
self.count_zeros()
#[inline(always)]
fn zeros(&self) -> usize {
self.count_zeros() as usize
}

@@ -192,0 +198,0 @@

@@ -39,8 +39,2 @@ /*! `BitVec` – `Vec<bool>` in overdrive.

#[cfg(all(feature = "alloc", not(feature = "std")))]
extern crate alloc;
#[cfg(feature = "std")]
extern crate core;
#[macro_use]

@@ -50,3 +44,3 @@ mod macros;

mod bits;
mod endian;
mod cursor;
mod slice;

@@ -56,4 +50,4 @@

bits::Bits,
endian::{
Endian,
cursor::{
Cursor,
BigEndian,

@@ -60,0 +54,0 @@ LittleEndian,

/** Construct a `BitVec` out of a literal array in source code, like `vec!`.
`bitvec!` can be invoked in a number of ways. It takes the name of an
`Endian` implementation, the name of a `Bits`-implementing primitive, and
`Cursor` implementation, the name of a `Bits`-implementing primitive, and
zero or more primitives (integer, floating-point, or bool) which are used to

@@ -9,6 +9,6 @@ build the bits. Each primitive literal corresponds to one bit, and is

`bitvec!` can be invoked with no specifiers, an `Endian` specifier, or an
`Endian` and a `Bits` specifier. It cannot be invoked with a `Bits`
specifier but no `Endian` specifier, due to overlap in how those tokens are
matched by the macro system.
`bitvec!` can be invoked with no specifiers, a `Cursor` specifier, or a `Cursor`
and a `Bits` specifier. It cannot be invoked with a `Bits` specifier but no
`Cursor` specifier, due to overlap in how those tokens are matched by the macro
system.

@@ -104,4 +104,4 @@ Like `vec!`, `bitvec!` supports bit lists `[0, 1, …]` and repetition

#[doc(hidden)]
impl<E: $crate :: Endian, T: $crate :: Bits> core::ops::ShlAssign< $t >
for crate::BitSlice<E, T>
impl<C: $crate :: Cursor, T: $crate :: Bits> core::ops::ShlAssign< $t >
for crate::BitSlice<C, T>
{

@@ -114,4 +114,4 @@ fn shl_assign(&mut self, shamt: $t ) {

#[doc(hidden)]
impl<E: $crate :: Endian, T: $crate :: Bits> core::ops::ShrAssign< $t >
for crate::BitSlice<E, T>
impl<C: $crate :: Cursor, T: $crate :: Bits> core::ops::ShrAssign< $t >
for crate::BitSlice<C, T>
{

@@ -130,4 +130,4 @@ fn shr_assign(&mut self, shamt: $t ) {

#[doc(hidden)]
impl<E: $crate :: Endian, T: $crate :: Bits> core::ops::Shl< $t >
for $crate :: BitVec<E, T>
impl<C: $crate :: Cursor, T: $crate :: Bits> core::ops::Shl< $t >
for $crate :: BitVec<C, T>
{

@@ -142,4 +142,4 @@ type Output = <Self as core::ops::Shl<usize>>::Output;

#[doc(hidden)]
impl<E: $crate :: Endian, T: $crate :: Bits> core::ops::ShlAssign< $t >
for $crate :: BitVec<E, T>
impl<C: $crate :: Cursor, T: $crate :: Bits> core::ops::ShlAssign< $t >
for $crate :: BitVec<C, T>
{

@@ -152,4 +152,4 @@ fn shl_assign(&mut self, shamt: $t ) {

#[doc(hidden)]
impl<E: $crate :: Endian, T: $crate :: Bits> core::ops::Shr< $t >
for $crate :: BitVec<E, T>
impl<C: $crate :: Cursor, T: $crate :: Bits> core::ops::Shr< $t >
for $crate :: BitVec<C, T>
{

@@ -164,4 +164,4 @@ type Output = <Self as core::ops::Shr<usize>>::Output;

#[doc(hidden)]
impl<E: $crate :: Endian, T: $crate :: Bits> core::ops::ShrAssign< $t >
for $crate :: BitVec<E, T>
impl<C: $crate :: Cursor, T: $crate :: Bits> core::ops::ShrAssign< $t >
for $crate :: BitVec<C, T>
{

@@ -168,0 +168,0 @@ fn shr_assign(&mut self, shamt: $t ) {

+244
-106

@@ -95,3 +95,3 @@ /*! `BitSlice` Wide Reference

`BitSlice` is a newtype wrapper over `[T]`, and as such can only be held by
reference. It is impossible to create a `Box<BitSlice<E, T>>` from this library,
reference. It is impossible to create a `Box<BitSlice<C, T>>` from this library,
and assembling one yourself is Undefined Behavior for which this library is not

@@ -109,3 +109,3 @@ responsible. **Do not try to create a `Box<BitSlice>`.** If you want an owned

- `E: Endian` must be an implementor of the `Endian` trait. `BitVec` takes a
- `C: Cursor` must be an implementor of the `Cursor` trait. `BitVec` takes a
`PhantomData` marker for access to the associated functions, and will never

@@ -121,11 +121,11 @@ make use of an instance of the trait. The default implementations,

**/
#[cfg_attr(nightly, repr(transparent))]
pub struct BitSlice<E = crate::BigEndian, T = u8>
where E: crate::Endian, T: crate::Bits {
_endian: PhantomData<E>,
#[repr(transparent)]
pub struct BitSlice<C = crate::BigEndian, T = u8>
where C: crate::Cursor, T: crate::Bits {
_cursor: PhantomData<C>,
inner: [T],
}
impl<E, T> BitSlice<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> BitSlice<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Gets the bit value at the given position.

@@ -149,3 +149,3 @@ ///

let (elt, bit) = T::split(index);
self.as_ref()[elt].get(E::curr::<T>(bit))
self.as_ref()[elt].get(C::curr::<T>(bit))
}

@@ -172,3 +172,3 @@

let (elt, bit) = T::split(index);
self.as_mut()[elt].set(E::curr::<T>(bit), value);
self.as_mut()[elt].set(C::curr::<T>(bit), value);
}

@@ -205,4 +205,3 @@

// Gallop the filled elements
let store = self.as_ref();
for elt in &store[.. self.elts()] {
for elt in self.body() {
if *elt != T::from(!0) {

@@ -213,7 +212,5 @@ return false;

// Walk the partial tail
let bits = self.bits();
if bits > 0 {
let tail = store[self.elts()];
for bit in 0 .. bits {
if !tail.get(E::curr::<T>(bit)) {
if let Some(tail) = self.tail() {
for bit in 0 .. self.bits() {
if !tail.get(C::curr::<T>(bit)) {
return false;

@@ -255,4 +252,3 @@ }

// Gallop the filled elements
let store = self.as_ref();
for elt in &store[.. self.elts()] {
for elt in self.body() {
if *elt != T::from(0) {

@@ -263,7 +259,5 @@ return true;

// Walk the partial tail
let bits = self.bits();
if bits > 0 {
let tail = store[self.elts()];
for bit in 0 .. bits {
if tail.get(E::curr::<T>(bit)) {
if let Some(tail) = self.tail() {
for bit in 0 .. self.bits() {
if tail.get(C::curr::<T>(bit)) {
return true;

@@ -377,8 +371,11 @@ }

/// use bitvec::*;
/// let bv = bitvec![1, 0, 1, 0, 1];
/// assert_eq!(bv.count_ones(), 3);
/// let bv = bitvec![1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1];
/// assert_eq!(bv.count_ones(), 7);
/// # }
/// ```
pub fn count_ones(&self) -> usize {
self.into_iter().filter(|b| *b).count()
self.body().iter().map(T::ones).sum::<usize>() +
self.tail().map(|t| (0 .. self.bits())
.map(|n| t.get(C::curr::<T>(n))).filter(|b| *b).count()
).unwrap_or(0)
}

@@ -393,8 +390,11 @@

/// use bitvec::*;
/// let bv = bitvec![0, 1, 0, 1, 0];
/// assert_eq!(bv.count_zeros(), 3);
/// let bv = bitvec![1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1];
/// assert_eq!(bv.count_zeros(), 6);
/// # }
/// ```
pub fn count_zeros(&self) -> usize {
self.into_iter().filter(|b| !b).count()
self.body().iter().map(T::zeros).sum::<usize>() +
self.tail().map(|t| (0 .. self.bits())
.map(|n| t.get(C::curr::<T>(n))).filter(|b| !*b).count()
).unwrap_or(0)
}

@@ -506,3 +506,3 @@

/// iterator does.
pub fn iter(&self) -> Iter<E, T> {
pub fn iter(&self) -> Iter<C, T> {
self.into_iter()

@@ -557,6 +557,9 @@ }

///
/// This is a crate-local function. It only appears in the docs so that it
/// can be tested.
///
/// # Examples
///
/// ```rust,ignore
/// # #[cfg(feature = "alloc")] {
/// ```rust
/// # #[cfg(all(feature = "alloc", feature = "testing"))] {
/// use bitvec::*;

@@ -569,13 +572,148 @@ /// let bv = bitvec![1; 10];

/// ```
///
/// This test is never compiled because the functions it calls are not
/// accessible to the test crate.
pub(crate) fn raw_len(&self) -> usize {
#[cfg(feature = "testing")]
pub fn raw_len(&self) -> usize { self.raw_len_inner() }
#[cfg(not(feature = "testing"))]
pub(crate) fn raw_len(&self) -> usize { self.raw_len_inner() }
#[doc(hidden)]
#[inline(always)]
fn raw_len_inner(&self) -> usize {
self.elts() + if self.bits() > 0 { 1 } else { 0 }
}
/// Gets access to the set of all filled elements as a slice.
///
/// This is primarily useful for bulk operations on the filled elements.
///
/// This is a crate-local function. It only appears in the docs so that it
/// can be tested.
///
/// # Examples
///
/// ```rust
/// # #[cfg(all(feature = "alloc", feature = "testing"))] {
/// use bitvec::*;
/// let bv = bitvec![1; 10];
/// let body: &[u8] = bv.body();
/// assert_eq!(body.len(), 1);
/// # }
/// ```
#[cfg(feature = "testing")]
pub fn body(&self) -> &[T] { self.body_inner() }
#[cfg(not(feature = "testing"))]
pub(crate) fn body(&self) -> &[T] { self.body_inner() }
#[doc(hidden)]
#[inline(always)]
fn body_inner(&self) -> &[T] {
let elts = self.elts();
&self.as_ref()[.. elts]
}
/// Gets mutable access to the set of all filled elements as a slice.
///
/// This is primarily useful for bulk operations on the filled elements.
///
/// This is a crate-local function. It only appears in the docs so that it
/// can be tested.
///
/// # Examples
///
/// ```rust
/// # #[cfg(all(feature = "alloc", feature = "testing"))] {
/// use bitvec::*;
/// let mut bv = bitvec![1; 10];
/// assert!(bv[0]);
/// {
/// let body: &mut [u8] = bv.body_mut();
/// assert_eq!(body.len(), 1);
/// assert_eq!(body[0], 0xFF);
/// body[0] = 0;
/// assert_eq!(body[0], 0x00);
/// }
/// assert!(!bv[0]);
/// # }
/// ```
#[cfg(feature = "testing")]
pub fn body_mut(&mut self) -> &mut [T] { self.body_mut_inner() }
#[cfg(not(feature = "testing"))]
pub(crate) fn body_mut(&mut self) -> &mut [T] { self.body_mut_inner() }
#[doc(hidden)]
#[inline(always)]
fn body_mut_inner(&mut self) -> &mut [T] {
let elts = self.elts();
&mut self.as_mut()[.. elts]
}
/// Gets access to the partially-filled tail, if it exists.
///
/// This is a crate-local function. It only appears in the docs so that it
/// can be tested.
///
/// # Examples
///
/// ```rust
/// # #[cfg(all(feature = "alloc", feature = "testing"))] {
/// use bitvec::*;
/// let bv = bitvec![1; 10];
/// let tail: &u8 = bv.tail().unwrap();
/// assert_eq!(*tail, 0b1100_0000);
/// # }
/// ```
#[cfg(feature = "testing")]
pub fn tail(&self) -> Option<&T> { self.tail_inner() }
#[cfg(not(feature = "testing"))]
pub(crate) fn tail(&self) -> Option<&T> { self.tail_inner() }
#[doc(hidden)]
#[inline(always)]
fn tail_inner(&self) -> Option<&T> {
if self.bits() > 0 {
let elts = self.elts();
Some(&self.as_ref()[elts])
}
else {
None
}
}
/// Gets mutable access to the partially-filled tail, if it exists.
///
/// This is a crate-local function. It only appears in the docs so that it
/// can be tested.
///
/// # Examples
///
/// ```rust
/// # #[cfg(all(feature = "alloc", feature = "testing"))] {
/// use bitvec::*;
/// let mut bv = bitvec![1; 10];
/// bv.push(false);
/// assert!(!bv[10]);
/// {
/// let tail: &mut u8 = bv.tail_mut().unwrap();
/// assert_eq!(*tail, 0b1100_0000);
/// *tail = 0xFF;
/// assert_eq!(*tail, 0xFF);
/// }
/// assert!(bv[10]);
/// # }
/// ```
#[cfg(feature = "testing")]
pub fn tail_mut(&mut self) -> Option<&mut T> { self.tail_mut_inner() }
#[cfg(not(feature = "testing"))]
pub(crate) fn tail_mut(&mut self) -> Option<&mut T> { self.tail_mut_inner() }
#[doc(hidden)]
#[inline(always)]
fn tail_mut_inner(&mut self) -> Option<&mut T> {
if self.bits() > 0 {
let elts = self.elts();
Some(&mut self.as_mut()[elts])
}
else {
None
}
}
/// Prints a type header into the Formatter.
#[cfg(feature = "alloc")]
pub(crate) fn fmt_header(&self, fmt: &mut Formatter) -> fmt::Result {
write!(fmt, "BitSlice<{}, {}>", E::TY, T::TY)
write!(fmt, "BitSlice<{}, {}>", C::TY, T::TY)
}

@@ -630,3 +768,3 @@

for bit in 0 .. bits {
let cur = E::curr::<T>(bit);
let cur = C::curr::<T>(bit);
out.write_str(if elt.get(cur) { "1" } else { "0" })?;

@@ -640,5 +778,5 @@ }

#[cfg(feature = "alloc")]
impl<E, T> ToOwned for BitSlice<E, T>
where E: crate::Endian, T: crate::Bits {
type Owned = crate::BitVec<E, T>;
impl<C, T> ToOwned for BitSlice<C, T>
where C: crate::Cursor, T: crate::Bits {
type Owned = crate::BitVec<C, T>;

@@ -671,7 +809,7 @@ /// Clones a borrowed `BitSlice` into an owned `BitVec`.

impl<E, T> Eq for BitSlice<E, T>
where E: crate::Endian, T: crate::Bits {}
impl<C, T> Eq for BitSlice<C, T>
where C: crate::Cursor, T: crate::Bits {}
impl<E, T> Ord for BitSlice<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Ord for BitSlice<C, T>
where C: crate::Cursor, T: crate::Bits {
fn cmp(&self, rhs: &Self) -> Ordering {

@@ -692,3 +830,3 @@ match self.partial_cmp(rhs) {

impl<A, B, C, D> PartialEq<BitSlice<C, D>> for BitSlice<A, B>
where A: crate::Endian, B: crate::Bits, C: crate::Endian, D: crate::Bits {
where A: crate::Cursor, B: crate::Bits, C: crate::Cursor, D: crate::Bits {
/// Performs a comparison by `==`.

@@ -727,3 +865,3 @@ ///

impl<A, B, C, D> PartialOrd<BitSlice<C, D>> for BitSlice<A, B>
where A: crate::Endian, B: crate::Bits, C: crate::Endian, D: crate::Bits {
where A: crate::Cursor, B: crate::Bits, C: crate::Cursor, D: crate::Bits {
/// Performs a comparison by `<` or `>`.

@@ -760,4 +898,4 @@ ///

/// partially-filled tail element (if present).
impl<E, T> AsMut<[T]> for BitSlice<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> AsMut<[T]> for BitSlice<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Accesses the underlying store.

@@ -785,4 +923,4 @@ ///

/// partially-filled tail element (if present).
impl<E, T> AsRef<[T]> for BitSlice<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> AsRef<[T]> for BitSlice<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Accesses the underlying store.

@@ -808,5 +946,5 @@ ///

/// always completely fill the original slice, and will not have a partial tail.
impl<'a, E, T> From<&'a [T]> for &'a BitSlice<E, T>
where E: crate::Endian, T: 'a + crate::Bits {
/// Wraps an `&[T: Bits]` in an `&BitSlice<E: Endian, T>`. The endianness
impl<'a, C, T> From<&'a [T]> for &'a BitSlice<C, T>
where C: crate::Cursor, T: 'a + crate::Bits {
/// Wraps an `&[T: Bits]` in an `&BitSlice<C: Cursor, T>`. The endianness
/// must be specified by the call site. The element type cannot be changed.

@@ -845,5 +983,5 @@ ///

/// a partial tail.
impl<'a, E, T> From<&'a mut [T]> for &'a mut BitSlice<E, T>
where E: crate::Endian, T: 'a + crate::Bits {
/// Wraps an `&mut [T: Bits]` in an `&mut BitSlice<E: Endian, T>`. The
impl<'a, C, T> From<&'a mut [T]> for &'a mut BitSlice<C, T>
where C: crate::Cursor, T: 'a + crate::Bits {
/// Wraps an `&mut [T: Bits]` in an `&mut BitSlice<C: Cursor, T>`. The
/// endianness must be specified by the call site. The element type cannot

@@ -879,3 +1017,3 @@ /// be changed.

///
/// The output is of the form `BitSlice<E, T> [ELT, *]` where `<E, T>` is the
/// The output is of the form `BitSlice<C, T> [ELT, *]` where `<C, T>` is the
/// endianness and element type, with square brackets on each end of the bits

@@ -889,4 +1027,4 @@ /// and all the elements of the array printed in binary. The printout is always

#[cfg(feature = "alloc")]
impl<E, T> Debug for BitSlice<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Debug for BitSlice<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Renders the `BitSlice` type header and contents for debug.

@@ -932,4 +1070,4 @@ ///

#[cfg(feature = "alloc")]
impl<E, T> Display for BitSlice<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Display for BitSlice<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Renders the `BitSlice` contents for display.

@@ -952,4 +1090,4 @@ ///

/// Writes the contents of the `BitSlice`, in semantic bit order, into a hasher.
impl<E, T> Hash for BitSlice<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Hash for BitSlice<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Writes each bit of the `BitSlice`, as a full `bool`, into the hasher.

@@ -969,6 +1107,6 @@ fn hash<H>(&self, hasher: &mut H)

/// `DoubleEndedIterator` as it has known ends.
impl<'a, E, T> IntoIterator for &'a BitSlice<E, T>
where E: crate::Endian, T: 'a + crate::Bits {
impl<'a, C, T> IntoIterator for &'a BitSlice<C, T>
where C: crate::Cursor, T: 'a + crate::Bits {
type Item = bool;
type IntoIter = Iter<'a, E, T>;
type IntoIter = Iter<'a, C, T>;

@@ -1011,4 +1149,4 @@ /// Iterates over the slice.

/// and then using addition, or by using `BitVec`s instead of `BitSlice`s.
impl<'a, E, T> AddAssign<&'a BitSlice<E, T>> for BitSlice<E, T>
where E: crate::Endian, T: crate::Bits {
impl<'a, C, T> AddAssign<&'a BitSlice<C, T>> for BitSlice<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Performs unsigned wrapping addition in place.

@@ -1037,3 +1175,3 @@ ///

/// ```
fn add_assign(&mut self, addend: &'a BitSlice<E, T>) {
fn add_assign(&mut self, addend: &'a BitSlice<C, T>) {
use core::iter::repeat;

@@ -1060,4 +1198,4 @@ // zero-extend the addend if it’s shorter than self

/// is extended with zero, clearing all remaining bits in `self`.
impl<E, T, I> BitAndAssign<I> for BitSlice<E, T>
where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> {
impl<C, T, I> BitAndAssign<I> for BitSlice<C, T>
where C: crate::Cursor, T: crate::Bits, I: IntoIterator<Item=bool> {
/// `AND`s a bitstream into a slice.

@@ -1088,4 +1226,4 @@ ///

/// extended with zero, leaving all remaining bits in `self` as they were.
impl<E, T, I> BitOrAssign<I> for BitSlice<E, T>
where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> {
impl<C, T, I> BitOrAssign<I> for BitSlice<C, T>
where C: crate::Cursor, T: crate::Bits, I: IntoIterator<Item=bool> {
/// `OR`s a bitstream into a slice.

@@ -1115,4 +1253,4 @@ ///

/// is extended with zero, leaving all remaining bits in `self` as they were.
impl<E, T, I> BitXorAssign<I> for BitSlice<E, T>
where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> {
impl<C, T, I> BitXorAssign<I> for BitSlice<C, T>
where C: crate::Cursor, T: crate::Bits, I: IntoIterator<Item=bool> {
/// `XOR`s a bitstream into a slice.

@@ -1142,4 +1280,4 @@ ///

/// length of the `BitSlice`.
impl<'a, E, T> Index<usize> for &'a BitSlice<E, T>
where E: crate::Endian, T: 'a + crate::Bits {
impl<'a, C, T> Index<usize> for &'a BitSlice<C, T>
where C: crate::Cursor, T: 'a + crate::Bits {
type Output = bool;

@@ -1170,4 +1308,4 @@

/// This index is not recommended for public use.
impl<'a, E, T> Index<(usize, u8)> for &'a BitSlice<E, T>
where E: crate::Endian, T: 'a + crate::Bits {
impl<'a, C, T> Index<(usize, u8)> for &'a BitSlice<C, T>
where C: crate::Cursor, T: 'a + crate::Bits {
type Output = bool;

@@ -1215,4 +1353,4 @@

/// Because `BitSlice` cannot move, the negation is performed in place.
impl<'a, E, T> Neg for &'a mut BitSlice<E, T>
where E: crate::Endian, T: 'a + crate::Bits {
impl<'a, C, T> Neg for &'a mut BitSlice<C, T>
where C: crate::Cursor, T: 'a + crate::Bits {
type Output = Self;

@@ -1272,8 +1410,8 @@

// Fill an element with all 1 bits
let elt: [T; 1] = [!T::default()];
let elt: [T; 1] = [! unsafe { mem::zeroed() }];
if self.any() {
// Turn a slice reference `[T; 1]` into a bit-slice reference
// `[u1; 1]`
let addend: &BitSlice<E, T> = {
unsafe { mem::transmute::<&[T], &BitSlice<E, T>>(&elt) }
let addend: &BitSlice<C, T> = {
unsafe { mem::transmute::<&[T], &BitSlice<C, T>>(&elt) }
};

@@ -1294,4 +1432,4 @@ // And add it (if the slice was not all-ones).

/// operator rather than a consuming/returning operator.
impl<'a, E, T> Not for &'a mut BitSlice<E, T>
where E: crate::Endian, T: 'a + crate::Bits {
impl<'a, C, T> Not for &'a mut BitSlice<C, T>
where C: crate::Cursor, T: 'a + crate::Bits {
type Output = Self;

@@ -1354,4 +1492,4 @@

/// A shift amount of zero is a no-op, and returns immediately.
impl<E, T> ShlAssign<usize> for BitSlice<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> ShlAssign<usize> for BitSlice<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Shifts a slice left, in place.

@@ -1452,4 +1590,4 @@ ///

/// A shift amount of zero is a no-op, and returns immediately.
impl<E, T> ShrAssign<usize> for BitSlice<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> ShrAssign<usize> for BitSlice<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Shifts a slice right, in place.

@@ -1514,5 +1652,5 @@ ///

#[doc(hidden)]
pub struct Iter<'a, E, T>
where E: 'a + crate::Endian, T: 'a + crate::Bits {
inner: &'a BitSlice<E, T>,
pub struct Iter<'a, C, T>
where C: 'a + crate::Cursor, T: 'a + crate::Bits {
inner: &'a BitSlice<C, T>,
head: usize,

@@ -1522,4 +1660,4 @@ tail: usize,

impl<'a, E, T> Iter<'a, E, T>
where E: 'a + crate::Endian, T: 'a + crate::Bits {
impl<'a, C, T> Iter<'a, C, T>
where C: 'a + crate::Cursor, T: 'a + crate::Bits {
fn reset(&mut self) {

@@ -1531,4 +1669,4 @@ self.head = 0;

impl<'a, E, T> DoubleEndedIterator for Iter<'a, E, T>
where E: 'a + crate::Endian, T: 'a + crate::Bits {
impl<'a, C, T> DoubleEndedIterator for Iter<'a, C, T>
where C: 'a + crate::Cursor, T: 'a + crate::Bits {
fn next_back(&mut self) -> Option<Self::Item> {

@@ -1546,4 +1684,4 @@ if self.tail > self.head {

impl<'a, E, T> ExactSizeIterator for Iter<'a, E, T>
where E: 'a + crate::Endian, T: 'a + crate::Bits {
impl<'a, C, T> ExactSizeIterator for Iter<'a, C, T>
where C: 'a + crate::Cursor, T: 'a + crate::Bits {
fn len(&self) -> usize {

@@ -1554,5 +1692,5 @@ self.tail - self.head

impl<'a, E, T> From<&'a BitSlice<E, T>> for Iter<'a, E, T>
where E: 'a + crate::Endian, T: 'a + crate::Bits {
fn from(src: &'a BitSlice<E, T>) -> Self {
impl<'a, C, T> From<&'a BitSlice<C, T>> for Iter<'a, C, T>
where C: 'a + crate::Cursor, T: 'a + crate::Bits {
fn from(src: &'a BitSlice<C, T>) -> Self {
let len = src.len();

@@ -1567,4 +1705,4 @@ Self {

impl<'a, E, T> Iterator for Iter<'a, E, T>
where E: 'a + crate::Endian, T: 'a + crate::Bits {
impl<'a, C, T> Iterator for Iter<'a, C, T>
where C: 'a + crate::Cursor, T: 'a + crate::Bits {
type Item = bool;

@@ -1571,0 +1709,0 @@

+127
-127

@@ -100,3 +100,3 @@ /*! `BitVec` structure

- `E: Endian` must be an implementor of the `Endian` trait. `BitVec` takes a
- `C: Cursor` must be an implementor of the `Cursor` trait. `BitVec` takes a
`PhantomData` marker for access to the associated functions, and will never

@@ -112,12 +112,12 @@ make use of an instance of the trait. The default implementations,

**/
#[cfg_attr(nightly, repr(transparent))]
pub struct BitVec<E = crate::BigEndian, T = u8>
where E: crate::Endian, T: crate::Bits {
_endian: PhantomData<E>,
#[repr(transparent)]
pub struct BitVec<C = crate::BigEndian, T = u8>
where C: crate::Cursor, T: crate::Bits {
_cursor: PhantomData<C>,
inner: Vec<T>,
}
impl<E, T> BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
/// Constructs a new, empty, `BitVec<E, T>`.
impl<C, T> BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Constructs a new, empty, `BitVec<C, T>`.
///

@@ -136,3 +136,3 @@ /// The vector will not allocate until bits are pushed onto it.

Self {
_endian: PhantomData,
_cursor: PhantomData,
inner: Vec::new(),

@@ -160,3 +160,3 @@ }

inner: Vec::with_capacity(cap),
_endian: PhantomData,
_cursor: PhantomData,
}

@@ -196,3 +196,3 @@ }

// Get a cursor to the bit that matches the semantic count.
let cursor = E::curr::<T>(bit);
let cursor = C::curr::<T>(bit);
// Insert `value` at the current cursor.

@@ -487,3 +487,3 @@ self.do_with_tail(|elt| elt.set(cursor, value));

let len = self.len();
self.do_with_vec(|v| v.push(Default::default()));
self.do_with_vec(|v| v.push(unsafe { mem::zeroed() }));
unsafe {

@@ -498,3 +498,3 @@ self.inner.set_len(len);

fn fmt_header(&self, fmt: &mut Formatter) -> fmt::Result {
write!(fmt, "BitVec<{}, {}>", E::TY, T::TY)
write!(fmt, "BitVec<{}, {}>", C::TY, T::TY)
}

@@ -504,4 +504,4 @@ }

/// Signifies that `BitSlice` is the borrowed form of `BitVec`.
impl<E, T> Borrow<crate::BitSlice<E, T>> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Borrow<crate::BitSlice<C, T>> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Borrows the `BitVec` as a `BitSlice`.

@@ -518,3 +518,3 @@ ///

/// ```
fn borrow(&self) -> &crate::BitSlice<E, T> {
fn borrow(&self) -> &crate::BitSlice<C, T> {
&*self

@@ -525,4 +525,4 @@ }

/// Signifies that `BitSlice` is the borrowed form of `BitVec`.
impl<E, T> BorrowMut<crate::BitSlice<E, T>> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> BorrowMut<crate::BitSlice<C, T>> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Mutably borrows the `BitVec` as a `BitSlice`.

@@ -541,3 +541,3 @@ ///

/// ```
fn borrow_mut(&mut self) -> &mut crate::BitSlice<E, T> {
fn borrow_mut(&mut self) -> &mut crate::BitSlice<C, T> {
&mut *self

@@ -547,4 +547,4 @@ }

impl<E, T> Clone for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Clone for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
fn clone(&self) -> Self {

@@ -570,7 +570,7 @@ let mut out = Self::from(self.as_ref());

impl<E, T> Eq for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {}
impl<C, T> Eq for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {}
impl<E, T> Ord for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Ord for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
fn cmp(&self, rhs: &Self) -> Ordering {

@@ -588,3 +588,3 @@ crate::BitSlice::cmp(&self, &rhs)

impl<A, B, C, D> PartialEq<BitVec<C, D>> for BitVec<A, B>
where A: crate::Endian, B: crate::Bits, C: crate::Endian, D: crate::Bits {
where A: crate::Cursor, B: crate::Bits, C: crate::Cursor, D: crate::Bits {
/// Performs a comparison by `==`.

@@ -626,3 +626,3 @@ ///

impl<A, B, C, D> PartialOrd<BitVec<C, D>> for BitVec<A, B>
where A: crate::Endian, B: crate::Bits, C: crate::Endian, D: crate::Bits {
where A: crate::Cursor, B: crate::Bits, C: crate::Cursor, D: crate::Bits {
/// Performs a comparison by `<` or `>`.

@@ -648,4 +648,4 @@ ///

/// the partially-filled tail.
impl<E, T> AsMut<[T]> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> AsMut<[T]> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Accesses the underlying store.

@@ -670,4 +670,4 @@ ///

/// the partially-filled tail.
impl<E, T> AsRef<[T]> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> AsRef<[T]> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Accesses the underlying store.

@@ -691,5 +691,5 @@ ///

/// just as `&[T].into()` yields a `Vec`, `&BitSlice.into()` yields a `BitVec`.
impl<'a, E, T> From<&'a crate::BitSlice<E, T>> for BitVec<E, T>
where E: crate::Endian, T: 'a + crate::Bits {
fn from(src: &'a crate::BitSlice<E, T>) -> Self {
impl<'a, C, T> From<&'a crate::BitSlice<C, T>> for BitVec<C, T>
where C: crate::Cursor, T: 'a + crate::Bits {
fn from(src: &'a crate::BitSlice<C, T>) -> Self {
src.to_owned()

@@ -703,4 +703,4 @@ }

/// use.
impl<'a, E, T> From<&'a [bool]> for BitVec<E, T>
where E: crate::Endian, T: 'a + crate::Bits {
impl<'a, C, T> From<&'a [bool]> for BitVec<C, T>
where C: crate::Cursor, T: 'a + crate::Bits {
fn from(src: &'a [bool]) -> Self {

@@ -723,5 +723,5 @@ let mut out = Self::with_capacity(src.len());

/// it can only borrow the source and not take ownership.
impl<'a, E, T> From<&'a [T]> for BitVec<E, T>
where E: crate::Endian, T: 'a + crate::Bits {
/// Builds a `BitVec<E: Endian, T: Bits>` from a borrowed `&[T]`.
impl<'a, C, T> From<&'a [T]> for BitVec<C, T>
where C: crate::Cursor, T: 'a + crate::Bits {
/// Builds a `BitVec<C: Cursor, T: Bits>` from a borrowed `&[T]`.
///

@@ -737,3 +737,3 @@ /// # Examples

fn from(src: &'a [T]) -> Self {
<&crate::BitSlice<E, T>>::from(src).to_owned()
<&crate::BitSlice<C, T>>::from(src).to_owned()
}

@@ -747,5 +747,5 @@ }

/// worry about using the correct cursor type.
impl<E, T> From<Box<[T]>> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
/// Consumes a `Box<[T: Bits]>` and creates a `BitVec<E: Endian, T>` from
impl<C, T> From<Box<[T]>> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Consumes a `Box<[T: Bits]>` and creates a `BitVec<C: Cursor, T>` from
/// it.

@@ -772,5 +772,5 @@ ///

/// worry about using the correct cursor type.
impl<E, T> From<Vec<T>> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
/// Consumes a `Vec<T: Bits>` and creates a `BitVec<E: Endian, T>` from it.
impl<C, T> From<Vec<T>> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Consumes a `Vec<T: Bits>` and creates a `BitVec<C: Cursor, T>` from it.
///

@@ -790,3 +790,3 @@ /// # Examples

inner: src,
_endian: PhantomData::<E>,
_cursor: PhantomData::<C>,
};

@@ -853,8 +853,8 @@ unsafe {

impl<E, T> Default for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Default for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
fn default() -> Self {
Self {
inner: Default::default(),
_endian: Default::default(),
_cursor: Default::default(),
}

@@ -866,3 +866,3 @@ }

///
/// The output is of the form `BitVec<E, T> [ELT, *]`, where `<E, T>` is the
/// The output is of the form `BitVec<C, T> [ELT, *]`, where `<C, T>` is the
/// endianness and element type, with square brackets on each end of the bits

@@ -875,4 +875,4 @@ /// and all the live elements in the vector printed in binary. The printout is

/// than separated by a space.
impl<E, T> Debug for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Debug for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Renders the `BitVec` type header and contents for debug.

@@ -913,4 +913,4 @@ ///

/// elements and print that slice instead.
impl<E, T> Display for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Display for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Renders the `BitVec` contents for display.

@@ -931,8 +931,8 @@ ///

/// Writes the contents of the `BitVec`, in semantic bit order, into a hasher.
impl<E, T> Hash for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Hash for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Writes each bit of the `BitVec`, as a full `bool`, into the hasher.
fn hash<H>(&self, hasher: &mut H)
where H: Hasher {
<crate::BitSlice<E, T> as Hash>::hash(&self, hasher)
<crate::BitSlice<C, T> as Hash>::hash(&self, hasher)
}

@@ -946,4 +946,4 @@ }

/// source into `self` when the source is `BitSlice`-compatible.
impl<E, T> Extend<bool> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Extend<bool> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Extends a `BitVec` from another bitstream.

@@ -975,4 +975,4 @@ ///

/// of `bool`.
impl<E, T> FromIterator<bool> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> FromIterator<bool> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Collects an iterator of `bool` into a vector.

@@ -1007,7 +1007,7 @@ ///

/// and `DoubleEndedIterator`, since they have known ends.
impl<E, T> IntoIterator for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> IntoIterator for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
type Item = bool;
#[doc(hidden)]
type IntoIter = IntoIter<E, T>;
type IntoIter = IntoIter<C, T>;

@@ -1047,4 +1047,4 @@ /// Iterates over the vector.

/// correctness in arithmetic at this time.
impl<E, T> Add for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Add for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
type Output = Self;

@@ -1095,4 +1095,4 @@

/// correctness in arithmetic at this time.
impl<E, T> AddAssign for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> AddAssign for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Adds another `BitVec` into `self`.

@@ -1125,3 +1125,3 @@ ///

let mut c = false;
let mut stack = BitVec::<E, T>::with_capacity(self.len());
let mut stack = BitVec::<C, T>::with_capacity(self.len());
// Reverse self, reverse addend and zero-extend, and zip both together.

@@ -1176,4 +1176,4 @@ // This walks both vecs from rightmost to leftmost, and considers an

/// other, the extra bits will be ignored.
impl<E, T, I> BitAnd<I> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> {
impl<C, T, I> BitAnd<I> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits, I: IntoIterator<Item=bool> {
type Output = Self;

@@ -1201,4 +1201,4 @@

/// shorter than `self`, `self` will be truncated when the other stream expires.
impl<E, T, I> BitAndAssign<I> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> {
impl<C, T, I> BitAndAssign<I> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits, I: IntoIterator<Item=bool> {
/// `AND`s another bitstream into a vector.

@@ -1230,4 +1230,4 @@ ///

/// other, the extra bits will be ignored.
impl<E, T, I> BitOr<I> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> {
impl<C, T, I> BitOr<I> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits, I: IntoIterator<Item=bool> {
type Output = Self;

@@ -1255,4 +1255,4 @@

/// shorter than `self`, `self` will be truncated when the other stream expires.
impl<E, T, I> BitOrAssign<I> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> {
impl<C, T, I> BitOrAssign<I> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits, I: IntoIterator<Item=bool> {
/// `OR`s another bitstream into a vector.

@@ -1284,4 +1284,4 @@ ///

/// other, the extra bits will be ignored.
impl<E, T, I> BitXor<I> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> {
impl<C, T, I> BitXor<I> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits, I: IntoIterator<Item=bool> {
type Output = Self;

@@ -1309,4 +1309,4 @@

/// shorter than `self`, `self` will be truncated when the other stream expires.
impl<E, T, I> BitXorAssign<I> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits, I: IntoIterator<Item=bool> {
impl<C, T, I> BitXorAssign<I> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits, I: IntoIterator<Item=bool> {
/// `XOR`s another bitstream into a vector.

@@ -1336,5 +1336,5 @@ ///

/// This mimics the separation between `Vec<T>` and `[T]`.
impl<E, T> Deref for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
type Target = crate::BitSlice<E, T>;
impl<C, T> Deref for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
type Target = crate::BitSlice<C, T>;

@@ -1361,4 +1361,4 @@ /// Dereferences `&BitVec` down to `&BitSlice`.

/// This mimics the separation between `Vec<T>` and `[T]`.
impl<E, T> DerefMut for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> DerefMut for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Dereferences `&mut BitVec` down to `&mut BitSlice`.

@@ -1382,4 +1382,4 @@ ///

/// Readies the underlying storage for Drop.
impl<E, T> Drop for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Drop for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Restore the interior `Vec` to sane condition before it drops.

@@ -1397,4 +1397,4 @@ fn drop(&mut self) {

/// the `BitVec`.
impl<E, T> Index<usize> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Index<usize> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
type Output = bool;

@@ -1429,3 +1429,3 @@

let (elt, bit) = T::split(cursor);
if (self.inner[elt]).get(E::curr::<T>(bit)) { &true } else { &false }
if (self.inner[elt]).get(C::curr::<T>(bit)) { &true } else { &false }
}

@@ -1445,4 +1445,4 @@ }

/// This index is not recommended for public use.
impl<E, T> Index<(usize, u8)> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Index<(usize, u8)> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
type Output = bool;

@@ -1463,3 +1463,3 @@

assert!(T::join(elt, bit) < self.len(), "Index out of range!");
if (self.inner[elt]).get(E::curr::<T>(bit)) { &true } else { &false }
if (self.inner[elt]).get(C::curr::<T>(bit)) { &true } else { &false }
}

@@ -1478,4 +1478,4 @@ }

/// correctness in arithmetic at this time.
impl<E, T> Neg for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Neg for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
type Output = Self;

@@ -1500,3 +1500,3 @@

self = !self;
self += BitVec::<E, T>::from(&[true] as &[bool]);
self += BitVec::<C, T>::from(&[true] as &[bool]);
self

@@ -1513,4 +1513,4 @@ }

/// rather than a consuming/returning operator.
impl<E, T> Not for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Not for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
type Output = Self;

@@ -1568,4 +1568,4 @@

/// and zeroes its memory. This is *not* an error.
impl<E, T> Shl<usize> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Shl<usize> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
type Output = Self;

@@ -1622,4 +1622,4 @@

/// and zeroes its memory. This is *not* an error.
impl<E, T> ShlAssign<usize> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> ShlAssign<usize> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Shifts a `BitVec` to the left in place, shortening it.

@@ -1691,4 +1691,4 @@ ///

/// error.
impl<E, T> Shr<usize> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Shr<usize> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
type Output = Self;

@@ -1747,4 +1747,4 @@

/// error.
impl<E, T> ShrAssign<usize> for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> ShrAssign<usize> for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Shifts a `BitVec` to the right in place, lengthening it and filling the

@@ -1809,4 +1809,4 @@ /// front with 0.

/// correctness in arithmetic at this time.
impl<E, T> Sub for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Sub for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
type Output = Self;

@@ -1865,4 +1865,4 @@

/// correctness in arithmetic at this time.
impl<E, T> SubAssign for BitVec<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> SubAssign for BitVec<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Subtracts another `BitVec` from `self`.

@@ -1919,5 +1919,5 @@ ///

#[doc(hidden)]
pub struct IntoIter<E, T>
where E: crate::Endian, T: crate::Bits {
bv: BitVec<E, T>,
pub struct IntoIter<C, T>
where C: crate::Cursor, T: crate::Bits {
bv: BitVec<C, T>,
head: usize,

@@ -1927,5 +1927,5 @@ tail: usize,

impl<E, T> IntoIter<E, T>
where E: crate::Endian, T: crate::Bits {
fn new(bv: BitVec<E, T>) -> Self {
impl<C, T> IntoIter<C, T>
where C: crate::Cursor, T: crate::Bits {
fn new(bv: BitVec<C, T>) -> Self {
let tail = bv.len();

@@ -1945,4 +1945,4 @@ Self {

impl<E, T> DoubleEndedIterator for IntoIter<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> DoubleEndedIterator for IntoIter<C, T>
where C: crate::Cursor, T: crate::Bits {
/// Yields the back-most bit of the collection.

@@ -1966,4 +1966,4 @@ ///

impl<E, T> ExactSizeIterator for IntoIter<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> ExactSizeIterator for IntoIter<C, T>
where C: crate::Cursor, T: crate::Bits {
// Override the default implementation with a fixed calculation. The type

@@ -1984,5 +1984,5 @@ // is guaranteed to be well-behaved, so there is no point in building two

impl<E, T> From<BitVec<E, T>> for IntoIter<E, T>
where E: crate::Endian, T: crate::Bits {
fn from(bv: BitVec<E, T>) -> Self {
impl<C, T> From<BitVec<C, T>> for IntoIter<C, T>
where C: crate::Cursor, T: crate::Bits {
fn from(bv: BitVec<C, T>) -> Self {
Self::new(bv)

@@ -1992,4 +1992,4 @@ }

impl<E, T> Iterator for IntoIter<E, T>
where E: crate::Endian, T: crate::Bits {
impl<C, T> Iterator for IntoIter<C, T>
where C: crate::Cursor, T: crate::Bits {
type Item = bool;

@@ -1996,0 +1996,0 @@

# Development Notes
## Features
By default, this crate assumes `std` is present, and links against it.
`#![no_std]` can be turned on by disabling default features and enabling the
`alloc` feature, with either the `--features=alloc` Cargo flag or the
```toml
[dependencies.bitvec]
version = "*"
default-features = false
features = ["alloc"]
```
configuration.
The `alloc` feature links agains the `alloc` crate, and changes the symbol
imports needed to retain full functionality even without `std`.
Disabling the `alloc` feature removes the `BitVec` type, the `bitvec!` macro,
and all dynamic memory usage. The `BitSlice` type only loses its formatting
traits.
The configuration attributes in the source code are arrayed in order of
increasing functionality. That is, `#[cfg(not(feature = "alloc"))]` is first,
since it is only true when both `alloc` and `std` features are disabled, then
`#[cfg(all(feature = "alloc", not(feature = "std")))]` is second, since it is
true when `alloc` is enabled but `std` is not, and `#[cfg(feature = "std")]` is
last, since it is true when both `alloc` and `std` are present.
The `std` feature depends on `alloc`, so it is impossible to have `std` enabled
but `alloc` disabled.
/*! Endianness Markers
`BitVec` does not have a concept of byte- or element- level endianness, but
*does* have a concept of bit-level endianness. This module defines orders of
traversal of an element in the `BitVec` storage.
!*/
use super::bits::Bits;
/// Travels an element starting at the Most Significant Bit and ending at the
/// Least Significant Bit.
pub struct BigEndian;
/// Travels an element starting at the Least Significant Bit and ending at the
/// Most Significant Bit.
pub struct LittleEndian;
/** A manipulator trait for Endianness.
# Usage
`BitVec` stores semantic count, not a cursor into an element, as its `bits`
value. The methods on `Endian` all return a cursor into a storage element.
- `curr` computes the bit index of the count given. In Little-Endian order, this
is the identity function (bit indices count up “left” from LSb), and in
Big-Endian order, this subtracts the count given from `T::MASK` (bit indices
count down “right” from MSb).
- `next` computes the next index forward from the count given. In Little-Endian
order, this increments (moving up from LSb towards MSb); in Big-Endian order,
this decrements (moving down from MSb towards LSb).
- `prev` computes the previous index backward from the count given. In
Little-Endian order, this decrements (moving down towards LSb from MSb); in
Big-Endian order, this increments (moving up towards MSb from LSb).
- `jump` computes a number of whole elements to move, as well as the bit index
within the destination element of the target bit.
You should use `curr` to look up a bit at a known point, such as when indexing a
`BitVec`; you should use `next` or `prev` to implement push, pop, and iteration;
you should use `jump` only to implement striding iterators in a manner faster
than the default (which just repeatedly calls `next` and drops most yielded
values).
# Notes
All functions *take* a semantic count into a storage element, which will always
move upwards from zero, but all functions *return* an actual index to a specific
bit in the element achieved by shifting right and masking off all but the LSb of
the output. The output is *not* a semantic count, and does not need converted to
an index with `curr`. It therefore cannot be stored as the new semantic count
during a mutation. The caller is responsible for maintaining count status.
`next` and `prev` signal when they cross the boundary of a storage element. If
their second return value is true, then the first return value is an index into
the storage element either after (`next`) or before (`prev`) the element for
which the input count referred. The caller is responsible for ensuring that they
use the returned index in the correct storage element by inspecting this flag
and moving their selection accordingly.
`jump` returns the number of storage elements the caller will have to move their
cursor before indexing. `next` and `prev` can only move zero or one elements, so
their flag is a `bool` rather than an `isize`. The order swap for `jump` is
because the number of elements to move is expected to be a more significant part
of its return value than the edge flag is in `next` and `prev`.
**/
pub trait Endian {
/// Compute the bit index at a given count.
///
/// In Little-Endian, this is a no-op; in Big-Endian, it subtracts the index
/// from `T::MASK` (the maximum value).
fn curr<T: Bits>(count: u8) -> u8;
/// Compute the semantic index that logically follows the given index.
///
/// The first value returned must be passed into `curr` in order to index
/// into an element. The second value indicates whether the increment points
/// into a different element.
fn next<T: Bits>(count: u8) -> (u8, bool) {
let next = count.wrapping_add(1) & T::MASK;
let wrap = next == 0;
(next, wrap)
}
/// Compute the semantic index that logically precedes the given index.
///
/// The first value returned must be passed into `curr` in order to index
/// into an element. The second value indicates whether the decrement points
/// into a different element.
fn prev<T: Bits>(count: u8) -> (u8, bool) {
let (next, wrap) = count.overflowing_sub(1);
(next & T::MASK, wrap)
}
/// Computes the bit index at a given semantic offset from the current
/// cursor.
///
/// Returns a tuple where the first value is the number of whole storage
/// elements to move, and the second is the bit index within the element.
fn jump<T: Bits>(count: u8, offset: isize) -> (isize, u8) {
assert!(count < T::WIDTH, "Bit count out of range for the storage type");
// Add offset to *count*, not to the current bit index, because this
// math doesn't know how to move around in an ordering. The offset is
// signed in count order, not Endian order.
// Subtraction can never fail, because count is always >= 0 and
// `0 - isize::MIN` is `isize::MIN`, which does not overflow.
// In a non-overflowing addition, the result will be the position of
// the target bit
match (count as isize).overflowing_add(offset) {
// If the addition overflows, then the offset is positive. Add as
// unsigned and use that.
// Note that this is guaranteed not to overflow `usize::MAX`
// because converting two positive signed integers to unsigned
// doubles the domain, which will always be enormously wider than
// the domain of count.
(_, true) => {
let far = Self::curr::<T>(count) as usize + offset as usize;
// The number of elements advanced is, conveniently, the number
// of bits advanced integer-divided by the number of bits in
// the elements, which even more conveniently, is equivalent to
// right-shift by the number of bits required to index an
// element. Note that we don't cast until *after* the shift, in
// order to ensure that it is zero-filled at the high bits.
let elements = (far >> T::BITS) as isize;
// The new bit position of the cursor is the new position
// modulo the number of bits in the element (equivalent to
// bit-and of the provided mask).
let pos = (far & (T::MASK as usize)) as u8;
(elements, pos)
},
// If `far` is negative, then the jump leaves the element going
// backward. If `far` is greater than `T::MASK`, then the jump
// leaves the element going forward.
(far, _) if far < 0 || far > T::MASK as isize => {
let elements = far >> T::BITS;
let pos = (far & (T::MASK as isize)) as u8;
(elements, Self::curr::<T>(pos))
},
// Otherwise, `far` is the *bit count* in the current element. It
// must still be converted from count to bit index.
(far, _) => {
(0, Self::curr::<T>(far as u8))
},
}
}
#[doc(hidden)]
const TY: &'static str = "";
}
impl Endian for BigEndian {
fn curr<T: Bits>(count: u8) -> u8 {
assert!(count < T::WIDTH, "Index out of range of the storage type");
T::MASK - count
}
const TY: &'static str = "BigEndian";
}
impl Endian for LittleEndian {
fn curr<T: Bits>(count: u8) -> u8 {
assert!(count < T::WIDTH, "Index out of range of the storage type");
count
}
const TY: &'static str = "LittleEndian";
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn incr_edge() {
assert_eq!(LittleEndian::next::<u8>(7), (0, true));
assert_eq!(BigEndian::next::<u8>(7), (0, true));
assert_eq!(LittleEndian::next::<u16>(15), (0, true));
assert_eq!(BigEndian::next::<u16>(15), (0, true));
assert_eq!(LittleEndian::next::<u32>(31), (0, true));
assert_eq!(BigEndian::next::<u32>(31), (0, true));
assert_eq!(LittleEndian::next::<u64>(63), (0, true));
assert_eq!(BigEndian::next::<u64>(63), (0, true));
}
#[test]
fn decr_edge() {
assert_eq!(LittleEndian::prev::<u8>(0), (7, true));
assert_eq!(BigEndian::prev::<u8>(0), (7, true));
assert_eq!(LittleEndian::prev::<u16>(0), (15, true));
assert_eq!(BigEndian::prev::<u16>(0), (15, true));
assert_eq!(LittleEndian::prev::<u32>(0), (31, true));
assert_eq!(BigEndian::prev::<u32>(0), (31, true));
assert_eq!(LittleEndian::prev::<u64>(0), (63, true));
assert_eq!(BigEndian::prev::<u64>(0), (63, true));
}
#[test]
fn jump_inside_elt() {
// TODO(myrrlyn): test the other two types.
let (elt, bit) = LittleEndian::jump::<u8>(5, 2);
assert_eq!(elt, 0);
assert_eq!(bit, 7);
// Counts start from 0, so count 5 is the SIXTH bit
let (elt, bit) = BigEndian::jump::<u8>(5, 2);
assert_eq!(elt, 0);
assert_eq!(bit, 0);
let (elt, bit) = LittleEndian::jump::<u32>(20, 8);
assert_eq!(elt, 0);
assert_eq!(bit, 28);
// In Big-Endian order, count 20 is bit 11, and moving that backward by
// 8 is addition, up to 19.
let (elt, bit) = BigEndian::jump::<u32>(20, -8);
assert_eq!(elt, 0);
assert_eq!(bit, 19);
}
#[test]
fn jump_backwards() {
// TODO(myrrlyn): Test the other three types.
let (elt, bit) = LittleEndian::jump::<u32>(10, -15);
assert_eq!(elt, -1);
// Moving backwards through LE starts at MSb and decrements
// 10 - 10 is 0, 0 - 1 is 31, 31 - 4 is 27
assert_eq!(bit, 27);
let (elt, bit) = BigEndian::jump::<u32>(10, -15);
assert_eq!(elt, -1);
// Moving backwards through BE starts at LSb and increments
// 10 - 10 is count 0 (bit 31), then the cursor crosses the boundary
// and counts 0, 1, 2, 3, 4.
assert_eq!(bit, 4);
}
#[test]
fn jump_forwards() {
// TODO(myrrlyn): Test the other three types.
let (elt, bit) = LittleEndian::jump::<u32>(25, 10);
assert_eq!(elt, 1);
assert_eq!(bit, 3);
let (elt, bit) = BigEndian::jump::<u32>(25, 10);
assert_eq!(elt, 1);
// Moving forwards through BE starts at MSb and decrements. 25 + 6 is
// count 31 (bit 0), then the cursor crosses the boundary and counts
// 31, 30, 29, 28.
assert_eq!(bit, 28);
}
#[test]
fn jump_overflow() {
// TODO(myrrlyn): Test the other three types.
// Force an overflowing stride. We expect the destination bit *count*
// to be one less than the starting point (which on BigEndian will be
// `MASK - start - 1`), and the elements skipped to be
// `isize::MIN >> BITS` (an overflowing isize add will set the high bit
// as the `usize` repr).
let start = 20;
let (elt, bit) = LittleEndian::jump::<u32>(start, core::isize::MAX);
assert_eq!(elt as usize, core::isize::MIN as usize >> u32::BITS);
assert_eq!(bit, start - 1);
let (elt, bit) = BigEndian::jump::<u32>(start, core::isize::MAX);
assert_eq!(elt as usize, core::isize::MIN as usize >> u32::BITS);
assert_eq!(bit, BigEndian::curr::<u32>(start) - 1);
}
#[test]
fn curr_reversible() {
for n in 0 .. 8 {
assert_eq!(n, BigEndian::curr::<u8>(BigEndian::curr::<u8>(n)));
}
for n in 0 .. 16 {
assert_eq!(n, BigEndian::curr::<u16>(BigEndian::curr::<u16>(n)));
}
for n in 0 .. 32 {
assert_eq!(n, BigEndian::curr::<u32>(BigEndian::curr::<u32>(n)));
}
for n in 0 .. 64 {
assert_eq!(n, BigEndian::curr::<u64>(BigEndian::curr::<u64>(n)));
}
for n in 0 .. 8 {
assert_eq!(n, LittleEndian::curr::<u8>(LittleEndian::curr::<u8>(n)));
}
for n in 0 .. 16 {
assert_eq!(n, LittleEndian::curr::<u16>(LittleEndian::curr::<u16>(n)));
}
for n in 0 .. 32 {
assert_eq!(n, LittleEndian::curr::<u32>(LittleEndian::curr::<u32>(n)));
}
for n in 0 .. 64 {
assert_eq!(n, LittleEndian::curr::<u64>(LittleEndian::curr::<u64>(n)));
}
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet