use core::{
borrow::{
Borrow,
BorrowMut,
},
cmp,
convert::TryFrom,
fmt::{
self,
Debug,
Display,
Formatter,
},
hash::{
Hash,
Hasher,
},
marker::Unpin,
};
use tap::TryConv;
use super::BitArray;
use crate::{
index::BitIdx,
mem,
order::BitOrder,
slice::BitSlice,
store::BitStore,
view::BitViewSized,
};
#[cfg(not(tarpaulin_include))]
impl<A, O> Borrow<BitSlice<A::Store, O>> for BitArray<A, O>
where
A: BitViewSized,
O: BitOrder,
{
#[inline]
fn borrow(&self) -> &BitSlice<A::Store, O> {
self.as_bitslice()
}
}
#[cfg(not(tarpaulin_include))]
impl<A, O> BorrowMut<BitSlice<A::Store, O>> for BitArray<A, O>
where
A: BitViewSized,
O: BitOrder,
{
#[inline]
fn borrow_mut(&mut self) -> &mut BitSlice<A::Store, O> {
self.as_mut_bitslice()
}
}
impl<A, O> Clone for BitArray<A, O>
where
A: BitViewSized,
O: BitOrder,
{
#[inline]
fn clone(&self) -> Self {
let mut out = Self::ZERO;
for (dst, src) in
out.as_raw_mut_slice().iter_mut().zip(self.as_raw_slice())
{
dst.store_value(src.load_value());
}
out
}
}
impl<A, O> Eq for BitArray<A, O>
where
A: BitViewSized,
O: BitOrder,
{
}
#[cfg(not(tarpaulin_include))]
impl<A, O> Ord for BitArray<A, O>
where
A: BitViewSized,
O: BitOrder,
{
#[inline]
fn cmp(&self, other: &Self) -> cmp::Ordering {
self.as_bitslice().cmp(other.as_bitslice())
}
}
#[cfg(not(tarpaulin_include))]
impl<O1, A, O2, T> PartialEq<BitArray<A, O2>> for BitSlice<T, O1>
where
O1: BitOrder,
O2: BitOrder,
A: BitViewSized,
T: BitStore,
{
#[inline]
fn eq(&self, other: &BitArray<A, O2>) -> bool {
self == other.as_bitslice()
}
}
#[cfg(not(tarpaulin_include))]
impl<A, O, Rhs> PartialEq<Rhs> for BitArray<A, O>
where
A: BitViewSized,
O: BitOrder,
Rhs: ?Sized,
BitSlice<A::Store, O>: PartialEq<Rhs>,
{
#[inline]
fn eq(&self, other: &Rhs) -> bool {
self.as_bitslice() == other
}
}
#[cfg(not(tarpaulin_include))]
impl<A, T, O> PartialOrd<BitArray<A, O>> for BitSlice<T, O>
where
A: BitViewSized,
T: BitStore,
O: BitOrder,
{
#[inline]
fn partial_cmp(&self, other: &BitArray<A, O>) -> Option<cmp::Ordering> {
self.partial_cmp(other.as_bitslice())
}
}
#[cfg(not(tarpaulin_include))]
impl<A, O, Rhs> PartialOrd<Rhs> for BitArray<A, O>
where
A: BitViewSized,
O: BitOrder,
Rhs: ?Sized,
BitSlice<A::Store, O>: PartialOrd<Rhs>,
{
#[inline]
fn partial_cmp(&self, other: &Rhs) -> Option<cmp::Ordering> {
self.as_bitslice().partial_cmp(other)
}
}
#[cfg(not(tarpaulin_include))]
impl<A, O> AsRef<BitSlice<A::Store, O>> for BitArray<A, O>
where
A: BitViewSized,
O: BitOrder,
{
#[inline]
fn as_ref(&self) -> &BitSlice<A::Store, O> {
self.as_bitslice()
}
}
#[cfg(not(tarpaulin_include))]
impl<A, O> AsMut<BitSlice<A::Store, O>> for BitArray<A, O>
where
A: BitViewSized,
O: BitOrder,
{
#[inline]
fn as_mut(&mut self) -> &mut BitSlice<A::Store, O> {
self.as_mut_bitslice()
}
}
#[cfg(not(tarpaulin_include))]
impl<A, O> From<A> for BitArray<A, O>
where
A: BitViewSized,
O: BitOrder,
{
#[inline]
fn from(data: A) -> Self {
Self::new(data)
}
}
impl<A, O> TryFrom<&BitSlice<A::Store, O>> for BitArray<A, O>
where
A: BitViewSized,
O: BitOrder,
{
type Error = TryFromBitSliceError;
#[inline]
fn try_from(src: &BitSlice<A::Store, O>) -> Result<Self, Self::Error> {
src.try_conv::<&Self>().map(|this| this.clone())
}
}
impl<A, O> TryFrom<&BitSlice<A::Store, O>> for &BitArray<A, O>
where
A: BitViewSized,
O: BitOrder,
{
type Error = TryFromBitSliceError;
#[inline]
fn try_from(src: &BitSlice<A::Store, O>) -> Result<Self, Self::Error> {
TryFromBitSliceError::new::<A, O>(src).map(|()| unsafe {
&*src
.as_bitspan()
.address()
.to_const()
.cast::<BitArray<A, O>>()
})
}
}
impl<A, O> TryFrom<&mut BitSlice<A::Store, O>> for &mut BitArray<A, O>
where
A: BitViewSized,
O: BitOrder,
{
type Error = TryFromBitSliceError;
#[inline]
fn try_from(src: &mut BitSlice<A::Store, O>) -> Result<Self, Self::Error> {
TryFromBitSliceError::new::<A, O>(src).map(|()| unsafe {
&mut *src
.as_mut_bitspan()
.address()
.to_mut()
.cast::<BitArray<A, O>>()
})
}
}
impl<A, O> Default for BitArray<A, O>
where
A: BitViewSized,
O: BitOrder,
{
#[inline]
fn default() -> Self {
Self::ZERO
}
}
impl<A, O> Debug for BitArray<A, O>
where
A: BitViewSized,
O: BitOrder,
{
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
self.as_bitspan().render(fmt, "Array", None)?;
fmt.write_str(" ")?;
Display::fmt(self, fmt)
}
}
easy_fmt! {
impl Binary
impl Display
impl LowerHex
impl Octal
impl UpperHex
for BitArray
}
#[cfg(not(tarpaulin_include))]
impl<A, O> Hash for BitArray<A, O>
where
A: BitViewSized,
O: BitOrder,
{
#[inline]
fn hash<H>(&self, hasher: &mut H)
where H: Hasher {
self.as_bitslice().hash(hasher);
}
}
impl<A, O> Copy for BitArray<A, O>
where
O: BitOrder,
A: BitViewSized + Copy,
{
}
impl<A, O> Unpin for BitArray<A, O>
where
A: BitViewSized,
O: BitOrder,
{
}
#[repr(transparent)]
#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
#[doc = include_str!("../../doc/array/TryFromBitSliceError.md")]
pub struct TryFromBitSliceError(InnerError);
impl TryFromBitSliceError {
#[inline]
fn new<A, O>(bits: &BitSlice<A::Store, O>) -> Result<(), Self>
where
O: BitOrder,
A: BitViewSized,
{
InnerError::new::<A, O>(bits).map_err(Self)
}
}
impl Debug for TryFromBitSliceError {
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
fmt.write_str("TryFromBitSliceError::")?;
match self.0 {
InnerError::UnequalLen { actual, expected } => {
write!(fmt, "UnequalLen({} != {})", actual, expected)
},
InnerError::Misaligned => fmt.write_str("Misaligned"),
}
}
}
#[cfg(not(tarpaulin_include))]
impl Display for TryFromBitSliceError {
#[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
match self.0 {
InnerError::UnequalLen { actual, expected } => write!(
fmt,
"bit-slice with length {} cannot be viewed as bit-array with \
length {}",
actual, expected,
),
InnerError::Misaligned => fmt.write_str(
"a bit-slice must begin at the front edge of a storage element \
in order to be viewed as a bit-array",
),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for TryFromBitSliceError {}
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum InnerError {
UnequalLen {
actual: usize,
expected: usize,
},
Misaligned,
}
impl InnerError {
#[inline]
fn new<A, O>(bits: &BitSlice<A::Store, O>) -> Result<(), Self>
where
O: BitOrder,
A: BitViewSized,
{
let bitspan = bits.as_bitspan();
let actual = bitspan.len();
let expected = mem::bits_of::<A>();
if actual != expected {
return Err(Self::UnequalLen { actual, expected });
}
if bitspan.head() != BitIdx::<<A::Store as BitStore>::Mem>::MIN {
return Err(Self::Misaligned);
}
Ok(())
}
}