use core::iter::FusedIterator;
use core::marker::PhantomData;
use core::ptr;
use super::traits::NtSingleList;
use crate::traits::{NtListElement, NtTypedList};
#[repr(C)]
pub struct NtSingleListHead<E: NtListElement<L>, L: NtTypedList<T = NtSingleList>> {
pub(crate) next: *mut NtSingleListEntry<E, L>,
}
impl<E, L> NtSingleListHead<E, L>
where
E: NtListElement<L>,
L: NtTypedList<T = NtSingleList>,
{
pub fn new() -> Self {
Self {
next: ptr::null_mut(),
}
}
pub fn clear(&mut self) {
self.next = ptr::null_mut();
}
pub(crate) fn entry(element: &mut E) -> *mut NtSingleListEntry<E, L> {
let element_ptr = element as *mut E;
let entry = unsafe { element_ptr.cast::<u8>().add(E::offset()).cast::<E>() };
entry.cast()
}
pub unsafe fn front(&self) -> Option<&E> {
(!self.is_empty()).then(|| NtSingleListEntry::containing_record(self.next))
}
pub unsafe fn front_mut(&mut self) -> Option<&mut E> {
(!self.is_empty()).then(|| NtSingleListEntry::containing_record_mut(self.next))
}
pub fn is_empty(&self) -> bool {
self.next.is_null()
}
pub unsafe fn iter(&self) -> Iter<E, L> {
Iter {
current: self.next,
phantom: PhantomData,
}
}
pub unsafe fn iter_mut(&mut self) -> IterMut<E, L> {
IterMut {
current: self.next,
phantom: PhantomData,
}
}
pub unsafe fn len(&self) -> usize {
self.iter().count()
}
pub unsafe fn pop_front(&mut self) -> Option<&mut E> {
(!self.is_empty()).then(|| {
let entry = self.next;
self.next = (*entry).next;
NtSingleListEntry::containing_record_mut(entry)
})
}
pub unsafe fn push_front(&mut self, element: &mut E) {
let entry = Self::entry(element);
(*entry).next = self.next;
self.next = entry;
}
pub unsafe fn retain<F>(&mut self, mut f: F)
where
F: FnMut(&mut E) -> bool,
{
let mut previous = (self as *mut Self).cast();
let mut current = self.next;
while !current.is_null() {
let element = NtSingleListEntry::containing_record_mut(current);
if f(element) {
previous = current;
} else {
(*previous).next = (*current).next;
}
current = (*current).next;
}
}
}
impl<E, L> Default for NtSingleListHead<E, L>
where
E: NtListElement<L>,
L: NtTypedList<T = NtSingleList>,
{
fn default() -> Self {
Self::new()
}
}
pub struct Iter<'a, E: NtListElement<L>, L: NtTypedList<T = NtSingleList>> {
current: *const NtSingleListEntry<E, L>,
phantom: PhantomData<&'a NtSingleListHead<E, L>>,
}
impl<'a, E, L> Iterator for Iter<'a, E, L>
where
E: NtListElement<L>,
L: NtTypedList<T = NtSingleList>,
{
type Item = &'a E;
fn next(&mut self) -> Option<&'a E> {
if self.current.is_null() {
None
} else {
unsafe {
let element_ptr = self.current;
self.current = (*self.current).next;
Some(NtSingleListEntry::<E, L>::containing_record(element_ptr))
}
}
}
}
impl<'a, E, L> FusedIterator for Iter<'a, E, L>
where
E: NtListElement<L>,
L: NtTypedList<T = NtSingleList>,
{
}
pub struct IterMut<'a, E: NtListElement<L>, L: NtTypedList<T = NtSingleList>> {
current: *mut NtSingleListEntry<E, L>,
phantom: PhantomData<&'a mut NtSingleListHead<E, L>>,
}
impl<'a, E, L> Iterator for IterMut<'a, E, L>
where
E: NtListElement<L>,
L: NtTypedList<T = NtSingleList>,
{
type Item = &'a mut E;
fn next(&mut self) -> Option<&'a mut E> {
if self.current.is_null() {
None
} else {
unsafe {
let element_ptr = self.current;
self.current = (*self.current).next;
Some(NtSingleListEntry::containing_record_mut(element_ptr))
}
}
}
}
impl<'a, E, L> FusedIterator for IterMut<'a, E, L>
where
E: NtListElement<L>,
L: NtTypedList<T = NtSingleList>,
{
}
#[derive(Debug)]
#[repr(C)]
pub struct NtSingleListEntry<E: NtListElement<L>, L: NtTypedList<T = NtSingleList>> {
pub(crate) next: *mut NtSingleListEntry<E, L>,
}
impl<E, L> NtSingleListEntry<E, L>
where
E: NtListElement<L>,
L: NtTypedList<T = NtSingleList>,
{
pub fn new() -> Self {
Self {
next: ptr::null_mut(),
}
}
pub(crate) unsafe fn containing_record<'a>(ptr: *const Self) -> &'a E {
let element_ptr = unsafe { ptr.cast::<u8>().sub(E::offset()).cast::<Self>() };
unsafe { &*element_ptr.cast() }
}
pub(crate) unsafe fn containing_record_mut<'a>(ptr: *mut Self) -> &'a mut E {
let element_ptr = unsafe { ptr.cast::<u8>().sub(E::offset()).cast::<Self>() };
unsafe { &mut *element_ptr.cast() }
}
}
impl<E, L> Default for NtSingleListEntry<E, L>
where
E: NtListElement<L>,
L: NtTypedList<T = NtSingleList>,
{
fn default() -> Self {
Self::new()
}
}