use crate::sync::ArcBorrow;
use crate::types::Opaque;
use core::iter::{DoubleEndedIterator, FusedIterator};
use core::marker::PhantomData;
use core::ptr;
use pin_init::PinInit;
mod impl_list_item_mod;
#[doc(inline)]
pub use self::impl_list_item_mod::{
impl_has_list_links,
impl_has_list_links_self_ptr,
impl_list_item,
HasListLinks,
HasSelfPtr, };
mod arc;
#[doc(inline)]
pub use self::arc::{
impl_list_arc_safe,
AtomicTracker,
ListArc,
ListArcSafe,
TryNewListArc, };
mod arc_field;
#[doc(inline)]
pub use self::arc_field::{
define_list_arc_field_getter,
ListArcField, };
pub struct List<T: ?Sized + ListItem<ID>, const ID: u64 = 0> {
first: *mut ListLinksFields,
_ty: PhantomData<ListArc<T, ID>>,
}
unsafe impl<T, const ID: u64> Send for List<T, ID>
where
ListArc<T, ID>: Send,
T: ?Sized + ListItem<ID>,
{
}
unsafe impl<T, const ID: u64> Sync for List<T, ID>
where
ListArc<T, ID>: Sync,
T: ?Sized + ListItem<ID>,
{
}
pub unsafe trait ListItem<const ID: u64 = 0>: ListArcSafe<ID> {
unsafe fn view_links(me: *const Self) -> *mut ListLinks<ID>;
unsafe fn view_value(me: *mut ListLinks<ID>) -> *const Self;
unsafe fn prepare_to_insert(me: *const Self) -> *mut ListLinks<ID>;
unsafe fn post_remove(me: *mut ListLinks<ID>) -> *const Self;
}
#[repr(C)]
#[derive(Copy, Clone)]
struct ListLinksFields {
next: *mut ListLinksFields,
prev: *mut ListLinksFields,
}
#[repr(transparent)]
pub struct ListLinks<const ID: u64 = 0> {
inner: Opaque<ListLinksFields>,
}
unsafe impl<const ID: u64> Send for ListLinks<ID> {}
unsafe impl<const ID: u64> Sync for ListLinks<ID> {}
impl<const ID: u64> ListLinks<ID> {
pub fn new() -> impl PinInit<Self> {
ListLinks {
inner: Opaque::new(ListLinksFields {
prev: ptr::null_mut(),
next: ptr::null_mut(),
}),
}
}
#[inline]
unsafe fn fields(me: *mut Self) -> *mut ListLinksFields {
unsafe { Opaque::cast_into(ptr::addr_of!((*me).inner)) }
}
#[inline]
unsafe fn from_fields(me: *mut ListLinksFields) -> *mut Self {
me.cast()
}
}
#[repr(C)]
pub struct ListLinksSelfPtr<T: ?Sized, const ID: u64 = 0> {
pub inner: ListLinks<ID>,
self_ptr: Opaque<*const T>,
}
unsafe impl<T: ?Sized + Send, const ID: u64> Send for ListLinksSelfPtr<T, ID> {}
unsafe impl<T: ?Sized + Sync, const ID: u64> Sync for ListLinksSelfPtr<T, ID> {}
impl<T: ?Sized, const ID: u64> ListLinksSelfPtr<T, ID> {
pub fn new() -> impl PinInit<Self> {
Self {
inner: ListLinks {
inner: Opaque::new(ListLinksFields {
prev: ptr::null_mut(),
next: ptr::null_mut(),
}),
},
self_ptr: Opaque::uninit(),
}
}
pub unsafe fn raw_get_self_ptr(me: *const Self) -> *const Opaque<*const T> {
unsafe { ptr::addr_of!((*me).self_ptr) }
}
}
impl<T: ?Sized + ListItem<ID>, const ID: u64> List<T, ID> {
pub const fn new() -> Self {
Self {
first: ptr::null_mut(),
_ty: PhantomData,
}
}
pub fn is_empty(&self) -> bool {
self.first.is_null()
}
unsafe fn insert_inner(
&mut self,
item: ListArc<T, ID>,
next: *mut ListLinksFields,
) -> *mut ListLinksFields {
let raw_item = ListArc::into_raw(item);
let list_links = unsafe { T::prepare_to_insert(raw_item) };
let item = unsafe { ListLinks::fields(list_links) };
if next.is_null() {
unsafe {
(*item).next = item;
(*item).prev = item;
}
self.first = item;
} else {
let prev = unsafe { (*next).prev };
unsafe {
(*item).next = next;
(*item).prev = prev;
(*prev).next = item;
(*next).prev = item;
}
}
item
}
pub fn push_back(&mut self, item: ListArc<T, ID>) {
unsafe { self.insert_inner(item, self.first) };
}
pub fn push_front(&mut self, item: ListArc<T, ID>) {
let new_elem = unsafe { self.insert_inner(item, self.first) };
self.first = new_elem;
}
pub fn pop_back(&mut self) -> Option<ListArc<T, ID>> {
if self.is_empty() {
return None;
}
let last = unsafe { (*self.first).prev };
Some(unsafe { self.remove_internal(last) })
}
pub fn pop_front(&mut self) -> Option<ListArc<T, ID>> {
if self.is_empty() {
return None;
}
Some(unsafe { self.remove_internal(self.first) })
}
pub unsafe fn remove(&mut self, item: &T) -> Option<ListArc<T, ID>> {
let mut item = unsafe { ListLinks::fields(T::view_links(item)) };
let ListLinksFields { next, prev } = unsafe { *item };
debug_assert_eq!(next.is_null(), prev.is_null());
if !next.is_null() {
unsafe {
debug_assert_eq!(item, (*next).prev);
item = (*next).prev;
}
Some(unsafe { self.remove_internal_inner(item, next, prev) })
} else {
None
}
}
unsafe fn remove_internal(&mut self, item: *mut ListLinksFields) -> ListArc<T, ID> {
let ListLinksFields { next, prev } = unsafe { *item };
unsafe { self.remove_internal_inner(item, next, prev) }
}
unsafe fn remove_internal_inner(
&mut self,
item: *mut ListLinksFields,
next: *mut ListLinksFields,
prev: *mut ListLinksFields,
) -> ListArc<T, ID> {
unsafe {
(*next).prev = prev;
(*prev).next = next;
}
unsafe {
(*item).prev = ptr::null_mut();
(*item).next = ptr::null_mut();
}
if self.first == item {
self.first = unsafe { (*prev).next };
}
let list_links = unsafe { ListLinks::from_fields(item) };
let raw_item = unsafe { T::post_remove(list_links) };
unsafe { ListArc::from_raw(raw_item) }
}
pub fn push_all_back(&mut self, other: &mut List<T, ID>) {
if self.is_empty() {
self.first = other.first;
} else if !other.is_empty() {
let other_first = other.first;
let other_last = unsafe { (*other_first).prev };
let self_first = self.first;
let self_last = unsafe { (*self_first).prev };
unsafe {
(*self_first).prev = other_last;
(*other_last).next = self_first;
(*self_last).next = other_first;
(*other_first).prev = self_last;
}
}
other.first = ptr::null_mut();
}
pub fn cursor_front(&mut self) -> Cursor<'_, T, ID> {
Cursor {
next: self.first,
list: self,
}
}
pub fn cursor_back(&mut self) -> Cursor<'_, T, ID> {
Cursor {
next: core::ptr::null_mut(),
list: self,
}
}
pub fn iter(&self) -> Iter<'_, T, ID> {
Iter {
current: self.first,
stop: self.first,
_ty: PhantomData,
}
}
}
impl<T: ?Sized + ListItem<ID>, const ID: u64> Default for List<T, ID> {
fn default() -> Self {
List::new()
}
}
impl<T: ?Sized + ListItem<ID>, const ID: u64> Drop for List<T, ID> {
fn drop(&mut self) {
while let Some(item) = self.pop_front() {
drop(item);
}
}
}
#[derive(Clone)]
pub struct Iter<'a, T: ?Sized + ListItem<ID>, const ID: u64 = 0> {
current: *mut ListLinksFields,
stop: *mut ListLinksFields,
_ty: PhantomData<&'a ListArc<T, ID>>,
}
impl<'a, T: ?Sized + ListItem<ID>, const ID: u64> Iterator for Iter<'a, T, ID> {
type Item = ArcBorrow<'a, T>;
fn next(&mut self) -> Option<ArcBorrow<'a, T>> {
if self.current.is_null() {
return None;
}
let current = self.current;
let next = unsafe { (*current).next };
self.current = if next != self.stop {
next
} else {
ptr::null_mut()
};
let item = unsafe { T::view_value(ListLinks::from_fields(current)) };
Some(unsafe { ArcBorrow::from_raw(item) })
}
}
pub struct Cursor<'a, T: ?Sized + ListItem<ID>, const ID: u64 = 0> {
list: &'a mut List<T, ID>,
next: *mut ListLinksFields,
}
impl<'a, T: ?Sized + ListItem<ID>, const ID: u64> Cursor<'a, T, ID> {
fn prev_ptr(&self) -> *mut ListLinksFields {
let mut next = self.next;
let first = self.list.first;
if next == first {
return core::ptr::null_mut();
}
if next.is_null() {
next = first;
}
unsafe { (*next).prev }
}
pub fn peek_next(&mut self) -> Option<CursorPeek<'_, 'a, T, true, ID>> {
if self.next.is_null() {
return None;
}
Some(CursorPeek {
ptr: self.next,
cursor: self,
})
}
pub fn peek_prev(&mut self) -> Option<CursorPeek<'_, 'a, T, false, ID>> {
let prev = self.prev_ptr();
if prev.is_null() {
return None;
}
Some(CursorPeek {
ptr: prev,
cursor: self,
})
}
pub fn move_next(&mut self) -> bool {
if self.next.is_null() {
return false;
}
let mut next = unsafe { (*self.next).next };
if next == self.list.first {
next = core::ptr::null_mut();
}
self.next = next;
true
}
pub fn move_prev(&mut self) -> bool {
if self.next == self.list.first {
return false;
}
self.next = self.prev_ptr();
true
}
fn insert_inner(&mut self, item: ListArc<T, ID>) -> *mut ListLinksFields {
let ptr = if self.next.is_null() {
self.list.first
} else {
self.next
};
let item = unsafe { self.list.insert_inner(item, ptr) };
if self.next == self.list.first {
self.list.first = item;
}
item
}
pub fn insert(mut self, item: ListArc<T, ID>) {
self.insert_inner(item);
}
pub fn insert_next(&mut self, item: ListArc<T, ID>) {
self.next = self.insert_inner(item);
}
pub fn insert_prev(&mut self, item: ListArc<T, ID>) {
self.insert_inner(item);
}
pub fn remove_next(&mut self) -> Option<ListArc<T, ID>> {
self.peek_next().map(|v| v.remove())
}
pub fn remove_prev(&mut self) -> Option<ListArc<T, ID>> {
self.peek_prev().map(|v| v.remove())
}
}
pub struct CursorPeek<'a, 'b, T: ?Sized + ListItem<ID>, const ISNEXT: bool, const ID: u64> {
cursor: &'a mut Cursor<'b, T, ID>,
ptr: *mut ListLinksFields,
}
impl<'a, 'b, T: ?Sized + ListItem<ID>, const ISNEXT: bool, const ID: u64>
CursorPeek<'a, 'b, T, ISNEXT, ID>
{
pub fn remove(self) -> ListArc<T, ID> {
if ISNEXT {
self.cursor.move_next();
}
unsafe { self.cursor.list.remove_internal(self.ptr) }
}
pub fn arc(&self) -> ArcBorrow<'_, T> {
let me = unsafe { T::view_value(ListLinks::from_fields(self.ptr)) };
unsafe { ArcBorrow::from_raw(me) }
}
}
impl<'a, 'b, T: ?Sized + ListItem<ID>, const ISNEXT: bool, const ID: u64> core::ops::Deref
for CursorPeek<'a, 'b, T, ISNEXT, ID>
{
type Target = T;
fn deref(&self) -> &T {
let me = unsafe { T::view_value(ListLinks::from_fields(self.ptr)) };
unsafe { &*me }
}
}
impl<'a, T: ?Sized + ListItem<ID>, const ID: u64> FusedIterator for Iter<'a, T, ID> {}
impl<'a, T: ?Sized + ListItem<ID>, const ID: u64> IntoIterator for &'a List<T, ID> {
type IntoIter = Iter<'a, T, ID>;
type Item = ArcBorrow<'a, T>;
fn into_iter(self) -> Iter<'a, T, ID> {
self.iter()
}
}
pub struct IntoIter<T: ?Sized + ListItem<ID>, const ID: u64 = 0> {
list: List<T, ID>,
}
impl<T: ?Sized + ListItem<ID>, const ID: u64> Iterator for IntoIter<T, ID> {
type Item = ListArc<T, ID>;
fn next(&mut self) -> Option<ListArc<T, ID>> {
self.list.pop_front()
}
}
impl<T: ?Sized + ListItem<ID>, const ID: u64> FusedIterator for IntoIter<T, ID> {}
impl<T: ?Sized + ListItem<ID>, const ID: u64> DoubleEndedIterator for IntoIter<T, ID> {
fn next_back(&mut self) -> Option<ListArc<T, ID>> {
self.list.pop_back()
}
}
impl<T: ?Sized + ListItem<ID>, const ID: u64> IntoIterator for List<T, ID> {
type IntoIter = IntoIter<T, ID>;
type Item = ListArc<T, ID>;
fn into_iter(self) -> IntoIter<T, ID> {
IntoIter { list: self }
}
}