use core::cell::Cell;
use core::fmt;
use core::ptr::{null_mut, NonNull};
use core::sync::atomic::{AtomicPtr, Ordering};
use crate::link_ops::{self, DefaultLinkOps};
use crate::pointer_ops::PointerOps;
use crate::xor_linked_list::XorLinkedListOps;
use crate::Adapter;
pub unsafe trait SinglyLinkedListOps: link_ops::LinkOps {
    unsafe fn next(&self, ptr: Self::LinkPtr) -> Option<Self::LinkPtr>;
    unsafe fn set_next(&mut self, ptr: Self::LinkPtr, next: Option<Self::LinkPtr>);
}
#[repr(align(2))]
pub struct Link {
    next: Cell<Option<NonNull<Link>>>,
}
const UNLINKED_MARKER: Option<NonNull<Link>> =
    unsafe { Some(NonNull::new_unchecked(1 as *mut Link)) };
impl Link {
    #[inline]
    pub const fn new() -> Link {
        Link {
            next: Cell::new(UNLINKED_MARKER),
        }
    }
    #[inline]
    pub fn is_linked(&self) -> bool {
        self.next.get() != UNLINKED_MARKER
    }
    #[inline]
    pub unsafe fn force_unlink(&self) {
        self.next.set(UNLINKED_MARKER);
    }
}
impl DefaultLinkOps for Link {
    type Ops = LinkOps;
    const NEW: Self::Ops = LinkOps;
}
unsafe impl Send for Link {}
impl Clone for Link {
    #[inline]
    fn clone(&self) -> Link {
        Link::new()
    }
}
impl Default for Link {
    #[inline]
    fn default() -> Link {
        Link::new()
    }
}
impl fmt::Debug for Link {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if self.is_linked() {
            write!(f, "linked")
        } else {
            write!(f, "unlinked")
        }
    }
}
#[derive(Clone, Copy, Default)]
pub struct LinkOps;
unsafe impl link_ops::LinkOps for LinkOps {
    type LinkPtr = NonNull<Link>;
    #[inline]
    unsafe fn acquire_link(&mut self, ptr: Self::LinkPtr) -> bool {
        if ptr.as_ref().is_linked() {
            false
        } else {
            ptr.as_ref().next.set(None);
            true
        }
    }
    #[inline]
    unsafe fn release_link(&mut self, ptr: Self::LinkPtr) {
        ptr.as_ref().next.set(UNLINKED_MARKER);
    }
}
unsafe impl SinglyLinkedListOps for LinkOps {
    #[inline]
    unsafe fn next(&self, ptr: Self::LinkPtr) -> Option<Self::LinkPtr> {
        ptr.as_ref().next.get()
    }
    #[inline]
    unsafe fn set_next(&mut self, ptr: Self::LinkPtr, next: Option<Self::LinkPtr>) {
        ptr.as_ref().next.set(next);
    }
}
unsafe impl XorLinkedListOps for LinkOps {
    #[inline]
    unsafe fn next(
        &self,
        ptr: Self::LinkPtr,
        prev: Option<Self::LinkPtr>,
    ) -> Option<Self::LinkPtr> {
        let packed = ptr
            .as_ref()
            .next
            .get()
            .map(|x| x.as_ptr() as usize)
            .unwrap_or(0);
        let raw = packed ^ prev.map(|x| x.as_ptr() as usize).unwrap_or(0);
        NonNull::new(raw as *mut _)
    }
    #[inline]
    unsafe fn prev(
        &self,
        ptr: Self::LinkPtr,
        next: Option<Self::LinkPtr>,
    ) -> Option<Self::LinkPtr> {
        let packed = ptr
            .as_ref()
            .next
            .get()
            .map(|x| x.as_ptr() as usize)
            .unwrap_or(0);
        let raw = packed ^ next.map(|x| x.as_ptr() as usize).unwrap_or(0);
        NonNull::new(raw as *mut _)
    }
    #[inline]
    unsafe fn set(
        &mut self,
        ptr: Self::LinkPtr,
        prev: Option<Self::LinkPtr>,
        next: Option<Self::LinkPtr>,
    ) {
        let new_packed = prev.map(|x| x.as_ptr() as usize).unwrap_or(0)
            ^ next.map(|x| x.as_ptr() as usize).unwrap_or(0);
        let new_next = NonNull::new(new_packed as *mut _);
        ptr.as_ref().next.set(new_next);
    }
    #[inline]
    unsafe fn replace_next_or_prev(
        &mut self,
        ptr: Self::LinkPtr,
        old: Option<Self::LinkPtr>,
        new: Option<Self::LinkPtr>,
    ) {
        let packed = ptr
            .as_ref()
            .next
            .get()
            .map(|x| x.as_ptr() as usize)
            .unwrap_or(0);
        let new_packed = packed
            ^ old.map(|x| x.as_ptr() as usize).unwrap_or(0)
            ^ new.map(|x| x.as_ptr() as usize).unwrap_or(0);
        let new_next = NonNull::new(new_packed as *mut _);
        ptr.as_ref().next.set(new_next);
    }
}
#[repr(align(2))]
pub struct AtomicLink {
    next: AtomicPtr<AtomicLink>,
}
const ATOMIC_UNLINKED_MARKER: *mut AtomicLink = 1 as *mut AtomicLink;
impl AtomicLink {
    #[inline]
    pub const fn new() -> AtomicLink {
        AtomicLink {
            next: AtomicPtr::new(ATOMIC_UNLINKED_MARKER),
        }
    }
    #[inline]
    pub fn is_linked(&self) -> bool {
        self.next.load(Ordering::Relaxed) != ATOMIC_UNLINKED_MARKER
    }
    #[inline]
    pub unsafe fn force_unlink(&self) {
        self.next.store(ATOMIC_UNLINKED_MARKER, Ordering::Release);
    }
    #[inline]
    unsafe fn next_exclusive(&self) -> &Cell<Option<NonNull<AtomicLink>>> {
        core::mem::transmute(&self.next)
    }
}
impl DefaultLinkOps for AtomicLink {
    type Ops = AtomicLinkOps;
    const NEW: Self::Ops = AtomicLinkOps;
}
unsafe impl Send for AtomicLink {}
unsafe impl Sync for AtomicLink {}
impl Clone for AtomicLink {
    #[inline]
    fn clone(&self) -> AtomicLink {
        AtomicLink::new()
    }
}
impl Default for AtomicLink {
    #[inline]
    fn default() -> AtomicLink {
        AtomicLink::new()
    }
}
impl fmt::Debug for AtomicLink {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if self.is_linked() {
            write!(f, "linked")
        } else {
            write!(f, "unlinked")
        }
    }
}
#[derive(Clone, Copy, Default)]
pub struct AtomicLinkOps;
unsafe impl link_ops::LinkOps for AtomicLinkOps {
    type LinkPtr = NonNull<AtomicLink>;
    #[inline]
    unsafe fn acquire_link(&mut self, ptr: Self::LinkPtr) -> bool {
        ptr.as_ref()
            .next
            .compare_exchange(
                ATOMIC_UNLINKED_MARKER,
                null_mut(),
                Ordering::Acquire,
                Ordering::Relaxed,
            )
            .is_ok()
    }
    #[inline]
    unsafe fn release_link(&mut self, ptr: Self::LinkPtr) {
        ptr.as_ref()
            .next
            .store(ATOMIC_UNLINKED_MARKER, Ordering::Release)
    }
}
unsafe impl SinglyLinkedListOps for AtomicLinkOps {
    #[inline]
    unsafe fn next(&self, ptr: Self::LinkPtr) -> Option<Self::LinkPtr> {
        ptr.as_ref().next_exclusive().get()
    }
    #[inline]
    unsafe fn set_next(&mut self, ptr: Self::LinkPtr, next: Option<Self::LinkPtr>) {
        ptr.as_ref().next_exclusive().set(next);
    }
}
unsafe impl XorLinkedListOps for AtomicLinkOps {
    #[inline]
    unsafe fn next(
        &self,
        ptr: Self::LinkPtr,
        prev: Option<Self::LinkPtr>,
    ) -> Option<Self::LinkPtr> {
        let packed = ptr
            .as_ref()
            .next_exclusive()
            .get()
            .map(|x| x.as_ptr() as usize)
            .unwrap_or(0);
        let raw = packed ^ prev.map(|x| x.as_ptr() as usize).unwrap_or(0);
        NonNull::new(raw as *mut _)
    }
    #[inline]
    unsafe fn prev(
        &self,
        ptr: Self::LinkPtr,
        next: Option<Self::LinkPtr>,
    ) -> Option<Self::LinkPtr> {
        let packed = ptr
            .as_ref()
            .next_exclusive()
            .get()
            .map(|x| x.as_ptr() as usize)
            .unwrap_or(0);
        let raw = packed ^ next.map(|x| x.as_ptr() as usize).unwrap_or(0);
        NonNull::new(raw as *mut _)
    }
    #[inline]
    unsafe fn set(
        &mut self,
        ptr: Self::LinkPtr,
        prev: Option<Self::LinkPtr>,
        next: Option<Self::LinkPtr>,
    ) {
        let new_packed = prev.map(|x| x.as_ptr() as usize).unwrap_or(0)
            ^ next.map(|x| x.as_ptr() as usize).unwrap_or(0);
        let new_next = NonNull::new(new_packed as *mut _);
        ptr.as_ref().next_exclusive().set(new_next);
    }
    #[inline]
    unsafe fn replace_next_or_prev(
        &mut self,
        ptr: Self::LinkPtr,
        old: Option<Self::LinkPtr>,
        new: Option<Self::LinkPtr>,
    ) {
        let packed = ptr
            .as_ref()
            .next_exclusive()
            .get()
            .map(|x| x.as_ptr() as usize)
            .unwrap_or(0);
        let new_packed = packed
            ^ old.map(|x| x.as_ptr() as usize).unwrap_or(0)
            ^ new.map(|x| x.as_ptr() as usize).unwrap_or(0);
        let new_next = NonNull::new(new_packed as *mut _);
        ptr.as_ref().next_exclusive().set(new_next);
    }
}
#[inline]
unsafe fn link_between<T: SinglyLinkedListOps>(
    link_ops: &mut T,
    ptr: T::LinkPtr,
    prev: Option<T::LinkPtr>,
    next: Option<T::LinkPtr>,
) {
    if let Some(prev) = prev {
        link_ops.set_next(prev, Some(ptr));
    }
    link_ops.set_next(ptr, next);
}
#[inline]
unsafe fn link_after<T: SinglyLinkedListOps>(link_ops: &mut T, ptr: T::LinkPtr, prev: T::LinkPtr) {
    link_between(link_ops, ptr, Some(prev), link_ops.next(prev));
}
#[inline]
unsafe fn replace_with<T: SinglyLinkedListOps>(
    link_ops: &mut T,
    ptr: T::LinkPtr,
    prev: Option<T::LinkPtr>,
    new: T::LinkPtr,
) {
    if let Some(prev) = prev {
        link_ops.set_next(prev, Some(new));
    }
    link_ops.set_next(new, link_ops.next(ptr));
    link_ops.release_link(ptr);
}
#[inline]
unsafe fn remove<T: SinglyLinkedListOps>(
    link_ops: &mut T,
    ptr: T::LinkPtr,
    prev: Option<T::LinkPtr>,
) {
    if let Some(prev) = prev {
        link_ops.set_next(prev, link_ops.next(ptr));
    }
    link_ops.release_link(ptr);
}
#[inline]
unsafe fn splice<T: SinglyLinkedListOps>(
    link_ops: &mut T,
    start: T::LinkPtr,
    end: T::LinkPtr,
    prev: Option<T::LinkPtr>,
    next: Option<T::LinkPtr>,
) {
    link_ops.set_next(end, next);
    if let Some(prev) = prev {
        link_ops.set_next(prev, Some(start));
    }
}
pub struct Cursor<'a, A: Adapter>
where
    A::LinkOps: SinglyLinkedListOps,
{
    current: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
    list: &'a SinglyLinkedList<A>,
}
impl<'a, A: Adapter> Clone for Cursor<'a, A>
where
    A::LinkOps: SinglyLinkedListOps,
{
    #[inline]
    fn clone(&self) -> Cursor<'a, A> {
        Cursor {
            current: self.current,
            list: self.list,
        }
    }
}
impl<'a, A: Adapter> Cursor<'a, A>
where
    A::LinkOps: SinglyLinkedListOps,
{
    #[inline]
    pub fn is_null(&self) -> bool {
        self.current.is_none()
    }
    #[inline]
    pub fn get(&self) -> Option<&'a <A::PointerOps as PointerOps>::Value> {
        Some(unsafe { &*self.list.adapter.get_value(self.current?) })
    }
    #[inline]
    pub fn clone_pointer(&self) -> Option<<A::PointerOps as PointerOps>::Pointer>
    where
        <A::PointerOps as PointerOps>::Pointer: Clone,
    {
        let raw_pointer = self.get()? as *const <A::PointerOps as PointerOps>::Value;
        Some(unsafe {
            crate::pointer_ops::clone_pointer_from_raw(self.list.adapter.pointer_ops(), raw_pointer)
        })
    }
    #[inline]
    pub fn move_next(&mut self) {
        if let Some(current) = self.current {
            self.current = unsafe { self.list.adapter.link_ops().next(current) };
        } else {
            self.current = self.list.head;
        }
    }
    #[inline]
    pub fn peek_next(&self) -> Cursor<'_, A> {
        let mut next = self.clone();
        next.move_next();
        next
    }
}
pub struct CursorMut<'a, A: Adapter>
where
    A::LinkOps: SinglyLinkedListOps,
{
    current: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
    list: &'a mut SinglyLinkedList<A>,
}
impl<'a, A: Adapter> CursorMut<'a, A>
where
    A::LinkOps: SinglyLinkedListOps,
{
    #[inline]
    pub fn is_null(&self) -> bool {
        self.current.is_none()
    }
    #[inline]
    pub fn get(&self) -> Option<&<A::PointerOps as PointerOps>::Value> {
        Some(unsafe { &*self.list.adapter.get_value(self.current?) })
    }
    #[inline]
    pub fn as_cursor(&self) -> Cursor<'_, A> {
        Cursor {
            current: self.current,
            list: self.list,
        }
    }
    #[inline]
    pub fn move_next(&mut self) {
        if let Some(current) = self.current {
            self.current = unsafe { self.list.adapter.link_ops().next(current) };
        } else {
            self.current = self.list.head;
        }
    }
    #[inline]
    pub fn peek_next(&self) -> Cursor<'_, A> {
        let mut next = self.as_cursor();
        next.move_next();
        next
    }
    #[inline]
    pub fn remove_next(&mut self) -> Option<<A::PointerOps as PointerOps>::Pointer> {
        unsafe {
            let next = if let Some(current) = self.current {
                self.list.adapter.link_ops().next(current)
            } else {
                self.list.head
            }?;
            if self.is_null() {
                self.list.head = self.list.adapter.link_ops().next(next);
            }
            remove(self.list.adapter.link_ops_mut(), next, self.current);
            Some(
                self.list
                    .adapter
                    .pointer_ops()
                    .from_raw(self.list.adapter.get_value(next)),
            )
        }
    }
    #[inline]
    pub fn replace_next_with(
        &mut self,
        val: <A::PointerOps as PointerOps>::Pointer,
    ) -> Result<<A::PointerOps as PointerOps>::Pointer, <A::PointerOps as PointerOps>::Pointer>
    {
        unsafe {
            let next = if let Some(current) = self.current {
                self.list.adapter.link_ops().next(current)
            } else {
                self.list.head
            };
            match next {
                Some(next) => {
                    let new = self.list.node_from_value(val);
                    if self.is_null() {
                        self.list.head = Some(new);
                    }
                    replace_with(self.list.adapter.link_ops_mut(), next, self.current, new);
                    Ok(self
                        .list
                        .adapter
                        .pointer_ops()
                        .from_raw(self.list.adapter.get_value(next)))
                }
                None => Err(val),
            }
        }
    }
    #[inline]
    pub fn insert_after(&mut self, val: <A::PointerOps as PointerOps>::Pointer) {
        unsafe {
            let new = self.list.node_from_value(val);
            if let Some(current) = self.current {
                link_after(self.list.adapter.link_ops_mut(), new, current);
            } else {
                link_between(self.list.adapter.link_ops_mut(), new, None, self.list.head);
                self.list.head = Some(new);
            }
        }
    }
    #[inline]
    pub fn splice_after(&mut self, mut list: SinglyLinkedList<A>) {
        if let Some(head) = list.head {
            unsafe {
                let next = if let Some(current) = self.current {
                    self.list.adapter.link_ops().next(current)
                } else {
                    self.list.head
                };
                if let Some(next) = next {
                    let mut tail = head;
                    while let Some(x) = self.list.adapter.link_ops().next(tail) {
                        tail = x;
                    }
                    splice(
                        self.list.adapter.link_ops_mut(),
                        head,
                        tail,
                        self.current,
                        Some(next),
                    );
                    if self.is_null() {
                        self.list.head = list.head;
                    }
                } else {
                    if let Some(current) = self.current {
                        self.list
                            .adapter
                            .link_ops_mut()
                            .set_next(current, list.head);
                    } else {
                        self.list.head = list.head;
                    }
                }
                list.head = None;
            }
        }
    }
    #[inline]
    pub fn split_after(&mut self) -> SinglyLinkedList<A>
    where
        A: Clone,
    {
        if let Some(current) = self.current {
            unsafe {
                let list = SinglyLinkedList {
                    head: self.list.adapter.link_ops().next(current),
                    adapter: self.list.adapter.clone(),
                };
                self.list.adapter.link_ops_mut().set_next(current, None);
                list
            }
        } else {
            let list = SinglyLinkedList {
                head: self.list.head,
                adapter: self.list.adapter.clone(),
            };
            self.list.head = None;
            list
        }
    }
    #[inline]
    pub fn into_ref(self) -> Option<&'a <A::PointerOps as PointerOps>::Value> {
        Some(unsafe { &*self.list.adapter.get_value(self.current?) })
    }
}
pub struct SinglyLinkedList<A: Adapter>
where
    A::LinkOps: SinglyLinkedListOps,
{
    head: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
    adapter: A,
}
impl<A: Adapter> SinglyLinkedList<A>
where
    A::LinkOps: SinglyLinkedListOps,
{
    #[inline]
    fn node_from_value(
        &mut self,
        val: <A::PointerOps as PointerOps>::Pointer,
    ) -> <A::LinkOps as link_ops::LinkOps>::LinkPtr {
        use link_ops::LinkOps;
        unsafe {
            let raw = self.adapter.pointer_ops().into_raw(val);
            let link = self.adapter.get_link(raw);
            if !self.adapter.link_ops_mut().acquire_link(link) {
                self.adapter.pointer_ops().from_raw(raw);
                panic!("attempted to insert an object that is already linked");
            }
            link
        }
    }
    #[cfg(not(feature = "nightly"))]
    #[inline]
    pub fn new(adapter: A) -> SinglyLinkedList<A> {
        SinglyLinkedList {
            head: None,
            adapter,
        }
    }
    #[cfg(feature = "nightly")]
    #[inline]
    pub const fn new(adapter: A) -> SinglyLinkedList<A> {
        SinglyLinkedList {
            head: None,
            adapter,
        }
    }
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.head.is_none()
    }
    #[inline]
    pub fn cursor(&self) -> Cursor<'_, A> {
        Cursor {
            current: None,
            list: self,
        }
    }
    #[inline]
    pub fn cursor_mut(&mut self) -> CursorMut<'_, A> {
        CursorMut {
            current: None,
            list: self,
        }
    }
    #[inline]
    pub unsafe fn cursor_from_ptr(
        &self,
        ptr: *const <A::PointerOps as PointerOps>::Value,
    ) -> Cursor<'_, A> {
        Cursor {
            current: Some(self.adapter.get_link(ptr)),
            list: self,
        }
    }
    #[inline]
    pub unsafe fn cursor_mut_from_ptr(
        &mut self,
        ptr: *const <A::PointerOps as PointerOps>::Value,
    ) -> CursorMut<'_, A> {
        CursorMut {
            current: Some(self.adapter.get_link(ptr)),
            list: self,
        }
    }
    #[inline]
    pub fn front(&self) -> Cursor<'_, A> {
        let mut cursor = self.cursor();
        cursor.move_next();
        cursor
    }
    #[inline]
    pub fn front_mut(&mut self) -> CursorMut<'_, A> {
        let mut cursor = self.cursor_mut();
        cursor.move_next();
        cursor
    }
    #[inline]
    pub fn iter(&self) -> Iter<'_, A> {
        Iter {
            current: self.head,
            list: self,
        }
    }
    #[inline]
    pub fn clear(&mut self) {
        use link_ops::LinkOps;
        let mut current = self.head;
        self.head = None;
        while let Some(x) = current {
            unsafe {
                let next = self.adapter.link_ops().next(x);
                self.adapter.link_ops_mut().release_link(x);
                self.adapter
                    .pointer_ops()
                    .from_raw(self.adapter.get_value(x));
                current = next;
            }
        }
    }
    #[inline]
    pub fn fast_clear(&mut self) {
        self.head = None;
    }
    #[inline]
    pub fn take(&mut self) -> SinglyLinkedList<A>
    where
        A: Clone,
    {
        let list = SinglyLinkedList {
            head: self.head,
            adapter: self.adapter.clone(),
        };
        self.head = None;
        list
    }
    #[inline]
    pub fn push_front(&mut self, val: <A::PointerOps as PointerOps>::Pointer) {
        self.cursor_mut().insert_after(val);
    }
    #[inline]
    pub fn pop_front(&mut self) -> Option<<A::PointerOps as PointerOps>::Pointer> {
        self.cursor_mut().remove_next()
    }
}
unsafe impl<A: Adapter + Sync> Sync for SinglyLinkedList<A>
where
    <A::PointerOps as PointerOps>::Value: Sync,
    A::LinkOps: SinglyLinkedListOps,
{
}
unsafe impl<A: Adapter + Send> Send for SinglyLinkedList<A>
where
    <A::PointerOps as PointerOps>::Pointer: Send,
    A::LinkOps: SinglyLinkedListOps,
{
}
impl<A: Adapter> Drop for SinglyLinkedList<A>
where
    A::LinkOps: SinglyLinkedListOps,
{
    #[inline]
    fn drop(&mut self) {
        self.clear();
    }
}
impl<A: Adapter> IntoIterator for SinglyLinkedList<A>
where
    A::LinkOps: SinglyLinkedListOps,
{
    type Item = <A::PointerOps as PointerOps>::Pointer;
    type IntoIter = IntoIter<A>;
    #[inline]
    fn into_iter(self) -> IntoIter<A> {
        IntoIter { list: self }
    }
}
impl<'a, A: Adapter + 'a> IntoIterator for &'a SinglyLinkedList<A>
where
    A::LinkOps: SinglyLinkedListOps,
{
    type Item = &'a <A::PointerOps as PointerOps>::Value;
    type IntoIter = Iter<'a, A>;
    #[inline]
    fn into_iter(self) -> Iter<'a, A> {
        self.iter()
    }
}
impl<A: Adapter + Default> Default for SinglyLinkedList<A>
where
    A::LinkOps: SinglyLinkedListOps,
{
    fn default() -> SinglyLinkedList<A> {
        SinglyLinkedList::new(A::default())
    }
}
impl<A: Adapter> fmt::Debug for SinglyLinkedList<A>
where
    A::LinkOps: SinglyLinkedListOps,
    <A::PointerOps as PointerOps>::Value: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_list().entries(self.iter()).finish()
    }
}
pub struct Iter<'a, A: Adapter>
where
    A::LinkOps: SinglyLinkedListOps,
{
    current: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
    list: &'a SinglyLinkedList<A>,
}
impl<'a, A: Adapter + 'a> Iterator for Iter<'a, A>
where
    A::LinkOps: SinglyLinkedListOps,
{
    type Item = &'a <A::PointerOps as PointerOps>::Value;
    #[inline]
    fn next(&mut self) -> Option<&'a <A::PointerOps as PointerOps>::Value> {
        let current = self.current?;
        self.current = unsafe { self.list.adapter.link_ops().next(current) };
        Some(unsafe { &*self.list.adapter.get_value(current) })
    }
}
impl<'a, A: Adapter + 'a> Clone for Iter<'a, A>
where
    A::LinkOps: SinglyLinkedListOps,
{
    #[inline]
    fn clone(&self) -> Iter<'a, A> {
        Iter {
            current: self.current,
            list: self.list,
        }
    }
}
pub struct IntoIter<A: Adapter>
where
    A::LinkOps: SinglyLinkedListOps,
{
    list: SinglyLinkedList<A>,
}
impl<A: Adapter> Iterator for IntoIter<A>
where
    A::LinkOps: SinglyLinkedListOps,
{
    type Item = <A::PointerOps as PointerOps>::Pointer;
    #[inline]
    fn next(&mut self) -> Option<<A::PointerOps as PointerOps>::Pointer> {
        self.list.pop_front()
    }
}
#[cfg(test)]
mod tests {
    use super::{Link, SinglyLinkedList};
    use std::fmt;
    use std::format;
    use std::rc::Rc;
    use std::vec::Vec;
    struct Obj {
        link1: Link,
        link2: Link,
        value: u32,
    }
    impl fmt::Debug for Obj {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            write!(f, "{}", self.value)
        }
    }
    intrusive_adapter!(ObjAdapter1 = Rc<Obj>: Obj { link1: Link });
    intrusive_adapter!(ObjAdapter2 = Rc<Obj>: Obj { link2: Link });
    fn make_obj(value: u32) -> Rc<Obj> {
        Rc::new(Obj {
            link1: Link::new(),
            link2: Link::default(),
            value,
        })
    }
    #[test]
    fn test_link() {
        let a = make_obj(1);
        assert!(!a.link1.is_linked());
        assert!(!a.link2.is_linked());
        let mut b = SinglyLinkedList::<ObjAdapter1>::default();
        assert!(b.is_empty());
        b.push_front(a.clone());
        assert!(!b.is_empty());
        assert!(a.link1.is_linked());
        assert!(!a.link2.is_linked());
        assert_eq!(format!("{:?}", a.link1), "linked");
        assert_eq!(format!("{:?}", a.link2), "unlinked");
        assert_eq!(
            b.pop_front().unwrap().as_ref() as *const _,
            a.as_ref() as *const _
        );
        assert!(b.is_empty());
        assert!(!a.link1.is_linked());
        assert!(!a.link2.is_linked());
    }
    #[test]
    fn test_cursor() {
        let a = make_obj(1);
        let b = make_obj(2);
        let c = make_obj(3);
        let mut l = SinglyLinkedList::new(ObjAdapter1::new());
        let mut cur = l.cursor_mut();
        assert!(cur.is_null());
        assert!(cur.get().is_none());
        assert!(cur.remove_next().is_none());
        assert_eq!(
            cur.replace_next_with(a.clone()).unwrap_err().as_ref() as *const _,
            a.as_ref() as *const _
        );
        cur.insert_after(c.clone());
        cur.insert_after(a.clone());
        cur.move_next();
        cur.insert_after(b.clone());
        cur.move_next();
        cur.move_next();
        assert!(cur.peek_next().is_null());
        cur.move_next();
        assert!(cur.is_null());
        cur.move_next();
        assert!(!cur.is_null());
        assert_eq!(cur.get().unwrap() as *const _, a.as_ref() as *const _);
        {
            let mut cur2 = cur.as_cursor();
            assert_eq!(cur2.get().unwrap() as *const _, a.as_ref() as *const _);
            assert_eq!(cur2.peek_next().get().unwrap().value, 2);
            cur2.move_next();
            assert_eq!(cur2.get().unwrap().value, 2);
            cur2.move_next();
            assert_eq!(cur2.get().unwrap() as *const _, c.as_ref() as *const _);
            cur2.move_next();
            assert!(cur2.is_null());
            assert!(cur2.clone().get().is_none());
        }
        assert_eq!(cur.get().unwrap() as *const _, a.as_ref() as *const _);
        assert_eq!(
            cur.remove_next().unwrap().as_ref() as *const _,
            b.as_ref() as *const _
        );
        assert_eq!(cur.get().unwrap() as *const _, a.as_ref() as *const _);
        cur.insert_after(b.clone());
        assert_eq!(cur.get().unwrap() as *const _, a.as_ref() as *const _);
        cur.move_next();
        assert_eq!(cur.get().unwrap() as *const _, b.as_ref() as *const _);
        assert_eq!(
            cur.remove_next().unwrap().as_ref() as *const _,
            c.as_ref() as *const _
        );
        assert!(!c.link1.is_linked());
        assert!(a.link1.is_linked());
        assert_eq!(cur.get().unwrap() as *const _, b.as_ref() as *const _);
        cur.move_next();
        assert!(cur.is_null());
        assert_eq!(
            cur.replace_next_with(c.clone()).unwrap().as_ref() as *const _,
            a.as_ref() as *const _
        );
        assert!(!a.link1.is_linked());
        assert!(c.link1.is_linked());
        assert!(cur.is_null());
        cur.move_next();
        assert_eq!(cur.get().unwrap() as *const _, c.as_ref() as *const _);
        assert_eq!(
            cur.replace_next_with(a.clone()).unwrap().as_ref() as *const _,
            b.as_ref() as *const _
        );
        assert!(a.link1.is_linked());
        assert!(!b.link1.is_linked());
        assert!(c.link1.is_linked());
        assert_eq!(cur.get().unwrap() as *const _, c.as_ref() as *const _);
    }
    #[test]
    fn test_split_splice() {
        let mut l1 = SinglyLinkedList::new(ObjAdapter1::new());
        let mut l2 = SinglyLinkedList::new(ObjAdapter1::new());
        let mut l3 = SinglyLinkedList::new(ObjAdapter1::new());
        let a = make_obj(1);
        let b = make_obj(2);
        let c = make_obj(3);
        let d = make_obj(4);
        l1.cursor_mut().insert_after(d);
        l1.cursor_mut().insert_after(c);
        l1.cursor_mut().insert_after(b);
        l1.cursor_mut().insert_after(a);
        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 2, 3, 4]);
        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), []);
        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), []);
        {
            let mut cur = l1.front_mut();
            cur.move_next();
            l2 = cur.split_after();
        }
        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 2]);
        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), [3, 4]);
        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), []);
        {
            let mut cur = l2.front_mut();
            l3 = cur.split_after();
        }
        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 2]);
        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), [3]);
        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), [4]);
        {
            let mut cur = l1.front_mut();
            cur.splice_after(l2.take());
        }
        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 3, 2]);
        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), []);
        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), [4]);
        {
            let mut cur = l1.cursor_mut();
            cur.splice_after(l3.take());
        }
        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), [4, 1, 3, 2]);
        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), []);
        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), []);
        {
            let mut cur = l1.cursor_mut();
            l2 = cur.split_after();
        }
        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), []);
        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), [4, 1, 3, 2]);
        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), []);
        {
            let mut cur = l2.front_mut();
            cur.move_next();
            l3 = cur.split_after();
        }
        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), []);
        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), [4, 1]);
        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), [3, 2]);
        {
            let mut cur = l2.front_mut();
            cur.splice_after(l3.take());
        }
        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), []);
        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), [4, 3, 2, 1]);
        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), []);
        {
            let mut cur = l3.cursor_mut();
            cur.splice_after(l2.take());
        }
        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), []);
        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), []);
        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), [4, 3, 2, 1]);
        {
            let mut cur = l3.front_mut();
            cur.move_next();
            l2 = cur.split_after();
        }
        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), []);
        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), [2, 1]);
        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), [4, 3]);
        {
            let mut cur = l2.front_mut();
            cur.move_next();
            cur.splice_after(l3.take());
        }
        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), []);
        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), [2, 1, 4, 3]);
        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), []);
    }
    #[test]
    fn test_iter() {
        let mut l = SinglyLinkedList::new(ObjAdapter1::new());
        let a = make_obj(1);
        let b = make_obj(2);
        let c = make_obj(3);
        let d = make_obj(4);
        l.cursor_mut().insert_after(d.clone());
        l.cursor_mut().insert_after(c.clone());
        l.cursor_mut().insert_after(b.clone());
        l.cursor_mut().insert_after(a.clone());
        assert_eq!(l.front().get().unwrap().value, 1);
        unsafe {
            assert_eq!(l.cursor_from_ptr(b.as_ref()).get().unwrap().value, 2);
            assert_eq!(l.cursor_mut_from_ptr(c.as_ref()).get().unwrap().value, 3);
        }
        let mut v = Vec::new();
        for x in &l {
            v.push(x.value);
        }
        assert_eq!(v, [1, 2, 3, 4]);
        assert_eq!(
            l.iter().clone().map(|x| x.value).collect::<Vec<_>>(),
            [1, 2, 3, 4]
        );
        assert_eq!(l.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 2, 3, 4]);
        assert_eq!(format!("{:?}", l), "[1, 2, 3, 4]");
        let mut v = Vec::new();
        for x in l.take() {
            v.push(x.value);
        }
        assert_eq!(v, [1, 2, 3, 4]);
        assert!(l.is_empty());
        assert!(!a.link1.is_linked());
        assert!(!b.link1.is_linked());
        assert!(!c.link1.is_linked());
        assert!(!d.link1.is_linked());
        l.cursor_mut().insert_after(d.clone());
        l.cursor_mut().insert_after(c.clone());
        l.cursor_mut().insert_after(b.clone());
        l.cursor_mut().insert_after(a.clone());
        l.clear();
        assert!(l.is_empty());
        assert!(!a.link1.is_linked());
        assert!(!b.link1.is_linked());
        assert!(!c.link1.is_linked());
        assert!(!d.link1.is_linked());
    }
    #[test]
    fn test_multi_list() {
        let mut l1 = SinglyLinkedList::new(ObjAdapter1::new());
        let mut l2 = SinglyLinkedList::new(ObjAdapter2::new());
        let a = make_obj(1);
        let b = make_obj(2);
        let c = make_obj(3);
        let d = make_obj(4);
        l1.cursor_mut().insert_after(d.clone());
        l1.cursor_mut().insert_after(c.clone());
        l1.cursor_mut().insert_after(b.clone());
        l1.cursor_mut().insert_after(a.clone());
        l2.cursor_mut().insert_after(a);
        l2.cursor_mut().insert_after(b);
        l2.cursor_mut().insert_after(c);
        l2.cursor_mut().insert_after(d);
        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 2, 3, 4]);
        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), [4, 3, 2, 1]);
    }
    #[test]
    fn test_fast_clear() {
        let mut l = SinglyLinkedList::new(ObjAdapter1::new());
        let a = make_obj(1);
        let b = make_obj(2);
        let c = make_obj(3);
        l.cursor_mut().insert_after(a.clone());
        l.cursor_mut().insert_after(b.clone());
        l.cursor_mut().insert_after(c.clone());
        l.fast_clear();
        assert!(l.is_empty());
        assert!(a.link1.is_linked());
        assert!(b.link1.is_linked());
        assert!(c.link1.is_linked());
        unsafe {
            a.link1.force_unlink();
            b.link1.force_unlink();
            c.link1.force_unlink();
        }
        assert!(l.is_empty());
        assert!(!a.link1.is_linked());
        assert!(!b.link1.is_linked());
        assert!(!c.link1.is_linked());
    }
    #[test]
    fn test_non_static() {
        #[derive(Clone)]
        struct Obj<'a, T> {
            link: Link,
            value: &'a T,
        }
        intrusive_adapter!(ObjAdapter<'a, T> = &'a Obj<'a, T>: Obj<'a, T> {link: Link} where T: 'a);
        let v = 5;
        let a = Obj {
            link: Link::new(),
            value: &v,
        };
        let b = a.clone();
        let mut l = SinglyLinkedList::new(ObjAdapter::new());
        l.cursor_mut().insert_after(&a);
        l.cursor_mut().insert_after(&b);
        assert_eq!(*l.front().get().unwrap().value, 5);
        assert_eq!(*l.front().get().unwrap().value, 5);
    }
    macro_rules! test_clone_pointer {
        ($ptr: ident, $ptr_import: path) => {
            use $ptr_import;
            #[derive(Clone)]
            struct Obj {
                link: Link,
                value: usize,
            }
            intrusive_adapter!(ObjAdapter = $ptr<Obj>: Obj { link: Link });
            let a = $ptr::new(Obj {
                link: Link::new(),
                value: 5,
            });
            let mut l = SinglyLinkedList::new(ObjAdapter::new());
            l.cursor_mut().insert_after(a.clone());
            assert_eq!(2, $ptr::strong_count(&a));
            let pointer = l.front().clone_pointer().unwrap();
            assert_eq!(pointer.value, 5);
            assert_eq!(3, $ptr::strong_count(&a));
            l.clear();
            assert!(l.front().clone_pointer().is_none());
        };
    }
    #[test]
    fn test_clone_pointer_rc() {
        test_clone_pointer!(Rc, std::rc::Rc);
    }
    #[test]
    fn test_clone_pointer_arc() {
        test_clone_pointer!(Arc, std::sync::Arc);
    }
}