use super::*;
#[repr(transparent)]
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct VolSeries<T, R, W, const C: usize, const S: usize> {
base: VolAddress<T, R, W>,
}
impl<T, R, W, const C: usize, const S: usize> VolSeries<T, R, W, C, S> {
#[inline]
#[must_use]
pub const unsafe fn new(base: usize) -> Self {
Self { base: VolAddress::new(base) }
}
#[inline]
#[must_use]
pub const unsafe fn len(self) -> usize {
C
}
#[inline]
#[must_use]
pub const unsafe fn stride(self) -> usize {
S
}
#[inline]
#[must_use]
#[track_caller]
pub const fn index(self, i: usize) -> VolAddress<T, R, W> {
if i < C {
unsafe { self.base.cast::<[u8; S]>().add(i).cast::<T>() }
} else {
#[allow(unconditional_panic)]
unsafe {
VolAddress::new([usize::MAX][1])
}
}
}
#[inline]
#[must_use]
pub const fn get(self, i: usize) -> Option<VolAddress<T, R, W>> {
if i < C {
Some(unsafe { self.base.cast::<[u8; S]>().add(i).cast::<T>() })
} else {
None
}
}
#[inline]
#[must_use]
pub const fn iter(self) -> VolSeriesIter<T, R, W, S> {
VolSeriesIter { base: self.base, count: C }
}
}
impl<T, R, W, const C: usize, const S: usize> Clone
for VolSeries<T, R, W, C, S>
{
#[inline]
#[must_use]
fn clone(&self) -> Self {
*self
}
}
impl<T, R, W, const C: usize, const S: usize> Copy
for VolSeries<T, R, W, C, S>
{
}
impl<T, R, W, const C: usize, const S: usize> core::fmt::Debug
for VolSeries<T, R, W, C, S>
{
#[cold]
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(f, "VolSeries<{elem_ty}, r{readability}, w{writeability}, c{count}, s{stride:#X}>({address:#X})",
elem_ty = core::any::type_name::<T>(),
readability=core::any::type_name::<R>(),
writeability=core::any::type_name::<W>(),
count=C,
stride=S,
address=self.base.address.get())
}
}
#[repr(C)]
pub struct VolSeriesIter<T, R, W, const S: usize> {
pub(crate) base: VolAddress<T, R, W>,
pub(crate) count: usize,
}
impl<T, R, W, const S: usize> Clone for VolSeriesIter<T, R, W, S> {
#[inline]
#[must_use]
fn clone(&self) -> Self {
Self { base: self.base, count: self.count }
}
}
impl<T, R, W, const S: usize> core::iter::Iterator
for VolSeriesIter<T, R, W, S>
{
type Item = VolAddress<T, R, W>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.count > 0 {
let out = Some(self.base);
self.count -= 1;
self.base = unsafe { self.base.cast::<[u8; S]>().add(1).cast::<T>() };
out
} else {
None
}
}
#[inline]
#[must_use]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.count, Some(self.count))
}
#[inline]
#[must_use]
fn count(self) -> usize {
self.count
}
#[inline]
#[must_use]
fn last(self) -> Option<Self::Item> {
if self.count > 0 {
Some(unsafe {
self.base.cast::<[u8; S]>().add(self.count - 1).cast::<T>()
})
} else {
None
}
}
#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
if n < self.count {
self.count -= n;
self.base = unsafe { self.base.cast::<[u8; S]>().add(1 + n).cast::<T>() };
Some(self.base)
} else {
self.count = 0;
None
}
}
}
impl<T, R, W, const S: usize> core::iter::DoubleEndedIterator
for VolSeriesIter<T, R, W, S>
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
if self.count > 0 {
let out = Some(unsafe {
self.base.cast::<[u8; S]>().add(self.count - 1).cast::<T>()
});
self.count -= 1;
out
} else {
None
}
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
if n < self.count {
self.count -= n;
Some(unsafe { self.base.cast::<[u8; S]>().add(1 + n).cast::<T>() })
} else {
self.count = 0;
None
}
}
}
#[test]
#[allow(bad_style)]
fn test_impl_Iterator_for_VolSeriesIter() {
let i: VolSeriesIter<u16, (), (), 0x100> = VolSeriesIter {
base: unsafe { VolAddress::new(core::mem::align_of::<u16>()) },
count: 4,
};
let mut i_c = i.clone().map(|a| a.as_usize());
assert_eq!(i_c.next(), Some(0x002));
assert_eq!(i_c.next(), Some(0x102));
assert_eq!(i_c.next(), Some(0x202));
assert_eq!(i_c.next(), Some(0x302));
assert_eq!(i_c.next(), None);
assert_eq!(i_c.next(), None);
let i_c = i.clone();
assert_eq!(i_c.size_hint(), (4, Some(4)));
let i_c = i.clone();
assert_eq!(i_c.count(), 4);
let i_c = i.clone().map(|a| a.as_usize());
assert_eq!(i_c.last(), Some(0x302));
let mut i_c = i.clone().map(|a| a.as_usize());
assert_eq!(i_c.nth(0), Some(0x002));
assert_eq!(i_c.nth(0), Some(0x102));
assert_eq!(i_c.nth(0), Some(0x202));
assert_eq!(i_c.nth(0), Some(0x302));
assert_eq!(i_c.nth(0), None);
assert_eq!(i_c.nth(0), None);
let mut i_c = i.clone().map(|a| a.as_usize());
assert_eq!(i_c.nth(1), Some(0x102));
assert_eq!(i_c.nth(1), Some(0x302));
assert_eq!(i_c.nth(1), None);
assert_eq!(i_c.nth(1), None);
let mut i_c = i.clone().map(|a| a.as_usize());
assert_eq!(i_c.nth(2), Some(0x202));
assert_eq!(i_c.nth(2), None);
assert_eq!(i_c.nth(2), None);
let mut i_c = i.clone().map(|a| a.as_usize());
assert_eq!(i_c.nth(3), Some(0x302));
assert_eq!(i_c.nth(3), None);
assert_eq!(i_c.nth(3), None);
let mut i_c = i.clone().map(|a| a.as_usize());
assert_eq!(i_c.nth(4), None);
assert_eq!(i_c.nth(4), None);
}
#[test]
#[allow(bad_style)]
fn test_impl_DoubleEndedIterator_for_VolSeriesIter() {
let i: VolSeriesIter<u16, (), (), 0x100> = VolSeriesIter {
base: unsafe { VolAddress::new(core::mem::align_of::<u16>()) },
count: 4,
};
let mut i_c = i.clone().map(|a| a.as_usize());
assert_eq!(i_c.next_back(), Some(0x302));
assert_eq!(i_c.next_back(), Some(0x202));
assert_eq!(i_c.next_back(), Some(0x102));
assert_eq!(i_c.next_back(), Some(0x002));
assert_eq!(i_c.next_back(), None);
assert_eq!(i_c.next_back(), None);
let mut i_c = i.clone().map(|a| a.as_usize());
assert_eq!(i_c.nth_back(0), Some(0x302));
assert_eq!(i_c.nth_back(0), Some(0x202));
assert_eq!(i_c.nth_back(0), Some(0x102));
assert_eq!(i_c.nth_back(0), Some(0x002));
assert_eq!(i_c.nth_back(0), None);
assert_eq!(i_c.nth_back(0), None);
let mut i_c = i.clone().map(|a| a.as_usize());
assert_eq!(i_c.nth_back(1), Some(0x202));
assert_eq!(i_c.nth_back(1), Some(0x002));
assert_eq!(i_c.nth_back(1), None);
assert_eq!(i_c.nth_back(1), None);
let mut i_c = i.clone().map(|a| a.as_usize());
assert_eq!(i_c.nth_back(2), Some(0x102));
assert_eq!(i_c.nth_back(2), None);
assert_eq!(i_c.nth_back(2), None);
let mut i_c = i.clone().map(|a| a.as_usize());
assert_eq!(i_c.nth_back(3), Some(0x002));
assert_eq!(i_c.nth_back(3), None);
assert_eq!(i_c.nth_back(3), None);
let mut i_c = i.clone().map(|a| a.as_usize());
assert_eq!(i_c.nth_back(4), None);
assert_eq!(i_c.nth_back(4), None);
}