Sign In

bitvec

Package Overview
Dependencies
Maintainers
1
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

Comparing version
0.21.2
to
0.22.0
+225
src/boxed/iter.rs
//! By-value buffer iteration.
use core::{
fmt::{
self,
Debug,
Formatter,
},
iter::FusedIterator,
};
use super::BitBox;
use crate::{
order::BitOrder,
ptr::{
BitPtrRange,
Mut,
},
slice::BitSlice,
store::BitStore,
};
/// This is not present on `Box<[T]>`, but is needed to fit into the general
/// operator implementations.
#[cfg(not(tarpaulin_include))]
impl<O, T> IntoIterator for BitBox<O, T>
where
O: BitOrder,
T: BitStore,
{
type IntoIter = IntoIter<O, T>;
type Item = bool;
#[inline(always)]
fn into_iter(self) -> Self::IntoIter {
IntoIter::new(self)
}
}
/** An iterator that moves out of a [`BitVec`].
This `struct` is created by the [`into_iter`] method on [`BitVec`] (provided by
the [`IntoIterator`] trait).
# Original
[`vec::IntoIter`](alloc::vec::IntoIter)
[`BitVec`]: crate::vec::BitVec
[`IntoIterator`]: core::iter::IntoIterator
[`into_iter`]: core::iter::IntoIterator::into_iter
**/
pub struct IntoIter<O, T>
where
O: BitOrder,
T: BitStore,
{
/// The buffer being iterated.
_buf: BitBox<O, T>,
/// A bit-pointer iterator over the buffer’s contents.
iter: BitPtrRange<Mut, O, T>,
}
impl<O, T> IntoIter<O, T>
where
O: BitOrder,
T: BitStore,
{
/// Constructs an iterator over a [`BitBox`] or [`BitVec`].
///
/// [`BitBox`]: crate::vec::BitBox
/// [`BitVec`]: crate::vec::BitVec
fn new(mut this: BitBox<O, T>) -> Self {
let iter = this.as_mut_bitptr_range();
Self { _buf: this, iter }
}
/// Returns the remaining bits of this iterator as a [`BitSlice`].
///
/// # Original
///
/// [`vec::IntoIter::as_slice`](alloc::vec::IntoIter::as_slice)
///
/// # Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let bv = bitvec![0, 1, 0, 1];
/// let mut into_iter = bv.into_iter();
///
/// assert_eq!(into_iter.as_bitslice(), bits![0, 1, 0, 1]);
/// let _ = into_iter.next().unwrap();
/// assert_eq!(into_iter.as_bitslice(), bits![1, 0, 1]);
/// ```
///
/// [`BitSlice`]: crate::slice::BitSlice
#[inline]
pub fn as_bitslice(&self) -> &BitSlice<O, T> {
self.iter.clone().into_bitspan().to_bitslice_ref()
}
#[doc(hidden)]
#[inline(always)]
#[cfg(not(tarpalin_include))]
#[deprecated = "Use `as_bitslice` to view the underlying slice"]
pub fn as_slice(&self) -> &BitSlice<O, T> {
self.as_bitslice()
}
/// Returns the remaining bits of this iterator as a mutable [`BitSlice`].
///
/// # Original
///
/// [`vec::IntoIter::as_mut_slice`](alloc::vec::IntoIter::as_mut_slice)
///
/// # Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let bv = bitvec![0, 1, 0, 1];
/// let mut into_iter = bv.into_iter();
///
/// assert_eq!(into_iter.as_bitslice(), bits![0, 1, 0, 1]);
/// into_iter.as_mut_bitslice().set(2, true);
/// assert!(!into_iter.next().unwrap());
/// assert!(into_iter.next().unwrap());
/// assert!(into_iter.next().unwrap());
/// ```
///
/// [`BitSlice`]: crate::slice::BitSlice
#[inline]
pub fn as_mut_bitslice(&mut self) -> &mut BitSlice<O, T> {
self.iter.clone().into_bitspan().to_bitslice_mut()
}
#[doc(hidden)]
#[inline(always)]
#[cfg(not(tarpaulin_include))]
#[deprecated = "Use `as_mut_bitslice` to view the underlying slice"]
pub fn as_mut_slice(&mut self) -> &mut BitSlice<O, T> {
self.as_mut_bitslice()
}
}
#[cfg(not(tarpaulin_include))]
impl<O, T> Debug for IntoIter<O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
fmt.debug_tuple("IntoIter")
.field(&self.as_bitslice())
.finish()
}
}
impl<O, T> Iterator for IntoIter<O, T>
where
O: BitOrder,
T: BitStore,
{
type Item = bool;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(crate::ptr::range::read_raw)
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
#[inline(always)]
fn count(self) -> usize {
self.len()
}
#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.iter.nth(n).map(crate::ptr::range::read_raw)
}
#[inline(always)]
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
}
impl<O, T> DoubleEndedIterator for IntoIter<O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.next_back().map(crate::ptr::range::read_raw)
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.iter.nth_back(n).map(crate::ptr::range::read_raw)
}
}
impl<O, T> ExactSizeIterator for IntoIter<O, T>
where
O: BitOrder,
T: BitStore,
{
#[inline(always)]
fn len(&self) -> usize {
self.iter.len()
}
}
impl<O, T> FusedIterator for IntoIter<O, T>
where
O: BitOrder,
T: BitStore,
{
}
+1
-1
{
"git": {
"sha1": "ce89796b29a1ce5a9f668527a72001ab38d67935"
"sha1": "8aa9cdceb53490f4042e11578c3a5d2dcba701a9"
}
}

@@ -14,6 +14,3 @@ /*! Benchmarks for `BitSlice::copy_from_slice`.

use bitvec::{
mem::{
elts,
BitMemory,
},
mem::elts,
prelude::*,

@@ -29,2 +26,3 @@ };

};
use funty::IsNumber;
use tap::tap::Tap;

@@ -73,3 +71,3 @@

move |name| BenchmarkId::new(name, n),
n * FACTOR * <u8 as BitMemory>::BITS as usize,
n * FACTOR * <u8 as IsNumber>::BITS as usize,
Throughput::Bytes((n * FACTOR) as u64),

@@ -99,4 +97,4 @@ )

group.throughput(thrpt);
let words = bits / <usize as BitMemory>::BITS as usize;
let bytes = bits / <u8 as BitMemory>::BITS as usize;
let words = bits / <usize as IsNumber>::BITS as usize;
let bytes = bits / <u8 as IsNumber>::BITS as usize;

@@ -142,4 +140,4 @@ let (src_words, dst_words) =

group.throughput(thrpt);
let words = bits / <usize as BitMemory>::BITS as usize;
let bytes = bits / <u8 as BitMemory>::BITS as usize;
let words = bits / <usize as IsNumber>::BITS as usize;
let bytes = bits / <u8 as IsNumber>::BITS as usize;

@@ -207,4 +205,4 @@ let (src_words, dst_words) =

group.throughput(thrpt);
let words = bits / <usize as BitMemory>::BITS as usize;
let bytes = bits / <u8 as BitMemory>::BITS as usize;
let words = bits / <usize as IsNumber>::BITS as usize;
let bytes = bits / <u8 as IsNumber>::BITS as usize;

@@ -211,0 +209,0 @@ let (src_words, dst_words) =

# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]

@@ -40,3 +38,3 @@ name = "atty"

name = "bitvec"
version = "0.21.2"
version = "0.22.0"
dependencies = [

@@ -684,4 +682,7 @@ "bincode",

name = "wyz"
version = "0.2.0"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
checksum = "129e027ad65ce1453680623c3fb5163cbf7107bfe1aa32257e7d0e63f9ced188"
dependencies = [
"tap",
]

@@ -16,3 +16,3 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO

name = "bitvec"
version = "0.21.2"
version = "0.22.0"
authors = ["myrrlyn <self@myrrlyn.dev>"]

@@ -50,3 +50,3 @@ include = ["Cargo.toml", "LICENSE.txt", "README.md", "src/**/*.rs", "benches/*.rs"]

[dependencies.wyz]
version = "0.2"
version = "0.4"
default-features = false

@@ -53,0 +53,0 @@ [dev-dependencies.bincode]

@@ -24,2 +24,3 @@ /*! Memory access guards.

use funty::IsInteger;
use radium::Radium;

@@ -83,3 +84,3 @@

fn clear_bits(&self, mask: BitMask<Self::Item>) {
self.fetch_and(!mask.value(), atomic::Ordering::Relaxed);
self.fetch_and(!mask.into_inner(), atomic::Ordering::Relaxed);
}

@@ -106,3 +107,3 @@

fn set_bits(&self, mask: BitMask<Self::Item>) {
self.fetch_or(mask.value(), atomic::Ordering::Relaxed);
self.fetch_or(mask.into_inner(), atomic::Ordering::Relaxed);
}

@@ -129,3 +130,3 @@

fn invert_bits(&self, mask: BitMask<Self::Item>) {
self.fetch_xor(mask.value(), atomic::Ordering::Relaxed);
self.fetch_xor(mask.into_inner(), atomic::Ordering::Relaxed);
}

@@ -145,2 +146,9 @@

///
/// # Returns
///
/// The bit previously stored in `*self` at `index`. As these operations are
/// required to load the `*self` value from memory in order to work, the
/// previous value can be retained to reduce spurious loads elsewhere in the
/// crate.
///
/// # Effects

@@ -151,16 +159,12 @@ ///

/// other bits are unchanged.
fn write_bit<O>(&self, index: BitIdx<Self::Item>, value: bool)
fn write_bit<O>(&self, index: BitIdx<Self::Item>, value: bool) -> bool
where O: BitOrder {
if value {
self.fetch_or(
index.select::<O>().value(),
atomic::Ordering::Relaxed,
);
}
else {
self.fetch_and(
!index.select::<O>().value(),
atomic::Ordering::Relaxed,
);
}
let select = index.select::<O>().into_inner();
select
& if value {
self.fetch_or(select, atomic::Ordering::Relaxed)
}
else {
self.fetch_and(!select, atomic::Ordering::Relaxed)
} != <Self::Item>::ZERO
}

@@ -302,3 +306,9 @@

let bits = data.view_bits_mut::<LocalBits>();
let accessor = unsafe { &*(bits.as_bitspan().address().to_access()) };
let accessor = unsafe {
&*(bits
.as_bitspan()
.address()
.cast::<<u8 as BitStore>::Access>())
.to_const()
};
let aliased = unsafe {

@@ -305,0 +315,0 @@ &*(bits.as_bitspan().address().to_const()

@@ -30,5 +30,11 @@ /*! A statically-allocated, fixed-size, buffer containing a [`BitSlice`] region.

slice::BitSlice,
view::BitView,
view::BitViewSized,
};
mod iter;
mod ops;
mod traits;
pub use self::iter::IntoIter;
/* Note on C++ `std::bitset<N>` compatibility:

@@ -153,3 +159,3 @@

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -165,3 +171,3 @@ /// The ordering of bits within a storage element `V::Store`.

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -204,7 +210,7 @@ /// Constructs a new `BitArray` with its memory set to zero.

/// let bitarr = bitarr![Lsb0, usize; 0; 30];
/// let native: [usize; 1] = bitarr.value();
/// let native: [usize; 1] = bitarr.into_inner();
/// ```
#[inline(always)]
#[cfg(not(tarpaulin_include))]
pub fn value(self) -> V {
pub fn into_inner(self) -> V {
self.data

@@ -237,3 +243,3 @@ }

&self.data as *const V as *const V::Store,
V::const_elts(),
V::ELTS,
)

@@ -249,3 +255,3 @@ }

&mut self.data as *mut V as *mut V::Store,
V::const_elts(),
V::ELTS,
)

@@ -286,9 +292,3 @@ }

mod iter;
mod ops;
mod traits;
pub use self::iter::IntoIter;
#[cfg(test)]
mod tests;

@@ -15,9 +15,11 @@ //! Array iteration.

use super::BitArray;
use crate::{
array::BitArray,
mutability::Const,
order::BitOrder,
ptr::BitPtr,
ptr::{
BitPtr,
Const,
},
slice::BitSlice,
view::BitView,
view::BitViewSized,
};

@@ -31,9 +33,2 @@

# API Differences
The standard-library iterator is still unstable, as it depends on
const-generics. The [`BitView`] trait provides a rough simulacrum of
const-generic arrays until this feature stabilizes for use outside the standard
libraries.
[bit-array]: crate::array::BitArray

@@ -46,3 +41,3 @@ [`BitView`]: crate::view::BitView

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -56,3 +51,3 @@ /// The array being iterated.

/// - `alive.start <= alive.end`
/// - `alive.end <= V::const_bits()`
/// - `alive.end <= V::BITS`
alive: Range<usize>,

@@ -64,3 +59,3 @@ }

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -76,3 +71,3 @@ /// Creates a new iterator over the given `array`.

array,
alive: 0 .. V::const_bits(),
alive: 0 .. V::BITS,
}

@@ -138,3 +133,3 @@ }

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -152,3 +147,3 @@ #[inline]

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -189,3 +184,3 @@ type Item = bool;

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -207,3 +202,3 @@ #[inline]

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -219,4 +214,4 @@ #[inline(always)]

O: BitOrder,
V: BitView,
V: BitViewSized,
{
}

@@ -17,14 +17,15 @@ //! Port of the `[T; N]` operator implementations.

use super::BitArray;
use crate::{
array::BitArray,
order::BitOrder,
slice::BitSlice,
store::BitStore,
view::BitView,
view::BitViewSized,
};
#[cfg(not(tarpaulin_include))]
impl<O, V, Rhs> BitAnd<Rhs> for BitArray<O, V>
where
O: BitOrder,
V: BitView,
V: BitViewSized,
BitSlice<O, V::Store>: BitAndAssign<Rhs>,

@@ -41,6 +42,7 @@ {

#[cfg(not(tarpaulin_include))]
impl<O, V, Rhs> BitAndAssign<Rhs> for BitArray<O, V>
where
O: BitOrder,
V: BitView,
V: BitViewSized,
BitSlice<O, V::Store>: BitAndAssign<Rhs>,

@@ -54,6 +56,7 @@ {

#[cfg(not(tarpaulin_include))]
impl<O, V, Rhs> BitOr<Rhs> for BitArray<O, V>
where
O: BitOrder,
V: BitView,
V: BitViewSized,
BitSlice<O, V::Store>: BitOrAssign<Rhs>,

@@ -70,6 +73,7 @@ {

#[cfg(not(tarpaulin_include))]
impl<O, V, Rhs> BitOrAssign<Rhs> for BitArray<O, V>
where
O: BitOrder,
V: BitView,
V: BitViewSized,
BitSlice<O, V::Store>: BitOrAssign<Rhs>,

@@ -83,6 +87,7 @@ {

#[cfg(not(tarpaulin_include))]
impl<O, V, Rhs> BitXor<Rhs> for BitArray<O, V>
where
O: BitOrder,
V: BitView,
V: BitViewSized,
BitSlice<O, V::Store>: BitXorAssign<Rhs>,

@@ -99,6 +104,7 @@ {

#[cfg(not(tarpaulin_include))]
impl<O, V, Rhs> BitXorAssign<Rhs> for BitArray<O, V>
where
O: BitOrder,
V: BitView,
V: BitViewSized,
BitSlice<O, V::Store>: BitXorAssign<Rhs>,

@@ -116,3 +122,3 @@ {

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -131,3 +137,3 @@ type Target = BitSlice<O, V::Store>;

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -140,6 +146,7 @@ #[inline(always)]

#[cfg(not(tarpaulin_include))]
impl<O, V, Idx> Index<Idx> for BitArray<O, V>
where
O: BitOrder,
V: BitView,
V: BitViewSized,
BitSlice<O, V::Store>: Index<Idx>,

@@ -155,6 +162,7 @@ {

#[cfg(not(tarpaulin_include))]
impl<O, V, Idx> IndexMut<Idx> for BitArray<O, V>
where
O: BitOrder,
V: BitView,
V: BitViewSized,
BitSlice<O, V::Store>: IndexMut<Idx>,

@@ -171,3 +179,3 @@ {

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -174,0 +182,0 @@ type Output = Self;

@@ -7,3 +7,6 @@ //! Unit tests for the `array` module.

use crate::prelude::*;
use crate::{
prelude::*,
view::BitViewSized,
};

@@ -35,3 +38,3 @@ #[test]

let bits = BitArray::<LocalBits, _>::new(data);
assert_eq!(bits.value(), data);
assert_eq!(bits.into_inner(), data);
}

@@ -80,3 +83,3 @@

let mut iter = bitarr![0, 0, 0, 1, 1, 1, 0, 0, 0].into_iter();
let width = <[usize; 1] as BitView>::const_bits();
let width = <[usize; 1] as BitViewSized>::BITS;

@@ -83,0 +86,0 @@ let slice = iter.as_slice();

@@ -26,7 +26,7 @@ //! Non-operator trait implementations.

use super::{
BitArray,
IntoIter,
};
use crate::{
array::{
iter::IntoIter,
BitArray,
},
index::BitIdx,

@@ -36,3 +36,3 @@ order::BitOrder,

store::BitStore,
view::BitView,
view::BitViewSized,
};

@@ -44,3 +44,3 @@

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -57,3 +57,3 @@ #[inline(always)]

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -69,3 +69,3 @@ #[inline(always)]

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -87,3 +87,3 @@ #[inline]

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -95,3 +95,3 @@ }

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -108,3 +108,3 @@ #[inline]

O2: BitOrder,
V: BitView,
V: BitViewSized,
T: BitStore,

@@ -121,3 +121,3 @@ {

O: BitOrder,
V: BitView,
V: BitViewSized,
Rhs: ?Sized,

@@ -135,3 +135,3 @@ BitSlice<O, V::Store>: PartialEq<Rhs>,

O: BitOrder,
V: BitView,
V: BitViewSized,
T: BitStore,

@@ -148,3 +148,3 @@ {

O: BitOrder,
V: BitView,
V: BitViewSized,
Rhs: ?Sized,

@@ -163,3 +163,3 @@ BitSlice<O, V::Store>: PartialOrd<Rhs>,

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -176,3 +176,3 @@ #[inline(always)]

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -189,3 +189,3 @@ #[inline(always)]

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -201,3 +201,3 @@ #[inline(always)]

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -208,3 +208,3 @@ type Error = TryFromBitSliceError<'a, O, V::Store>;

fn try_from(src: &'a BitSlice<O, V::Store>) -> Result<Self, Self::Error> {
if src.len() != V::const_bits() {
if src.len() != V::BITS {
return Self::Error::err(src);

@@ -221,3 +221,3 @@ }

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -231,3 +231,3 @@ type Error = TryFromBitSliceError<'a, O, V::Store>;

// the array, and is aligned to the front of the element.
if src.len() != V::const_bits() || bitspan.head() != BitIdx::ZERO {
if src.len() != V::BITS || bitspan.head() != BitIdx::ZERO {
return Self::Error::err(src);

@@ -242,3 +242,3 @@ }

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -252,3 +252,3 @@ type Error = TryFromBitSliceError<'a, O, V::Store>;

let bitspan = src.as_mut_bitspan();
if src.len() != V::const_bits() || bitspan.head() != BitIdx::ZERO {
if src.len() != V::BITS || bitspan.head() != BitIdx::ZERO {
return Self::Error::err(&*src);

@@ -264,3 +264,3 @@ }

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -277,3 +277,3 @@ #[inline(always)]

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -289,3 +289,3 @@ #[inline]

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -304,3 +304,3 @@ #[inline]

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -317,3 +317,3 @@ #[inline]

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -330,3 +330,3 @@ #[inline]

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -343,3 +343,3 @@ #[inline]

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -356,3 +356,3 @@ #[inline]

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -370,3 +370,3 @@ #[inline]

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -386,3 +386,3 @@ type IntoIter = IntoIter<O, V>;

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -402,3 +402,3 @@ type IntoIter = <&'a BitSlice<O, V::Store> as IntoIterator>::IntoIter;

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -417,3 +417,3 @@ type IntoIter = <&'a mut BitSlice<O, V::Store> as IntoIterator>::IntoIter;

O: BitOrder,
V: BitView + Copy,
V: BitViewSized + Copy,
{

@@ -425,3 +425,3 @@ }

O: BitOrder,
V: BitView,
V: BitViewSized,
{

@@ -428,0 +428,0 @@ }

@@ -43,3 +43,2 @@ /*! A dynamically-allocated, fixed-size, buffer containing a [`BitSlice`]

index::BitIdx,
mutability::Mut,
order::{

@@ -52,2 +51,3 @@ BitOrder,

BitSpan,
Mut,
},

@@ -59,2 +59,9 @@ slice::BitSlice,

mod api;
mod iter;
mod ops;
mod traits;
pub use iter::IntoIter;
/** A frozen heap-allocated buffer of individual bits.

@@ -161,2 +168,3 @@

/// [`BitVec::from_bitslice`]: crate::vec::BitVec::from_bitslice
#[inline]
pub fn from_bitslice(slice: &BitSlice<O, T>) -> Self {

@@ -194,2 +202,3 @@ BitVec::from_bitslice(slice).into_boxed_bitslice()

/// [`BitSlice::MAX_ELTS`]: crate::slice::BitSlice::MAX_ELTS
#[inline]
pub fn from_boxed_slice(boxed: Box<[T]>) -> Self {

@@ -228,2 +237,3 @@ Self::try_from_boxed_slice(boxed)

/// ```
#[inline]
pub fn try_from_boxed_slice(boxed: Box<[T]>) -> Result<Self, Box<[T]>> {

@@ -262,2 +272,3 @@ let mut boxed = ManuallyDrop::new(boxed);

/// ```
#[inline]
pub fn into_boxed_slice(self) -> Box<[T]> {

@@ -350,2 +361,3 @@ self.pipe(ManuallyDrop::new)

/// ```
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn as_bitslice(&self) -> &BitSlice<O, T> {

@@ -368,2 +380,3 @@ self.bitspan.to_bitslice_ref()

/// ```
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn as_mut_bitslice(&mut self) -> &mut BitSlice<O, T> {

@@ -391,2 +404,3 @@ self.bitspan.to_bitslice_mut()

/// [`.as_bitslice()`]: Self::as_bitslice
#[inline]
pub fn as_slice(&self) -> &[T] {

@@ -417,2 +431,3 @@ let (data, len) =

/// [`.as_mut_bitslice()`]: Self::as_mut_bitslice
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [T] {

@@ -449,3 +464,3 @@ let (data, len) =

let (_, head, bits) = bp.raw_parts();
let head = head.value() as usize;
let head = head.into_inner() as usize;
let tail = head + bits;

@@ -494,7 +509,3 @@ let full = crate::mem::elts::<T::Mem>(tail) * T::Mem::BITS as usize;

mod api;
mod ops;
mod traits;
#[cfg(test)]
mod tests;

@@ -11,4 +11,4 @@ //! Port of the `Box<[T]>` inherent API.

use super::BitBox;
use crate::{
boxed::BitBox,
order::BitOrder,

@@ -15,0 +15,0 @@ ptr::BitSpan,

@@ -20,4 +20,4 @@ //! Port of the `Box<[T]>` operator implementations.

use super::BitBox;
use crate::{
boxed::BitBox,
order::BitOrder,

@@ -28,2 +28,3 @@ slice::BitSlice,

#[cfg(not(tarpaulin_include))]
impl<O, T, Rhs> BitAnd<Rhs> for BitBox<O, T>

@@ -44,2 +45,3 @@ where

#[cfg(not(tarpaulin_include))]
impl<O, T, Rhs> BitAndAssign<Rhs> for BitBox<O, T>

@@ -57,2 +59,3 @@ where

#[cfg(not(tarpaulin_include))]
impl<O, T, Rhs> BitOr<Rhs> for BitBox<O, T>

@@ -73,2 +76,3 @@ where

#[cfg(not(tarpaulin_include))]
impl<O, T, Rhs> BitOrAssign<Rhs> for BitBox<O, T>

@@ -86,2 +90,3 @@ where

#[cfg(not(tarpaulin_include))]
impl<O, T, Rhs> BitXor<Rhs> for BitBox<O, T>

@@ -102,2 +107,3 @@ where

#[cfg(not(tarpaulin_include))]
impl<O, T, Rhs> BitXorAssign<Rhs> for BitBox<O, T>

@@ -104,0 +110,0 @@ where

@@ -30,7 +30,9 @@ //! Non-operator trait implementations.

use super::BitBox;
use crate::{
boxed::BitBox,
mutability::Mut,
order::BitOrder,
ptr::BitSpan,
ptr::{
BitSpan,
Mut,
},
slice::BitSlice,

@@ -255,3 +257,3 @@ store::BitStore,

#[cfg(not(tarpaulin_include))]
impl<O, T> Into<Box<[T]>> for BitBox<O, T>
impl<O, T> From<BitBox<O, T>> for Box<[T]>
where

@@ -262,4 +264,4 @@ O: BitOrder,

#[inline(always)]
fn into(self) -> Box<[T]> {
self.into_boxed_slice()
fn from(bb: BitBox<O, T>) -> Self {
bb.into_boxed_slice()
}

@@ -315,3 +317,3 @@ }

{
#[inline]
#[inline(always)]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -328,3 +330,3 @@ Display::fmt(self.as_bitslice(), fmt)

{
#[inline]
#[inline(always)]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -341,3 +343,3 @@ Binary::fmt(self.as_bitslice(), fmt)

{
#[inline]
#[inline(always)]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -354,3 +356,3 @@ LowerHex::fmt(self.as_bitslice(), fmt)

{
#[inline]
#[inline(always)]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -367,3 +369,3 @@ Octal::fmt(self.as_bitslice(), fmt)

{
#[inline]
#[inline(always)]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -380,3 +382,3 @@ self.as_bitspan().render(fmt, "Box", None)

{
#[inline]
#[inline(always)]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -393,3 +395,3 @@ UpperHex::fmt(self.as_bitslice(), fmt)

{
#[inline]
#[inline(always)]
fn hash<H>(&self, state: &mut H)

@@ -401,19 +403,2 @@ where H: Hasher {

/// This is not present on `Box<[T]>`, but is needed to fit into the general
/// operator implementations.
#[cfg(not(tarpaulin_include))]
impl<O, T> IntoIterator for BitBox<O, T>
where
O: BitOrder,
T: BitStore,
{
type IntoIter = <crate::vec::BitVec<O, T> as IntoIterator>::IntoIter;
type Item = <Self::IntoIter as Iterator>::Item;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.into_bitvec().into_iter()
}
}
unsafe impl<O, T> Send for BitBox<O, T>

@@ -420,0 +405,0 @@ where

@@ -91,3 +91,3 @@ //! Internal support utilities.

/// This evaluates to a compile-time constant, and is removed during codegen.
#[inline(always)]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn match_order<O1, O2>() -> bool

@@ -101,6 +101,18 @@ where

/// Tests if two `BitStore` type parameters match each other.
///
/// This evaluates to a compile-time constant, and is removed during codegen.
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn match_store<T1, T2>() -> bool
where
T1: BitStore,
T2: BitStore,
{
TypeId::of::<T1>() == TypeId::of::<T2>()
}
/// Tests if two `<O, T>` type parameter pairs match each other.
///
/// This evaluates to a compile-time constant, and is removed during codegen.
#[inline(always)]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn match_types<O1, T1, O2, T2>() -> bool

@@ -113,3 +125,3 @@ where

{
match_order::<O1, O2>() && TypeId::of::<T1>() == TypeId::of::<T2>()
match_order::<O1, O2>() && match_store::<T1, T2>()
}

@@ -124,2 +136,3 @@

#[test]
#[allow(clippy::reversed_empty_ranges)] // I know.
fn check_range_asserts() {

@@ -126,0 +139,0 @@ assert!(catch_unwind(|| assert_range(7 .. 2, None)).is_err());

@@ -179,2 +179,3 @@ /*! Representations of the [`BitSlice`] region memory model.

/// [`Enclave`]: Self::Enclave
#[inline]
pub fn enclave(self) -> Option<(

@@ -205,2 +206,3 @@ BitIdx<T::Mem>,

/// [`Region`]: Self::Region
#[inline]
pub fn region(self) -> Option<(

@@ -231,2 +233,3 @@ &'a $($m)? BitSlice<O, T>,

/// [`BitSlice`]: crate::slice::BitSlice
#[inline]
pub(crate) fn new(slice: &'a $($m)? BitSlice<O, T>) -> Self {

@@ -238,3 +241,3 @@ let bitspan = slice.as_bitspan();

match (h.value(), e, t.value()) {
match (h.into_inner(), e, t.into_inner()) {
(_, 0, _) => Self::empty(),

@@ -249,2 +252,3 @@ (0, _, t) if t == w => Self::spanning(slice),

#[cfg_attr(not(tarpaulin_include), inline(always))]
fn empty() -> Self {

@@ -258,2 +262,3 @@ Self::Region {

#[inline]
fn major(

@@ -266,7 +271,7 @@ slice: &'a $($m)? BitSlice<O, T>,

slice,
(T::Mem::BITS as u8 - head.value()) as usize,
(T::Mem::BITS as u8 - head.into_inner()) as usize,
);
let (body, tail) = bit_domain!(split $($m)?
rest,
rest.len() - (tail.value() as usize),
rest.len() - (tail.into_inner() as usize),
);

@@ -280,2 +285,3 @@ Self::Region {

#[inline]
fn minor(

@@ -293,2 +299,3 @@ slice: &'a $($m)? BitSlice<O, T>,

#[inline]
fn partial_head(

@@ -300,3 +307,3 @@ slice: &'a $($m)? BitSlice<O, T>,

slice,
(T::Mem::BITS as u8 - head.value()) as usize,
(T::Mem::BITS as u8 - head.into_inner()) as usize,
);

@@ -314,2 +321,3 @@ let (head, body) = (

#[inline]
fn partial_tail(

@@ -327,3 +335,3 @@ slice: &'a $($m)? BitSlice<O, T>,

slice,
slice.len() - (tail.value() as usize),
slice.len() - (tail.into_inner() as usize),
);

@@ -341,2 +349,3 @@ let (body, tail) = (

#[cfg_attr(not(tarpaulin_include), inline(always))]
fn spanning(slice: &'a $($m)? BitSlice<O, T>) -> Self {

@@ -376,2 +385,3 @@ Self::Region {

{
#[inline(always)]
fn clone(&self) -> Self {

@@ -510,2 +520,3 @@ *self

/// [`Enclave`]: Self::Enclave
#[inline]
pub fn enclave(self) -> Option<(

@@ -535,2 +546,3 @@ BitIdx<T::Mem>,

/// [`Region`]: Self::Region
#[inline]
pub fn region(self) -> Option<(

@@ -549,2 +561,3 @@ Option<(BitIdx<T::Mem>, &'a T $(::$a)?)>,

#[inline]
pub(crate) fn new<O>(slice: &'a $($m)? BitSlice<O, T>) -> Self

@@ -558,3 +571,3 @@ where O: BitOrder {

let base = bitspan.address().to_const() as *const _;
match (head.value(), elts, tail.value()) {
match (head.into_inner(), elts, tail.into_inner()) {
(_, 0, _) => Self::empty(),

@@ -569,2 +582,3 @@ (0, _, t) if t == bits => Self::spanning(base, elts),

#[cfg_attr(not(tarpaulin_include), inline(always))]
fn empty() -> Self {

@@ -578,2 +592,3 @@ Self::Region {

#[inline]
fn major(

@@ -595,2 +610,3 @@ base: *const T $(::$a)?,

#[inline]
fn minor(

@@ -608,2 +624,3 @@ addr: *const T $(::$a)?,

#[inline]
fn partial_head(

@@ -623,2 +640,3 @@ base: *const T $(::$a)?,

#[inline]
fn partial_tail(

@@ -638,2 +656,3 @@ base: *const T $(::$a)?,

#[cfg_attr(not(tarpaulin_include), inline(always))]
fn spanning(base: *const T $(::$a)?, elts: usize) -> Self {

@@ -664,2 +683,3 @@ Self::Region {

{
#[inline(always)]
fn clone(&self) -> Self {

@@ -725,2 +745,3 @@ *self

{
#[inline]
fn len(&self) -> usize {

@@ -749,2 +770,3 @@ match self {

{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -751,0 +773,0 @@ fmt.debug_list()

@@ -227,3 +227,3 @@ /*! Batched load/store access to bitfields.

store::BitStore,
view::BitView,
view::BitViewSized,
};

@@ -323,2 +323,3 @@ #[cfg(feature = "alloc")]

/// [`self.len()`]: crate::slice::BitSlice::len
#[cfg_attr(not(tarpaulin_include), inline(always))]
fn load<M>(&self) -> M

@@ -374,2 +375,3 @@ where M: BitMemory {

/// [`store_le`]: Self::store_le
#[cfg_attr(not(tarpaulin_include), inline(always))]
fn store<M>(&mut self, value: M)

@@ -776,3 +778,3 @@ where M: BitMemory {

Domain::Enclave { head, elem, tail } => {
get::<T, M>(elem, Lsb0::mask(head, tail), head.value())
get::<T, M>(elem, Lsb0::mask(head, tail), head.into_inner())
},

@@ -805,4 +807,4 @@ Domain::Region { head, body, tail } => {

*/
if M::BITS > T::Mem::BITS {
accum <<= T::Mem::BITS;
if M::BITS > <T::Mem as IsNumber>::BITS {
accum <<= <T::Mem as IsNumber>::BITS;
}

@@ -813,4 +815,4 @@ accum |= resize::<T::Mem, M>(elem);

if let Some((head, elem)) = head {
let shamt = head.value();
let rshamt = T::Mem::BITS as u8 - shamt;
let shamt = head.into_inner();
let rshamt = <T::Mem as IsNumber>::BITS as u8 - shamt;
if M::BITS as u8 > rshamt {

@@ -881,3 +883,3 @@ accum <<= rshamt;

Domain::Enclave { head, elem, tail } => {
get::<T, M>(elem, Lsb0::mask(head, tail), head.value())
get::<T, M>(elem, Lsb0::mask(head, tail), head.into_inner())
},

@@ -888,9 +890,12 @@ Domain::Region { head, body, tail } => {

if let Some((head, elem)) = head {
accum =
get::<T, M>(elem, Lsb0::mask(head, None), head.value());
accum = get::<T, M>(
elem,
Lsb0::mask(head, None),
head.into_inner(),
);
}
for elem in body.iter().map(BitStore::load_value) {
if M::BITS > T::Mem::BITS {
accum <<= T::Mem::BITS;
if M::BITS > <T::Mem as IsNumber>::BITS {
accum <<= <T::Mem as IsNumber>::BITS;
}

@@ -901,3 +906,3 @@ accum |= resize::<T::Mem, M>(elem);

if let Some((elem, tail)) = tail {
let shamt = tail.value();
let shamt = tail.into_inner();
if M::BITS as u8 > shamt {

@@ -948,9 +953,14 @@ accum <<= shamt;

DomainMut::Enclave { head, elem, tail } => {
set::<T, M>(elem, value, Lsb0::mask(head, tail), head.value());
set::<T, M>(
elem,
value,
Lsb0::mask(head, tail),
head.into_inner(),
);
},
DomainMut::Region { head, body, tail } => {
if let Some((head, elem)) = head {
let shamt = head.value();
let shamt = head.into_inner();
set::<T, M>(elem, value, Lsb0::mask(head, None), shamt);
let lshamt = T::Mem::BITS as u8 - shamt;
let lshamt = <T::Mem as IsNumber>::BITS as u8 - shamt;
if M::BITS as u8 > lshamt {

@@ -966,4 +976,4 @@ value >>= lshamt;

elem.store_value(resize(value));
if M::BITS > T::Mem::BITS {
value >>= T::Mem::BITS;
if M::BITS > <T::Mem as IsNumber>::BITS {
value >>= <T::Mem as IsNumber>::BITS;
}

@@ -1010,3 +1020,8 @@ }

DomainMut::Enclave { head, elem, tail } => {
set::<T, M>(elem, value, Lsb0::mask(head, tail), head.value());
set::<T, M>(
elem,
value,
Lsb0::mask(head, tail),
head.into_inner(),
);
},

@@ -1016,3 +1031,3 @@ DomainMut::Region { head, body, tail } => {

set::<T, M>(elem, value, Lsb0::mask(None, tail), 0);
let shamt = tail.value();
let shamt = tail.into_inner();
if M::BITS as u8 > shamt {

@@ -1028,4 +1043,4 @@ value >>= shamt;

elem.store_value(resize(value));
if M::BITS > T::Mem::BITS {
value >>= T::Mem::BITS;
if M::BITS > <T::Mem as IsNumber>::BITS {
value >>= <T::Mem as IsNumber>::BITS;
}

@@ -1039,3 +1054,3 @@ }

Lsb0::mask(head, None),
head.value(),
head.into_inner(),
);

@@ -1104,3 +1119,3 @@ }

Msb0::mask(head, tail),
T::Mem::BITS as u8 - tail.value(),
<T::Mem as IsNumber>::BITS as u8 - tail.into_inner(),
),

@@ -1114,3 +1129,3 @@ Domain::Region { head, body, tail } => {

Msb0::mask(None, tail),
T::Mem::BITS as u8 - tail.value(),
<T::Mem as IsNumber>::BITS as u8 - tail.into_inner(),
);

@@ -1120,4 +1135,4 @@ }

for elem in body.iter().rev().map(BitStore::load_value) {
if M::BITS > T::Mem::BITS {
accum <<= T::Mem::BITS;
if M::BITS > <T::Mem as IsNumber>::BITS {
accum <<= <T::Mem as IsNumber>::BITS;
}

@@ -1128,3 +1143,4 @@ accum |= resize::<T::Mem, M>(elem);

if let Some((head, elem)) = head {
let shamt = T::Mem::BITS as u8 - head.value();
let shamt =
<T::Mem as IsNumber>::BITS as u8 - head.into_inner();
if M::BITS as u8 > shamt {

@@ -1197,3 +1213,3 @@ accum <<= shamt;

Msb0::mask(head, tail),
T::Mem::BITS as u8 - tail.value(),
<T::Mem as IsNumber>::BITS as u8 - tail.into_inner(),
),

@@ -1208,4 +1224,4 @@ Domain::Region { head, body, tail } => {

for elem in body.iter().map(BitStore::load_value) {
if M::BITS > T::Mem::BITS {
accum <<= T::Mem::BITS;
if M::BITS > <T::Mem as IsNumber>::BITS {
accum <<= <T::Mem as IsNumber>::BITS;
}

@@ -1216,3 +1232,3 @@ accum |= resize::<T::Mem, M>(elem);

if let Some((elem, tail)) = tail {
let shamt = tail.value();
let shamt = tail.into_inner();
if M::BITS as u8 > shamt {

@@ -1227,3 +1243,3 @@ accum <<= shamt;

Msb0::mask(None, tail),
T::Mem::BITS as u8 - shamt,
<T::Mem as IsNumber>::BITS as u8 - shamt,
);

@@ -1271,3 +1287,3 @@ }

Msb0::mask(head, tail),
T::Mem::BITS as u8 - tail.value(),
<T::Mem as IsNumber>::BITS as u8 - tail.into_inner(),
),

@@ -1277,3 +1293,4 @@ DomainMut::Region { head, body, tail } => {

set::<T, M>(elem, value, Msb0::mask(head, None), 0);
let shamt = T::Mem::BITS as u8 - head.value();
let shamt =
<T::Mem as IsNumber>::BITS as u8 - head.into_inner();
if M::BITS as u8 > shamt {

@@ -1289,4 +1306,4 @@ value >>= shamt;

elem.store_value(resize(value));
if M::BITS > T::Mem::BITS {
value >>= T::Mem::BITS;
if M::BITS > <T::Mem as IsNumber>::BITS {
value >>= <T::Mem as IsNumber>::BITS;
}

@@ -1300,3 +1317,3 @@ }

Msb0::mask(None, tail),
T::Mem::BITS as u8 - tail.value(),
<T::Mem as IsNumber>::BITS as u8 - tail.into_inner(),
);

@@ -1342,3 +1359,3 @@ }

Msb0::mask(head, tail),
T::Mem::BITS as u8 - tail.value(),
<T::Mem as IsNumber>::BITS as u8 - tail.into_inner(),
),

@@ -1351,6 +1368,6 @@ DomainMut::Region { head, body, tail } => {

Msb0::mask(None, tail),
T::Mem::BITS as u8 - tail.value(),
<T::Mem as IsNumber>::BITS as u8 - tail.into_inner(),
);
if M::BITS as u8 > tail.value() {
value >>= tail.value();
if M::BITS as u8 > tail.into_inner() {
value >>= tail.into_inner();
}

@@ -1364,4 +1381,4 @@ else {

elem.store_value(resize(value));
if M::BITS > T::Mem::BITS {
value >>= T::Mem::BITS;
if M::BITS > <T::Mem as IsNumber>::BITS {
value >>= <T::Mem as IsNumber>::BITS;
}

@@ -1378,8 +1395,10 @@ }

#[cfg(not(tarpaulin_include))]
impl<O, V> BitField for BitArray<O, V>
where
O: BitOrder,
V: BitView,
V: BitViewSized,
BitSlice<O, V::Store>: BitField,
{
#[inline(always)]
fn load_le<M>(&self) -> M

@@ -1390,2 +1409,3 @@ where M: BitMemory {

#[inline(always)]
fn load_be<M>(&self) -> M

@@ -1396,2 +1416,3 @@ where M: BitMemory {

#[inline(always)]
fn store_le<M>(&mut self, value: M)

@@ -1402,2 +1423,3 @@ where M: BitMemory {

#[inline(always)]
fn store_be<M>(&mut self, value: M)

@@ -1410,2 +1432,3 @@ where M: BitMemory {

#[cfg(feature = "alloc")]
#[cfg(not(tarpaulin_include))]
impl<O, T> BitField for BitBox<O, T>

@@ -1417,2 +1440,3 @@ where

{
#[inline(always)]
fn load_le<M>(&self) -> M

@@ -1423,2 +1447,3 @@ where M: BitMemory {

#[inline(always)]
fn load_be<M>(&self) -> M

@@ -1429,2 +1454,3 @@ where M: BitMemory {

#[inline(always)]
fn store_le<M>(&mut self, value: M)

@@ -1435,2 +1461,3 @@ where M: BitMemory {

#[inline(always)]
fn store_be<M>(&mut self, value: M)

@@ -1443,2 +1470,3 @@ where M: BitMemory {

#[cfg(feature = "alloc")]
#[cfg(not(tarpaulin_include))]
impl<O, T> BitField for BitVec<O, T>

@@ -1450,2 +1478,3 @@ where

{
#[inline(always)]
fn load_le<M>(&self) -> M

@@ -1456,2 +1485,3 @@ where M: BitMemory {

#[inline(always)]
fn load_be<M>(&self) -> M

@@ -1462,2 +1492,3 @@ where M: BitMemory {

#[inline(always)]
fn store_le<M>(&mut self, value: M)

@@ -1468,2 +1499,3 @@ where M: BitMemory {

#[inline(always)]
fn store_be<M>(&mut self, value: M)

@@ -1482,2 +1514,3 @@ where M: BitMemory {

/// [`M::BITS`]: funty::IsNumber::BITS
#[inline]
fn check<M>(action: &'static str, len: usize)

@@ -1536,2 +1569,3 @@ where M: BitMemory {

// the RHS operand.
#[inline]
#[allow(clippy::op_ref)]

@@ -1546,3 +1580,3 @@ fn get<T, M>(elem: &T, mask: BitMask<T::Mem>, shamt: u8) -> M

// Mask it against the slot
.pipe(|val| val & &mask.value())
.pipe(|val| val & &mask.into_inner())
// Shift it down to the LSedge

@@ -1592,2 +1626,3 @@ .pipe(|val| val >> &(shamt as usize))

**/
#[inline]
#[allow(clippy::op_ref)]

@@ -1600,3 +1635,3 @@ fn set<T, M>(elem: &T::Access, value: M, mask: BitMask<T::Mem>, shamt: u8)

// Convert the `mask` type to fit into the accessor.
let mask = BitMask::new(mask.value());
let mask = BitMask::new(mask.into_inner());
let value = value

@@ -1635,2 +1670,3 @@ // Resize the value to the expected input

**/
#[inline]
fn resize<T, U>(value: T) -> U

@@ -1653,2 +1689,3 @@ where

/// Performs little-endian byte-order register resizing.
#[cfg_attr(not(tarpaulin_include), inline(always))]
#[cfg(target_endian = "little")]

@@ -1671,2 +1708,3 @@ unsafe fn resize_inner<T, U>(

/// Performs big-endian byte-order register resizing.
#[cfg_attr(not(tarpaulin_include), inline(always))]
#[cfg(target_endian = "big")]

@@ -1673,0 +1711,0 @@ unsafe fn resize_inner<T, U>(

@@ -34,4 +34,4 @@ /*! I/O trait implementations.

use super::BitField;
use crate::{
field::BitField,
order::BitOrder,

@@ -38,0 +38,0 @@ slice::BitSlice,

@@ -143,2 +143,3 @@ /*! Well-typed counters and register descriptors.

/// [`Self::ZERO`]: Self::ZERO
#[inline]
pub fn new(value: u8) -> Result<Self, BitIdxError<R>> {

@@ -170,2 +171,3 @@ if value >= R::BITS as u8 {

/// [`Self::ZERO`]: Self::ZERO
#[inline]
pub unsafe fn new_unchecked(value: u8) -> Self {

@@ -186,13 +188,14 @@ debug_assert!(

///
/// This will always succeed if `self.value()` is a valid index in the `S`
/// register; it will return an error if the `self` index is too wide for
/// `S`.
/// This will always succeed if `self.into_inner()` is a valid index in the
/// `S` register; it will return an error if the `self` index is too wide
/// for `S`.
#[inline]
pub fn cast<S>(self) -> Result<BitIdx<S>, BitIdxError<S>>
where S: BitRegister {
BitIdx::new(self.value())
BitIdx::new(self.into_inner())
}
/// Removes the index wrapper, leaving the internal counter.
#[cfg(not(tarpaulin_include))]
pub fn value(self) -> u8 {
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn into_inner(self) -> u8 {
self.idx

@@ -211,2 +214,3 @@ }

/// - `.1`: Indicates that the new index is in the next register.
#[inline]
pub fn next(self) -> (Self, bool) {

@@ -230,2 +234,3 @@ let next = self.idx + 1;

/// - `.1`: Indicates that the new index is in the previous register.
#[inline]
pub fn prev(self) -> (Self, bool) {

@@ -245,3 +250,3 @@ let prev = self.idx.wrapping_sub(1);

/// [`O::at::<R>`]: crate::order::BitOrder::at
#[cfg(not(tarpaulin_include))]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn position<O>(self) -> BitPos<R>

@@ -258,3 +263,3 @@ where O: BitOrder {

/// [`O::select::<R>`]: crate::order::BitOrder::select
#[cfg(not(tarpaulin_include))]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn select<O>(self) -> BitSel<R>

@@ -270,3 +275,3 @@ where O: BitOrder {

/// [`Self::select`]: Self::select
#[cfg(not(tarpaulin_include))]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn mask<O>(self) -> BitMask<R>

@@ -302,2 +307,3 @@ where O: BitOrder {

/// [`Range<BitIdx<R>>`]: core::ops::Range
#[inline]
pub fn range(

@@ -310,3 +316,3 @@ self,

+ FusedIterator {
let (from, upto) = (self.value(), upto.value());
let (from, upto) = (self.into_inner(), upto.into_inner());
debug_assert!(from <= upto, "Ranges must run from low to high");

@@ -317,2 +323,3 @@ (from .. upto).map(|val| unsafe { Self::new_unchecked(val) })

/// Iterates over all possible index values.
#[inline]
pub fn range_all() -> impl Iterator<Item = Self>

@@ -347,3 +354,3 @@ + DoubleEndedIterator

pub fn offset(self, by: isize) -> (isize, Self) {
let val = self.value();
let val = self.into_inner();

@@ -421,7 +428,9 @@ /* Signed-add `val` to the jump distance. This will almost certainly not

/// [`BitTail::span`]: crate::index::BitTail::span
#[inline]
pub fn span(self, len: usize) -> (usize, BitTail<R>) {
unsafe { BitTail::<R>::new_unchecked(self.value()) }.span(len)
unsafe { BitTail::<R>::new_unchecked(self.into_inner()) }.span(len)
}
}
#[cfg(not(tarpaulin_include))]
impl<R> TryFrom<u8> for BitIdx<R>

@@ -432,2 +441,3 @@ where R: BitRegister

#[inline(always)]
fn try_from(value: u8) -> Result<Self, Self::Error> {

@@ -438,5 +448,7 @@ Self::new(value)

#[cfg(not(tarpaulin_include))]
impl<R> Binary for BitIdx<R>
where R: BitRegister
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -447,5 +459,7 @@ write!(fmt, "{:0>1$b}", self.idx, R::INDX as usize)

#[cfg(not(tarpaulin_include))]
impl<R> Debug for BitIdx<R>
where R: BitRegister
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -497,2 +511,3 @@ write!(fmt, "BitIdx<{}>({})", any::type_name::<R>(), self)

/// Debug builds panic when `value` is a valid index for `R`.
#[inline]
pub(crate) fn new(value: u8) -> Self {

@@ -512,4 +527,4 @@ debug_assert!(

/// Removes the error wrapper, leaving the internal counter.
#[cfg(not(tarpaulin_include))]
pub fn value(self) -> u8 {
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn into_inner(self) -> u8 {
self.err

@@ -519,5 +534,7 @@ }

#[cfg(not(tarpaulin_include))]
impl<R> Debug for BitIdxError<R>
where R: BitRegister
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -532,2 +549,3 @@ write!(fmt, "BitIdxErr<{}>({})", any::type_name::<R>(), self.err)

{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -623,2 +641,3 @@ write!(

/// [`Self::ZERO`]: Self::ZERO
#[inline]
pub fn new(value: u8) -> Option<Self> {

@@ -650,2 +669,3 @@ if value > R::BITS as u8 {

/// [`Self::ZERO`]: Self::ZERO
#[inline]
pub(crate) unsafe fn new_unchecked(value: u8) -> Self {

@@ -665,4 +685,4 @@ debug_assert!(

/// Removes the tail wrapper, leaving the internal counter.
#[cfg(not(tarpaulin_include))]
pub fn value(self) -> u8 {
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn into_inner(self) -> u8 {
self.end

@@ -690,2 +710,3 @@ }

/// [`Range<BitTail<R>>`]: core::ops::Range
#[inline]
pub fn range_from(

@@ -754,5 +775,7 @@ from: BitIdx<R>,

#[cfg(not(tarpaulin_include))]
impl<R> Binary for BitTail<R>
where R: BitRegister
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -763,5 +786,7 @@ write!(fmt, "{:0>1$b}", self.end, R::INDX as usize + 1)

#[cfg(not(tarpaulin_include))]
impl<R> Debug for BitTail<R>
where R: BitRegister
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -838,2 +863,3 @@ write!(fmt, "BitTail<{}>({})", any::type_name::<R>(), self)

/// and `None` when it is not.
#[inline]
pub fn new(value: u8) -> Option<Self> {

@@ -863,2 +889,3 @@ if value >= R::BITS as u8 {

/// `value`.
#[inline]
pub unsafe fn new_unchecked(value: u8) -> Self {

@@ -878,4 +905,4 @@ debug_assert!(

/// Removes the position wrapper, leaving the internal counter.
#[cfg(not(tarpaulin_include))]
pub fn value(self) -> u8 {
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn into_inner(self) -> u8 {
self.pos

@@ -887,2 +914,3 @@ }

/// This is always `1 << self.pos`.
#[inline(always)]
pub fn select(self) -> BitSel<R> {

@@ -897,3 +925,3 @@ unsafe { BitSel::new_unchecked(R::ONE << self.pos) }

/// [`Self::select`]: Self::select
#[cfg(not(tarpaulin_include))]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn mask(self) -> BitMask<R> {

@@ -904,2 +932,3 @@ self.select().mask()

/// Iterates over all possible position values.
#[inline]
pub(crate) fn range_all() -> impl Iterator<Item = Self>

@@ -910,9 +939,11 @@ + DoubleEndedIterator

BitIdx::<R>::range_all()
.map(|idx| unsafe { Self::new_unchecked(idx.value()) })
.map(|idx| unsafe { Self::new_unchecked(idx.into_inner()) })
}
}
#[cfg(not(tarpaulin_include))]
impl<R> Binary for BitPos<R>
where R: BitRegister
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -923,5 +954,7 @@ write!(fmt, "{:0>1$b}", self.pos, R::INDX as usize)

#[cfg(not(tarpaulin_include))]
impl<R> Debug for BitPos<R>
where R: BitRegister
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -999,2 +1032,3 @@ write!(fmt, "BitPos<{}>({})", any::type_name::<R>(), self)

/// [`BitPos`]: crate::index::BitPos
#[inline]
pub fn new(value: R) -> Option<Self> {

@@ -1027,2 +1061,3 @@ if value.count_ones() != 1 {

/// [`BitOrder::select`]: crate::order::BitOrder::select
#[inline]
pub unsafe fn new_unchecked(value: R) -> Self {

@@ -1039,4 +1074,4 @@ debug_assert!(

/// Removes the selector wrapper, leaving the internal counter.
#[cfg(not(tarpaulin_include))]
pub fn value(self) -> R {
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn into_inner(self) -> R {
self.sel

@@ -1053,2 +1088,3 @@ }

/// Iterates over all possible selector values.
#[inline]
pub fn range_all() -> impl Iterator<Item = Self>

@@ -1062,5 +1098,7 @@ + DoubleEndedIterator

#[cfg(not(tarpaulin_include))]
impl<R> Binary for BitSel<R>
where R: BitRegister
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -1071,5 +1109,7 @@ write!(fmt, "{:0>1$b}", self.sel, R::BITS as usize)

#[cfg(not(tarpaulin_include))]
impl<R> Debug for BitSel<R>
where R: BitRegister
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -1149,2 +1189,3 @@ write!(fmt, "BitSel<{}>({})", any::type_name::<R>(), self)

/// [`BitSel`]: crate::index::BitSel
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn new(value: R) -> Self {

@@ -1155,4 +1196,4 @@ Self { mask: value }

/// Removes the mask wrapper, leaving the internal value.
#[cfg(not(tarpaulin_include))]
pub fn value(self) -> R {
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn into_inner(self) -> R {
self.mask

@@ -1171,2 +1212,3 @@ }

/// Whether `self` is set high at `sel`.
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn test(&self, sel: BitSel<R>) -> bool {

@@ -1186,2 +1228,3 @@ self.mask & sel.sel != R::ZERO

/// The bit at `sel` is set high in `self`.
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn insert(&mut self, sel: BitSel<R>) {

@@ -1201,2 +1244,3 @@ self.mask |= sel.sel;

/// A copy of `self`, with `sel` set high.
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn combine(self, sel: BitSel<R>) -> Self {

@@ -1209,5 +1253,7 @@ Self {

#[cfg(not(tarpaulin_include))]
impl<R> Binary for BitMask<R>
where R: BitRegister
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -1218,5 +1264,7 @@ write!(fmt, "{:0>1$b}", self.mask, R::BITS as usize)

#[cfg(not(tarpaulin_include))]
impl<R> Debug for BitMask<R>
where R: BitRegister
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -1237,5 +1285,7 @@ write!(fmt, "BitMask<{}>({})", any::type_name::<R>(), self)

#[cfg(not(tarpaulin_include))]
impl<R> Sum<BitSel<R>> for BitMask<R>
where R: BitRegister
{
#[inline]
fn sum<I>(iter: I) -> Self

@@ -1247,2 +1297,3 @@ where I: Iterator<Item = BitSel<R>> {

#[cfg(not(tarpaulin_include))]
impl<R> BitAnd<R> for BitMask<R>

@@ -1253,2 +1304,3 @@ where R: BitRegister

#[inline]
fn bitand(self, rhs: R) -> Self::Output {

@@ -1261,2 +1313,3 @@ Self {

#[cfg(not(tarpaulin_include))]
impl<R> BitOr<R> for BitMask<R>

@@ -1267,2 +1320,3 @@ where R: BitRegister

#[inline]
fn bitor(self, rhs: R) -> Self::Output {

@@ -1275,2 +1329,3 @@ Self {

#[cfg(not(tarpaulin_include))]
impl<R> Not for BitMask<R>

@@ -1281,2 +1336,3 @@ where R: BitRegister

#[inline]
fn not(self) -> Self::Output {

@@ -1283,0 +1339,0 @@ Self { mask: !self.mask }

@@ -269,2 +269,12 @@ /*! # `bitvec` — Addressable Bits

#![deny(unconditional_recursion)]
// Clippy controls applicable in ordinary code.
#![allow(
clippy::single_char_add_str, // Bypass UTF-8 encoding.
)]
// Clippy controls only applicable in #[cfg(test)] testing modules.
#![cfg_attr(test, allow(
clippy::many_single_char_names, // Tests do not need descriptive bind names.
clippy::redundant_clone, // Does not matter in tests.
clippy::unusual_byte_groupings, // Literals are for region patterns.
))]

@@ -284,3 +294,2 @@ #[cfg(feature = "alloc")]

pub mod mem;
mod mutability;
pub mod order;

@@ -287,0 +296,0 @@ pub mod prelude;

@@ -113,3 +113,3 @@ //! Constructor macros for the crate’s collection types.

radium::if_atomic! { if atomic(32) {
let d = bitarr![Msb0, AtomicU32; 0, 0, 1, 0, 1];
let d = bitarr![Msb0, AtomicU32; 0, 0, 1, 0, 1];
} }

@@ -162,7 +162,6 @@

const ELTS: usize = $crate::__count_elts!($store; $($val),*);
type Data = [Celled; ELTS];
const DATA: Data =
$crate::__encode_bits!($order, Cell<$store>; $($val),*);
type Data = [$store; ELTS];
const DATA: Data = $crate::__encode_bits!($order, $store; $($val),*);
type This = $crate::array::BitArray<$order, Data>;
type This = $crate::array::BitArray<$order, [Celled; ELTS]>;
unsafe { core::mem::transmute::<_, This>(DATA) }

@@ -169,0 +168,0 @@ }};

@@ -399,4 +399,4 @@ /*! Internal implementation macros for the public exports.

/// Construct a `u8` from bits applied in Lsb0-order.
#[allow(clippy::many_single_char_names)]
#[allow(clippy::too_many_arguments)]
#[cfg_attr(not(tarpaulin_include), inline(always))]
#[allow(clippy::many_single_char_names, clippy::too_many_arguments)]
pub const fn u8_from_le_bits(

@@ -423,4 +423,4 @@ a: bool,

/// Construct a `u8` from bits applied in Msb0-order.
#[allow(clippy::many_single_char_names)]
#[allow(clippy::too_many_arguments)]
#[cfg_attr(not(tarpaulin_include), inline(always))]
#[allow(clippy::many_single_char_names, clippy::too_many_arguments)]
pub const fn u8_from_be_bits(

@@ -427,0 +427,0 @@ a: bool,

@@ -34,5 +34,5 @@ //! Unit tests for the `macros` module.

assert_eq!(slots.all.value(), [!0u8, 192]);
assert_eq!(slots.typ.value(), [!0u8, 3]);
let def: [usize; 1] = slots.def.value();
assert_eq!(slots.all.into_inner(), [!0u8, 192]);
assert_eq!(slots.typ.into_inner(), [!0u8, 3]);
let def: [usize; 1] = slots.def.into_inner();
assert_eq!(def[0].count_ones(), 10);

@@ -89,6 +89,6 @@ }

let uint: BitArray<Lsb0, [u8; 1]> = bitarr![Lsb0, u8; 1, 0, 1, 0];
assert_eq!(uint.value(), [5u8]);
assert_eq!(uint.into_inner(), [5u8]);
let cell: BitArray<Lsb0, [Cell<u8>; 1]> =
bitarr![Lsb0, Cell<u8>; 1, 0, 1, 0];
assert_eq!(cell.value()[0].get(), 5u8);
assert_eq!(cell.into_inner()[0].get(), 5u8);

@@ -101,3 +101,3 @@ let uint: BitArray<Msb0, [u16; 2]> = bitarr![Msb0, u16;

];
assert_eq!(uint.value(), [0x5569, 0x6e74]);
assert_eq!(uint.into_inner(), [0x5569, 0x6e74]);
let cell: BitArray<Msb0, [Cell<u16>; 2]> = bitarr![Msb0, Cell<u16>;

@@ -109,3 +109,3 @@ 0, 1, 0, 1, 0, 1, 0, 1,

];
let cells = cell.value();
let cells = cell.into_inner();
assert_eq!(cells[0].get(), 0x5569);

@@ -117,3 +117,3 @@ assert_eq!(cells[1].get(), 0x6e74);

];
assert_eq!(uint.value(), [13u32]);
assert_eq!(uint.into_inner(), [13u32]);
let cell: BitArray<Lsb0, [Cell<u32>; 1]> = bitarr![

@@ -123,3 +123,3 @@ crate::order::Lsb0, Cell<u32>;

];
assert_eq!(cell.value()[0].get(), 13u32);
assert_eq!(cell.into_inner()[0].get(), 13u32);

@@ -129,3 +129,3 @@ #[cfg(target_pointer_width = "64")]

let uint: BitArray<LocalBits, [u64; 2]> = bitarr![LocalBits, u64; 1; 70];
assert_eq!(uint.value(), [!0u64; 2]);
assert_eq!(uint.into_inner(), [!0u64; 2]);

@@ -135,10 +135,10 @@ let cell: BitArray<LocalBits, [Cell<u64>; 2]> = bitarr![

];
assert_eq!(cell.clone().value()[0].get(), !0u64);
assert_eq!(cell.value()[1].get(), !0u64);
assert_eq!(cell.clone().into_inner()[0].get(), !0u64);
assert_eq!(cell.into_inner()[1].get(), !0u64);
}
let uint: BitArray<Lsb0, [usize; 1]> = bitarr![1, 0, 1];
assert_eq!(uint.value(), [5usize]);
assert_eq!(uint.into_inner(), [5usize]);
let uint: BitArray<Lsb0, [usize; 1]> = bitarr![1; 30];
assert_eq!(uint.value(), [!0usize]);
assert_eq!(uint.into_inner(), [!0usize]);
}

@@ -145,0 +145,0 @@

@@ -88,3 +88,3 @@ /*! Ordering of bits within register elements.

/// fn at<R: BitRegister>(idx: BitIdx<R>) -> BitPos<R> {
/// BitPos::new(idx.value() ^ 4).unwrap()
/// BitPos::new(idx.into_inner() ^ 4).unwrap()
/// }

@@ -206,3 +206,5 @@ /// }

/// [`Self::at`]: Self::at
#[inline]
#[cfg(not(tarpaulin_include))]
fn select<R>(index: BitIdx<R>) -> BitSel<R>

@@ -267,12 +269,15 @@ where R: BitRegister {

unsafe impl BitOrder for Lsb0 {
#[cfg_attr(not(tarpaulin_include), inline(always))]
fn at<R>(index: BitIdx<R>) -> BitPos<R>
where R: BitRegister {
unsafe { BitPos::new_unchecked(index.value()) }
unsafe { BitPos::new_unchecked(index.into_inner()) }
}
#[cfg_attr(not(tarpaulin_include), inline(always))]
fn select<R>(index: BitIdx<R>) -> BitSel<R>
where R: BitRegister {
unsafe { BitSel::new_unchecked(R::ONE << index.value()) }
unsafe { BitSel::new_unchecked(R::ONE << index.into_inner()) }
}
#[inline]
fn mask<R>(

@@ -285,4 +290,4 @@ from: impl Into<Option<BitIdx<R>>>,

{
let from = from.into().unwrap_or(BitIdx::ZERO).value();
let upto = upto.into().unwrap_or(BitTail::LAST).value();
let from = from.into().unwrap_or(BitIdx::ZERO).into_inner();
let upto = upto.into().unwrap_or(BitTail::LAST).into_inner();
debug_assert!(

@@ -312,7 +317,9 @@ from <= upto,

unsafe impl BitOrder for Msb0 {
#[cfg_attr(not(tarpaulin_include), inline(always))]
fn at<R>(index: BitIdx<R>) -> BitPos<R>
where R: BitRegister {
unsafe { BitPos::new_unchecked(R::MASK - index.value()) }
unsafe { BitPos::new_unchecked(R::MASK - index.into_inner()) }
}
#[cfg_attr(not(tarpaulin_include), inline(always))]
fn select<R>(index: BitIdx<R>) -> BitSel<R>

@@ -325,5 +332,6 @@ where R: BitRegister {

let msbit: R = R::ONE << R::MASK;
unsafe { BitSel::new_unchecked(msbit >> index.value()) }
unsafe { BitSel::new_unchecked(msbit >> index.into_inner()) }
}
#[inline]
fn mask<R>(

@@ -336,4 +344,4 @@ from: impl Into<Option<BitIdx<R>>>,

{
let from = from.into().unwrap_or(BitIdx::ZERO).value();
let upto = upto.into().unwrap_or(BitTail::LAST).value();
let from = from.into().unwrap_or(BitIdx::ZERO).into_inner();
let upto = upto.into().unwrap_or(BitTail::LAST).into_inner();
debug_assert!(

@@ -407,2 +415,3 @@ from <= upto,

**/
#[inline(never)]
pub fn verify<O>(verbose: bool)

@@ -446,2 +455,3 @@ where O: BitOrder {

**/
#[inline(never)]
pub fn verify_for_type<O, R>(verbose: bool)

@@ -471,3 +481,3 @@ where

n,
pos.value(),
pos.into_inner(),
);

@@ -478,3 +488,3 @@ }

assert!(
pos.value() < R::BITS as u8,
pos.into_inner() < R::BITS as u8,
"Error when verifying the implementation of `BitOrder` for `{}`: \

@@ -485,3 +495,3 @@ Index {} produces a bit position ({}) that exceeds the type width \

n,
pos.value(),
pos.into_inner(),
R::BITS,

@@ -502,3 +512,3 @@ );

assert_eq!(
sel.value().count_ones(),
sel.into_inner().count_ones(),
1,

@@ -525,3 +535,3 @@ "Error when verifying the implementation of `BitOrder` for `{}`: \

sel,
pos.value(),
pos.into_inner(),
shl,

@@ -539,3 +549,3 @@ );

n,
pos.value(),
pos.into_inner(),
);

@@ -542,0 +552,0 @@ accum.insert(sel);

@@ -13,3 +13,3 @@ /*! [`bitvec`] symbol export.

bits,
field::BitField,
field::BitField as _,
order::{

@@ -28,3 +28,3 @@ BitOrder,

store::BitStore,
view::BitView,
view::BitView as _,
BitArr,

@@ -31,0 +31,0 @@ };

@@ -99,21 +99,23 @@ /*! Mirror of the [`core::ptr`] module and `bitvec`-specific pointer structures.

pub(crate) use self::span::BitSpan;
pub use crate::{
mutability::{
pub(crate) use self::{
address::AddressExt,
span::BitSpan,
};
pub use self::{
address::{
check_alignment,
Address,
Const,
MisalignError,
Mut,
Mutability,
NullPtrError,
},
ptr::{
address::{
Address,
AddressError,
},
proxy::BitRef,
range::BitPtrRange,
single::{
BitPtr,
BitPtrError,
},
span::BitSpanError,
proxy::BitRef,
range::BitPtrRange,
single::{
BitPtr,
BitPtrError,
},
span::BitSpanError,
};

@@ -192,3 +194,3 @@

/// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
#[inline]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub unsafe fn copy<O1, O2, T1, T2>(

@@ -254,3 +256,3 @@ src: BitPtr<Const, O1, T1>,

/// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
#[inline]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub unsafe fn copy_nonoverlapping<O1, O2, T1, T2>(

@@ -301,3 +303,3 @@ src: BitPtr<Const, O1, T1>,

**/
#[inline]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn eq<O, T1, T2>(a: BitPtr<Const, O, T1>, b: BitPtr<Const, O, T2>) -> bool

@@ -322,3 +324,3 @@ where

**/
#[inline]
#[inline(always)]
#[cfg(not(tarpaulin_include))]

@@ -361,3 +363,3 @@ pub fn hash<O, T, S>(hashee: BitPtr<Const, O, T>, into: &mut S)

**/
#[inline]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub unsafe fn read<O, T>(src: BitPtr<Const, O, T>) -> bool

@@ -423,3 +425,3 @@ where

**/
#[inline]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub unsafe fn read_volatile<O, T>(src: BitPtr<Const, O, T>) -> bool

@@ -466,3 +468,3 @@ where

**/
#[inline]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub unsafe fn replace<O, T>(dst: BitPtr<Mut, O, T>, src: bool) -> bool

@@ -501,3 +503,3 @@ where

**/
#[inline]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn bitslice_from_raw_parts<O, T>(

@@ -543,3 +545,3 @@ data: BitPtr<Const, O, T>,

**/
#[inline]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn bitslice_from_raw_parts_mut<O, T>(

@@ -592,3 +594,3 @@ data: BitPtr<Mut, O, T>,

**/
#[inline]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub unsafe fn swap<O1, O2, T1, T2>(

@@ -645,3 +647,3 @@ x: BitPtr<Mut, O1, T1>,

**/
#[inline]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub unsafe fn swap_nonoverlapping<O1, O2, T1, T2>(

@@ -698,3 +700,3 @@ x: BitPtr<Mut, O1, T1>,

**/
#[inline]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub unsafe fn write<O, T>(dst: BitPtr<Mut, O, T>, value: bool)

@@ -766,3 +768,3 @@ where

**/
#[inline]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub unsafe fn write_volatile<O, T>(dst: BitPtr<Mut, O, T>, value: bool)

@@ -769,0 +771,0 @@ where

@@ -1,13 +0,10 @@

//! Non-null, well-aligned, `BitStore` addresses with limited casting capability
/*! Address management.
This module only provides utilities for requiring that `T: BitStore` addresses
are well aligned to their type. It also exports the type-level mutability
tracking behavior now provided by [`wyz::comu`].
!*/
use core::{
any::{
type_name,
TypeId,
},
cmp,
convert::{
Infallible,
TryFrom,
},
any,
fmt::{

@@ -20,405 +17,152 @@ self,

},
hash::{
Hash,
Hasher,
},
marker::PhantomData,
mem::align_of,
ptr::NonNull,
mem,
};
use tap::pipe::Pipe;
use crate::{
mem::BitMemory,
mutability::{
Const,
Mut,
Mutability,
},
store::BitStore,
use tap::{
Pipe,
TryConv,
};
pub use wyz::comu::{
Address,
Const,
Mut,
Mutability,
NullPtrError,
};
use wyz::FmtForward;
/** A non-null, well-aligned, `BitStore` element address.
This adds non-null and well-aligned requirements to memory addresses so that the
crate can rely on these invariants throughout its implementation. The type is
public API, but opaque, and only constructible through conversions of pointer
and reference values.
# Type Parameters
- `M`: The mutability permissions of the source pointer.
- `T`: The referent type of the source pointer.
**/
#[repr(transparent)]
pub struct Address<M, T = usize>
where
M: Mutability,
T: BitStore,
{
/// `Address` is just a wrapper over `NonNull` with some additional casting
/// abilities.
inner: NonNull<T>,
/// In addition, `Address` tracks the write permissions of its source.
_mut: PhantomData<M>,
/// Ensures that an address is well-aligned to its referent type.
#[inline]
pub fn check_alignment<M, T>(
addr: Address<M, T>,
) -> Result<Address<M, T>, MisalignError<T>>
where M: Mutability {
let ptr = addr.to_const();
let mask = mem::align_of::<T>() - 1;
if ptr as usize & mask != 0 {
Err(MisalignError { ptr })
}
else {
Ok(addr)
}
}
#[cfg(not(tarpaulin_include))]
impl<M, T> Address<M, T>
where
M: Mutability,
T: BitStore,
{
/// The dangling address.
pub(crate) const DANGLING: Self = Self {
inner: NonNull::dangling(),
_mut: PhantomData,
};
/// Extension methods for raw pointers.
pub(crate) trait AddressExt<T> {
/// Tracks the original mutation capability of the source pointer.
type Permission: Mutability;
/// Attempts to create a new `Address` from a location value.
/// Forcibly wraps the raw pointer as an `Address`, without handling errors.
///
/// # Parameters
/// In debug builds, this will panic on null or misaligned pointers. In
/// release builds, it is permitted to remove the error-handling codepaths
/// and assume those invariants are upheld by the caller.
///
/// - `addr`: Any location value.
///
/// # Returns
///
/// If `addr` is not the null address, and is well-aligned for `T`, this
/// returns an `Address` wrapping it; if either condition is violated, this
/// returns the corresponding error.
#[inline]
pub(crate) fn new(addr: usize) -> Result<Self, AddressError<T>> {
let align_mask = align_of::<T>() - 1;
if addr & align_mask != 0 {
return Err(AddressError::Misaligned(addr as *const T));
}
NonNull::new(addr as *mut T)
.ok_or(AddressError::Null)
.map(|inner| Self {
inner,
_mut: PhantomData,
})
}
/// Creates a new `Address` without checking the value for correctness.
///
/// # Safety
///
/// `addr` must be well-aligned and not null.
#[inline(always)]
pub(crate) unsafe fn new_unchecked(addr: usize) -> Self {
Self {
inner: NonNull::new_unchecked(addr as *mut T),
_mut: PhantomData,
}
}
/// Removes write permissions from the `Address`.
#[inline(always)]
pub(crate) fn immut(self) -> Address<Const, T> {
let Self { inner, .. } = self;
Address {
inner,
..Address::DANGLING
}
}
/// Adds write permissions to the `Address`.
///
/// # Safety
///
/// When called on an `Address<Const, _>`, the address must have been
/// previously constructed from a mutable location and lowered with `immut`.
#[inline(always)]
pub(crate) unsafe fn assert_mut(self) -> Address<Mut, T> {
let Self { inner, .. } = self;
Address {
inner,
..Address::DANGLING
}
}
/// Applies `<*mut T>::offset`.
///
/// # Panics
///
/// This panics if the result of applying the offset is the null pointer.
#[inline]
pub(crate) unsafe fn offset(mut self, count: isize) -> Self {
self.inner = self
.inner
.as_ptr()
.offset(count)
.pipe(NonNull::new)
.expect("Offset cannot produce the null pointer");
self
}
/// Applies `<*mut T>::wrapping_offset`.
///
/// # Panics
///
/// This panics if the result of applying the offset is the null pointer.
#[inline]
pub(crate) fn wrapping_offset(mut self, count: isize) -> Self {
self.inner = self
.inner
.as_ptr()
.wrapping_offset(count)
.pipe(NonNull::new)
.expect("Wrapping offset cannot produce the null pointer");
self
}
/// Gets the address as a pointer to the access type.
#[inline(always)]
pub(crate) fn to_access(self) -> *const T::Access {
self.to_const().cast::<T::Access>()
}
/// Gets the address as a read-only pointer.
#[inline(always)]
pub fn to_const(self) -> *const T {
self.inner.as_ptr() as *const T
}
/// Gets the address as a read-only pointer to the register type.
#[inline(always)]
pub(crate) fn to_mem(self) -> *const T::Mem {
self.to_const().cast::<T::Mem>()
}
/// Gets the address as a non-null pointer.
#[inline(always)]
#[cfg(feature = "alloc")]
pub(crate) fn to_nonnull(self) -> NonNull<T> {
self.inner
}
/// Gets the raw numeric value of the address.
#[inline(always)]
pub(crate) fn value(self) -> usize {
self.inner.as_ptr() as usize
}
/// The caller must ensure that this is only called on non-null,
/// well-aligned, pointers. Pointers derived from Rust references or calls
/// to the Rust allocator API will always satisfy this.
unsafe fn force_wrap(self) -> Address<Self::Permission, T>;
}
#[cfg(not(tarpaulin_include))]
impl<T> Address<Mut, T>
where T: BitStore
{
/// Gets the address as a write-capable pointer.
#[inline(always)]
#[allow(clippy::clippy::wrong_self_convention)]
pub fn to_mut(self) -> *mut T {
self.inner.as_ptr()
}
impl<T> AddressExt<T> for *const T {
type Permission = Const;
/// Gets the address as a write-capable pointer to the register type.
#[inline(always)]
pub(crate) fn to_mem_mut(self) -> *mut T::Mem {
self.to_mut().cast::<T::Mem>()
unsafe fn force_wrap(self) -> Address<Const, T> {
self.try_conv::<Address<_, _>>()
// Don’t call this with null pointers.
.unwrap_or_else(|err| unreachable!("{}", err))
.pipe(check_alignment)
// Don’t call this with misaligned pointers either.
.unwrap_or_else(|err| unreachable!("{}", err))
}
}
#[cfg(not(tarpaulin_include))]
impl<M, T> Clone for Address<M, T>
where
M: Mutability,
T: BitStore,
{
#[inline(always)]
fn clone(&self) -> Self {
*self
}
}
impl<T> AddressExt<T> for *mut T {
type Permission = Mut;
#[cfg(not(tarpaulin_include))]
impl<T> From<&T> for Address<Const, T>
where T: BitStore
{
#[inline(always)]
fn from(elem: &T) -> Self {
Self {
inner: elem.into(),
_mut: PhantomData,
}
unsafe fn force_wrap(self) -> Address<Mut, T> {
self.try_conv::<Address<_, _>>()
.unwrap_or_else(|err| unreachable!("{}", err))
.pipe(check_alignment)
.unwrap_or_else(|err| unreachable!("{}", err))
}
}
#[cfg(not(tarpaulin_include))]
impl<T> From<&mut T> for Address<Mut, T>
where T: BitStore
{
#[inline(always)]
fn from(elem: &mut T) -> Self {
Self {
inner: elem.into(),
_mut: PhantomData,
}
}
/// Error produced when an address is insufficiently aligned to its type.
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct MisalignError<T> {
/// The misaligned pointer.
pub ptr: *const T,
}
#[cfg(not(tarpaulin_include))]
impl<T> TryFrom<*const T> for Address<Const, T>
where T: BitStore
{
type Error = AddressError<T>;
#[inline(always)]
fn try_from(elem: *const T) -> Result<Self, Self::Error> {
Self::new(elem as usize)
}
impl<T> MisalignError<T> {
const ALIGN: usize = mem::align_of::<T>();
const CTTZ: usize = Self::ALIGN.trailing_zeros() as usize;
}
#[cfg(not(tarpaulin_include))]
impl<T> TryFrom<*mut T> for Address<Mut, T>
where T: BitStore
{
type Error = AddressError<T>;
#[inline(always)]
fn try_from(elem: *mut T) -> Result<Self, Self::Error> {
Self::new(elem as usize)
}
}
impl<M, T> Eq for Address<M, T>
where
M: Mutability,
T: BitStore,
{
}
#[cfg(not(tarpaulin_include))]
impl<M1, M2, T1, T2> PartialEq<Address<M2, T2>> for Address<M1, T1>
where
M1: Mutability,
M2: Mutability,
T1: BitStore,
T2: BitStore,
{
impl<T> Debug for MisalignError<T> {
#[inline]
fn eq(&self, other: &Address<M2, T2>) -> bool {
TypeId::of::<T1::Mem>() == TypeId::of::<T2::Mem>()
&& self.value() == other.value()
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
fmt.debug_tuple("Misalign")
.field(&self.ptr.fmt_pointer())
.field(&Self::ALIGN)
.finish()
}
}
#[cfg(not(tarpaulin_include))]
impl<M, T> Ord for Address<M, T>
where
M: Mutability,
T: BitStore,
{
impl<T> Display for MisalignError<T> {
#[inline]
fn cmp(&self, other: &Self) -> cmp::Ordering {
self.partial_cmp(&other)
.expect("Addresses have a total ordering")
}
}
#[cfg(not(tarpaulin_include))]
impl<M1, M2, T1, T2> PartialOrd<Address<M2, T2>> for Address<M1, T1>
where
M1: Mutability,
M2: Mutability,
T1: BitStore,
T2: BitStore,
{
#[inline]
fn partial_cmp(&self, other: &Address<M2, T2>) -> Option<cmp::Ordering> {
if TypeId::of::<T1::Mem>() != TypeId::of::<T2::Mem>() {
return None;
};
self.value().partial_cmp(&other.value())
}
}
#[cfg(not(tarpaulin_include))]
impl<M, T> Debug for Address<M, T>
where
M: Mutability,
T: BitStore,
{
#[inline(always)]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
Debug::fmt(&self.to_const(), fmt)
write!(
fmt,
"Type {} requires {}-byte alignment: address ",
any::type_name::<T>(),
Self::ALIGN,
)?;
Pointer::fmt(&self.ptr, fmt)?;
write!(fmt, " must clear its least {} bits", Self::CTTZ)
}
}
#[cfg(not(tarpaulin_include))]
impl<M, T> Pointer for Address<M, T>
where
M: Mutability,
T: BitStore,
{
#[inline(always)]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
Pointer::fmt(&self.to_const(), fmt)
}
unsafe impl<T> Send for MisalignError<T> {
}
#[cfg(not(tarpaulin_include))]
impl<M, T> Hash for Address<M, T>
where
M: Mutability,
T: BitStore,
{
#[inline(always)]
fn hash<H>(&self, state: &mut H)
where H: Hasher {
self.inner.hash(state)
}
unsafe impl<T> Sync for MisalignError<T> {
}
impl<M, T> Copy for Address<M, T>
where
M: Mutability,
T: BitStore,
{
#[cfg(feature = "std")]
impl<T> std::error::Error for MisalignError<T> {
}
/// An error produced when consuming `BitStore` memory addresses.
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum AddressError<T>
where T: BitStore
{
/// `Address` cannot use the null pointer.
Null,
/// `Address` cannot be misaligned for the referent type `T`.
Misaligned(*const T),
}
#[test]
#[cfg(feature = "alloc")]
fn render() {
#[cfg(not(feature = "std"))]
use alloc::format;
use core::ptr::NonNull;
impl<T> From<Infallible> for AddressError<T>
where T: BitStore
{
fn from(_: Infallible) -> Self {
unreachable!("Infallible errors can never be produced");
}
assert_eq!(
format!(
"{}",
check_alignment(Address::<Const, u16>::new(
NonNull::new(0x13579 as *mut _).unwrap()
))
.unwrap_err()
),
"Type u16 requires 2-byte alignment: address 0x13579 must clear its \
least 1 bits"
);
assert_eq!(
format!(
"{}",
check_alignment(Address::<Const, u32>::new(
NonNull::new(0x13579 as *mut _).unwrap()
))
.unwrap_err()
),
"Type u32 requires 4-byte alignment: address 0x13579 must clear its \
least 2 bits"
);
}
impl<T> Display for AddressError<T>
where T: BitStore
{
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
match *self {
Self::Null => {
fmt.write_str("`bitvec` will not operate on the null pointer")
},
Self::Misaligned(ptr) => write!(
fmt,
"`bitvec` requires that the address {:p} clear its least {} \
bits to be aligned for type {}",
ptr,
T::Mem::INDX - 3,
type_name::<T::Mem>(),
),
}
}
}
#[cfg(feature = "std")]
impl<T> std::error::Error for AddressError<T> where T: BitStore
{
}

@@ -13,3 +13,2 @@ /*! Proxy reference for `&mut bool`.

use core::{
any::TypeId,
cell::Cell,

@@ -37,8 +36,9 @@ cmp,

use super::{
BitPtr,
Const,
Mut,
Mutability,
};
use crate::{
mutability::{
Const,
Mut,
Mutability,
},
order::{

@@ -48,3 +48,2 @@ BitOrder,

},
ptr::BitPtr,
store::BitStore,

@@ -492,6 +491,5 @@ };

// memory.
if TypeId::of::<M>() == TypeId::of::<Mut>() {
let value = self.data;
if M::CONTAINS_MUTABILITY {
unsafe {
self.bitptr.assert_mut().write(value);
self.bitptr.assert_mut().write(self.data);
}

@@ -498,0 +496,0 @@ }

//! Implementation of `Range<BitPtr>`.
use core::{
any::TypeId,
fmt::{

@@ -23,4 +22,11 @@ self,

#[cfg(feature = "alloc")]
use super::Mut;
use super::{
BitPtr,
BitSpan,
Mutability,
};
use crate::{
mutability::Mutability,
devel as dvl,
order::{

@@ -30,6 +36,2 @@ BitOrder,

},
ptr::{
BitPtr,
BitSpan,
},
store::BitStore,

@@ -95,3 +97,3 @@ };

/// Destructures the range back into its start and end pointers.
#[inline]
#[inline(always)]
#[cfg(not(tarpaulin_include))]

@@ -130,3 +132,4 @@ pub fn raw_parts(&self) -> (BitPtr<M, O, T>, BitPtr<M, O, T>) {

/// ```
#[inline]
#[inline(always)]
#[cfg(not(tarpaulin_include))]
pub fn is_empty(&self) -> bool {

@@ -178,3 +181,3 @@ self.start == self.end

/// ```
#[inline]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn contains<M2, T2>(&self, pointer: &BitPtr<M2, O, T2>) -> bool

@@ -201,3 +204,3 @@ where

/// This method may only be called when the range is non-empty.
#[inline]
#[cfg_attr(not(tarpaulin_include), inline(always))]
fn take_front(&mut self) -> BitPtr<M, O, T> {

@@ -212,3 +215,3 @@ let start = self.start;

/// This method may only be called when the range is non-empty.
#[inline]
#[cfg_attr(not(tarpaulin_include), inline(always))]
fn take_back(&mut self) -> BitPtr<M, O, T> {

@@ -254,3 +257,3 @@ let prev = unsafe { self.end.sub(1) };

fn eq(&self, other: &BitPtrRange<M2, O, T2>) -> bool {
if TypeId::of::<T1::Mem>() != TypeId::of::<T2::Mem>() {
if !dvl::match_store::<T1::Mem, T2::Mem>() {
return false;

@@ -289,3 +292,3 @@ }

#[cfg(not(tarpaulin_include))]
impl<M, O, T> Into<Range<BitPtr<M, O, T>>> for BitPtrRange<M, O, T>
impl<M, O, T> From<BitPtrRange<M, O, T>> for Range<BitPtr<M, O, T>>
where

@@ -297,4 +300,4 @@ M: Mutability,

#[inline(always)]
fn into(self) -> Range<BitPtr<M, O, T>> {
self.into_range()
fn from(bpr: BitPtrRange<M, O, T>) -> Self {
bpr.into_range()
}

@@ -360,3 +363,4 @@ }

#[inline]
#[inline(always)]
#[cfg(not(tarpaulin_include))]
fn size_hint(&self) -> (usize, Option<usize>) {

@@ -444,2 +448,14 @@ let len = self.len();

/// Dereferences the bit-pointer. This is guaranteed to be valid by the
/// iterator.
#[inline(always)]
#[cfg(feature = "alloc")]
pub(crate) fn read_raw<O, T>(bp: BitPtr<Mut, O, T>) -> bool
where
O: BitOrder,
T: BitStore,
{
unsafe { bp.read() }
}
#[cfg(test)]

@@ -451,4 +467,4 @@ mod tests {

use crate::{
mutability::Const,
order::Lsb0,
ptr::Const,
};

@@ -455,0 +471,0 @@

//! A pointer to a single bit.
use core::{
any::{
type_name,
TypeId,
},
any,
cmp,

@@ -30,6 +27,23 @@ convert::{

use funty::IsNumber;
use wyz::fmt::FmtForward;
use wyz::{
comu::Frozen,
fmt::FmtForward,
};
use super::{
Address,
AddressExt,
BitPtrRange,
BitRef,
BitSpan,
BitSpanError,
Const,
MisalignError,
Mut,
Mutability,
NullPtrError,
};
use crate::{
access::BitAccess,
devel as dvl,
index::{

@@ -39,7 +53,2 @@ BitIdx,

},
mutability::{
Const,
Mut,
Mutability,
},
order::{

@@ -49,10 +58,2 @@ BitOrder,

},
ptr::{
Address,
AddressError,
BitPtrRange,
BitRef,
BitSpan,
BitSpanError,
},
store::BitStore,

@@ -143,5 +144,3 @@ };

pub(crate) fn get_addr(&self) -> Address<M, T> {
unsafe {
ptr::read_unaligned(self as *const Self as *const Address<M, T>)
}
unsafe { ptr::addr_of!(self.addr).read_unaligned() }
}

@@ -221,2 +220,9 @@

/// Gets just the head counter.
#[inline(always)]
#[cfg(feature = "alloc")]
pub(crate) fn head(self) -> BitIdx<T::Mem> {
self.head
}
/// Produces a `BitSpan`, starting at `self` and running for `bits`.

@@ -339,2 +345,17 @@ ///

/// Freezes the pointer, forbidding direct mutation.
///
/// This is used as a necessary prerequisite to all mutation of memory.
/// `BitPtr` uses an implementation scoped to `Frozen<_>` to perform
/// alias-aware writes; see below.
#[inline]
pub(crate) fn freeze(self) -> BitPtr<Frozen<M>, O, T> {
let Self { addr, head, .. } = self;
BitPtr {
addr: addr.freeze(),
head,
..BitPtr::DANGLING
}
}
// `pointer` inherent API

@@ -608,11 +629,11 @@

*/
self.addr
.value()
.wrapping_sub(origin.addr.value())
(self.addr
.to_const() as usize)
.wrapping_sub(origin.addr.to_const()as usize)
// Pointers step by `T`, but **address values** step by `u8`.
.wrapping_mul(<u8 as IsNumber>::BITS as usize)
// `self.head` moves the end farther from origin,
.wrapping_add(self.head.value() as usize)
.wrapping_add(self.head.into_inner() as usize)
// and `origin.head` moves the origin closer to the end.
.wrapping_sub(origin.head.value() as usize) as isize
.wrapping_sub(origin.head.into_inner() as usize) as isize
}

@@ -754,3 +775,3 @@

// If the orderings match, then overlap is permitted and defined.
if TypeId::of::<O>() == TypeId::of::<O2>() {
if dvl::match_order::<O, O2>() {
let (addr, head) = dest.raw_parts();

@@ -865,3 +886,3 @@ let dst = BitPtr::<Mut, O, T2>::new(addr, head);

self.addr.to_const().align_offset(align),
self.head.value() as usize,
self.head.into_inner() as usize,
) {

@@ -936,6 +957,3 @@ (0, 0) => 0,

pub fn from_slice(slice: &[T]) -> Self {
Self::new(
unsafe { Address::new_unchecked(slice.as_ptr() as usize) },
BitIdx::ZERO,
)
Self::new(unsafe { slice.as_ptr().force_wrap() }, BitIdx::ZERO)
}

@@ -1023,6 +1041,3 @@

pub fn from_mut_slice(slice: &mut [T]) -> Self {
Self::new(
unsafe { Address::new_unchecked(slice.as_mut_ptr() as usize) },
BitIdx::ZERO,
)
Self::new(unsafe { slice.as_mut_ptr().force_wrap() }, BitIdx::ZERO)
}

@@ -1158,3 +1173,3 @@

pub unsafe fn write(self, value: bool) {
(&*self.addr.to_access()).write_bit::<O>(self.head, value);
self.replace(value);
}

@@ -1185,4 +1200,5 @@

pub unsafe fn write_volatile(self, val: bool) {
let select = O::select(self.head).value();
let mut tmp = self.addr.to_mem().read_volatile();
let select = O::select(self.head).into_inner();
let ptr = self.addr.cast::<T::Mem>().to_mut();
let mut tmp = ptr.read_volatile();
if val {

@@ -1194,3 +1210,3 @@ tmp |= &select;

}
self.addr.to_mem_mut().write_volatile(tmp);
ptr.write_volatile(tmp);
}

@@ -1211,5 +1227,3 @@

pub unsafe fn replace(self, src: bool) -> bool {
let out = self.read();
self.write(src);
out
self.freeze().frozen_write_bit(src)
}

@@ -1234,8 +1248,31 @@

{
let (a, b) = (self.read(), with.read());
self.write(b);
with.write(a);
self.write(with.replace(self.read()));
}
}
impl<M, O, T> BitPtr<Frozen<M>, O, T>
where
M: Mutability,
O: BitOrder,
T: BitStore,
{
/// Writes to a bit in memory.
///
/// # Safety
///
/// The caller is responsible for ensuring that the referent bit is safe to
/// modify. `bitvec` uses `&ref`/`*const` pointers for aliased write-capable
/// views, which the mutability tracking system currently does not support.
///
/// Once a pointer is frozen, even if it does *not* have write permissions
/// through either `Mut` or `Radium` in its start state, this method becomes
/// available. Use on incorrect pointers (f.ex. freezing an `&u8`) is
/// undefined.
#[inline]
pub(crate) unsafe fn frozen_write_bit(self, value: bool) -> bool {
(&*self.addr.cast::<T::Access>().to_const())
.write_bit::<O>(self.head, value)
}
}
#[cfg(not(tarpaulin_include))]

@@ -1291,7 +1328,8 @@ impl<M, O, T> Clone for BitPtr<M, O, T>

fn eq(&self, other: &BitPtr<M2, O, T2>) -> bool {
if TypeId::of::<T1::Mem>() != TypeId::of::<T2::Mem>() {
if !dvl::match_store::<T1::Mem, T2::Mem>() {
return false;
}
self.get_addr().value() == other.get_addr().value()
&& self.head.value() == other.head.value()
self.get_addr().to_const() as usize
== other.get_addr().to_const() as usize
&& self.head.into_inner() == other.head.into_inner()
}

@@ -1311,8 +1349,10 @@ }

fn partial_cmp(&self, other: &BitPtr<M2, O, T2>) -> Option<cmp::Ordering> {
if TypeId::of::<T1::Mem>() != TypeId::of::<T2::Mem>() {
if !dvl::match_store::<T1::Mem, T2::Mem>() {
return None;
}
match (self.get_addr().value()).cmp(&other.get_addr().value()) {
match (self.get_addr().to_const() as usize)
.cmp(&(other.get_addr().to_const() as usize))
{
cmp::Ordering::Equal => {
self.head.value().partial_cmp(&other.head.value())
self.head.into_inner().partial_cmp(&other.head.into_inner())
},

@@ -1382,13 +1422,10 @@ ord => Some(ord),

{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
write!(
fmt,
"*{} Bit<{}, {}>",
match TypeId::of::<M>() {
t if t == TypeId::of::<Const>() => "const",
t if t == TypeId::of::<Mut>() => "mut",
_ => unreachable!("No other implementors exist"),
},
type_name::<O>(),
type_name::<T>()
"{} Bit<{}, {}>",
M::RENDER,
any::type_name::<O>(),
any::type_name::<T>(),
)?;

@@ -1405,2 +1442,3 @@ Pointer::fmt(self, fmt)

{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -1442,15 +1480,17 @@ fmt.debug_tuple("")

{
/// The element address was somehow invalid.
InvalidAddress(AddressError<T>),
/// The bit index was somehow invalid.
InvalidIndex(BitIdxError<T::Mem>),
/// The null address was provided.
Null(NullPtrError),
/// The address was misaligned for the element type.
Misaligned(MisalignError<T>),
/// The bit index was invalid for the element type.
BadIndex(BitIdxError<T::Mem>),
}
#[cfg(not(tarpaulin_include))]
impl<T> From<AddressError<T>> for BitPtrError<T>
impl<T> From<NullPtrError> for BitPtrError<T>
where T: BitStore
{
#[inline(always)]
fn from(err: AddressError<T>) -> Self {
Self::InvalidAddress(err)
fn from(err: NullPtrError) -> Self {
Self::Null(err)
}

@@ -1460,2 +1500,12 @@ }

#[cfg(not(tarpaulin_include))]
impl<T> From<MisalignError<T>> for BitPtrError<T>
where T: BitStore
{
#[inline(always)]
fn from(err: MisalignError<T>) -> Self {
Self::Misaligned(err)
}
}
#[cfg(not(tarpaulin_include))]
impl<T> From<BitIdxError<T::Mem>> for BitPtrError<T>

@@ -1466,3 +1516,3 @@ where T: BitStore

fn from(err: BitIdxError<T::Mem>) -> Self {
Self::InvalidIndex(err)
Self::BadIndex(err)
}

@@ -1488,4 +1538,5 @@ }

match self {
Self::InvalidAddress(addr) => Display::fmt(addr, fmt),
Self::InvalidIndex(index) => Display::fmt(index, fmt),
Self::Null(err) => Display::fmt(err, fmt),
Self::Misaligned(err) => Display::fmt(err, fmt),
Self::BadIndex(err) => Display::fmt(err, fmt),
}

@@ -1495,10 +1546,2 @@ }

unsafe impl<T> Send for BitPtrError<T> where T: BitStore
{
}
unsafe impl<T> Sync for BitPtrError<T> where T: BitStore
{
}
#[cfg(feature = "std")]

@@ -1513,4 +1556,4 @@ impl<T> std::error::Error for BitPtrError<T> where T: BitStore

use crate::{
mutability::Const,
prelude::Lsb0,
ptr::Const,
};

@@ -1526,3 +1569,3 @@

assert_eq!(addr.to_const(), &data as *const _);
assert_eq!(indx.value(), head);
assert_eq!(indx.into_inner(), head);
}

@@ -1529,0 +1572,0 @@

@@ -25,2 +25,11 @@ //! Encoded pointer to a span region.

use super::{
Address,
BitPtr,
BitPtrError,
BitPtrRange,
Const,
Mut,
Mutability,
};
use crate::{

@@ -33,7 +42,2 @@ domain::Domain,

mem::BitMemory,
mutability::{
Const,
Mut,
Mutability,
},
order::{

@@ -43,7 +47,2 @@ BitOrder,

},
ptr::{
Address,
BitPtr,
BitPtrError,
},
slice::BitSlice,

@@ -283,2 +282,3 @@ store::BitStore,

/// expected logical mistake.
#[inline(always)]
#[cfg(feature = "alloc")]

@@ -288,3 +288,3 @@ #[cfg(not(tarpaulin_include))]

Self {
ptr: addr.to_nonnull().cast::<()>(),
ptr: addr.into_inner().cast::<()>(),
len: 0,

@@ -296,2 +296,3 @@ _or: PhantomData,

#[inline]
pub(crate) fn new(

@@ -334,2 +335,3 @@ addr: Address<M, T>,

/// [`::new`]: Self::new
#[inline]
pub(crate) unsafe fn new_unchecked(

@@ -340,4 +342,4 @@ addr: Address<M, T>,

) -> Self {
let head = head.value() as usize;
let ptr_data = addr.value() & Self::PTR_ADDR_MASK;
let head = head.into_inner() as usize;
let ptr_data = addr.to_const() as usize & Self::PTR_ADDR_MASK;
let ptr_head = head >> Self::LEN_HEAD_BITS;

@@ -392,2 +394,3 @@

// Mutable or immutable span descriptors can become immutable pointers.
#[inline]
pub(crate) fn to_bitslice_ptr(self) -> *const BitSlice<O, T> {

@@ -432,2 +435,3 @@ ptr::slice_from_raw_parts(

/// significantly in the result type. Use with caution.
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub(crate) fn cast<U>(self) -> BitSpan<M, O, U>

@@ -509,5 +513,5 @@ where U: BitStore {

Some((head, addr)) => BitSpan::new_unchecked(
Address::new_unchecked(addr as *const _ as usize),
Address::new(NonNull::from(addr)),
head,
t_bits - head.value() as usize + l_bits,
t_bits - head.into_inner() as usize + l_bits,
),

@@ -522,3 +526,3 @@ // If the head does not exist, then the left span only

BitSpan::new_unchecked(
Address::new_unchecked(l_addr as usize),
Address::new(NonNull::new(l_addr).unwrap()),
BitIdx::ZERO,

@@ -536,3 +540,3 @@ l_bits,

BitSpan::new_unchecked(
Address::new_unchecked(c_addr as usize),
Address::new(NonNull::new(c_addr).unwrap()),
BitIdx::ZERO,

@@ -559,9 +563,9 @@ c_bits,

if r.is_empty() {
Address::new_unchecked(addr as *const T as usize)
Address::new(NonNull::from(addr))
}
else {
Address::new_unchecked(r_addr as *const T as usize)
Address::new(NonNull::new(r_addr).unwrap())
},
BitIdx::ZERO,
tail.value() as usize + r_bits,
tail.into_inner() as usize + r_bits,
),

@@ -574,3 +578,3 @@ // If the tail does not exist, then the right span is only

BitSpan::new_unchecked(
Address::new_unchecked(r_addr as usize),
Address::new(NonNull::new(r_addr).unwrap()),
BitIdx::ZERO,

@@ -605,7 +609,8 @@ r_bits,

/// access type.
#[inline]
pub(crate) fn address(&self) -> Address<M, T> {
unsafe {
Address::new_unchecked(
self.ptr.as_ptr() as usize & Self::PTR_ADDR_MASK,
)
Address::new(NonNull::new_unchecked(
(self.ptr.as_ptr() as usize & Self::PTR_ADDR_MASK) as *mut T,
))
}

@@ -627,2 +632,3 @@ }

/// [`::new`]: Self::new
#[inline]
#[cfg(any(feature = "alloc", test))]

@@ -635,3 +641,3 @@ pub(crate) unsafe fn set_address<A>(&mut self, addr: A)

let addr = addr.try_into().unwrap();
let mut addr_value = addr.value();
let mut addr_value = addr.to_const() as usize;
addr_value &= Self::PTR_ADDR_MASK;

@@ -655,2 +661,3 @@ addr_value |= self.ptr.as_ptr() as usize & Self::PTR_HEAD_MASK;

/// [`self.address()`]: Self::pointer
#[inline]
pub(crate) fn head(&self) -> BitIdx<T::Mem> {

@@ -677,5 +684,6 @@ // Get the high part of the head counter out of the pointer.

/// `.addr` or `.bits`.
#[inline]
#[cfg(any(feature = "alloc", test))]
pub(crate) unsafe fn set_head(&mut self, head: BitIdx<T::Mem>) {
let head = head.value() as usize;
let head = head.into_inner() as usize;
let mut ptr = self.ptr.as_ptr() as usize;

@@ -700,2 +708,3 @@

/// A count of how many live bits the region pointer describes.
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub(crate) fn len(&self) -> usize {

@@ -718,2 +727,3 @@ self.len >> Self::LEN_HEAD_BITS

/// [`REGION_MAX_BITS`]: Self::REGION_MAX_BITS
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub(crate) unsafe fn set_len(&mut self, new_len: usize) {

@@ -730,2 +740,3 @@ debug_assert!(

/// Gets a pointer to the starting bit of the span.
#[inline]
pub(crate) fn as_bitptr(self) -> BitPtr<M, O, T> {

@@ -735,2 +746,7 @@ BitPtr::new(self.address(), self.head())

#[inline]
pub(crate) fn as_bitptr_range(self) -> BitPtrRange<M, O, T> {
unsafe { self.as_bitptr().range(self.len()) }
}
/// Gets the three logical components of the pointer.

@@ -748,2 +764,3 @@ ///

/// - `.2`: The number of live bits in the region.
#[inline]
pub(crate) fn raw_parts(&self) -> (Address<M, T>, BitIdx<T::Mem>, usize) {

@@ -768,5 +785,6 @@ (self.address(), self.head(), self.len())

/// [`self.address()`]: Self::pointer
#[inline]
pub(crate) fn elements(&self) -> usize {
// Find the distance of the last bit from the base address.
let total = self.len() + self.head().value() as usize;
let total = self.len() + self.head().into_inner() as usize;
// The element count is always the bit count divided by the bit width,

@@ -792,6 +810,7 @@ let base = total >> T::Mem::INDX;

/// It will be zero only when `self` is empty.
#[inline]
pub(crate) fn tail(&self) -> BitTail<T::Mem> {
let (head, len) = (self.head(), self.len());
if head.value() == 0 && len == 0 {
if head.into_inner() == 0 && len == 0 {
return BitTail::ZERO;

@@ -802,3 +821,3 @@ }

// modulated by the element width.
let tail = (head.value() as usize + len) & T::Mem::MASK as usize;
let tail = (head.into_inner() as usize + len) & T::Mem::MASK as usize;
/* If the tail is zero, wrap it to `T::Mem::BITS` as the maximal. This

@@ -831,5 +850,6 @@ upshifts `1` (tail is zero) or `0` (tail is not), then sets the upshift

/// [`T::Mem`]: crate::store::BitStore::Mem
#[inline]
pub(crate) unsafe fn incr_head(&mut self) {
// Increment the cursor, permitting rollover to `T::Mem::BITS`.
let head = self.head().value() as usize + 1;
let head = self.head().into_inner() as usize + 1;

@@ -932,2 +952,3 @@ // Write the low bits into the `.len` field, then discard them.

// Immutable pointers can only become immutable span descriptors.
#[inline]
pub(crate) fn from_bitslice_ptr(raw: *const BitSlice<O, T>) -> Self {

@@ -947,18 +968,2 @@ let slice_nn = match NonNull::new(raw as *const [()] as *mut [()]) {

}
/// Assert that an immutable span pointer is in fact mutable.
///
/// This can only be called from a context where a mutable span descriptor
/// was lowered to immutable and needs to be re-raised; it is Undefined
/// Behavior in the compiler to call it on a span descriptor that was never
/// mutable.
pub(crate) unsafe fn assert_mut(self) -> BitSpan<Mut, O, T> {
let Self { ptr, len, _or, .. } = self;
BitSpan {
ptr,
len,
_or,
_ty: PhantomData,
}
}
}

@@ -1017,2 +1022,3 @@

{
#[inline(always)]
fn clone(&self) -> Self {

@@ -1039,2 +1045,3 @@ *self

{
#[inline]
fn eq(&self, other: &BitSpan<M2, O, T2>) -> bool {

@@ -1046,4 +1053,4 @@ let (addr_a, head_a, bits_a) = self.raw_parts();

T1::Mem::BITS == T2::Mem::BITS
&& addr_a.value() == addr_b.value()
&& head_a.value() == head_b.value()
&& addr_a.to_const() as usize == addr_b.to_const() as usize
&& head_a.into_inner() == head_b.into_inner()
&& bits_a == bits_b

@@ -1193,2 +1200,3 @@ }

use core::{
convert::TryFrom,
mem,

@@ -1198,6 +1206,12 @@ ptr,

use tap::Pipe;
use super::*;
use crate::{
prelude::*,
ptr::AddressError,
ptr::{
check_alignment,
MisalignError,
NullPtrError,
},
};

@@ -1208,8 +1222,8 @@

assert!(matches!(
Address::<Const, u8>::new(0),
Err(AddressError::Null)
Address::<Const, u8>::try_from(ptr::null()),
Err(NullPtrError),
));
assert!(matches!(
Address::<Const, u16>::new(3),
Err(AddressError::Misaligned(addr)) if addr as usize == 3
Address::<Const, u16>::try_from(3 as *const u16).unwrap().pipe(check_alignment),
Err(MisalignError { ptr }) if ptr as usize == 3,
));

@@ -1231,3 +1245,3 @@

assert!(BitSpan::<_, Lsb0, _>::new(addr, head, !3).is_err());
addr = unsafe { Address::new_unchecked(!1) };
addr = Address::try_from(!1 as *const u16).unwrap();
assert!(BitSpan::<_, Lsb0, _>::new(addr, head, 50).is_err());

@@ -1308,24 +1322,2 @@ }

}
#[test]
#[cfg(feature = "alloc")]
fn render() {
#[cfg(not(feature = "std"))]
use alloc::format;
assert_eq!(
format!("{}", Address::<Const, u8>::new(0).unwrap_err()),
"`bitvec` will not operate on the null pointer"
);
assert_eq!(
format!("{}", Address::<Const, u16>::new(0x13579).unwrap_err()),
"`bitvec` requires that the address 0x13579 clear its least 1 bits \
to be aligned for type u16"
);
assert_eq!(
format!("{}", Address::<Const, u32>::new(0x13579).unwrap_err()),
"`bitvec` requires that the address 0x13579 clear its least 2 bits \
to be aligned for type u32"
);
}
}

@@ -7,4 +7,7 @@ #![cfg(test)]

use super::{
BitPtr,
Const,
};
use crate::{
mutability::Const,
order::{

@@ -14,3 +17,2 @@ Lsb0,

},
ptr::BitPtr,
slice::BitSlice,

@@ -17,0 +19,0 @@ };

@@ -72,10 +72,11 @@ /*! [`serde`]-powered de/serialization.

ptr::{
AddressError,
BitPtr,
BitPtrError,
BitSpanError,
MisalignError,
NullPtrError,
},
slice::BitSlice,
store::BitStore,
view::BitView,
view::BitViewSized,
};

@@ -99,3 +100,3 @@ #[cfg(feature = "alloc")]

state.serialize_field("head", &head.value())?;
state.serialize_field("head", &head.into_inner())?;
state.serialize_field("bits", &(self.len() as u64))?;

@@ -129,3 +130,3 @@ state.serialize_field("data", &self.domain())?;

O: BitOrder,
V: BitView + Serialize,
V: BitViewSized + Serialize,
{

@@ -136,3 +137,3 @@ #[inline]

unsafe { core::ptr::read(self) }
.value()
.into_inner()
.serialize(serializer)

@@ -143,2 +144,3 @@ }

#[cfg(feature = "alloc")]
#[cfg(not(tarpaulin_include))]
impl<O, T> Serialize for BitBox<O, T>

@@ -150,2 +152,3 @@ where

{
#[inline(always)]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>

@@ -158,2 +161,3 @@ where S: Serializer {

#[cfg(feature = "alloc")]
#[cfg(not(tarpaulin_include))]
impl<O, T> Serialize for BitVec<O, T>

@@ -165,2 +169,3 @@ where

{
#[inline(always)]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>

@@ -175,4 +180,5 @@ where S: Serializer {

O: BitOrder,
V: BitView + Deserialize<'de>,
V: BitViewSized + Deserialize<'de>,
{
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>

@@ -243,3 +249,3 @@ where D: Deserializer<'de> {

data.len()
.saturating_mul(T::Mem::BITS as usize)
.saturating_mul(<T::Mem as IsNumber>::BITS as usize)
.saturating_sub(head as usize),

@@ -254,5 +260,5 @@ );

.map_err(|err| match err {
BitSpanError::InvalidBitptr(BitPtrError::InvalidIndex(err)) => {
BitSpanError::InvalidBitptr(BitPtrError::BadIndex(err)) => {
de::Error::invalid_value(
Unexpected::Unsigned(err.value() as u64),
Unexpected::Unsigned(err.into_inner() as u64),
&"a head-bit index less than the deserialized element \

@@ -271,9 +277,9 @@ type’s bit width",

),
BitSpanError::InvalidBitptr(BitPtrError::InvalidAddress(
AddressError::Null,
BitSpanError::InvalidBitptr(BitPtrError::Null(
NullPtrError,
)) => {
unreachable!("The allocator will not produce a null pointer")
},
BitSpanError::InvalidBitptr(BitPtrError::InvalidAddress(
AddressError::Misaligned(_),
BitSpanError::InvalidBitptr(BitPtrError::Misaligned(
MisalignError { ptr: _ },
)) => {

@@ -298,2 +304,3 @@ unreachable!(

#[inline]
fn expecting(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -371,2 +378,3 @@ fmt.write_str("a BitSeq data series")

{
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>

@@ -386,2 +394,3 @@ where D: Deserializer<'de> {

{
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>

@@ -388,0 +397,0 @@ where D: Deserializer<'de> {

@@ -18,2 +18,6 @@ //! Port of the `[T]` operator implementations.

use super::{
BitSlice,
BitSliceIndex,
};
use crate::{

@@ -23,6 +27,2 @@ access::BitAccess,

order::BitOrder,
slice::{
BitSlice,
BitSliceIndex,
},
store::BitStore,

@@ -37,2 +37,3 @@ };

{
#[inline]
fn bitand_assign(&mut self, rhs: Rhs) {

@@ -50,2 +51,3 @@ let mut iter = rhs.into_iter();

{
#[inline]
fn bitor_assign(&mut self, rhs: Rhs) {

@@ -63,2 +65,3 @@ let mut iter = rhs.into_iter();

{
#[inline]
fn bitxor_assign(&mut self, rhs: Rhs) {

@@ -102,2 +105,3 @@ let mut iter = rhs.into_iter();

/// ```
#[inline]
fn index(&self, index: usize) -> &Self::Output {

@@ -122,2 +126,4 @@ // Convert the `BitRef` to `&'static bool`

#[inline(always)]
#[cfg(not(tarpaulin_include))]
fn index(&self, index: $t) -> &Self::Output {

@@ -133,2 +139,4 @@ index.index(self)

{
#[inline(always)]
#[cfg(not(tarpaulin_include))]
fn index_mut(&mut self, index: $t) -> &mut Self::Output {

@@ -135,0 +143,0 @@ index.index_mut(self)

@@ -18,2 +18,3 @@ /*! Specialization overrides.

use super::BitSlice;
use crate::{

@@ -28,3 +29,2 @@ devel as dvl,

},
slice::BitSlice,
store::BitStore,

@@ -46,2 +46,3 @@ };

/// Accelerates copies between disjoint slices with batch loads.
#[inline]
pub(crate) fn sp_copy_from_bitslice(&mut self, src: &Self) {

@@ -64,2 +65,3 @@ assert_eq!(

/// loads.
#[inline]
pub(crate) unsafe fn sp_copy_within_unchecked<R>(

@@ -118,2 +120,3 @@ &mut self,

/// Accelerates equality checking with batch loads.
#[inline]
pub(crate) fn sp_eq(&self, other: &Self) -> bool {

@@ -130,2 +133,3 @@ if self.len() != other.len() {

/// Seeks the index of the first `1` bit in the bit-slice.
#[inline]
pub(crate) fn sp_iter_ones_first(&self) -> Option<usize> {

@@ -136,6 +140,7 @@ let mut accum = 0;

Domain::Enclave { head, elem, tail } => {
let val = (Lsb0::mask(head, tail) & elem.load_value()).value();
let val =
(Lsb0::mask(head, tail) & elem.load_value()).into_inner();
if val != T::Mem::ZERO {
accum +=
val.trailing_zeros() as usize - head.value() as usize;
accum += val.trailing_zeros() as usize
- head.into_inner() as usize;
return Some(accum);

@@ -147,6 +152,6 @@ }

if let Some((head, elem)) = head {
let val =
(Lsb0::mask(head, None) & elem.load_value()).value();
accum +=
val.trailing_zeros() as usize - head.value() as usize;
let val = (Lsb0::mask(head, None) & elem.load_value())
.into_inner();
accum += val.trailing_zeros() as usize
- head.into_inner() as usize;
if val != T::Mem::ZERO {

@@ -166,4 +171,4 @@ return Some(accum);

if let Some((elem, tail)) = tail {
let val =
(Lsb0::mask(None, tail) & elem.load_value()).value();
let val = (Lsb0::mask(None, tail) & elem.load_value())
.into_inner();
if val != T::Mem::ZERO {

@@ -181,11 +186,13 @@ accum += val.trailing_zeros() as usize;

/// Seeks the index of the last `1` bit in the bit-slice.
#[inline]
pub(crate) fn sp_iter_ones_last(&self) -> Option<usize> {
let mut out = match self.len() {
0 => return None,
n => n,
n => n - 1,
};
(|| match self.domain() {
match self.domain() {
Domain::Enclave { head, elem, tail } => {
let val = (Lsb0::mask(head, tail) & elem.load_value()).value();
let dead_bits = T::Mem::BITS as u8 - tail.value();
let val =
(Lsb0::mask(head, tail) & elem.load_value()).into_inner();
let dead_bits = T::Mem::BITS as u8 - tail.into_inner();
if val != T::Mem::ZERO {

@@ -199,6 +206,6 @@ out -= val.leading_zeros() as usize - dead_bits as usize;

if let Some((elem, tail)) = tail {
let val =
(Lsb0::mask(None, tail) & elem.load_value()).value();
let val = (Lsb0::mask(None, tail) & elem.load_value())
.into_inner();
let dead_bits =
T::Mem::BITS as usize - tail.value() as usize;
T::Mem::BITS as usize - tail.into_inner() as usize;
out -= val.leading_zeros() as usize - dead_bits;

@@ -219,4 +226,4 @@ if val != T::Mem::ZERO {

if let Some((head, elem)) = head {
let val =
(Lsb0::mask(head, None) & elem.load_value()).value();
let val = (Lsb0::mask(head, None) & elem.load_value())
.into_inner();
if val != T::Mem::ZERO {

@@ -230,7 +237,7 @@ out -= val.leading_zeros() as usize;

},
})()
.map(|idx| idx - 1)
}
}
/// Seeks the index of the first `0` bit in the bit-slice.
#[inline]
pub(crate) fn sp_iter_zeros_first(&self) -> Option<usize> {

@@ -242,4 +249,6 @@ let mut accum = 0;

// Load, invert, then mask and search for `1`.
let val = (Lsb0::mask(head, tail) & !elem.load_value()).value();
accum += val.trailing_zeros() as usize - head.value() as usize;
let val =
(Lsb0::mask(head, tail) & !elem.load_value()).into_inner();
accum +=
val.trailing_zeros() as usize - head.into_inner() as usize;
if val != T::Mem::ZERO {

@@ -252,6 +261,6 @@ return Some(accum);

if let Some((head, elem)) = head {
let val =
(Lsb0::mask(head, None) & !elem.load_value()).value();
accum +=
val.trailing_zeros() as usize - head.value() as usize;
let val = (Lsb0::mask(head, None) & !elem.load_value())
.into_inner();
accum += val.trailing_zeros() as usize
- head.into_inner() as usize;
if val != T::Mem::ZERO {

@@ -271,4 +280,4 @@ return Some(accum);

if let Some((elem, tail)) = tail {
let val =
(Lsb0::mask(None, tail) & !elem.load_value()).value();
let val = (Lsb0::mask(None, tail) & !elem.load_value())
.into_inner();
accum += val.trailing_zeros() as usize;

@@ -286,11 +295,13 @@ if val != T::Mem::ZERO {

/// Seeks the index of the last `0` bit in the bit-slice.
#[inline]
pub(crate) fn sp_iter_zeros_last(&self) -> Option<usize> {
let mut out = match self.len() {
0 => return None,
n => n,
n => n - 1,
};
(|| match self.domain() {
match self.domain() {
Domain::Enclave { head, elem, tail } => {
let val = (Lsb0::mask(head, tail) & !elem.load_value()).value();
let dead_bits = T::Mem::BITS as u8 - tail.value();
let val =
(Lsb0::mask(head, tail) & !elem.load_value()).into_inner();
let dead_bits = T::Mem::BITS as u8 - tail.into_inner();
if val != T::Mem::ZERO {

@@ -304,6 +315,6 @@ out -= val.leading_zeros() as usize - dead_bits as usize;

if let Some((elem, tail)) = tail {
let val =
(Lsb0::mask(None, tail) & !elem.load_value()).value();
let val = (Lsb0::mask(None, tail) & !elem.load_value())
.into_inner();
let dead_bits =
T::Mem::BITS as usize - tail.value() as usize;
T::Mem::BITS as usize - tail.into_inner() as usize;
out -= val.leading_zeros() as usize - dead_bits;

@@ -324,4 +335,4 @@ if val != T::Mem::ZERO {

if let Some((head, elem)) = head {
let val =
(Lsb0::mask(head, None) & !elem.load_value()).value();
let val = (Lsb0::mask(head, None) & !elem.load_value())
.into_inner();
if val != T::Mem::ZERO {

@@ -335,4 +346,3 @@ out -= val.leading_zeros() as usize;

},
})()
.map(|idx| idx - 1)
}
}

@@ -354,2 +364,3 @@ }

/// Accelerates copies between disjoint slices with batch loads.
#[inline]
pub(crate) fn sp_copy_from_bitslice(&mut self, src: &Self) {

@@ -372,2 +383,3 @@ assert_eq!(

/// loads.
#[inline]
pub(crate) unsafe fn sp_copy_within_unchecked<R>(

@@ -408,2 +420,3 @@ &mut self,

/// Accelerates equality checking with batch loads.
#[inline]
pub(crate) fn sp_eq(&self, other: &Self) -> bool {

@@ -420,2 +433,3 @@ if self.len() != other.len() {

/// Seeks the index of the first `1` bit in the bit-slice.
#[inline]
pub(crate) fn sp_iter_ones_first(&self) -> Option<usize> {

@@ -426,4 +440,6 @@ let mut accum = 0;

Domain::Enclave { head, elem, tail } => {
let val = (Msb0::mask(head, tail) & elem.load_value()).value();
accum += val.leading_zeros() as usize - head.value() as usize;
let val =
(Msb0::mask(head, tail) & elem.load_value()).into_inner();
accum +=
val.leading_zeros() as usize - head.into_inner() as usize;
if val != T::Mem::ZERO {

@@ -436,6 +452,6 @@ return Some(accum);

if let Some((head, elem)) = head {
let val =
(Msb0::mask(head, None) & elem.load_value()).value();
accum +=
val.leading_zeros() as usize - head.value() as usize;
let val = (Msb0::mask(head, None) & elem.load_value())
.into_inner();
accum += val.leading_zeros() as usize
- head.into_inner() as usize;
if val != T::Mem::ZERO {

@@ -455,4 +471,4 @@ return Some(accum);

if let Some((elem, tail)) = tail {
let val =
(Msb0::mask(None, tail) & elem.load_value()).value();
let val = (Msb0::mask(None, tail) & elem.load_value())
.into_inner();
accum += val.leading_zeros() as usize;

@@ -470,2 +486,3 @@ if val != T::Mem::ZERO {

/// Seeks the index of the last `1` bit in the bit-slice.
#[inline]
pub(crate) fn sp_iter_ones_last(&self) -> Option<usize> {

@@ -479,4 +496,5 @@ // Set the state tracker to the last live index in the bit-slice.

Domain::Enclave { head, elem, tail } => {
let val = (Msb0::mask(head, tail) & elem.load_value()).value();
let dead_bits = T::Mem::BITS as u8 - tail.value();
let val =
(Msb0::mask(head, tail) & elem.load_value()).into_inner();
let dead_bits = T::Mem::BITS as u8 - tail.into_inner();
if val != T::Mem::ZERO {

@@ -490,6 +508,6 @@ out -= val.trailing_zeros() as usize - dead_bits as usize;

if let Some((elem, tail)) = tail {
let val =
(Msb0::mask(None, tail) & elem.load_value()).value();
let val = (Msb0::mask(None, tail) & elem.load_value())
.into_inner();
let dead_bits =
T::Mem::BITS as usize - tail.value() as usize;
T::Mem::BITS as usize - tail.into_inner() as usize;
out -= val.trailing_zeros() as usize - dead_bits;

@@ -510,4 +528,4 @@ if val != T::Mem::ZERO {

if let Some((head, elem)) = head {
let val =
(Msb0::mask(head, None) & elem.load_value()).value();
let val = (Msb0::mask(head, None) & elem.load_value())
.into_inner();
if val != T::Mem::ZERO {

@@ -525,2 +543,3 @@ out -= val.trailing_zeros() as usize;

/// Seeks the index of the first `0` bit in the bit-slice.
#[inline]
pub(crate) fn sp_iter_zeros_first(&self) -> Option<usize> {

@@ -531,4 +550,6 @@ let mut accum = 0;

Domain::Enclave { head, elem, tail } => {
let val = (Msb0::mask(head, tail) & !elem.load_value()).value();
accum += val.leading_zeros() as usize - head.value() as usize;
let val =
(Msb0::mask(head, tail) & !elem.load_value()).into_inner();
accum +=
val.leading_zeros() as usize - head.into_inner() as usize;
if val != T::Mem::ZERO {

@@ -541,6 +562,6 @@ return Some(accum);

if let Some((head, elem)) = head {
let val =
(Msb0::mask(head, None) & !elem.load_value()).value();
accum +=
val.leading_zeros() as usize - head.value() as usize;
let val = (Msb0::mask(head, None) & !elem.load_value())
.into_inner();
accum += val.leading_zeros() as usize
- head.into_inner() as usize;
if val != T::Mem::ZERO {

@@ -560,4 +581,4 @@ return Some(accum);

if let Some((elem, tail)) = tail {
let val =
(Msb0::mask(None, tail) & !elem.load_value()).value();
let val = (Msb0::mask(None, tail) & !elem.load_value())
.into_inner();
accum += val.leading_zeros() as usize;

@@ -575,2 +596,3 @@ if val != T::Mem::ZERO {

/// Seeks the index of the last `0` bit in the bit-slice.
#[inline]
pub(crate) fn sp_iter_zeros_last(&self) -> Option<usize> {

@@ -583,4 +605,5 @@ let mut out = match self.len() {

Domain::Enclave { head, elem, tail } => {
let val = (Msb0::mask(head, tail) & !elem.load_value()).value();
let dead_bits = T::Mem::BITS as u8 - tail.value();
let val =
(Msb0::mask(head, tail) & !elem.load_value()).into_inner();
let dead_bits = T::Mem::BITS as u8 - tail.into_inner();
if val != T::Mem::ZERO {

@@ -594,6 +617,6 @@ out -= val.trailing_zeros() as usize - dead_bits as usize;

if let Some((elem, tail)) = tail {
let val =
(Msb0::mask(None, tail) & !elem.load_value()).value();
let val = (Msb0::mask(None, tail) & !elem.load_value())
.into_inner();
let dead_bits =
T::Mem::BITS as usize - tail.value() as usize;
T::Mem::BITS as usize - tail.into_inner() as usize;
out -= val.trailing_zeros() as usize - dead_bits;

@@ -614,4 +637,4 @@ if val != T::Mem::ZERO {

if let Some((head, elem)) = head {
let val =
(Msb0::mask(head, None) & !elem.load_value()).value();
let val = (Msb0::mask(head, None) & !elem.load_value())
.into_inner();
if val != T::Mem::ZERO {

@@ -618,0 +641,0 @@ out -= val.trailing_zeros() as usize;

@@ -433,6 +433,6 @@ //! Unit tests for the `slice` module.

match R::BITS {
8 => BitPos::new(index.value() ^ 0b100).unwrap(),
16 => BitPos::new(index.value() ^ 0b1100).unwrap(),
32 => BitPos::new(index.value() ^ 0b11100).unwrap(),
64 => BitPos::new(index.value() ^ 0b111100).unwrap(),
8 => BitPos::new(index.into_inner() ^ 0b100).unwrap(),
16 => BitPos::new(index.into_inner() ^ 0b1100).unwrap(),
32 => BitPos::new(index.into_inner() ^ 0b11100).unwrap(),
64 => BitPos::new(index.into_inner() ^ 0b111100).unwrap(),
_ => unreachable!("No other integers are supported"),

@@ -439,0 +439,0 @@ }

@@ -6,3 +6,2 @@ //! Non-operator trait implementations.

use core::{
any::TypeId,
cmp,

@@ -24,2 +23,3 @@ convert::TryFrom,

},
hint,
str,

@@ -31,5 +31,7 @@ };

use super::BitSlice;
#[cfg(feature = "alloc")]
use crate::vec::BitVec;
use crate::{
devel as dvl,
domain::Domain,

@@ -41,3 +43,2 @@ order::{

},
slice::BitSlice,
store::BitStore,

@@ -59,2 +60,3 @@ view::BitView,

{
#[inline]
fn cmp(&self, rhs: &Self) -> cmp::Ordering {

@@ -80,2 +82,3 @@ self.partial_cmp(rhs)

{
#[inline]
fn eq(&self, rhs: &BitSlice<O2, T2>) -> bool {

@@ -92,6 +95,4 @@ let fallback = || {

if TypeId::of::<O1>() == TypeId::of::<O2>()
&& TypeId::of::<T1>() == TypeId::of::<T2>()
{
if TypeId::of::<O1>() == TypeId::of::<Lsb0>() {
if dvl::match_types::<O1, T1, O2, T2>() {
if dvl::match_order::<O1, Lsb0>() {
let this: &BitSlice<Lsb0, T1> =

@@ -103,3 +104,3 @@ unsafe { &*(self as *const _ as *const _) };

}
else if TypeId::of::<O1>() == TypeId::of::<Msb0>() {
else if dvl::match_order::<O1, Msb0>() {
let this: &BitSlice<Msb0, T1> =

@@ -123,2 +124,3 @@ unsafe { &*(self as *const _ as *const _) };

#[cfg(not(tarpaulin_include))]
impl<O1, O2, T1, T2> PartialEq<BitSlice<O2, T2>> for &BitSlice<O1, T1>

@@ -131,2 +133,3 @@ where

{
#[inline]
fn eq(&self, rhs: &BitSlice<O2, T2>) -> bool {

@@ -137,2 +140,3 @@ **self == rhs

#[cfg(not(tarpaulin_include))]
impl<O1, O2, T1, T2> PartialEq<BitSlice<O2, T2>> for &mut BitSlice<O1, T1>

@@ -145,2 +149,3 @@ where

{
#[inline]
fn eq(&self, rhs: &BitSlice<O2, T2>) -> bool {

@@ -153,2 +158,3 @@ **self == rhs

#[cfg(not(tarpaulin_include))]
impl<O1, O2, T1, T2> PartialEq<&BitSlice<O2, T2>> for BitSlice<O1, T1>

@@ -161,2 +167,3 @@ where

{
#[inline]
fn eq(&self, rhs: &&BitSlice<O2, T2>) -> bool {

@@ -167,2 +174,3 @@ *self == **rhs

#[cfg(not(tarpaulin_include))]
impl<O1, O2, T1, T2> PartialEq<&mut BitSlice<O2, T2>> for BitSlice<O1, T1>

@@ -175,2 +183,3 @@ where

{
#[inline]
fn eq(&self, rhs: &&mut BitSlice<O2, T2>) -> bool {

@@ -195,2 +204,3 @@ *self == **rhs

{
#[inline]
fn partial_cmp(&self, rhs: &BitSlice<O2, T2>) -> Option<cmp::Ordering> {

@@ -210,2 +220,3 @@ for (l, r) in self.iter().zip(rhs.iter()) {

#[cfg(not(tarpaulin_include))]
impl<O1, O2, T1, T2> PartialOrd<BitSlice<O2, T2>> for &BitSlice<O1, T1>

@@ -218,2 +229,3 @@ where

{
#[inline]
fn partial_cmp(&self, rhs: &BitSlice<O2, T2>) -> Option<cmp::Ordering> {

@@ -224,2 +236,3 @@ (*self).partial_cmp(rhs)

#[cfg(not(tarpaulin_include))]
impl<O1, O2, T1, T2> PartialOrd<BitSlice<O2, T2>> for &mut BitSlice<O1, T1>

@@ -232,2 +245,3 @@ where

{
#[inline]
fn partial_cmp(&self, rhs: &BitSlice<O2, T2>) -> Option<cmp::Ordering> {

@@ -240,2 +254,3 @@ (**self).partial_cmp(rhs)

#[cfg(not(tarpaulin_include))]
impl<O1, O2, T1, T2> PartialOrd<&BitSlice<O2, T2>> for BitSlice<O1, T1>

@@ -248,2 +263,3 @@ where

{
#[inline]
fn partial_cmp(&self, rhs: &&BitSlice<O2, T2>) -> Option<cmp::Ordering> {

@@ -254,2 +270,3 @@ (*self).partial_cmp(&**rhs)

#[cfg(not(tarpaulin_include))]
impl<O1, O2, T1, T2> PartialOrd<&mut BitSlice<O2, T2>> for BitSlice<O1, T1>

@@ -262,2 +279,3 @@ where

{
#[inline]
fn partial_cmp(&self, rhs: &&mut BitSlice<O2, T2>) -> Option<cmp::Ordering> {

@@ -270,2 +288,3 @@ (*self).partial_cmp(&**rhs)

#[cfg(not(tarpaulin_include))]
impl<O1, O2, T1, T2> PartialOrd<&mut BitSlice<O2, T2>> for &BitSlice<O1, T1>

@@ -278,2 +297,3 @@ where

{
#[inline]
fn partial_cmp(&self, rhs: &&mut BitSlice<O2, T2>) -> Option<cmp::Ordering> {

@@ -284,2 +304,3 @@ (**self).partial_cmp(&**rhs)

#[cfg(not(tarpaulin_include))]
impl<O1, O2, T1, T2> PartialOrd<&BitSlice<O2, T2>> for &mut BitSlice<O1, T1>

@@ -292,2 +313,3 @@ where

{
#[inline]
fn partial_cmp(&self, rhs: &&BitSlice<O2, T2>) -> Option<cmp::Ordering> {

@@ -298,2 +320,3 @@ (**self).partial_cmp(&**rhs)

#[cfg(not(tarpaulin_include))]
impl<'a, O, T> TryFrom<&'a [T]> for &'a BitSlice<O, T>

@@ -306,2 +329,3 @@ where

#[inline]
fn try_from(slice: &'a [T]) -> Result<Self, Self::Error> {

@@ -312,2 +336,3 @@ BitSlice::from_slice(slice).map_err(|_| slice)

#[cfg(not(tarpaulin_include))]
impl<'a, O, T> TryFrom<&'a mut [T]> for &'a mut BitSlice<O, T>

@@ -320,2 +345,3 @@ where

#[inline]
fn try_from(slice: &'a mut [T]) -> Result<Self, Self::Error> {

@@ -327,2 +353,3 @@ let slice_ptr = slice as *mut [T];

#[cfg(not(tarpaulin_include))]
impl<O, T> Default for &BitSlice<O, T>

@@ -333,2 +360,3 @@ where

{
#[inline(always)]
fn default() -> Self {

@@ -339,2 +367,3 @@ BitSlice::empty()

#[cfg(not(tarpaulin_include))]
impl<O, T> Default for &mut BitSlice<O, T>

@@ -345,2 +374,3 @@ where

{
#[inline(always)]
fn default() -> Self {

@@ -356,2 +386,3 @@ BitSlice::empty_mut()

{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -364,2 +395,3 @@ self.as_bitspan().render(fmt, "Slice", None)?;

#[cfg(not(tarpaulin_include))]
impl<O, T> Display for BitSlice<O, T>

@@ -370,2 +402,3 @@ where

{
#[inline(always)]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -411,3 +444,5 @@ Binary::fmt(self, fmt)

struct Seq<'a>(&'a [u8]);
#[cfg(not(tarpaulin_include))]
impl Debug for Seq<'_> {
#[inline(always)]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -474,3 +509,3 @@ fmt.write_str(unsafe {

v @ 10 ..= 16 => $base + (v - 10),
_ => unsafe { core::hint::unreachable_unchecked() },
_ => unsafe { hint::unreachable_unchecked() },
};

@@ -498,3 +533,4 @@ end += 1;

bits.get_unchecked(
head.value() as usize .. tail.value() as usize,
head.into_inner() as usize
.. tail.into_inner() as usize,
)

@@ -510,3 +546,3 @@ }

unsafe {
bits.get_unchecked(head.value() as usize ..)
bits.get_unchecked(head.into_inner() as usize ..)
}

@@ -522,3 +558,3 @@ .pipe(&mut writer);

unsafe {
bits.get_unchecked(.. tail.value() as usize)
bits.get_unchecked(.. tail.into_inner() as usize)
}

@@ -547,6 +583,7 @@ .pipe(&mut writer);

{
#[inline]
fn hash<H>(&self, hasher: &mut H)
where H: Hasher {
for bit in self {
hasher.write_u8(*bit as u8);
for bit in self.as_bitptr_range() {
hasher.write_u8(unsafe { bit.read() } as u8);
}

@@ -623,2 +660,3 @@ }

#[cfg_attr(not(tarpaulin_include), inline(always))]
fn to_owned(&self) -> Self::Owned {

@@ -625,0 +663,0 @@ BitVec::from_bitslice(self)

@@ -197,2 +197,3 @@ /*! Memory modeling.

/// [`BitAccess`]: crate::access::BitAccess
#[inline]
fn get_bit<O>(&self, index: BitIdx<Self::Mem>) -> bool

@@ -227,2 +228,3 @@ where O: BitOrder {

#[inline(always)]
fn load_value(&self) -> Self::Mem {

@@ -232,2 +234,3 @@ *self

#[inline(always)]
fn store_value(&mut self, value: Self::Mem) {

@@ -329,2 +332,3 @@ *self = value;

#[inline]
fn load_value(&self) -> Self::Mem {

@@ -334,2 +338,3 @@ self.load(core::sync::atomic::Ordering::Relaxed)

#[inline]
fn store_value(&mut self, value: Self::Mem) {

@@ -336,0 +341,0 @@ self.store(value, core::sync::atomic::Ordering::Relaxed);

@@ -28,2 +28,3 @@ /*! A dynamically-allocated buffer containing a [`BitSlice`] region.

use core::{
convert::TryInto,
mem::{

@@ -45,2 +46,7 @@ self,

pub use self::iter::{
Drain,
Splice,
};
pub use crate::boxed::IntoIter;
use crate::{

@@ -51,6 +57,2 @@ boxed::BitBox,

mem::BitRegister,
mutability::{
Const,
Mut,
},
order::{

@@ -64,2 +66,4 @@ BitOrder,

BitSpanError,
Const,
Mut,
},

@@ -70,2 +74,7 @@ slice::BitSlice,

mod api;
mod iter;
mod ops;
mod traits;
/** A contiguous growable array of bits.

@@ -335,3 +344,3 @@

pub fn from_bitslice(slice: &BitSlice<O, T>) -> Self {
let mut bitspan = slice.as_bitspan();
let bitspan = slice.as_bitspan();

@@ -357,4 +366,15 @@ let mut vec = bitspan

let bitspan = unsafe {
bitspan.set_address(vec.as_ptr() as *const T);
bitspan.assert_mut()
BitSpan::new_unchecked(
vec.as_mut_ptr()
.cast::<T>()
.try_into()
.unwrap_or_else(|err| {
unreachable!(
"The allocator produced an improper address: {}",
err
)
}),
bitspan.head(),
bitspan.len(),
)
};

@@ -411,2 +431,3 @@

/// [`BitSlice::<O, T>::from_slice`]: crate::slice::BitSlice::from_slice
#[inline]
pub fn from_slice(slice: &[T]) -> Result<Self, BitSpanError<T>> {

@@ -702,3 +723,3 @@ slice.pipe(BitSlice::from_slice).map(Self::from_bitslice)

pub fn set_uninitialized(&mut self, value: bool) {
let head = self.as_bitspan().head().value() as usize;
let head = self.as_bitspan().head().into_inner() as usize;
let tail = head + self.len();

@@ -740,3 +761,3 @@ let capa = self.capacity();

let bitspan = self.as_mut_bitspan();
let head = bitspan.head().value() as usize;
let head = bitspan.head().into_inner() as usize;
if head == 0 {

@@ -858,3 +879,3 @@ return;

/// [`as_mut_bitptr`]: Self::as_mut_bitptr
#[inline]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn as_bitptr(&self) -> BitPtr<Const, O, T> {

@@ -1040,2 +1061,3 @@ self.bitspan.as_bitptr().immut()

/// bit-vector, and drive all future memory access and allocation control.
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub(crate) unsafe fn from_fields(

@@ -1049,5 +1071,6 @@ bitspan: BitSpan<Mut, O, T>,

/// Removes the `::Unalias` marker from a bit-vector’s type signature.
#[cfg_attr(not(tarpaulin_include), inline(always))]
fn strip_unalias(this: BitVec<O, T::Unalias>) -> Self {
let (bitspan, capacity) = (this.bitspan.cast::<T>(), this.capacity);
core::mem::forget(this);
mem::forget(this);
Self { bitspan, capacity }

@@ -1076,3 +1099,4 @@ }

let elts = bitspan.elements();
let new_elts = crate::mem::elts::<T>(head.value() as usize + new_len);
let new_elts =
crate::mem::elts::<T>(head.into_inner() as usize + new_len);
let extra = new_elts - elts;

@@ -1112,14 +1136,3 @@ self.with_vec(|vec| {

mod api;
mod iter;
mod ops;
mod traits;
pub use self::iter::{
Drain,
IntoIter,
Splice,
};
#[cfg(test)]
mod tests;

@@ -15,24 +15,22 @@ //! Port of the `Vec<T>` inherent API.

use super::{
iter::{
Drain,
Splice,
},
BitVec,
};
use crate::{
boxed::BitBox,
index::BitTail,
mutability::{
Const,
Mut,
},
order::BitOrder,
ptr::{
Address,
AddressExt,
BitPtr,
BitSpan,
Const,
Mut,
},
slice::BitSlice,
store::BitStore,
vec::{
iter::{
Drain,
Splice,
},
BitVec,
},
};

@@ -130,5 +128,3 @@

let (addr, capacity) = (vec.as_mut_ptr(), vec.capacity());
let bitspan = BitSpan::uninhabited(unsafe {
Address::new_unchecked(addr as usize)
});
let bitspan = BitSpan::uninhabited(unsafe { addr.force_wrap() });
Self { bitspan, capacity }

@@ -266,3 +262,6 @@ }

bitspan: bitptr.span_unchecked(length),
capacity: crate::mem::elts::<T>(capacity),
capacity: crate::mem::elts::<T>(
// The capacity counts from `head`, not from 0.
capacity.saturating_add(bitptr.head().into_inner() as usize),
),
}

@@ -293,3 +292,3 @@ }

// capacity underflows.
.saturating_sub(self.bitspan.head().value() as usize)
.saturating_sub(self.bitspan.head().into_inner() as usize)
}

@@ -376,3 +375,3 @@

/// ```
#[inline]
#[cfg_attr(not(tarpaulin_include), inline(always))]
pub fn shrink_to_fit(&mut self) {

@@ -379,0 +378,0 @@ self.with_vec(|vec| vec.shrink_to_fit());

@@ -22,26 +22,41 @@ //! Iterators over `Vec<T>`.

},
ptr::NonNull,
};
use tap::{
pipe::Pipe,
tap::{
Tap,
TapOptional,
},
Pipe,
Tap,
TapOptional,
};
use super::BitVec;
use crate::{
boxed::BitBox,
devel as dvl,
mutability::Mutability,
order::BitOrder,
ptr::BitRef,
slice::{
BitSlice,
Iter,
ptr::{
BitPtrRange,
BitRef,
Mut,
Mutability,
},
slice::BitSlice,
store::BitStore,
vec::BitVec,
view::BitView,
};
/** Extends a `BitVec` from a `bool` producer.
# Notes
This is the second-slowest possible way to append bits to a bit-vector, second
only to `for bit in bits { bitvec.push(bit); }`. **Do not** use this if you have
any other choice.
If you are extending a bit-vector from the contents of a bit-slice, use
[`BitVec::extend_from_bitslice`] instead. That method will never be *slower*
than this. When the source bit-slice does not match the destination bit-vector’s
type parameters, it will still be faster by virtue of knowing the bit-slice
length upfront; when the type parameters match, it will optimize to `memcpy`
with some bookkeeping.
**/
impl<O, T> Extend<bool> for BitVec<O, T>

@@ -52,24 +67,28 @@ where

{
#[inline]
fn extend<I>(&mut self, iter: I)
where I: IntoIterator<Item = bool> {
let mut iter = iter.into_iter();
match iter.size_hint() {
(n, None) | (_, Some(n)) => {
// This body exists to try to accelerate the push-per-bit loop.
self.reserve(n);
let len = self.len();
let new_len = len + n;
let new = unsafe { self.get_unchecked_mut(len .. new_len) };
let mut pulled = 0;
for (slot, bit) in
unsafe { new.iter_mut().remove_alias() }.zip(iter.by_ref())
{
slot.set(bit);
pulled += 1;
}
#[allow(irrefutable_let_patterns)] // Removing the `if` is unstable.
if let (_, Some(n)) | (n, None) = iter.size_hint() {
self.reserve(n);
let len = self.len();
let new_len = len + n;
let new = unsafe { self.get_unchecked_mut(len .. new_len) };
let mut pulled = 0;
// In theory, using direct pointer writes ought to be the fastest
// general condition.
for (ptr, bit) in new.as_mut_bitptr_range().zip(iter.by_ref()) {
unsafe {
self.set_len(len + pulled);
ptr.write(bit);
}
},
pulled += 1;
}
unsafe {
self.set_len(len + pulled);
}
}
// Well-behaved iterators will reduce this to a single branch.
iter.for_each(|bit| self.push(bit));

@@ -84,2 +103,3 @@ }

{
#[inline]
fn extend<I>(&mut self, iter: I)

@@ -91,2 +111,4 @@ where I: IntoIterator<Item = &'a bool> {

/// ***DO NOT*** use this. You clearly have a [`BitSlice`]. Use
/// [`BitVec::extend_from_bitslice`].
impl<'a, M, O1, O2, T1, T2> Extend<BitRef<'a, M, O2, T2>> for BitVec<O1, T1>

@@ -100,2 +122,3 @@ where

{
#[inline]
fn extend<I>(&mut self, iter: I)

@@ -112,6 +135,7 @@ where I: IntoIterator<Item = BitRef<'a, M, O2, T2>> {

{
#[inline]
fn extend<I>(&mut self, iter: I)
where I: IntoIterator<Item = T> {
for elem in iter.into_iter() {
self.extend(BitSlice::<O, T>::from_element(&elem));
self.extend_from_bitslice(elem.view_bits::<O>());
}

@@ -126,6 +150,7 @@ }

{
#[inline]
fn extend<I>(&mut self, iter: I)
where I: IntoIterator<Item = &'a T> {
for elem in iter.into_iter() {
self.extend(BitSlice::<O, T>::from_element(elem));
self.extend_from_bitslice(elem.view_bits::<O>());
}

@@ -140,2 +165,3 @@ }

{
#[inline]
fn from_iter<I>(iter: I) -> Self

@@ -147,2 +173,4 @@ where I: IntoIterator<Item = bool> {

/// ***DO NOT*** use this. You clearly have a [`BitSlice`]. Use
/// [`BitVec::from_bitslice`] instead.
impl<'a, M, O1, O2, T1, T2> FromIterator<BitRef<'a, M, O2, T2>>

@@ -157,2 +185,3 @@ for BitVec<O1, T1>

{
#[inline]
fn from_iter<I>(iter: I) -> Self

@@ -169,2 +198,3 @@ where I: IntoIterator<Item = BitRef<'a, M, O2, T2>> {

{
#[inline]
fn from_iter<I>(iter: I) -> Self

@@ -182,3 +212,3 @@ where I: IntoIterator<Item = &'a bool> {

[Issue #83]: https://github.com/myrrlyn/bitvec/issues/83
[Issue #83]: https://github.com/bitvecto-rs/bitvec/issues/83
**/

@@ -190,2 +220,3 @@ impl<O, T> FromIterator<T> for BitVec<O, T>

{
#[inline]
fn from_iter<I>(iter: I) -> Self

@@ -202,2 +233,3 @@ where I: IntoIterator<Item = T> {

{
#[inline]
fn from_iter<I>(iter: I) -> Self

@@ -216,2 +248,3 @@ where I: IntoIterator<Item = &'a T> {

#[cfg(not(tarpaulin_include))]
impl<O, T> IntoIterator for BitVec<O, T>

@@ -222,10 +255,12 @@ where

{
type IntoIter = IntoIter<O, T>;
type Item = bool;
type IntoIter = <BitBox<O, T> as IntoIterator>::IntoIter;
type Item = <BitBox<O, T> as IntoIterator>::Item;
#[inline(always)]
fn into_iter(self) -> Self::IntoIter {
IntoIter::new(self)
self.into_boxed_bitslice().into_iter()
}
}
#[cfg(not(tarpaulin_include))]
impl<'a, O, T> IntoIterator for &'a BitVec<O, T>

@@ -239,2 +274,3 @@ where

#[inline(always)]
fn into_iter(self) -> Self::IntoIter {

@@ -245,2 +281,3 @@ self.as_bitslice().into_iter()

#[cfg(not(tarpaulin_include))]
impl<'a, O, T> IntoIterator for &'a mut BitVec<O, T>

@@ -254,2 +291,3 @@ where

#[inline(always)]
fn into_iter(self) -> Self::IntoIter {

@@ -260,201 +298,2 @@ self.as_mut_bitslice().into_iter()

/** An iterator that moves out of a [`BitVec`].
This `struct` is created by the [`into_iter`] method on [`BitVec`] (provided by
the [`IntoIterator`] trait).
# Original
[`vec::IntoIter`](alloc::vec::IntoIter)
[`BitVec`]: crate::vec::BitVec
[`IntoIterator`]: core::iter::IntoIterator
[`into_iter`]: core::iter::IntoIterator::into_iter
**/
pub struct IntoIter<O, T>
where
O: BitOrder,
T: BitStore,
{
/// The base address of the allocation.
base: NonNull<T>,
/// The allocation capacity, measured in elements `T`.
capa: usize,
/// A [`BitSlice`] iterator over the vector’s contents.
///
/// [`BitSlice`]: crate::slice::BitSlice
iter: Iter<'static, O, T>,
}
impl<O, T> IntoIter<O, T>
where
O: BitOrder,
T: BitStore,
{
/// Constructs an iterator over a [`BitVec`].
///
/// [`BitVec`]: crate::vec::BitVec
fn new(bv: BitVec<O, T>) -> Self {
let capa = bv.capacity;
// Construct a `BitSlice` iterator over the region, and detach its
// lifetime.
let iter = bv.bitspan.to_bitslice_ref().iter();
// Only the allocation’s base and capacity need to be kept for `Drop`.
let base = bv.bitspan.address().to_nonnull();
mem::forget(bv);
Self { base, capa, iter }
}
/// Returns the remaining bits of this iterator as a [`BitSlice`].
///
/// # Original
///
/// [`vec::IntoIter::as_slice`](alloc::vec::IntoIter::as_slice)
///
/// # Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let bv = bitvec![0, 1, 0, 1];
/// let mut into_iter = bv.into_iter();
///
/// assert_eq!(into_iter.as_bitslice(), bits![0, 1, 0, 1]);
/// let _ = into_iter.next().unwrap();
/// assert_eq!(into_iter.as_bitslice(), bits![1, 0, 1]);
/// ```
///
/// [`BitSlice`]: crate::slice::BitSlice
pub fn as_bitslice(&self) -> &BitSlice<O, T> {
self.iter.as_bitslice()
}
#[doc(hidden)]
#[inline(always)]
#[cfg(not(tarpalin_include))]
#[deprecated = "Use `as_bitslice` to view the underlying slice"]
pub fn as_slice(&self) -> &BitSlice<O, T> {
self.as_bitslice()
}
/// Returns the remaining bits of this iterator as a mutable [`BitSlice`].
///
/// # Original
///
/// [`vec::IntoIter::as_mut_slice`](alloc::vec::IntoIter::as_mut_slice)
///
/// # Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let bv = bitvec![0, 1, 0, 1];
/// let mut into_iter = bv.into_iter();
///
/// assert_eq!(into_iter.as_bitslice(), bits![0, 1, 0, 1]);
/// into_iter.as_mut_bitslice().set(2, true);
/// assert!(!into_iter.next().unwrap());
/// assert!(into_iter.next().unwrap());
/// assert!(into_iter.next().unwrap());
/// ```
///
/// [`BitSlice`]: crate::slice::BitSlice
pub fn as_mut_bitslice(&mut self) -> &mut BitSlice<O, T> {
let span = self.iter.as_bitslice().as_bitspan();
let span_mut = unsafe { span.assert_mut() };
span_mut.to_bitslice_mut()
}
#[doc(hidden)]
#[inline(always)]
#[cfg(not(tarpaulin_include))]
#[deprecated = "Use `as_mut_bitslice` to view the underlying slice"]
pub fn as_mut_slice(&mut self) -> &mut BitSlice<O, T> {
self.as_mut_bitslice()
}
}
#[cfg(not(tarpaulin_include))]
impl<O, T> Debug for IntoIter<O, T>
where
O: BitOrder,
T: BitStore,
{
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
fmt.debug_tuple("IntoIter")
.field(&self.as_bitslice())
.finish()
}
}
impl<O, T> Iterator for IntoIter<O, T>
where
O: BitOrder,
T: BitStore,
{
type Item = bool;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().as_deref().copied()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
fn count(self) -> usize {
self.len()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.iter.nth(n).as_deref().copied()
}
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
}
impl<O, T> DoubleEndedIterator for IntoIter<O, T>
where
O: BitOrder,
T: BitStore,
{
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.next_back().as_deref().copied()
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.iter.nth_back(n).as_deref().copied()
}
}
impl<O, T> ExactSizeIterator for IntoIter<O, T>
where
O: BitOrder,
T: BitStore,
{
fn len(&self) -> usize {
self.iter.len()
}
}
impl<O, T> FusedIterator for IntoIter<O, T>
where
O: BitOrder,
T: BitStore,
{
}
impl<O, T> Drop for IntoIter<O, T>
where
O: BitOrder,
T: BitStore,
{
fn drop(&mut self) {
// Rebuild the `Vec` governing the allocation, and run its destructor.
drop(unsafe { Vec::from_raw_parts(self.base.as_ptr(), 0, self.capa) });
}
}
/** A draining iterator for [`BitVec`].

@@ -477,5 +316,5 @@

/// Exclusive reference to the vector this drains.
source: NonNull<BitVec<O, T>>,
source: &'a mut BitVec<O, T>,
/// The range of the source vector’s buffer being drained.
drain: Iter<'a, O, T>,
drain: BitPtrRange<Mut, O, T>,
/// The range of the source vector’s preserved tail. This runs from the back

@@ -507,10 +346,7 @@ /// edge of the drained region to the vector’s original length.

source
.as_bitslice()
.get_unchecked(drain)
.as_mut_bitslice()
.get_unchecked_mut(drain)
// Detach the region from the `source` borrow.
.as_bitspan()
.to_bitslice_ref()
.iter()
.as_mut_bitptr_range()
};
let source = source.into();
Self {

@@ -535,4 +371,5 @@ source,

/// [`BitSlice`]: crate::slice::BitSlice
#[inline]
pub fn as_bitslice(&self) -> &'a BitSlice<O, T> {
self.drain.as_bitslice()
self.drain.clone().into_bitspan().to_bitslice_ref()
}

@@ -572,8 +409,9 @@

where I: Iterator<Item = bool> {
let bitvec = unsafe { self.source.as_mut() };
let bitvec = &mut *self.source;
// Get the length of the source vector. This will be grown as `iter`
// writes into the drain span.
let mut len = bitvec.len();
// Get the drain span as a bit-slice.
let span = unsafe { bitvec.get_unchecked_mut(len .. self.tail.start) };
// Get the drain span as a bit-pointer range.
let span = unsafe { bitvec.get_unchecked_mut(len .. self.tail.start) }
.as_mut_bitptr_range();

@@ -583,7 +421,9 @@ // Set the exit flag to assume completion.

// Write the `iter` bits into the drain `span`.
for slot in span {
for ptr in span {
// While the `iter` is not exhausted, write it into the span and
// increase the vector length counter.
if let Some(bit) = iter.next() {
slot.set(bit);
unsafe {
ptr.write(bit);
}
len += 1;

@@ -625,3 +465,3 @@ }

let bitvec = self.source.as_mut();
let bitvec = &mut *self.source;
let tail_len = self.tail.end - self.tail.start;

@@ -649,2 +489,3 @@

#[cfg(not(tarpaulin_include))]
impl<O, T> AsRef<BitSlice<O, T>> for Drain<'_, O, T>

@@ -655,2 +496,3 @@ where

{
#[inline(always)]
fn as_ref(&self) -> &BitSlice<O, T> {

@@ -667,6 +509,5 @@ self.as_bitslice()

{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
fmt.debug_tuple("Drain")
.field(&self.drain.as_bitslice())
.finish()
fmt.debug_tuple("Drain").field(&self.as_bitslice()).finish()
}

@@ -682,6 +523,8 @@ }

#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.drain.next().as_deref().copied()
self.drain.next().map(crate::ptr::range::read_raw)
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {

@@ -691,2 +534,3 @@ self.drain.size_hint()

#[inline(always)]
fn count(self) -> usize {

@@ -696,6 +540,8 @@ self.len()

#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.drain.nth(n).as_deref().copied()
self.drain.nth(n).map(crate::ptr::range::read_raw)
}
#[inline(always)]
fn last(mut self) -> Option<Self::Item> {

@@ -711,8 +557,10 @@ self.next_back()

{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.drain.next_back().as_deref().copied()
self.drain.next_back().map(crate::ptr::range::read_raw)
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.drain.nth_back(n).as_deref().copied()
self.drain.nth_back(n).map(crate::ptr::range::read_raw)
}

@@ -726,2 +574,3 @@ }

{
#[inline(always)]
fn len(&self) -> usize {

@@ -768,3 +617,3 @@ self.drain.len()

// Otherwise, access the source vector,
let bitvec = unsafe { self.source.as_mut() };
let bitvec = &mut *self.source;
// And grab its current end.

@@ -830,4 +679,10 @@ let old_len = bitvec.len();

/// Constructs a splice out of a drain and a replacement.
pub(super) fn new<II>(drain: Drain<'a, O, T>, splice: II) -> Self
where II: IntoIterator<IntoIter = I, Item = bool> {
#[inline]
pub(super) fn new<IntoIter>(
drain: Drain<'a, O, T>,
splice: IntoIter,
) -> Self
where
IntoIter: IntoIterator<IntoIter = I, Item = bool>,
{
let splice = splice.into_iter();

@@ -846,2 +701,3 @@ Self { drain, splice }

#[inline]
fn next(&mut self) -> Option<Self::Item> {

@@ -858,3 +714,3 @@ self.drain.next().tap_some(|_| {

unsafe {
let bv = self.drain.source.as_mut();
let bv = &mut *self.drain.source;
let len = bv.len();

@@ -868,2 +724,3 @@ bv.set_len_unchecked(len + 1);

#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {

@@ -873,2 +730,3 @@ self.drain.size_hint()

#[inline(always)]
fn count(self) -> usize {

@@ -878,2 +736,3 @@ self.len()

#[inline(always)]
fn last(mut self) -> Option<Self::Item> {

@@ -890,2 +749,3 @@ self.next_back()

{
#[inline(always)]
fn next_back(&mut self) -> Option<Self::Item> {

@@ -895,2 +755,3 @@ self.drain.next_back()

#[inline(always)]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {

@@ -907,2 +768,3 @@ self.drain.nth_back(n)

{
#[inline(always)]
fn len(&self) -> usize {

@@ -930,3 +792,3 @@ self.drain.len()

let tail_len = tail.end - tail.start;
let bitvec = unsafe { self.drain.source.as_mut() };
let bitvec = &mut *self.drain.source;

@@ -933,0 +795,0 @@ // If the `drain` has no tail span, then extend the vector with the

@@ -20,2 +20,3 @@ //! Port of the `Vec<T>` operator implementations.

use super::BitVec;
use crate::{

@@ -25,5 +26,5 @@ order::BitOrder,

store::BitStore,
vec::BitVec,
};
#[cfg(not(tarpaulin_include))]
impl<O, T, Rhs> BitAnd<Rhs> for BitVec<O, T>

@@ -37,2 +38,3 @@ where

#[inline(always)]
fn bitand(mut self, rhs: Rhs) -> Self::Output {

@@ -44,2 +46,3 @@ self &= rhs;

#[cfg(not(tarpaulin_include))]
impl<O, T, Rhs> BitAndAssign<Rhs> for BitVec<O, T>

@@ -51,2 +54,3 @@ where

{
#[inline(always)]
fn bitand_assign(&mut self, rhs: Rhs) {

@@ -57,2 +61,3 @@ *self.as_mut_bitslice() &= rhs;

#[cfg(not(tarpaulin_include))]
impl<O, T, Rhs> BitOr<Rhs> for BitVec<O, T>

@@ -66,2 +71,3 @@ where

#[inline(always)]
fn bitor(mut self, rhs: Rhs) -> Self::Output {

@@ -73,2 +79,3 @@ self |= rhs;

#[cfg(not(tarpaulin_include))]
impl<O, T, Rhs> BitOrAssign<Rhs> for BitVec<O, T>

@@ -80,2 +87,3 @@ where

{
#[inline(always)]
fn bitor_assign(&mut self, rhs: Rhs) {

@@ -86,2 +94,3 @@ *self.as_mut_bitslice() |= rhs;

#[cfg(not(tarpaulin_include))]
impl<O, T, Rhs> BitXor<Rhs> for BitVec<O, T>

@@ -95,2 +104,3 @@ where

#[inline(always)]
fn bitxor(mut self, rhs: Rhs) -> Self::Output {

@@ -102,2 +112,3 @@ self ^= rhs;

#[cfg(not(tarpaulin_include))]
impl<O, T, Rhs> BitXorAssign<Rhs> for BitVec<O, T>

@@ -109,2 +120,3 @@ where

{
#[inline(always)]
fn bitxor_assign(&mut self, rhs: Rhs) {

@@ -115,2 +127,3 @@ *self.as_mut_bitslice() ^= rhs;

#[cfg(not(tarpaulin_include))]
impl<O, T> Deref for BitVec<O, T>

@@ -123,2 +136,3 @@ where

#[inline(always)]
fn deref(&self) -> &Self::Target {

@@ -129,2 +143,3 @@ self.as_bitslice()

#[cfg(not(tarpaulin_include))]
impl<O, T> DerefMut for BitVec<O, T>

@@ -135,2 +150,3 @@ where

{
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {

@@ -141,2 +157,3 @@ self.as_mut_bitslice()

#[cfg(not(tarpaulin_include))]
impl<O, T> Drop for BitVec<O, T>

@@ -147,2 +164,3 @@ where

{
#[inline(always)]
fn drop(&mut self) {

@@ -154,2 +172,3 @@ // Run the `Vec` destructor to deällocate the buffer.

#[cfg(not(tarpaulin_include))]
impl<O, T, Idx> Index<Idx> for BitVec<O, T>

@@ -163,2 +182,3 @@ where

#[inline(always)]
fn index(&self, index: Idx) -> &Self::Output {

@@ -169,2 +189,3 @@ self.as_bitslice().index(index)

#[cfg(not(tarpaulin_include))]
impl<O, T, Idx> IndexMut<Idx> for BitVec<O, T>

@@ -176,2 +197,3 @@ where

{
#[inline(always)]
fn index_mut(&mut self, index: Idx) -> &mut Self::Output {

@@ -184,4 +206,5 @@ self.as_mut_bitslice().index_mut(index)

on the value of bits in the buffer that are outside the domain of
`BitVec::as_mit_bitslice`.
[`BitVec::as_mut_bitslice`].
**/
#[cfg(not(tarpaulin_include))]
impl<O, T> Not for BitVec<O, T>

@@ -194,2 +217,3 @@ where

#[inline]
fn not(mut self) -> Self::Output {

@@ -196,0 +220,0 @@ for elem in self.as_mut_raw_slice() {

@@ -27,4 +27,5 @@ //! Non-operator trait implementations.

use tap::tap::Tap;
use tap::Tap;
use super::BitVec;
use crate::{

@@ -35,5 +36,5 @@ boxed::BitBox,

store::BitStore,
vec::BitVec,
};
#[cfg(not(tarpaulin_include))]
impl<O, T> Borrow<BitSlice<O, T>> for BitVec<O, T>

@@ -44,2 +45,3 @@ where

{
#[inline(always)]
fn borrow(&self) -> &BitSlice<O, T> {

@@ -50,2 +52,3 @@ self.as_bitslice()

#[cfg(not(tarpaulin_include))]
impl<O, T> BorrowMut<BitSlice<O, T>> for BitVec<O, T>

@@ -56,2 +59,3 @@ where

{
#[inline(always)]
fn borrow_mut(&mut self) -> &mut BitSlice<O, T> {

@@ -85,2 +89,3 @@ self.as_mut_bitslice()

#[cfg(not(tarpaulin_include))]
impl<O, T> Ord for BitVec<O, T>

@@ -91,2 +96,3 @@ where

{
#[inline]
fn cmp(&self, other: &Self) -> cmp::Ordering {

@@ -97,2 +103,3 @@ self.as_bitslice().cmp(other.as_bitslice())

#[cfg(not(tarpaulin_include))]
impl<O1, O2, T1, T2> PartialEq<BitVec<O2, T2>> for BitSlice<O1, T1>

@@ -105,2 +112,3 @@ where

{
#[inline]
fn eq(&self, other: &BitVec<O2, T2>) -> bool {

@@ -111,2 +119,3 @@ self == other.as_bitslice()

#[cfg(not(tarpaulin_include))]
impl<O1, O2, T1, T2> PartialEq<BitVec<O2, T2>> for &BitSlice<O1, T1>

@@ -119,2 +128,3 @@ where

{
#[inline]
fn eq(&self, other: &BitVec<O2, T2>) -> bool {

@@ -125,2 +135,3 @@ *self == other.as_bitslice()

#[cfg(not(tarpaulin_include))]
impl<O1, O2, T1, T2> PartialEq<BitVec<O2, T2>> for &mut BitSlice<O1, T1>

@@ -133,2 +144,3 @@ where

{
#[inline]
fn eq(&self, other: &BitVec<O2, T2>) -> bool {

@@ -139,2 +151,3 @@ **self == other.as_bitslice()

#[cfg(not(tarpaulin_include))]
impl<O, T, Rhs> PartialEq<Rhs> for BitVec<O, T>

@@ -146,2 +159,3 @@ where

{
#[inline]
fn eq(&self, other: &Rhs) -> bool {

@@ -152,2 +166,3 @@ other == self.as_bitslice()

#[cfg(not(tarpaulin_include))]
impl<O1, O2, T1, T2> PartialOrd<BitVec<O2, T2>> for BitSlice<O1, T1>

@@ -160,2 +175,3 @@ where

{
#[inline]
fn partial_cmp(&self, other: &BitVec<O2, T2>) -> Option<cmp::Ordering> {

@@ -166,2 +182,3 @@ self.partial_cmp(other.as_bitslice())

#[cfg(not(tarpaulin_include))]
impl<'a, O1, O2, T1, T2> PartialOrd<BitVec<O2, T2>> for &'a BitSlice<O1, T1>

@@ -174,2 +191,3 @@ where

{
#[inline]
fn partial_cmp(&self, other: &BitVec<O2, T2>) -> Option<cmp::Ordering> {

@@ -180,2 +198,3 @@ self.partial_cmp(other.as_bitslice())

#[cfg(not(tarpaulin_include))]
impl<'a, O1, O2, T1, T2> PartialOrd<BitVec<O2, T2>> for &'a mut BitSlice<O1, T1>

@@ -188,2 +207,3 @@ where

{
#[inline]
fn partial_cmp(&self, other: &BitVec<O2, T2>) -> Option<cmp::Ordering> {

@@ -194,2 +214,3 @@ self.partial_cmp(other.as_bitslice())

#[cfg(not(tarpaulin_include))]
impl<O, T, Rhs> PartialOrd<Rhs> for BitVec<O, T>

@@ -201,2 +222,3 @@ where

{
#[inline]
fn partial_cmp(&self, other: &Rhs) -> Option<cmp::Ordering> {

@@ -207,2 +229,3 @@ other.partial_cmp(self.as_bitslice())

#[cfg(not(tarpaulin_include))]
impl<O, T> AsRef<BitSlice<O, T>> for BitVec<O, T>

@@ -213,2 +236,3 @@ where

{
#[inline(always)]
fn as_ref(&self) -> &BitSlice<O, T> {

@@ -219,2 +243,3 @@ self.as_bitslice()

#[cfg(not(tarpaulin_include))]
impl<O, T> AsMut<BitSlice<O, T>> for BitVec<O, T>

@@ -225,2 +250,3 @@ where

{
#[inline(always)]
fn as_mut(&mut self) -> &mut BitSlice<O, T> {

@@ -231,2 +257,3 @@ self.as_mut_bitslice()

#[cfg(not(tarpaulin_include))]
impl<'a, O, T> From<&'a BitSlice<O, T>> for BitVec<O, T>

@@ -237,2 +264,3 @@ where

{
#[inline(always)]
fn from(slice: &'a BitSlice<O, T>) -> Self {

@@ -243,2 +271,3 @@ Self::from_bitslice(slice)

#[cfg(not(tarpaulin_include))]
impl<'a, O, T> From<&'a mut BitSlice<O, T>> for BitVec<O, T>

@@ -249,2 +278,3 @@ where

{
#[inline(always)]
fn from(slice: &'a mut BitSlice<O, T>) -> Self {

@@ -255,2 +285,3 @@ Self::from_bitslice(slice)

#[cfg(not(tarpaulin_include))]
impl<O, T> From<BitBox<O, T>> for BitVec<O, T>

@@ -261,2 +292,3 @@ where

{
#[inline(always)]
fn from(boxed: BitBox<O, T>) -> Self {

@@ -267,3 +299,4 @@ boxed.into_bitvec()

impl<O, T> Into<Vec<T>> for BitVec<O, T>
#[cfg(not(tarpaulin_include))]
impl<O, T> From<BitVec<O, T>> for Vec<T>
where

@@ -273,7 +306,9 @@ O: BitOrder,

{
fn into(self) -> Vec<T> {
self.into_vec()
#[inline(always)]
fn from(bv: BitVec<O, T>) -> Self {
bv.into_vec()
}
}
#[cfg(not(tarpaulin_include))]
impl<O, T> TryFrom<Vec<T>> for BitVec<O, T>

@@ -286,2 +321,3 @@ where

#[inline(always)]
fn try_from(vec: Vec<T>) -> Result<Self, Self::Error> {

@@ -292,2 +328,3 @@ Self::try_from_vec(vec)

#[cfg(not(tarpaulin_include))]
impl<O, T> Default for BitVec<O, T>

@@ -298,2 +335,3 @@ where

{
#[inline(always)]
fn default() -> Self {

@@ -309,2 +347,3 @@ Self::new()

{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -320,2 +359,3 @@ self.as_bitspan().render(fmt, "Vec", &[(

#[cfg(not(tarpaulin_include))]
impl<O, T> Display for BitVec<O, T>

@@ -326,2 +366,3 @@ where

{
#[inline(always)]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -332,2 +373,3 @@ Display::fmt(self.as_bitslice(), fmt)

#[cfg(not(tarpaulin_include))]
impl<O, T> Binary for BitVec<O, T>

@@ -338,2 +380,3 @@ where

{
#[inline(always)]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -344,2 +387,3 @@ Binary::fmt(self.as_bitslice(), fmt)

#[cfg(not(tarpaulin_include))]
impl<O, T> LowerHex for BitVec<O, T>

@@ -350,2 +394,3 @@ where

{
#[inline(always)]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -356,2 +401,3 @@ LowerHex::fmt(self.as_bitslice(), fmt)

#[cfg(not(tarpaulin_include))]
impl<O, T> Octal for BitVec<O, T>

@@ -362,2 +408,3 @@ where

{
#[inline(always)]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -368,2 +415,3 @@ Octal::fmt(self.as_bitslice(), fmt)

#[cfg(not(tarpaulin_include))]
impl<O, T> UpperHex for BitVec<O, T>

@@ -374,2 +422,3 @@ where

{
#[inline(always)]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {

@@ -386,2 +435,3 @@ UpperHex::fmt(self.as_bitslice(), fmt)

{
#[inline(always)]
fn hash<H>(&self, state: &mut H)

@@ -388,0 +438,0 @@ where H: Hasher {

@@ -35,10 +35,4 @@ /*! [`BitSlice`] view adapters for memory regions.

use crate::{
mem::BitRegister,
order::BitOrder,
ptr::BitPtr,
slice::{
from_raw_parts_unchecked,
from_raw_parts_unchecked_mut,
BitSlice,
},
slice::BitSlice,
store::BitStore,

@@ -102,16 +96,2 @@ };

where O: BitOrder;
/// Produces the number of bits that the implementing type can hold.
#[doc(hidden)]
#[inline]
fn const_bits() -> usize
where Self: Sized {
Self::const_elts()
* <<Self::Store as BitStore>::Mem as IsNumber>::BITS as usize
}
/// Produces the number of memory elements that the implementing type holds.
#[doc(hidden)]
fn const_elts() -> usize
where Self: Sized;
}

@@ -136,8 +116,2 @@

}
#[doc(hidden)]
#[inline(always)]
fn const_elts() -> usize {
1
}
}

@@ -162,14 +136,5 @@

}
/// Slices cannot implement this function.
#[cold]
#[doc(hidden)]
#[inline(never)]
fn const_elts() -> usize {
unreachable!("This cannot be called on unsized slices")
}
}
#[cfg(not(tarpaulin_include))]
impl<T> BitView for [T; 0]
impl<T, const N: usize> BitView for [T; N]
where T: BitStore

@@ -179,62 +144,39 @@ {

#[inline(always)]
#[inline]
fn view_bits<O>(&self) -> &BitSlice<O, T>
where O: BitOrder {
BitSlice::empty()
BitSlice::from_slice(&self[..])
.expect("array was too long to view as bits")
}
#[inline(always)]
#[inline]
fn view_bits_mut<O>(&mut self) -> &mut BitSlice<O, T>
where O: BitOrder {
BitSlice::empty_mut()
BitSlice::from_slice_mut(&mut self[..])
.expect("array was too long to view as bits")
}
}
#[doc(hidden)]
fn const_elts() -> usize {
0
}
/// Helper for size awareness on `Sized` storage regions.
pub trait BitViewSized: BitView + Sized {
/// Counts the number of elements `T` contained in the type.
const ELTS: usize;
/// Counts the number of bits contained in the type.
const BITS: usize =
Self::ELTS * <<Self::Store as BitStore>::Mem as IsNumber>::BITS as usize;
}
// Replace with a const-generic once that becomes available.
macro_rules! view_bits {
($($n:expr),+ $(,)?) => { $(
impl<T> BitView for [T; $n]
where T: BitStore {
type Store = T;
/// Elements are equivalent to `[T; 1]`.
impl<T> BitViewSized for T
where T: BitStore
{
const ELTS: usize = 1;
}
#[inline]
fn view_bits<O>(&self) -> &BitSlice<O, T>
where O: BitOrder {
unsafe { from_raw_parts_unchecked(
BitPtr::from_slice(&self[..]),
$n * T::Mem::BITS as usize,
) }
}
#[inline]
fn view_bits_mut<O>(&mut self) -> &mut BitSlice<O, T>
where O: BitOrder {
unsafe { from_raw_parts_unchecked_mut(
BitPtr::from_mut_slice(&mut self[..]),
$n * T::Mem::BITS as usize,
) }
}
#[doc(hidden)]
#[inline(always)]
#[cfg(not(tarpaulin_include))]
fn const_elts() -> usize {
$n
}
}
)+ };
impl<T, const N: usize> BitViewSized for [T; N]
where T: BitStore
{
const ELTS: usize = N;
}
view_bits!(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64
);
/** Views a region as an immutable [`BitSlice`] only.

@@ -342,3 +284,3 @@

A: AsRef<[T]>,
T: BitStore + BitRegister,
T: BitStore,
{

@@ -356,3 +298,3 @@ #[inline]

A: AsMut<[T]>,
T: BitStore + BitRegister,
T: BitStore,
{

@@ -368,3 +310,6 @@ #[inline]

mod tests {
use crate::prelude::*;
use crate::{
prelude::*,
view::BitViewSized,
};

@@ -386,11 +331,11 @@ #[test]

assert_eq!(<u8 as BitView>::const_bits(), 8);
assert_eq!(<u16 as BitView>::const_bits(), 16);
assert_eq!(<u32 as BitView>::const_bits(), 32);
assert_eq!(<u8 as BitViewSized>::BITS, 8);
assert_eq!(<u16 as BitViewSized>::BITS, 16);
assert_eq!(<u32 as BitViewSized>::BITS, 32);
#[cfg(target_pointer_width = "64")]
{
assert_eq!(<u64 as BitView>::const_bits(), 64);
assert_eq!(<u64 as BitViewSized>::BITS, 64);
}
}
}
/*! Tracking mutability through the trait system.
This module enables the pointer structure system to enforce
!*/
/// A marker trait for distinguishing `*const` vs `*mut` when working with
/// structs, rather than raw pointers.
pub trait Mutability: 'static + seal::Sealed {}
/// An immutable pointer.
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct Const;
impl Mutability for Const {
}
impl seal::Sealed for Const {
}
/// A mutable pointer. Contexts with a `Mutable` may lower to `Immutable`, then
/// re-raise to `Mutable`; contexts with `Immutable` may not raise to `Mutable`
/// on their own.
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct Mut;
impl Mutability for Mut {
}
impl seal::Sealed for Mut {
}
#[doc(hidden)]
mod seal {
#[doc(hidden)]
pub trait Sealed {}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display