#[macro_export]
macro_rules! bytevec {
($vis:vis struct $name:ident (bool);) => {
$crate::paste::paste! { $crate::byteslice! { $vis struct [< $name Slice >](bool); } }
$crate::__bytevec_core!($vis, $name, bool, 1, unsigned, bool_type, 0);
};
($vis:vis struct $name:ident (u $width:literal);) => {
$crate::paste::paste! { $crate::byteslice! { $vis struct [< $name Slice >](u $width); } }
$crate::__bytevec_core!($vis, $name, u128, $width, unsigned, int_type, 0);
};
($vis:vis struct $name:ident (i $width:literal);) => {
$crate::paste::paste! { $crate::byteslice! { $vis struct [< $name Slice >](i $width); } }
$crate::__bytevec_core!($vis, $name, i128, $width, signed, int_type, 0);
};
($vis:vis struct $name:ident (bool, $cap:literal);) => {
$crate::paste::paste! { $crate::byteslice! { $vis struct [< $name Slice >](bool); } }
$crate::__bytevec_core!($vis, $name, bool, 1, unsigned, bool_type, $cap);
};
($vis:vis struct $name:ident (u $width:literal, $cap:literal);) => {
$crate::paste::paste! { $crate::byteslice! { $vis struct [< $name Slice >](u $width); } }
$crate::__bytevec_core!($vis, $name, u128, $width, unsigned, int_type, $cap);
};
($vis:vis struct $name:ident (i $width:literal, $cap:literal);) => {
$crate::paste::paste! { $crate::byteslice! { $vis struct [< $name Slice >](i $width); } }
$crate::__bytevec_core!($vis, $name, i128, $width, signed, int_type, $cap);
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __bytevec_core {
($vis:vis, $name:ident, $elem_ty:ty, $width:literal, $signed_tag:ident, $type_tag:ident, $default_cap:literal) => {
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
$vis struct $name {
pub data: $crate::alloc::vec::Vec<u8>,
pub len: usize,
}
impl Default for $name {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl core::fmt::Debug for $name {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut list = f.debug_list();
for i in 0..self.len { list.entry(&self.get(i)); }
list.finish()
}
}
$crate::paste::paste! {
impl $name {
pub const ELEMENT_WIDTH: usize = $width;
#[inline]
pub fn new() -> Self {
if $default_cap > 0 {
Self::with_capacity($default_cap)
} else {
Self {
data: $crate::alloc::vec::Vec::new(),
len: 0,
}
}
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
let byte_cap = (capacity * $width + 7) / 8;
Self {
data: $crate::alloc::vec::Vec::with_capacity(byte_cap),
len: 0,
}
}
#[inline]
pub fn len(&self) -> usize {
self.len
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len == 0
}
#[inline]
pub fn clear(&mut self) {
self.data.clear();
self.len = 0;
}
#[inline]
pub fn capacity(&self) -> usize {
(self.data.capacity() * 8) / $width
}
#[inline]
pub fn push(&mut self, value: $elem_ty) {
let bit_offset = self.len * $width;
let required_bytes = (bit_offset + $width + 7) / 8;
while self.data.len() < required_bytes {
self.data.push(0);
}
self.len += 1;
self.set(self.len - 1, value);
}
#[inline]
pub fn pop(&mut self) -> Option<$elem_ty> {
if self.len == 0 {
return None;
}
let value = self.get(self.len - 1);
self.len -= 1;
let required_bytes = (self.len * $width + 7) / 8;
self.data.truncate(required_bytes);
Some(value)
}
#[inline]
pub fn as_slice(&self) -> [< $name Slice >]<'_> {
[< $name Slice >]::new(&self.data, self.len)
}
#[inline]
pub fn as_mut_slice(&mut self) -> [< $name SliceMut >]<'_> {
[< $name SliceMut >]::new(&mut self.data, self.len)
}
#[inline]
pub fn get(&self, index: usize) -> $elem_ty {
self.as_slice().get(index)
}
#[inline]
pub fn set(&mut self, index: usize, value: $elem_ty) {
self.as_mut_slice().set(index, value)
}
#[inline]
pub fn as_bytes(&self) -> &[u8] {
&self.data
}
#[inline]
pub fn as_mut_bytes(&mut self) -> &mut [u8] {
&mut self.data
}
#[inline]
pub fn iter(&self) -> [< $name Slice Iter >]<'_> {
self.into_iter()
}
}
impl<'a> IntoIterator for &'a $name {
type Item = $elem_ty;
type IntoIter = [< $name Slice Iter >]<'a>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.as_slice().into_iter()
}
}
}
};
}