#![cfg_attr(not(feature = "std"), no_std)]
#![deny(unsafe_code)]
#![warn(missing_docs, rust_2018_idioms)]
#![allow(clippy::needless_doctest_main)]
#[cfg(all(feature = "alloc", not(feature = "std")))]
extern crate alloc;
mod accel;
mod bits;
pub mod align;
pub mod bytes;
pub mod format;
pub mod morton;
#[cfg(feature = "explain")]
pub mod explain;
pub use bits::Bits;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum BitError {
IndexOutOfRange,
InvalidRange,
FieldValueTooLarge,
AlignmentZero,
AlignmentNotPowerOfTwo,
Overflow,
UnderflowFromZero,
InsufficientBytes,
}
impl core::fmt::Display for BitError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(match self {
BitError::IndexOutOfRange => "bit index out of range",
BitError::InvalidRange => "invalid bit range",
BitError::FieldValueTooLarge => "value does not fit in target bit field",
BitError::AlignmentZero => "alignment must be nonzero",
BitError::AlignmentNotPowerOfTwo => "alignment must be a power of two",
BitError::Overflow => "arithmetic overflow",
BitError::UnderflowFromZero => "operation undefined for zero",
BitError::InsufficientBytes => "byte slice too short",
})
}
}
#[cfg(feature = "std")]
impl std::error::Error for BitError {}
pub trait IntoBitRange {
fn into_bit_range(self) -> (u32, u32);
}
impl IntoBitRange for core::ops::Range<u32> {
#[inline]
fn into_bit_range(self) -> (u32, u32) { (self.start, self.end) }
}
impl IntoBitRange for (u32, u32) {
#[inline]
fn into_bit_range(self) -> (u32, u32) { self }
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[repr(transparent)]
pub struct Flags<T>(pub T);
macro_rules! impl_flags {
($($ty:ty),*) => { $(
impl Flags<$ty> {
#[inline] pub const fn empty() -> Self { Self(0) }
#[inline] pub const fn all() -> Self { Self(!(0 as $ty)) }
#[inline] pub const fn from_bits(b: $ty) -> Self { Self(b) }
#[inline] pub const fn bits(self) -> $ty { self.0 }
#[inline] pub const fn has(self, flags: $ty) -> bool { (self.0 & flags) == flags }
#[inline] pub const fn has_all(self, flags: $ty) -> bool { Self::has(self, flags) }
#[inline] pub const fn has_any(self, flags: $ty) -> bool { (self.0 & flags) != 0 }
#[inline] pub const fn with(self, flags: $ty) -> Self { Self(self.0 | flags) }
#[inline] pub const fn without(self, flags: $ty) -> Self { Self(self.0 & !flags) }
#[inline] pub const fn toggled(self, flags: $ty) -> Self { Self(self.0 ^ flags) }
#[inline] pub fn enable(&mut self, flags: $ty) { self.0 |= flags; }
#[inline] pub fn disable(&mut self, flags: $ty) { self.0 &= !flags; }
#[inline] pub fn toggle(&mut self, flags: $ty) { self.0 ^= flags; }
}
impl From<$ty> for Flags<$ty> { #[inline] fn from(v: $ty) -> Self { Self(v) } }
impl From<Flags<$ty>> for $ty { #[inline] fn from(f: Flags<$ty>) -> Self { f.0 } }
)* };
}
impl_flags!(u8, u16, u32, u64, u128, usize);
pub mod prelude {
pub use crate::{BitError, Bits, Flags, IntoBitRange};
}