intrusive_collections/
xor_linked_list.rs

1// Copyright 2016 Amanieu d'Antras
2// Copyright 2020 Amari Robinson
3//
4// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
5// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
6// http://opensource.org/licenses/MIT>, at your option. This file may not be
7// copied, modified, or distributed except according to those terms.
8
9//! Intrusive xor doubly-linked list which uses less memory than a regular doubly linked list.
10//!
11//! In exchange for less memory use, it is impossible to create a cursor from a pointer to
12//! an element.
13
14use core::cell::Cell;
15use core::fmt;
16use core::ptr::NonNull;
17use core::sync::atomic::{AtomicUsize, Ordering};
18
19use crate::link_ops::{self, DefaultLinkOps};
20use crate::pointer_ops::PointerOps;
21use crate::singly_linked_list::SinglyLinkedListOps;
22use crate::Adapter;
23// Necessary for Rust 1.56 compatability
24#[allow(unused_imports)]
25use crate::unchecked_option::UncheckedOptionExt;
26
27// =============================================================================
28// XorLinkedListOps
29// =============================================================================
30
31/// Link operations for `XorLinkedList`.
32pub unsafe trait XorLinkedListOps: link_ops::LinkOps {
33    /// Returns the "next" link pointer of `ptr`.
34    ///
35    /// # Safety
36    /// `prev` must have been previously passed to the [`set`] method, or
37    /// `prev` must be equal to the `new` argument previously passed to [`replace_next_or_prev`].
38    ///
39    /// An implementation of `next` must not panic.
40    ///
41    /// [`replace_next_or_prev`]: #tymethod.replace_next_or_prev
42    /// [`set`]: #tymethod.set
43    unsafe fn next(&self, ptr: Self::LinkPtr, prev: Option<Self::LinkPtr>)
44        -> Option<Self::LinkPtr>;
45
46    /// Returns the "prev" link pointer of `ptr`.
47    ///
48    /// # Safety
49    /// `next` must have been previously passed to the [`set`] method, or
50    /// `next` must be equal to the `new` argument previously passed to [`replace_next_or_prev`].
51    ///
52    /// An implementation of `prev` must not panic.
53    ///
54    /// [`replace_next_or_prev`]: #tymethod.replace_next_or_prev
55    /// [`set`]: #tymethod.set
56    unsafe fn prev(&self, ptr: Self::LinkPtr, next: Option<Self::LinkPtr>)
57        -> Option<Self::LinkPtr>;
58
59    /// Assigns the "prev" and "next" link pointers of `ptr`.
60    ///
61    /// # Safety
62    /// An implementation of `set` must not panic.
63    unsafe fn set(
64        &mut self,
65        ptr: Self::LinkPtr,
66        prev: Option<Self::LinkPtr>,
67        next: Option<Self::LinkPtr>,
68    );
69
70    /// Replaces the "next" or "prev" link pointer of `ptr`.
71    ///
72    /// # Safety
73    /// `old` must be equal to either the `next` or `prev` argument previously passed to the [`set`] method, or
74    /// `old` must be equal to the `new` argument previously passed to `replace_next_or_prev`.
75    ///
76    /// An implementation of `replace_next_or_prev` must not panic.
77    ///
78    /// [`set`]: #tymethod.set
79    unsafe fn replace_next_or_prev(
80        &mut self,
81        ptr: Self::LinkPtr,
82        old: Option<Self::LinkPtr>,
83        new: Option<Self::LinkPtr>,
84    );
85}
86
87// =============================================================================
88// Link
89// =============================================================================
90
91/// Intrusive link that allows an object to be inserted into a
92/// `XorLinkedList`.
93#[repr(align(2))]
94pub struct Link {
95    packed: Cell<usize>,
96}
97
98// Use a special value to indicate an unlinked node
99const UNLINKED_MARKER: usize = 1_usize;
100
101impl Link {
102    /// Creates a new `Link`.
103    #[inline]
104    pub const fn new() -> Link {
105        Link {
106            packed: Cell::new(UNLINKED_MARKER),
107        }
108    }
109
110    /// Checks whether the `Link` is linked into a `XorLinkedList`.
111    #[inline]
112    pub fn is_linked(&self) -> bool {
113        self.packed.get() != UNLINKED_MARKER
114    }
115
116    /// Forcibly unlinks an object from a `XorLinkedList`.
117    ///
118    /// # Safety
119    ///
120    /// It is undefined behavior to call this function while still linked into a
121    /// `XorLinkedList`. The only situation where this function is useful is
122    /// after calling `fast_clear` on a `XorLinkedList`, since this clears
123    /// the collection without marking the nodes as unlinked.
124    #[inline]
125    pub unsafe fn force_unlink(&self) {
126        self.packed.set(UNLINKED_MARKER);
127    }
128}
129
130impl DefaultLinkOps for Link {
131    type Ops = LinkOps;
132
133    const NEW: Self::Ops = LinkOps;
134}
135
136// An object containing a link can be sent to another thread if it is unlinked.
137unsafe impl Send for Link {}
138
139// Provide an implementation of Clone which simply initializes the new link as
140// unlinked. This allows structs containing a link to derive Clone.
141impl Clone for Link {
142    #[inline]
143    fn clone(&self) -> Link {
144        Link::new()
145    }
146}
147
148// Same as above
149impl Default for Link {
150    #[inline]
151    fn default() -> Link {
152        Link::new()
153    }
154}
155
156// Provide an implementation of Debug so that structs containing a link can
157// still derive Debug.
158impl fmt::Debug for Link {
159    #[inline]
160    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
161        // There isn't anything sensible to print here except whether the link
162        // is currently in a list.
163        if self.is_linked() {
164            write!(f, "linked")
165        } else {
166            write!(f, "unlinked")
167        }
168    }
169}
170
171// =============================================================================
172// LinkOps
173// =============================================================================
174
175/// Default `LinkOps` implementation for `XorLinkedList`.
176#[derive(Clone, Copy, Default)]
177pub struct LinkOps;
178
179unsafe impl link_ops::LinkOps for LinkOps {
180    type LinkPtr = NonNull<Link>;
181
182    #[inline]
183    unsafe fn acquire_link(&mut self, ptr: Self::LinkPtr) -> bool {
184        if ptr.as_ref().is_linked() {
185            false
186        } else {
187            ptr.as_ref().packed.set(0);
188            true
189        }
190    }
191
192    #[inline]
193    unsafe fn release_link(&mut self, ptr: Self::LinkPtr) {
194        ptr.as_ref().packed.set(UNLINKED_MARKER);
195    }
196}
197
198unsafe impl XorLinkedListOps for LinkOps {
199    #[inline]
200    unsafe fn next(
201        &self,
202        ptr: Self::LinkPtr,
203        prev: Option<Self::LinkPtr>,
204    ) -> Option<Self::LinkPtr> {
205        let raw = ptr.as_ref().packed.get() ^ prev.map(|x| x.as_ptr() as usize).unwrap_or(0);
206        NonNull::new(raw as *mut _)
207    }
208
209    #[inline]
210    unsafe fn prev(
211        &self,
212        ptr: Self::LinkPtr,
213        next: Option<Self::LinkPtr>,
214    ) -> Option<Self::LinkPtr> {
215        let raw = ptr.as_ref().packed.get() ^ next.map(|x| x.as_ptr() as usize).unwrap_or(0);
216        NonNull::new(raw as *mut _)
217    }
218
219    #[inline]
220    unsafe fn set(
221        &mut self,
222        ptr: Self::LinkPtr,
223        prev: Option<Self::LinkPtr>,
224        next: Option<Self::LinkPtr>,
225    ) {
226        let new_packed = prev.map(|x| x.as_ptr() as usize).unwrap_or(0)
227            ^ next.map(|x| x.as_ptr() as usize).unwrap_or(0);
228        ptr.as_ref().packed.set(new_packed);
229    }
230
231    #[inline]
232    unsafe fn replace_next_or_prev(
233        &mut self,
234        ptr: Self::LinkPtr,
235        old: Option<Self::LinkPtr>,
236        new: Option<Self::LinkPtr>,
237    ) {
238        let new_packed = ptr.as_ref().packed.get()
239            ^ old.map(|x| x.as_ptr() as usize).unwrap_or(0)
240            ^ new.map(|x| x.as_ptr() as usize).unwrap_or(0);
241
242        ptr.as_ref().packed.set(new_packed);
243    }
244}
245
246unsafe impl SinglyLinkedListOps for LinkOps {
247    #[inline]
248    unsafe fn next(&self, ptr: Self::LinkPtr) -> Option<Self::LinkPtr> {
249        let raw = ptr.as_ref().packed.get();
250        NonNull::new(raw as *mut _)
251    }
252
253    #[inline]
254    unsafe fn set_next(&mut self, ptr: Self::LinkPtr, next: Option<Self::LinkPtr>) {
255        ptr.as_ref()
256            .packed
257            .set(next.map(|x| x.as_ptr() as usize).unwrap_or(0));
258    }
259}
260
261// =============================================================================
262// AtomicLink
263// =============================================================================
264
265/// Intrusive link that allows an object to be inserted into a
266/// `XorLinkedList`. This link allows the structure to be shared between threads.
267#[repr(align(2))]
268pub struct AtomicLink {
269    packed: AtomicUsize,
270}
271
272impl AtomicLink {
273    /// Creates a new `Link`.
274    #[inline]
275    pub const fn new() -> AtomicLink {
276        AtomicLink {
277            packed: AtomicUsize::new(UNLINKED_MARKER),
278        }
279    }
280
281    /// Checks whether the `Link` is linked into a `XorLinkedList`.
282    #[inline]
283    pub fn is_linked(&self) -> bool {
284        self.packed.load(core::sync::atomic::Ordering::Relaxed) != UNLINKED_MARKER
285    }
286
287    /// Forcibly unlinks an object from a `XorLinkedList`.
288    ///
289    /// # Safety
290    ///
291    /// It is undefined behavior to call this function while still linked into a
292    /// `XorLinkedList`. The only situation where this function is useful is
293    /// after calling `fast_clear` on a `XorLinkedList`, since this clears
294    /// the collection without marking the nodes as unlinked.
295    #[inline]
296    pub unsafe fn force_unlink(&self) {
297        self.packed.store(UNLINKED_MARKER, Ordering::Release);
298    }
299
300    /// Access the `packed` pointer in an exclusive context.
301    ///
302    /// # Safety
303    ///
304    /// This can only be called after `acquire_link` has been succesfully called.
305    #[inline]
306    unsafe fn packed_exclusive(&self) -> &Cell<usize> {
307        // This is safe because currently AtomicUsize has the same representation Cell<usize>.
308        core::mem::transmute(&self.packed)
309    }
310}
311
312impl DefaultLinkOps for AtomicLink {
313    type Ops = AtomicLinkOps;
314
315    const NEW: Self::Ops = AtomicLinkOps;
316}
317
318// An object containing a link can be sent to another thread since `acquire_link` is atomic.
319unsafe impl Send for AtomicLink {}
320
321// An object containing a link can be shared between threads since `acquire_link` is atomic.
322unsafe impl Sync for AtomicLink {}
323
324impl Clone for AtomicLink {
325    #[inline]
326    fn clone(&self) -> AtomicLink {
327        AtomicLink::new()
328    }
329}
330
331impl Default for AtomicLink {
332    #[inline]
333    fn default() -> AtomicLink {
334        AtomicLink::new()
335    }
336}
337
338// Provide an implementation of Debug so that structs containing a link can
339// still derive Debug.
340impl fmt::Debug for AtomicLink {
341    #[inline]
342    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
343        // There isn't anything sensible to print here except whether the link
344        // is currently in a list.
345        if self.is_linked() {
346            write!(f, "linked")
347        } else {
348            write!(f, "unlinked")
349        }
350    }
351}
352
353// =============================================================================
354// AtomicLinkOps
355// =============================================================================
356
357/// Default `AtomicLinkOps` implementation for `LinkedList`.
358#[derive(Clone, Copy, Default)]
359pub struct AtomicLinkOps;
360
361const LINKED_DEFAULT_VALUE: usize = 0;
362
363unsafe impl link_ops::LinkOps for AtomicLinkOps {
364    type LinkPtr = NonNull<AtomicLink>;
365
366    #[inline]
367    unsafe fn acquire_link(&mut self, ptr: Self::LinkPtr) -> bool {
368        ptr.as_ref()
369            .packed
370            .compare_exchange(
371                UNLINKED_MARKER,
372                LINKED_DEFAULT_VALUE,
373                Ordering::Acquire,
374                Ordering::Relaxed,
375            )
376            .is_ok()
377    }
378
379    #[inline]
380    unsafe fn release_link(&mut self, ptr: Self::LinkPtr) {
381        ptr.as_ref()
382            .packed
383            .store(UNLINKED_MARKER, Ordering::Release)
384    }
385}
386
387unsafe impl XorLinkedListOps for AtomicLinkOps {
388    #[inline]
389    unsafe fn next(
390        &self,
391        ptr: Self::LinkPtr,
392        prev: Option<Self::LinkPtr>,
393    ) -> Option<Self::LinkPtr> {
394        let raw =
395            ptr.as_ref().packed_exclusive().get() ^ prev.map(|x| x.as_ptr() as usize).unwrap_or(0);
396        NonNull::new(raw as *mut _)
397    }
398
399    #[inline]
400    unsafe fn prev(
401        &self,
402        ptr: Self::LinkPtr,
403        next: Option<Self::LinkPtr>,
404    ) -> Option<Self::LinkPtr> {
405        let raw =
406            ptr.as_ref().packed_exclusive().get() ^ next.map(|x| x.as_ptr() as usize).unwrap_or(0);
407        NonNull::new(raw as *mut _)
408    }
409
410    #[inline]
411    unsafe fn set(
412        &mut self,
413        ptr: Self::LinkPtr,
414        prev: Option<Self::LinkPtr>,
415        next: Option<Self::LinkPtr>,
416    ) {
417        let new_packed = prev.map(|x| x.as_ptr() as usize).unwrap_or(0)
418            ^ next.map(|x| x.as_ptr() as usize).unwrap_or(0);
419        ptr.as_ref().packed_exclusive().set(new_packed);
420    }
421
422    #[inline]
423    unsafe fn replace_next_or_prev(
424        &mut self,
425        ptr: Self::LinkPtr,
426        old: Option<Self::LinkPtr>,
427        new: Option<Self::LinkPtr>,
428    ) {
429        let new_packed = ptr.as_ref().packed_exclusive().get()
430            ^ old.map(|x| x.as_ptr() as usize).unwrap_or(0)
431            ^ new.map(|x| x.as_ptr() as usize).unwrap_or(0);
432
433        ptr.as_ref().packed_exclusive().set(new_packed);
434    }
435}
436
437unsafe impl SinglyLinkedListOps for AtomicLinkOps {
438    #[inline]
439    unsafe fn next(&self, ptr: Self::LinkPtr) -> Option<Self::LinkPtr> {
440        let raw = ptr.as_ref().packed_exclusive().get();
441        NonNull::new(raw as *mut _)
442    }
443
444    #[inline]
445    unsafe fn set_next(&mut self, ptr: Self::LinkPtr, next: Option<Self::LinkPtr>) {
446        ptr.as_ref()
447            .packed_exclusive()
448            .set(next.map(|x| x.as_ptr() as usize).unwrap_or(0));
449    }
450}
451
452#[inline]
453unsafe fn link_between<T: XorLinkedListOps>(
454    link_ops: &mut T,
455    ptr: T::LinkPtr,
456    prev: Option<T::LinkPtr>,
457    next: Option<T::LinkPtr>,
458) {
459    if let Some(prev) = prev {
460        let prev_of_prev = link_ops.prev(prev, next);
461        link_ops.set(prev, prev_of_prev, Some(ptr));
462    }
463    if let Some(next) = next {
464        let next_of_next = link_ops.next(next, prev);
465        link_ops.set(next, Some(ptr), next_of_next);
466    }
467    link_ops.set(ptr, prev, next);
468}
469
470// =============================================================================
471// Cursor, CursorMut, CursorOwning
472// =============================================================================
473
474/// A cursor which provides read-only access to a `XorLinkedList`.
475pub struct Cursor<'a, A: Adapter>
476where
477    A::LinkOps: XorLinkedListOps,
478{
479    current: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
480    prev: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
481    next: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
482    list: &'a XorLinkedList<A>,
483}
484
485impl<'a, A: Adapter> Clone for Cursor<'a, A>
486where
487    A::LinkOps: XorLinkedListOps,
488{
489    #[inline]
490    fn clone(&self) -> Cursor<'a, A> {
491        Cursor {
492            current: self.current,
493            prev: self.prev,
494            next: self.next,
495            list: self.list,
496        }
497    }
498}
499
500impl<'a, A: Adapter> Cursor<'a, A>
501where
502    A::LinkOps: XorLinkedListOps,
503{
504    /// Checks if the cursor is currently pointing to the null object.
505    #[inline]
506    pub fn is_null(&self) -> bool {
507        self.current.is_none()
508    }
509
510    /// Returns a reference to the object that the cursor is currently
511    /// pointing to.
512    ///
513    /// This returns `None` if the cursor is currently pointing to the null
514    /// object.
515    #[inline]
516    pub fn get(&self) -> Option<&'a <A::PointerOps as PointerOps>::Value> {
517        Some(unsafe { &*self.list.adapter.get_value(self.current?) })
518    }
519
520    /// Clones and returns the pointer that points to the element that the
521    /// cursor is referencing.
522    ///
523    /// This returns `None` if the cursor is currently pointing to the null
524    /// object.
525    #[inline]
526    pub fn clone_pointer(&self) -> Option<<A::PointerOps as PointerOps>::Pointer>
527    where
528        <A::PointerOps as PointerOps>::Pointer: Clone,
529    {
530        let raw_pointer = unsafe { self.list.adapter.get_value(self.current?) };
531        Some(unsafe {
532            crate::pointer_ops::clone_pointer_from_raw(self.list.adapter.pointer_ops(), raw_pointer)
533        })
534    }
535
536    /// Moves the cursor to the next element of the `XorLinkedList`.
537    ///
538    /// If the cursor is pointer to the null object then this will move it to
539    /// the first element of the `XorLinkedList`. If it is pointing to the
540    /// last element of the `XorLinkedList` then this will move it to the
541    /// null object.
542    #[inline]
543    pub fn move_next(&mut self) {
544        let prev = self.current;
545        self.current = self.next;
546        unsafe {
547            if let Some(current) = self.current {
548                self.prev = prev;
549                self.next = self.list.adapter.link_ops().next(current, prev);
550            } else {
551                self.prev = self.list.tail;
552                self.next = self.list.head;
553            }
554        }
555    }
556
557    /// Moves the cursor to the previous element of the `XorLinkedList`.
558    ///
559    /// If the cursor is pointer to the null object then this will move it to
560    /// the last element of the `XorLinkedList`. If it is pointing to the first
561    /// element of the `XorLinkedList` then this will move it to the null object.
562    #[inline]
563    pub fn move_prev(&mut self) {
564        let next = self.current;
565        self.current = self.prev;
566        unsafe {
567            if let Some(current) = self.current {
568                self.prev = self.list.adapter.link_ops().prev(current, next);
569                self.next = next;
570            } else {
571                self.prev = self.list.tail;
572                self.next = self.list.head;
573            }
574        }
575    }
576
577    /// Returns a cursor pointing to the next element of the `XorLinkedList`.
578    ///
579    /// If the cursor is pointer to the null object then this will return the
580    /// first element of the `XorLinkedList`. If it is pointing to the last
581    /// element of the `XorLinkedList` then this will return a null cursor.
582    #[inline]
583    pub fn peek_next(&self) -> Cursor<'_, A> {
584        let mut next = self.clone();
585        next.move_next();
586        next
587    }
588
589    /// Returns a cursor pointing to the previous element of the `XorLinkedList`.
590    ///
591    /// If the cursor is pointer to the null object then this will return the
592    /// last element of the `XorLinkedList`. If it is pointing to the first
593    /// element of the `XorLinkedList` then this will return a null cursor.
594    #[inline]
595    pub fn peek_prev(&self) -> Cursor<'_, A> {
596        let mut prev = self.clone();
597        prev.move_prev();
598        prev
599    }
600}
601
602/// A cursor which provides mutable access to a `XorLinkedList`.
603pub struct CursorMut<'a, A: Adapter>
604where
605    A::LinkOps: XorLinkedListOps,
606{
607    current: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
608    prev: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
609    next: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
610    list: &'a mut XorLinkedList<A>,
611}
612
613impl<'a, A: Adapter> CursorMut<'a, A>
614where
615    A::LinkOps: XorLinkedListOps,
616{
617    /// Checks if the cursor is currently pointing to the null object.
618    #[inline]
619    pub fn is_null(&self) -> bool {
620        self.current.is_none()
621    }
622
623    /// Returns a reference to the object that the cursor is currently
624    /// pointing to.
625    ///
626    /// This returns None if the cursor is currently pointing to the null
627    /// object.
628    #[inline]
629    pub fn get(&self) -> Option<&<A::PointerOps as PointerOps>::Value> {
630        Some(unsafe { &*self.list.adapter.get_value(self.current?) })
631    }
632
633    /// Returns a read-only cursor pointing to the current element.
634    ///
635    /// The lifetime of the returned `Cursor` is bound to that of the
636    /// `CursorMut`, which means it cannot outlive the `CursorMut` and that the
637    /// `CursorMut` is frozen for the lifetime of the `Cursor`.
638    #[inline]
639    pub fn as_cursor(&self) -> Cursor<'_, A> {
640        Cursor {
641            current: self.current,
642            prev: self.prev,
643            next: self.next,
644            list: self.list,
645        }
646    }
647
648    /// Moves the cursor to the next element of the `XorLinkedList`.
649    ///
650    /// If the cursor is pointer to the null object then this will move it to
651    /// the first element of the `XorLinkedList`. If it is pointing to the
652    /// last element of the `XorLinkedList` then this will move it to the
653    /// null object.
654    #[inline]
655    pub fn move_next(&mut self) {
656        let prev = self.current;
657        self.current = self.next;
658        unsafe {
659            if let Some(current) = self.current {
660                self.prev = prev;
661                self.next = self.list.adapter.link_ops().next(current, prev);
662            } else {
663                self.prev = self.list.tail;
664                self.next = self.list.head;
665            }
666        }
667    }
668
669    /// Moves the cursor to the previous element of the `XorLinkedList`.
670    ///
671    /// If the cursor is pointer to the null object then this will move it to
672    /// the last element of the `XorLinkedList`. If it is pointing to the first
673    /// element of the `XorLinkedList` then this will move it to the null object.
674    #[inline]
675    pub fn move_prev(&mut self) {
676        let next = self.current;
677        self.current = self.prev;
678        unsafe {
679            if let Some(current) = self.current {
680                self.prev = self.list.adapter.link_ops().prev(current, next);
681                self.next = next;
682            } else {
683                self.prev = self.list.tail;
684                self.next = self.list.head;
685            }
686        }
687    }
688
689    /// Returns a cursor pointing to the next element of the `XorLinkedList`.
690    ///
691    /// If the cursor is pointer to the null object then this will return the
692    /// first element of the `XorLinkedList`. If it is pointing to the last
693    /// element of the `XorLinkedList` then this will return a null cursor.
694    #[inline]
695    pub fn peek_next(&self) -> Cursor<'_, A> {
696        let mut next = self.as_cursor();
697        next.move_next();
698        next
699    }
700
701    /// Returns a cursor pointing to the previous element of the `XorLinkedList`.
702    ///
703    /// If the cursor is pointer to the null object then this will return the
704    /// last element of the `XorLinkedList`. If it is pointing to the first
705    /// element of the `XorLinkedList` then this will return a null cursor.
706    #[inline]
707    pub fn peek_prev(&self) -> Cursor<'_, A> {
708        let mut prev = self.as_cursor();
709        prev.move_prev();
710        prev
711    }
712
713    /// Removes the current element from the `XorLinkedList`.
714    ///
715    /// A pointer to the element that was removed is returned, and the cursor is
716    /// moved to point to the next element in the `XorLinkedList`.
717    ///
718    /// If the cursor is currently pointing to the null object then no element
719    /// is removed and `None` is returned.
720    #[inline]
721    pub fn remove(&mut self) -> Option<<A::PointerOps as PointerOps>::Pointer> {
722        use link_ops::LinkOps;
723
724        unsafe {
725            let current = self.current?;
726            let result = current;
727
728            self.list.adapter.link_ops_mut().release_link(current);
729            if let Some(prev) = self.prev {
730                self.list.adapter.link_ops_mut().replace_next_or_prev(
731                    prev,
732                    Some(current),
733                    self.next,
734                );
735            }
736            if let Some(next) = self.next {
737                self.list.adapter.link_ops_mut().replace_next_or_prev(
738                    next,
739                    Some(current),
740                    self.prev,
741                );
742            }
743            if self.list.head == Some(current) {
744                self.list.head = self.next;
745            }
746            if self.list.tail == Some(current) {
747                self.list.tail = self.prev;
748            }
749            self.current = self.next;
750            if let Some(current) = self.current {
751                self.next = self.list.adapter.link_ops().next(current, self.prev);
752            } else {
753                self.prev = self.list.tail;
754                self.next = self.list.head;
755            }
756
757            Some(
758                self.list
759                    .adapter
760                    .pointer_ops()
761                    .from_raw(self.list.adapter.get_value(result)),
762            )
763        }
764    }
765
766    /// Removes the current element from the `XorLinkedList` and inserts another
767    /// object in its place.
768    ///
769    /// A pointer to the element that was removed is returned, and the cursor is
770    /// modified to point to the newly added element.
771    ///
772    /// If the cursor is currently pointing to the null object then an error is
773    /// returned containing the given `val` parameter.
774    ///
775    /// # Panics
776    ///
777    /// Panics if the new element is already linked to a different intrusive
778    /// collection.
779    #[inline]
780    pub fn replace_with(
781        &mut self,
782        val: <A::PointerOps as PointerOps>::Pointer,
783    ) -> Result<<A::PointerOps as PointerOps>::Pointer, <A::PointerOps as PointerOps>::Pointer>
784    {
785        use link_ops::LinkOps;
786
787        unsafe {
788            if let Some(current) = self.current {
789                let new = self.list.node_from_value(val);
790                let result = current;
791
792                if self.list.head == Some(current) {
793                    self.list.head = Some(new);
794                }
795                if self.list.tail == Some(current) {
796                    self.list.tail = Some(new);
797                }
798
799                if let Some(prev) = self.prev {
800                    self.list.adapter.link_ops_mut().replace_next_or_prev(
801                        prev,
802                        Some(current),
803                        Some(new),
804                    );
805                }
806                if let Some(next) = self.next {
807                    self.list.adapter.link_ops_mut().replace_next_or_prev(
808                        next,
809                        Some(current),
810                        Some(new),
811                    );
812                }
813
814                self.list
815                    .adapter
816                    .link_ops_mut()
817                    .set(new, self.prev, self.next);
818                self.list.adapter.link_ops_mut().release_link(result);
819                self.current = Some(new);
820
821                Ok(self
822                    .list
823                    .adapter
824                    .pointer_ops()
825                    .from_raw(self.list.adapter.get_value(result)))
826            } else {
827                Err(val)
828            }
829        }
830    }
831
832    /// Inserts a new element into the `XorLinkedList` after the current one.
833    ///
834    /// If the cursor is pointing at the null object then the new element is
835    /// inserted at the front of the `XorLinkedList`.
836    ///
837    /// # Panics
838    ///
839    /// Panics if the new element is already linked to a different intrusive
840    /// collection.
841    #[inline]
842    pub fn insert_after(&mut self, val: <A::PointerOps as PointerOps>::Pointer) {
843        unsafe {
844            let new = self.list.node_from_value(val);
845            if let Some(current) = self.current {
846                link_between(
847                    self.list.adapter.link_ops_mut(),
848                    new,
849                    Some(current),
850                    self.next,
851                );
852                if self.next.is_none() {
853                    // Current pointer was tail
854                    self.list.tail = Some(new);
855                }
856                self.next = Some(new);
857            } else {
858                link_between(self.list.adapter.link_ops_mut(), new, None, self.list.head);
859                self.list.head = Some(new);
860                if self.list.tail.is_none() {
861                    self.list.tail = Some(new);
862                }
863                self.prev = self.list.tail;
864                self.next = self.list.head;
865            }
866        }
867    }
868
869    /// Inserts a new element into the `XorLinkedList` before the current one.
870    ///
871    /// If the cursor is pointing at the null object then the new element is
872    /// inserted at the end of the `XorLinkedList`.
873    ///
874    /// # Panics
875    ///
876    /// Panics if the new element is already linked to a different intrusive
877    /// collection.
878    #[inline]
879    pub fn insert_before(&mut self, val: <A::PointerOps as PointerOps>::Pointer) {
880        unsafe {
881            let new = self.list.node_from_value(val);
882            if let Some(current) = self.current {
883                link_between(
884                    self.list.adapter.link_ops_mut(),
885                    new,
886                    self.prev,
887                    Some(current),
888                );
889                if self.prev.is_none() {
890                    // Current pointer was tail
891                    self.list.head = Some(new);
892                }
893                self.prev = Some(new);
894            } else {
895                link_between(self.list.adapter.link_ops_mut(), new, self.list.tail, None);
896                self.list.tail = Some(new);
897                if self.list.head.is_none() {
898                    self.list.head = Some(new);
899                }
900                self.prev = self.list.tail;
901                self.next = self.list.head;
902            }
903        }
904    }
905
906    /// Inserts the elements from the given `XorLinkedList` after the current one.
907    ///
908    /// If the cursor is pointing at the null object then the new elements are
909    /// inserted at the start of the `XorLinkedList`.
910    #[inline]
911    pub fn splice_after(&mut self, mut list: XorLinkedList<A>) {
912        if !list.is_empty() {
913            unsafe {
914                let head = list.head.unwrap_unchecked();
915                let tail = list.tail.unwrap_unchecked();
916
917                let link_ops = self.list.adapter.link_ops_mut();
918
919                if let Some(current) = self.current {
920                    if let Some(next) = self.next {
921                        link_ops.replace_next_or_prev(next, Some(current), Some(tail));
922                        link_ops.replace_next_or_prev(tail, None, Some(next));
923                    }
924                    link_ops.replace_next_or_prev(head, None, Some(current));
925                    self.next = list.head;
926                    link_ops.set(current, self.prev, self.next);
927                } else {
928                    if let Some(x) = self.list.head {
929                        link_ops.replace_next_or_prev(tail, None, Some(x));
930                        link_ops.replace_next_or_prev(x, None, Some(tail));
931                    }
932                    self.list.head = list.head;
933                    self.next = list.head;
934                }
935                if self.list.tail == self.current {
936                    self.list.tail = list.tail;
937                }
938                list.head = None;
939                list.tail = None;
940            }
941        }
942    }
943
944    /// Moves all element from the given `XorLinkedList` before the current one.
945    ///
946    /// If the cursor is pointing at the null object then the new elements are
947    /// inserted at the end of the `XorLinkedList`.
948    #[inline]
949    pub fn splice_before(&mut self, mut list: XorLinkedList<A>) {
950        if !list.is_empty() {
951            unsafe {
952                let head = list.head.unwrap_unchecked();
953                let tail = list.tail.unwrap_unchecked();
954
955                let link_ops = self.list.adapter.link_ops_mut();
956
957                if let Some(current) = self.current {
958                    if let Some(prev) = self.prev {
959                        link_ops.replace_next_or_prev(prev, Some(current), Some(head));
960                        link_ops.replace_next_or_prev(head, None, Some(prev));
961                    }
962                    link_ops.replace_next_or_prev(tail, None, Some(current));
963                    self.prev = list.tail;
964                    link_ops.set(current, self.prev, self.next);
965                } else {
966                    if let Some(x) = self.list.tail {
967                        link_ops.replace_next_or_prev(head, None, Some(x));
968                        link_ops.replace_next_or_prev(x, None, Some(head));
969                    }
970                    self.list.head = list.head;
971                    self.next = list.head;
972                }
973                if self.list.tail == self.current {
974                    self.list.tail = list.tail;
975                }
976                list.head = None;
977                list.tail = None;
978            }
979        }
980    }
981
982    /// Splits the list into two after the current element. This will return a
983    /// new list consisting of everything after the cursor, with the original
984    /// list retaining everything before.
985    ///
986    /// If the cursor is pointing at the null object then the entire contents
987    /// of the `XorLinkedList` are moved.
988    #[inline]
989    pub fn split_after(&mut self) -> XorLinkedList<A>
990    where
991        A: Clone,
992    {
993        if let Some(current) = self.current {
994            unsafe {
995                let mut list = XorLinkedList {
996                    head: self.next,
997                    tail: self.list.tail,
998                    adapter: self.list.adapter.clone(),
999                };
1000                if let Some(head) = list.head {
1001                    self.list.adapter.link_ops_mut().replace_next_or_prev(
1002                        head,
1003                        Some(current),
1004                        None,
1005                    );
1006                    self.next = None;
1007                } else {
1008                    list.tail = None;
1009                }
1010                self.list
1011                    .adapter
1012                    .link_ops_mut()
1013                    .set(current, self.prev, None);
1014                self.list.tail = self.current;
1015                list
1016            }
1017        } else {
1018            let list = XorLinkedList {
1019                head: self.list.head,
1020                tail: self.list.tail,
1021                adapter: self.list.adapter.clone(),
1022            };
1023            self.list.head = None;
1024            self.list.tail = None;
1025            list
1026        }
1027    }
1028
1029    /// Splits the list into two before the current element. This will return a
1030    /// new list consisting of everything before the cursor, with the original
1031    /// list retaining everything after.
1032    ///
1033    /// If the cursor is pointing at the null object then the entire contents
1034    /// of the `XorLinkedList` are moved.
1035    #[inline]
1036    pub fn split_before(&mut self) -> XorLinkedList<A>
1037    where
1038        A: Clone,
1039    {
1040        if let Some(current) = self.current {
1041            unsafe {
1042                let mut list = XorLinkedList {
1043                    head: self.list.head,
1044                    tail: self.prev,
1045                    adapter: self.list.adapter.clone(),
1046                };
1047                if let Some(tail) = list.tail {
1048                    self.list.adapter.link_ops_mut().replace_next_or_prev(
1049                        tail,
1050                        Some(current),
1051                        None,
1052                    );
1053                    self.prev = None;
1054                } else {
1055                    list.head = None;
1056                }
1057                self.list
1058                    .adapter
1059                    .link_ops_mut()
1060                    .set(current, None, self.next);
1061                self.list.head = self.current;
1062                list
1063            }
1064        } else {
1065            let list = XorLinkedList {
1066                head: self.list.head,
1067                tail: self.list.tail,
1068                adapter: self.list.adapter.clone(),
1069            };
1070            self.list.head = None;
1071            self.list.tail = None;
1072            list
1073        }
1074    }
1075
1076    /// Consumes `CursorMut` and returns a reference to the object that
1077    /// the cursor is currently pointing to. Unlike [get](Self::get),
1078    /// the returned reference's lifetime is tied to `XorLinkedList`'s lifetime.
1079    ///
1080    /// This returns None if the cursor is currently pointing to the null object.
1081    #[inline]
1082    pub fn into_ref(self) -> Option<&'a <A::PointerOps as PointerOps>::Value> {
1083        Some(unsafe { &*self.list.adapter.get_value(self.current?) })
1084    }
1085}
1086
1087/// A cursor with ownership over the `XorLinkedList` it points into.
1088pub struct CursorOwning<A: Adapter>
1089where
1090    A::LinkOps: XorLinkedListOps,
1091{
1092    current: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
1093    prev: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
1094    next: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
1095    list: XorLinkedList<A>,
1096}
1097
1098impl<A: Adapter> CursorOwning<A>
1099where
1100    A::LinkOps: XorLinkedListOps,
1101{
1102    /// Consumes self and returns the inner `XorLinkedList`.
1103    #[inline]
1104    pub fn into_inner(self) -> XorLinkedList<A> {
1105        self.list
1106    }
1107
1108    /// Returns a read-only cursor pointing to the current element.
1109    ///
1110    /// The lifetime of the returned `Cursor` is bound to that of the
1111    /// `CursorOwning`, which means it cannot outlive the `CursorOwning` and that the
1112    /// `CursorOwning` is frozen for the lifetime of the `Cursor`.
1113    ///
1114    /// Mutations of the returned cursor are _not_ reflected in the original.
1115    #[inline]
1116    pub fn as_cursor(&self) -> Cursor<'_, A> {
1117        Cursor {
1118            current: self.current,
1119            prev: self.prev,
1120            next: self.next,
1121            list: &self.list,
1122        }
1123    }
1124
1125    /// Perform action with mutable reference to the cursor.
1126    ///
1127    /// All mutations of the cursor are reflected in the original.
1128    #[inline]
1129    pub fn with_cursor_mut<T>(&mut self, f: impl FnOnce(&mut CursorMut<'_, A>) -> T) -> T {
1130        let mut cursor = CursorMut {
1131            current: self.current,
1132            prev: self.prev,
1133            next: self.next,
1134            list: &mut self.list,
1135        };
1136
1137        let ret = f(&mut cursor);
1138
1139        self.current = cursor.current;
1140        self.prev = cursor.prev;
1141        self.next = cursor.next;
1142
1143        ret
1144    }
1145}
1146unsafe impl<A: Adapter> Send for CursorOwning<A>
1147where
1148    XorLinkedList<A>: Send,
1149    A::LinkOps: XorLinkedListOps,
1150{
1151}
1152
1153// =============================================================================
1154// XorLinkedList
1155// =============================================================================
1156
1157/// Intrusive xor doubly-linked list which uses less memory than a regular doubly linked list
1158///
1159/// In exchange for less memory use, it is impossible to create a cursor from a pointer to
1160/// an element.
1161///
1162/// When this collection is dropped, all elements linked into it will be
1163/// converted back to owned pointers and dropped.
1164pub struct XorLinkedList<A: Adapter>
1165where
1166    A::LinkOps: XorLinkedListOps,
1167{
1168    head: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
1169    tail: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
1170    adapter: A,
1171}
1172
1173impl<A: Adapter> XorLinkedList<A>
1174where
1175    A::LinkOps: XorLinkedListOps,
1176{
1177    #[inline]
1178    fn node_from_value(
1179        &mut self,
1180        val: <A::PointerOps as PointerOps>::Pointer,
1181    ) -> <A::LinkOps as link_ops::LinkOps>::LinkPtr {
1182        use link_ops::LinkOps;
1183
1184        unsafe {
1185            let raw = self.adapter.pointer_ops().into_raw(val);
1186            let link = self.adapter.get_link(raw);
1187
1188            if !self.adapter.link_ops_mut().acquire_link(link) {
1189                // convert the node back into a pointer
1190                self.adapter.pointer_ops().from_raw(raw);
1191
1192                panic!("attempted to insert an object that is already linked");
1193            }
1194
1195            link
1196        }
1197    }
1198
1199    /// Creates an empty `XorLinkedList`.
1200    #[cfg(not(feature = "nightly"))]
1201    #[inline]
1202    pub fn new(adapter: A) -> XorLinkedList<A> {
1203        XorLinkedList {
1204            head: None,
1205            tail: None,
1206            adapter,
1207        }
1208    }
1209
1210    /// Creates an empty `XorLinkedList`.
1211    #[cfg(feature = "nightly")]
1212    #[inline]
1213    pub const fn new(adapter: A) -> XorLinkedList<A> {
1214        XorLinkedList {
1215            head: None,
1216            tail: None,
1217            adapter,
1218        }
1219    }
1220
1221    /// Returns `true` if the `XorLinkedList` is empty.
1222    #[inline]
1223    pub fn is_empty(&self) -> bool {
1224        self.head.is_none()
1225    }
1226
1227    /// Returns a null `Cursor` for this list.
1228    #[inline]
1229    pub fn cursor(&self) -> Cursor<'_, A> {
1230        Cursor {
1231            current: None,
1232            prev: self.tail,
1233            next: self.head,
1234            list: self,
1235        }
1236    }
1237
1238    /// Returns a null `CursorMut` for this list.
1239    #[inline]
1240    pub fn cursor_mut(&mut self) -> CursorMut<'_, A> {
1241        CursorMut {
1242            current: None,
1243            prev: self.tail,
1244            next: self.head,
1245            list: self,
1246        }
1247    }
1248
1249    /// Returns a null `CursorOwning` for this list.
1250    #[inline]
1251    pub fn cursor_owning(self) -> CursorOwning<A> {
1252        CursorOwning {
1253            current: None,
1254            prev: self.tail,
1255            next: self.head,
1256            list: self,
1257        }
1258    }
1259
1260    /// Creates a `Cursor` from a pointer to an element and a pointer to the previous element.
1261    ///
1262    /// # Safety
1263    ///
1264    /// `ptr` must be a pointer to an object that is part of this list.
1265    /// `prev` must be a pointer to an object that is the previous object in this list (null for the head)
1266    #[inline]
1267    pub unsafe fn cursor_from_ptr_and_prev(
1268        &self,
1269        ptr: *const <A::PointerOps as PointerOps>::Value,
1270        prev: *const <A::PointerOps as PointerOps>::Value,
1271    ) -> Cursor<'_, A> {
1272        let current = self.adapter.get_link(ptr);
1273        let prev = if !prev.is_null() {
1274            Some(self.adapter.get_link(prev))
1275        } else {
1276            None
1277        };
1278        let next = self.adapter.link_ops().next(current, prev);
1279
1280        Cursor {
1281            current: Some(current),
1282            prev,
1283            next,
1284            list: self,
1285        }
1286    }
1287
1288    /// Creates a `CursorMut` from a pointer to an element and a pointer to the previous element.
1289    ///
1290    /// # Safety
1291    ///
1292    /// `ptr` must be a pointer to an object that is part of this list.
1293    /// `prev` must be a pointer to an object that is the previous object in this list (null for the head)
1294    #[inline]
1295    pub unsafe fn cursor_mut_from_ptr_and_prev(
1296        &mut self,
1297        ptr: *const <A::PointerOps as PointerOps>::Value,
1298        prev: *const <A::PointerOps as PointerOps>::Value,
1299    ) -> CursorMut<'_, A> {
1300        let current = self.adapter.get_link(ptr);
1301        let prev = if !prev.is_null() {
1302            Some(self.adapter.get_link(prev))
1303        } else {
1304            None
1305        };
1306        let next = self.adapter.link_ops().next(current, prev);
1307
1308        CursorMut {
1309            current: Some(current),
1310            prev,
1311            next,
1312            list: self,
1313        }
1314    }
1315
1316    /// Creates a `CursorOwning` from a pointer to an element and a pointer to the previous element.
1317    ///
1318    /// # Safety
1319    ///
1320    /// `ptr` must be a pointer to an object that is part of this list.
1321    /// `prev` must be a pointer to an object that is the previous object in this list (null for the head)
1322    #[inline]
1323    pub unsafe fn cursor_owning_from_ptr_and_prev(
1324        self,
1325        ptr: *const <A::PointerOps as PointerOps>::Value,
1326        prev: *const <A::PointerOps as PointerOps>::Value,
1327    ) -> CursorOwning<A> {
1328        let current = self.adapter.get_link(ptr);
1329        let prev = if !prev.is_null() {
1330            Some(self.adapter.get_link(prev))
1331        } else {
1332            None
1333        };
1334        let next = self.adapter.link_ops().next(current, prev);
1335
1336        CursorOwning {
1337            current: Some(current),
1338            prev,
1339            next,
1340            list: self,
1341        }
1342    }
1343
1344    /// Creates a `Cursor` from a pointer to an element and a pointer to the next element.
1345    ///
1346    /// # Safety
1347    ///
1348    /// `ptr` must be a pointer to an object that is part of this list.
1349    /// `next` must be a pointer to an object that is the next object in this list (null for the tail)
1350    #[inline]
1351    pub unsafe fn cursor_from_ptr_and_next(
1352        &self,
1353        ptr: *const <A::PointerOps as PointerOps>::Value,
1354        next: *const <A::PointerOps as PointerOps>::Value,
1355    ) -> Cursor<'_, A> {
1356        let current = self.adapter.get_link(ptr);
1357        let next = if !next.is_null() {
1358            Some(self.adapter.get_link(next))
1359        } else {
1360            None
1361        };
1362        let prev = self.adapter.link_ops().prev(current, next);
1363
1364        Cursor {
1365            current: Some(current),
1366            prev,
1367            next,
1368            list: self,
1369        }
1370    }
1371
1372    /// Creates a `CursorMut` from a pointer to an element and a pointer to the next element.
1373    ///
1374    /// # Safety
1375    ///
1376    /// `ptr` must be a pointer to an object that is part of this list.
1377    /// `next` must be a pointer to an object that is the next object in this list (null for the tail)
1378    #[inline]
1379    pub unsafe fn cursor_mut_from_ptr_and_next(
1380        &mut self,
1381        ptr: *const <A::PointerOps as PointerOps>::Value,
1382        next: *const <A::PointerOps as PointerOps>::Value,
1383    ) -> CursorMut<'_, A> {
1384        let current = self.adapter.get_link(ptr);
1385        let next = if !next.is_null() {
1386            Some(self.adapter.get_link(next))
1387        } else {
1388            None
1389        };
1390        let prev = self.adapter.link_ops().prev(current, next);
1391
1392        CursorMut {
1393            current: Some(current),
1394            prev,
1395            next,
1396            list: self,
1397        }
1398    }
1399
1400    /// Creates a `CursorOwning` from a pointer to an element and a pointer to the next element.
1401    ///
1402    /// # Safety
1403    ///
1404    /// `ptr` must be a pointer to an object that is part of this list.
1405    /// `next` must be a pointer to an object that is the next object in this list (null for the tail)
1406    #[inline]
1407    pub unsafe fn cursor_owning_from_ptr_and_next(
1408        self,
1409        ptr: *const <A::PointerOps as PointerOps>::Value,
1410        next: *const <A::PointerOps as PointerOps>::Value,
1411    ) -> CursorOwning<A> {
1412        let current = self.adapter.get_link(ptr);
1413        let next = if !next.is_null() {
1414            Some(self.adapter.get_link(next))
1415        } else {
1416            None
1417        };
1418        let prev = self.adapter.link_ops().prev(current, next);
1419
1420        CursorOwning {
1421            current: Some(current),
1422            prev,
1423            next,
1424            list: self,
1425        }
1426    }
1427
1428    /// Returns a `Cursor` pointing to the first element of the list. If the
1429    /// list is empty then a null cursor is returned.
1430    #[inline]
1431    pub fn front(&self) -> Cursor<'_, A> {
1432        let mut cursor = self.cursor();
1433        cursor.move_next();
1434        cursor
1435    }
1436
1437    /// Returns a `CursorMut` pointing to the first element of the list. If the
1438    /// the list is empty then a null cursor is returned.
1439    #[inline]
1440    pub fn front_mut(&mut self) -> CursorMut<'_, A> {
1441        let mut cursor = self.cursor_mut();
1442        cursor.move_next();
1443        cursor
1444    }
1445
1446    /// Returns a `CursorOwning` pointing to the first element of the list. If the
1447    /// the list is empty then a null cursor is returned.
1448    #[inline]
1449    pub fn front_owning(self) -> CursorOwning<A> {
1450        let mut cursor = self.cursor_owning();
1451        cursor.with_cursor_mut(|c| c.move_next());
1452        cursor
1453    }
1454
1455    /// Returns a `Cursor` pointing to the last element of the list. If the list
1456    /// is empty then a null cursor is returned.
1457    #[inline]
1458    pub fn back(&self) -> Cursor<'_, A> {
1459        let mut cursor = self.cursor();
1460        cursor.move_prev();
1461        cursor
1462    }
1463
1464    /// Returns a `CursorMut` pointing to the last element of the list. If the
1465    /// list is empty then a null cursor is returned.
1466    #[inline]
1467    pub fn back_mut(&mut self) -> CursorMut<'_, A> {
1468        let mut cursor = self.cursor_mut();
1469        cursor.move_prev();
1470        cursor
1471    }
1472
1473    /// Returns a `CursorOwning` pointing to the last element of the list. If the
1474    /// list is empty then a null cursor is returned.
1475    #[inline]
1476    pub fn back_owning(self) -> CursorOwning<A> {
1477        let mut cursor = self.cursor_owning();
1478        cursor.with_cursor_mut(|c| c.move_prev());
1479        cursor
1480    }
1481
1482    /// Gets an iterator over the objects in the `XorLinkedList`.
1483    #[inline]
1484    pub fn iter(&self) -> Iter<'_, A> {
1485        Iter {
1486            prev_head: None,
1487            head: self.head,
1488            tail: self.tail,
1489            next_tail: None,
1490            list: self,
1491        }
1492    }
1493
1494    /// Removes all elements from the `XorLinkedList`.
1495    ///
1496    /// This will unlink all object currently in the list, which requires
1497    /// iterating through all elements in the `XorLinkedList`. Each element is
1498    /// converted back to an owned pointer and then dropped.
1499    #[inline]
1500    pub fn clear(&mut self) {
1501        use link_ops::LinkOps;
1502
1503        let mut current = self.head;
1504        let mut prev = None;
1505        self.head = None;
1506        self.tail = None;
1507        while let Some(x) = current {
1508            unsafe {
1509                let next = self.adapter.link_ops().next(x, prev);
1510                self.adapter.link_ops_mut().release_link(x);
1511                self.adapter
1512                    .pointer_ops()
1513                    .from_raw(self.adapter.get_value(x));
1514                prev = current;
1515                current = next;
1516            }
1517        }
1518    }
1519
1520    /// Empties the `XorLinkedList` without unlinking or freeing objects in it.
1521    ///
1522    /// Since this does not unlink any objects, any attempts to link these
1523    /// objects into another `XorLinkedList` will fail but will not cause any
1524    /// memory unsafety. To unlink those objects manually, you must call the
1525    /// `force_unlink` function on them.
1526    #[inline]
1527    pub fn fast_clear(&mut self) {
1528        self.head = None;
1529        self.tail = None;
1530    }
1531
1532    /// Takes all the elements out of the `XorLinkedList`, leaving it empty.
1533    /// The taken elements are returned as a new `XorLinkedList`.
1534    #[inline]
1535    pub fn take(&mut self) -> XorLinkedList<A>
1536    where
1537        A: Clone,
1538    {
1539        let list = XorLinkedList {
1540            head: self.head,
1541            tail: self.tail,
1542            adapter: self.adapter.clone(),
1543        };
1544        self.head = None;
1545        self.tail = None;
1546        list
1547    }
1548
1549    /// Inserts a new element at the start of the `XorLinkedList`.
1550    #[inline]
1551    pub fn push_front(&mut self, val: <A::PointerOps as PointerOps>::Pointer) {
1552        self.cursor_mut().insert_after(val);
1553    }
1554
1555    /// Inserts a new element at the end of the `XorLinkedList`.
1556    #[inline]
1557    pub fn push_back(&mut self, val: <A::PointerOps as PointerOps>::Pointer) {
1558        self.cursor_mut().insert_before(val);
1559    }
1560
1561    /// Removes the first element of the `XorLinkedList`.
1562    ///
1563    /// This returns `None` if the `XorLinkedList` is empty.
1564    #[inline]
1565    pub fn pop_front(&mut self) -> Option<<A::PointerOps as PointerOps>::Pointer> {
1566        self.front_mut().remove()
1567    }
1568
1569    /// Removes the last element of the `XorLinkedList`.
1570    ///
1571    /// This returns `None` if the `XorLinkedList` is empty.
1572    #[inline]
1573    pub fn pop_back(&mut self) -> Option<<A::PointerOps as PointerOps>::Pointer> {
1574        self.back_mut().remove()
1575    }
1576
1577    /// Reverses the list in-place.
1578    ///
1579    /// Due to the structure of `XorLinkedList`, this operation is O(1).
1580    #[inline]
1581    pub fn reverse(&mut self) {
1582        core::mem::swap(&mut self.head, &mut self.tail);
1583    }
1584}
1585
1586// Allow read-only access to values from multiple threads
1587unsafe impl<A: Adapter + Sync> Sync for XorLinkedList<A>
1588where
1589    <A::PointerOps as PointerOps>::Value: Sync,
1590    A::LinkOps: XorLinkedListOps,
1591{
1592}
1593
1594// Allow sending to another thread if the ownership (represented by the <A::PointerOps as PointerOps>::Pointer owned
1595// pointer type) can be transferred to another thread.
1596unsafe impl<A: Adapter + Send> Send for XorLinkedList<A>
1597where
1598    <A::PointerOps as PointerOps>::Pointer: Send,
1599    A::LinkOps: XorLinkedListOps,
1600{
1601}
1602
1603// Drop all owned pointers if the collection is dropped
1604impl<A: Adapter> Drop for XorLinkedList<A>
1605where
1606    A::LinkOps: XorLinkedListOps,
1607{
1608    #[inline]
1609    fn drop(&mut self) {
1610        self.clear();
1611    }
1612}
1613
1614impl<A: Adapter> IntoIterator for XorLinkedList<A>
1615where
1616    A::LinkOps: XorLinkedListOps,
1617{
1618    type Item = <A::PointerOps as PointerOps>::Pointer;
1619    type IntoIter = IntoIter<A>;
1620
1621    #[inline]
1622    fn into_iter(self) -> IntoIter<A> {
1623        IntoIter { list: self }
1624    }
1625}
1626
1627impl<'a, A: Adapter + 'a> IntoIterator for &'a XorLinkedList<A>
1628where
1629    A::LinkOps: XorLinkedListOps,
1630{
1631    type Item = &'a <A::PointerOps as PointerOps>::Value;
1632    type IntoIter = Iter<'a, A>;
1633
1634    #[inline]
1635    fn into_iter(self) -> Iter<'a, A> {
1636        self.iter()
1637    }
1638}
1639
1640impl<A: Adapter + Default> Default for XorLinkedList<A>
1641where
1642    A::LinkOps: XorLinkedListOps,
1643{
1644    fn default() -> XorLinkedList<A> {
1645        XorLinkedList::new(A::default())
1646    }
1647}
1648
1649impl<A: Adapter> fmt::Debug for XorLinkedList<A>
1650where
1651    A::LinkOps: XorLinkedListOps,
1652    <A::PointerOps as PointerOps>::Value: fmt::Debug,
1653{
1654    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1655        f.debug_list().entries(self.iter()).finish()
1656    }
1657}
1658
1659// =============================================================================
1660// Iter
1661// =============================================================================
1662
1663/// An iterator over references to the items of a `XorLinkedList`.
1664pub struct Iter<'a, A: Adapter>
1665where
1666    A::LinkOps: XorLinkedListOps,
1667{
1668    prev_head: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
1669    head: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
1670    tail: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
1671    next_tail: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
1672    list: &'a XorLinkedList<A>,
1673}
1674impl<'a, A: Adapter + 'a> Iterator for Iter<'a, A>
1675where
1676    A::LinkOps: XorLinkedListOps,
1677{
1678    type Item = &'a <A::PointerOps as PointerOps>::Value;
1679
1680    #[inline]
1681    fn next(&mut self) -> Option<&'a <A::PointerOps as PointerOps>::Value> {
1682        let head = self.head?;
1683
1684        if Some(head) == self.tail {
1685            self.prev_head = None;
1686            self.head = None;
1687            self.next_tail = None;
1688            self.tail = None;
1689        } else {
1690            let next = unsafe { self.list.adapter.link_ops().next(head, self.prev_head) };
1691            self.prev_head = self.head;
1692            self.head = next;
1693        }
1694        Some(unsafe { &*self.list.adapter.get_value(head) })
1695    }
1696}
1697impl<'a, A: Adapter + 'a> DoubleEndedIterator for Iter<'a, A>
1698where
1699    A::LinkOps: XorLinkedListOps,
1700{
1701    #[inline]
1702    fn next_back(&mut self) -> Option<&'a <A::PointerOps as PointerOps>::Value> {
1703        let tail = self.tail?;
1704
1705        if Some(tail) == self.head {
1706            self.prev_head = None;
1707            self.head = None;
1708            self.next_tail = None;
1709            self.tail = None;
1710        } else {
1711            let new_tail = unsafe { self.list.adapter.link_ops().prev(tail, self.next_tail) };
1712            self.next_tail = self.tail;
1713            self.tail = new_tail;
1714        }
1715        Some(unsafe { &*self.list.adapter.get_value(tail) })
1716    }
1717}
1718impl<'a, A: Adapter + 'a> Clone for Iter<'a, A>
1719where
1720    A::LinkOps: XorLinkedListOps,
1721{
1722    #[inline]
1723    fn clone(&self) -> Iter<'a, A> {
1724        Iter {
1725            prev_head: self.prev_head,
1726            head: self.head,
1727            tail: self.tail,
1728            next_tail: self.next_tail,
1729            list: self.list,
1730        }
1731    }
1732}
1733
1734// =============================================================================
1735// IntoIter
1736// =============================================================================
1737
1738/// An iterator which consumes a `XorLinkedList`.
1739pub struct IntoIter<A: Adapter>
1740where
1741    A::LinkOps: XorLinkedListOps,
1742{
1743    list: XorLinkedList<A>,
1744}
1745impl<A: Adapter> Iterator for IntoIter<A>
1746where
1747    A::LinkOps: XorLinkedListOps,
1748{
1749    type Item = <A::PointerOps as PointerOps>::Pointer;
1750
1751    #[inline]
1752    fn next(&mut self) -> Option<<A::PointerOps as PointerOps>::Pointer> {
1753        self.list.pop_front()
1754    }
1755}
1756impl<A: Adapter> DoubleEndedIterator for IntoIter<A>
1757where
1758    A::LinkOps: XorLinkedListOps,
1759{
1760    #[inline]
1761    fn next_back(&mut self) -> Option<<A::PointerOps as PointerOps>::Pointer> {
1762        self.list.pop_back()
1763    }
1764}
1765
1766// =============================================================================
1767// Tests
1768// =============================================================================
1769
1770#[cfg(test)]
1771mod tests {
1772    use crate::UnsafeRef;
1773
1774    use super::{CursorOwning, Link, XorLinkedList};
1775    use core::cell::Cell;
1776    use core::ptr;
1777    use std::boxed::Box;
1778    use std::fmt;
1779    use std::format;
1780    use std::rc::Rc;
1781    use std::vec::Vec;
1782
1783    struct Obj {
1784        link1: Link,
1785        link2: Link,
1786        value: u32,
1787    }
1788    impl fmt::Debug for Obj {
1789        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1790            write!(f, "{}", self.value)
1791        }
1792    }
1793    intrusive_adapter!(RcObjAdapter1 = Rc<Obj>: Obj { link1: Link });
1794    intrusive_adapter!(RcObjAdapter2 = Rc<Obj>: Obj { link2: Link });
1795    intrusive_adapter!(UnsafeRefObjAdapter1 = UnsafeRef<Obj>: Obj { link1: Link });
1796
1797    fn make_rc_obj(value: u32) -> Rc<Obj> {
1798        Rc::new(make_obj(value))
1799    }
1800
1801    fn make_obj(value: u32) -> Obj {
1802        Obj {
1803            link1: Link::new(),
1804            link2: Link::default(),
1805            value,
1806        }
1807    }
1808
1809    #[test]
1810    fn test_link() {
1811        let a = make_rc_obj(1);
1812        assert!(!a.link1.is_linked());
1813        assert!(!a.link2.is_linked());
1814
1815        let mut b = XorLinkedList::<RcObjAdapter1>::default();
1816        assert!(b.is_empty());
1817
1818        b.cursor_mut().insert_after(a.clone());
1819        assert!(!b.is_empty());
1820        assert!(a.link1.is_linked());
1821        assert!(!a.link2.is_linked());
1822        assert_eq!(format!("{:?}", a.link1), "linked");
1823        assert_eq!(format!("{:?}", a.link2), "unlinked");
1824
1825        assert_eq!(
1826            b.front_mut().remove().unwrap().as_ref() as *const _,
1827            a.as_ref() as *const _
1828        );
1829        assert!(b.is_empty());
1830        assert!(!a.link1.is_linked());
1831        assert!(!a.link2.is_linked());
1832    }
1833
1834    #[test]
1835    fn test_cursor() {
1836        let a = make_rc_obj(1);
1837        let b = make_rc_obj(2);
1838        let c = make_rc_obj(3);
1839
1840        let mut l = XorLinkedList::new(RcObjAdapter1::new());
1841        let mut cur = l.cursor_mut();
1842        assert!(cur.is_null());
1843        assert!(cur.get().is_none());
1844        assert!(cur.remove().is_none());
1845        assert_eq!(
1846            cur.replace_with(a.clone()).unwrap_err().as_ref() as *const _,
1847            a.as_ref() as *const _
1848        );
1849
1850        cur.insert_before(a.clone());
1851        cur.insert_before(c.clone());
1852        cur.move_prev();
1853        cur.insert_before(b.clone());
1854        assert!(cur.peek_next().is_null());
1855        cur.move_next();
1856        assert!(cur.is_null());
1857
1858        cur.move_next();
1859        assert!(cur.peek_prev().is_null());
1860        assert!(!cur.is_null());
1861        assert_eq!(cur.get().unwrap() as *const _, a.as_ref() as *const _);
1862
1863        {
1864            let mut cur2 = cur.as_cursor();
1865            assert_eq!(cur2.get().unwrap() as *const _, a.as_ref() as *const _);
1866            assert_eq!(cur2.peek_next().get().unwrap().value, 2);
1867            cur2.move_next();
1868            assert_eq!(cur2.get().unwrap().value, 2);
1869            cur2.move_next();
1870            assert_eq!(cur2.peek_prev().get().unwrap().value, 2);
1871            assert_eq!(cur2.get().unwrap() as *const _, c.as_ref() as *const _);
1872            cur2.move_prev();
1873            assert_eq!(cur2.get().unwrap() as *const _, b.as_ref() as *const _);
1874            cur2.move_next();
1875            assert_eq!(cur2.get().unwrap() as *const _, c.as_ref() as *const _);
1876            cur2.move_next();
1877            assert!(cur2.is_null());
1878            assert!(cur2.clone().get().is_none());
1879        }
1880        assert_eq!(cur.get().unwrap() as *const _, a.as_ref() as *const _);
1881
1882        cur.move_next();
1883        assert_eq!(
1884            cur.remove().unwrap().as_ref() as *const _,
1885            b.as_ref() as *const _
1886        );
1887        assert_eq!(cur.get().unwrap() as *const _, c.as_ref() as *const _);
1888        cur.insert_after(b.clone());
1889        assert_eq!(cur.get().unwrap() as *const _, c.as_ref() as *const _);
1890        cur.move_prev();
1891        assert_eq!(cur.get().unwrap() as *const _, a.as_ref() as *const _);
1892        assert_eq!(
1893            cur.remove().unwrap().as_ref() as *const _,
1894            a.as_ref() as *const _
1895        );
1896        assert!(!a.link1.is_linked());
1897        assert!(c.link1.is_linked());
1898        assert_eq!(cur.get().unwrap() as *const _, c.as_ref() as *const _);
1899        assert_eq!(
1900            cur.replace_with(a.clone()).unwrap().as_ref() as *const _,
1901            c.as_ref() as *const _
1902        );
1903        assert!(a.link1.is_linked());
1904        assert!(!c.link1.is_linked());
1905        assert_eq!(cur.get().unwrap() as *const _, a.as_ref() as *const _);
1906        cur.move_next();
1907        assert_eq!(
1908            cur.replace_with(c.clone()).unwrap().as_ref() as *const _,
1909            b.as_ref() as *const _
1910        );
1911        assert!(a.link1.is_linked());
1912        assert!(!b.link1.is_linked());
1913        assert!(c.link1.is_linked());
1914        assert_eq!(cur.get().unwrap() as *const _, c.as_ref() as *const _);
1915    }
1916
1917    #[test]
1918    fn test_cursor_owning() {
1919        struct Container {
1920            cur: CursorOwning<RcObjAdapter1>,
1921        }
1922
1923        let mut l = XorLinkedList::new(RcObjAdapter1::new());
1924        l.push_back(make_rc_obj(1));
1925        l.push_back(make_rc_obj(2));
1926        l.push_back(make_rc_obj(3));
1927        l.push_back(make_rc_obj(4));
1928        let mut con = Container {
1929            cur: l.cursor_owning(),
1930        };
1931        assert!(con.cur.as_cursor().is_null());
1932
1933        con.cur = con.cur.into_inner().front_owning();
1934        assert_eq!(con.cur.as_cursor().get().unwrap().value, 1);
1935
1936        con.cur.with_cursor_mut(|c| c.move_next());
1937        assert_eq!(con.cur.as_cursor().get().unwrap().value, 2);
1938
1939        con.cur = con.cur.into_inner().back_owning();
1940        assert_eq!(con.cur.as_cursor().get().unwrap().value, 4);
1941    }
1942
1943    #[test]
1944    fn test_push_pop() {
1945        let a = make_rc_obj(1);
1946        let b = make_rc_obj(2);
1947        let c = make_rc_obj(3);
1948
1949        let mut l = XorLinkedList::new(RcObjAdapter1::new());
1950        l.push_front(a);
1951        assert_eq!(l.iter().map(|x| x.value).collect::<Vec<_>>(), [1]);
1952        l.push_front(b);
1953        assert_eq!(l.iter().map(|x| x.value).collect::<Vec<_>>(), [2, 1]);
1954        l.push_back(c);
1955        assert_eq!(l.iter().map(|x| x.value).collect::<Vec<_>>(), [2, 1, 3]);
1956        assert_eq!(l.pop_front().unwrap().value, 2);
1957        assert_eq!(l.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 3]);
1958        assert_eq!(l.pop_back().unwrap().value, 3);
1959        assert_eq!(l.iter().map(|x| x.value).collect::<Vec<_>>(), [1]);
1960        assert_eq!(l.pop_front().unwrap().value, 1);
1961        assert_eq!(l.iter().map(|x| x.value).collect::<Vec<_>>(), []);
1962        assert!(l.pop_front().is_none());
1963        assert_eq!(l.iter().map(|x| x.value).collect::<Vec<_>>(), []);
1964        assert!(l.pop_back().is_none());
1965        assert_eq!(l.iter().map(|x| x.value).collect::<Vec<_>>(), []);
1966    }
1967
1968    #[test]
1969    fn test_split_splice() {
1970        let mut l1 = XorLinkedList::new(RcObjAdapter1::new());
1971        let mut l2 = XorLinkedList::new(RcObjAdapter1::new());
1972        let mut l3 = XorLinkedList::new(RcObjAdapter1::new());
1973
1974        let a = make_rc_obj(1);
1975        let b = make_rc_obj(2);
1976        let c = make_rc_obj(3);
1977        let d = make_rc_obj(4);
1978        l1.cursor_mut().insert_before(a);
1979        l1.cursor_mut().insert_before(b);
1980        l1.cursor_mut().insert_before(c);
1981        l1.cursor_mut().insert_before(d);
1982        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 2, 3, 4]);
1983        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), []);
1984        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), []);
1985        {
1986            let mut cur = l1.front_mut();
1987            cur.move_next();
1988            l2 = cur.split_after();
1989        }
1990        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 2]);
1991        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), [3, 4]);
1992        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), []);
1993        {
1994            let mut cur = l2.back_mut();
1995            l3 = cur.split_before();
1996        }
1997        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 2]);
1998        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), [4]);
1999        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), [3]);
2000        {
2001            let mut cur = l1.front_mut();
2002            cur.splice_after(l2.take());
2003        }
2004        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 4, 2]);
2005        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), []);
2006        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), [3]);
2007        {
2008            let mut cur = l1.front_mut();
2009            cur.move_next();
2010            cur.splice_before(l3.take());
2011        }
2012        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 3, 4, 2]);
2013        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), []);
2014        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), []);
2015        {
2016            let mut cur = l2.cursor_mut();
2017            cur.splice_after(l1.take());
2018        }
2019        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), []);
2020        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 3, 4, 2]);
2021        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), []);
2022        {
2023            let mut cur = l1.cursor_mut();
2024            cur.splice_before(l2.take());
2025        }
2026        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 3, 4, 2]);
2027        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), []);
2028        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), []);
2029        {
2030            let mut cur = l1.cursor_mut();
2031            l2 = cur.split_after();
2032        }
2033        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), []);
2034        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 3, 4, 2]);
2035        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), []);
2036        {
2037            let mut cur = l2.cursor_mut();
2038            l1 = cur.split_before();
2039        }
2040        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 3, 4, 2]);
2041        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), []);
2042        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), []);
2043        {
2044            let mut cur = l1.front_mut();
2045            l2 = cur.split_before();
2046        }
2047        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 3, 4, 2]);
2048        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), []);
2049        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), []);
2050        {
2051            let mut cur = l1.back_mut();
2052            l2 = cur.split_after();
2053        }
2054        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 3, 4, 2]);
2055        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), []);
2056        assert_eq!(l3.iter().map(|x| x.value).collect::<Vec<_>>(), []);
2057    }
2058
2059    #[test]
2060    fn test_iter() {
2061        let mut l = XorLinkedList::new(RcObjAdapter1::new());
2062        let a = make_rc_obj(1);
2063        let b = make_rc_obj(2);
2064        let c = make_rc_obj(3);
2065        let d = make_rc_obj(4);
2066        l.cursor_mut().insert_before(a.clone());
2067        l.cursor_mut().insert_before(b.clone());
2068        l.cursor_mut().insert_before(c.clone());
2069        l.cursor_mut().insert_before(d.clone());
2070
2071        assert_eq!(l.front().get().unwrap().value, 1);
2072        assert_eq!(l.back().get().unwrap().value, 4);
2073        unsafe {
2074            let mut cursor = l.cursor_from_ptr_and_prev(b.as_ref(), a.as_ref());
2075            assert_eq!(cursor.get().unwrap().value, 2);
2076            cursor.move_next();
2077            assert_eq!(cursor.get().unwrap().value, 3);
2078
2079            assert_eq!(
2080                l.cursor_mut_from_ptr_and_next(c.as_ref(), d.as_ref())
2081                    .get()
2082                    .unwrap()
2083                    .value,
2084                3
2085            );
2086
2087            assert_eq!(
2088                l.cursor_mut_from_ptr_and_prev(a.as_ref(), ptr::null())
2089                    .get()
2090                    .unwrap()
2091                    .value,
2092                1
2093            );
2094            assert_eq!(
2095                l.cursor_mut_from_ptr_and_next(d.as_ref(), ptr::null())
2096                    .get()
2097                    .unwrap()
2098                    .value,
2099                4
2100            );
2101
2102            let mut cursor = l.cursor_from_ptr_and_next(d.as_ref(), ptr::null());
2103            assert_eq!(cursor.get().unwrap().value, 4);
2104            cursor.move_prev();
2105            assert_eq!(cursor.get().unwrap().value, 3);
2106            cursor.move_next();
2107            assert_eq!(cursor.get().unwrap().value, 4);
2108            cursor.move_next();
2109            assert!(cursor.is_null());
2110        }
2111
2112        let mut v = Vec::new();
2113        for x in &l {
2114            v.push(x.value);
2115        }
2116        assert_eq!(v, [1, 2, 3, 4]);
2117        assert_eq!(
2118            l.iter().clone().map(|x| x.value).collect::<Vec<_>>(),
2119            [1, 2, 3, 4]
2120        );
2121        assert_eq!(
2122            l.iter().rev().map(|x| x.value).collect::<Vec<_>>(),
2123            [4, 3, 2, 1]
2124        );
2125        assert_eq!(l.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 2, 3, 4]);
2126
2127        assert_eq!(format!("{:?}", l), "[1, 2, 3, 4]");
2128
2129        let mut v = Vec::new();
2130        for x in l.take() {
2131            v.push(x.value);
2132        }
2133        assert_eq!(v, [1, 2, 3, 4]);
2134        assert!(l.is_empty());
2135        assert!(!a.link1.is_linked());
2136        assert!(!b.link1.is_linked());
2137        assert!(!c.link1.is_linked());
2138        assert!(!d.link1.is_linked());
2139
2140        l.cursor_mut().insert_before(a.clone());
2141        l.cursor_mut().insert_before(b.clone());
2142        l.cursor_mut().insert_before(c.clone());
2143        l.cursor_mut().insert_before(d.clone());
2144        l.clear();
2145        assert!(l.is_empty());
2146        assert!(!a.link1.is_linked());
2147        assert!(!b.link1.is_linked());
2148        assert!(!c.link1.is_linked());
2149        assert!(!d.link1.is_linked());
2150
2151        v.clear();
2152        l.cursor_mut().insert_before(a.clone());
2153        l.cursor_mut().insert_before(b.clone());
2154        l.cursor_mut().insert_before(c.clone());
2155        l.cursor_mut().insert_before(d.clone());
2156        for x in l.into_iter().rev() {
2157            v.push(x.value);
2158        }
2159        assert_eq!(v, [4, 3, 2, 1]);
2160        assert!(!a.link1.is_linked());
2161        assert!(!b.link1.is_linked());
2162        assert!(!c.link1.is_linked());
2163        assert!(!d.link1.is_linked());
2164    }
2165
2166    #[test]
2167    fn test_multi_list() {
2168        let mut l1 = XorLinkedList::new(RcObjAdapter1::new());
2169        let mut l2 = XorLinkedList::new(RcObjAdapter2::new());
2170        let a = make_rc_obj(1);
2171        let b = make_rc_obj(2);
2172        let c = make_rc_obj(3);
2173        let d = make_rc_obj(4);
2174        l1.cursor_mut().insert_before(a.clone());
2175        l1.cursor_mut().insert_before(b.clone());
2176        l1.cursor_mut().insert_before(c.clone());
2177        l1.cursor_mut().insert_before(d.clone());
2178        l2.cursor_mut().insert_after(a);
2179        l2.cursor_mut().insert_after(b);
2180        l2.cursor_mut().insert_after(c);
2181        l2.cursor_mut().insert_after(d);
2182        assert_eq!(l1.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 2, 3, 4]);
2183        assert_eq!(l2.iter().map(|x| x.value).collect::<Vec<_>>(), [4, 3, 2, 1]);
2184    }
2185
2186    #[test]
2187    fn test_fast_clear_force_unlink() {
2188        let mut l = XorLinkedList::new(UnsafeRefObjAdapter1::new());
2189        let a = UnsafeRef::from_box(Box::new(make_obj(1)));
2190        let b = UnsafeRef::from_box(Box::new(make_obj(2)));
2191        let c = UnsafeRef::from_box(Box::new(make_obj(3)));
2192        l.cursor_mut().insert_before(a.clone());
2193        l.cursor_mut().insert_before(b.clone());
2194        l.cursor_mut().insert_before(c.clone());
2195
2196        l.fast_clear();
2197        assert!(l.is_empty());
2198
2199        unsafe {
2200            assert!(a.link1.is_linked());
2201            assert!(b.link1.is_linked());
2202            assert!(c.link1.is_linked());
2203
2204            a.link1.force_unlink();
2205            b.link1.force_unlink();
2206            c.link1.force_unlink();
2207
2208            assert!(l.is_empty());
2209
2210            assert!(!a.link1.is_linked());
2211            assert!(!b.link1.is_linked());
2212            assert!(!c.link1.is_linked());
2213        }
2214
2215        unsafe {
2216            UnsafeRef::into_box(a);
2217            UnsafeRef::into_box(b);
2218            UnsafeRef::into_box(c);
2219        }
2220    }
2221
2222    #[test]
2223    fn test_reverse() {
2224        let mut l = XorLinkedList::new(RcObjAdapter1::new());
2225
2226        l.push_back(make_rc_obj(1));
2227        l.push_back(make_rc_obj(2));
2228        l.push_back(make_rc_obj(3));
2229        l.push_back(make_rc_obj(4));
2230        assert_eq!(l.iter().map(|x| x.value).collect::<Vec<_>>(), [1, 2, 3, 4]);
2231
2232        l.reverse();
2233        assert_eq!(l.iter().map(|x| x.value).collect::<Vec<_>>(), [4, 3, 2, 1]);
2234
2235        l.push_back(make_rc_obj(5));
2236        l.push_back(make_rc_obj(6));
2237        assert_eq!(
2238            l.iter().map(|x| x.value).collect::<Vec<_>>(),
2239            [4, 3, 2, 1, 5, 6]
2240        );
2241
2242        l.reverse();
2243        assert_eq!(
2244            l.iter().map(|x| x.value).collect::<Vec<_>>(),
2245            [6, 5, 1, 2, 3, 4]
2246        );
2247    }
2248
2249    #[test]
2250    fn test_non_static() {
2251        #[derive(Clone)]
2252        struct Obj<'a, T> {
2253            link: Link,
2254            value: &'a T,
2255        }
2256        intrusive_adapter!(ObjAdapter<'a, T> = &'a Obj<'a, T>: Obj<'a, T> {link: Link} where T: 'a);
2257
2258        let v = 5;
2259        let a = Obj {
2260            link: Link::new(),
2261            value: &v,
2262        };
2263        let b = a.clone();
2264        let mut l = XorLinkedList::new(ObjAdapter::new());
2265        l.cursor_mut().insert_before(&a);
2266        l.cursor_mut().insert_before(&b);
2267        assert_eq!(*l.front().get().unwrap().value, 5);
2268        assert_eq!(*l.back().get().unwrap().value, 5);
2269    }
2270
2271    #[test]
2272    fn test_drop() {
2273        #[derive(Clone)]
2274        struct Obj<'a> {
2275            link: Link,
2276            value: &'a Cell<u32>,
2277        }
2278        impl<'a> Drop for Obj<'a> {
2279            fn drop(&mut self) {
2280                let val = self.value.get();
2281                self.value.set(val + 1);
2282            }
2283        }
2284        intrusive_adapter!(ObjAdapter<'a> = Box<Obj<'a>>: Obj<'a> {link: Link});
2285
2286        let v = Cell::new(0);
2287        let obj = Obj {
2288            link: Link::new(),
2289            value: &v,
2290        };
2291        let mut l = XorLinkedList::new(ObjAdapter::new());
2292        l.cursor_mut().insert_before(Box::new(obj.clone()));
2293        l.cursor_mut().insert_before(Box::new(obj.clone()));
2294        assert_eq!(l.front().get().unwrap().value.get(), 0);
2295        assert_eq!(l.back().get().unwrap().value.get(), 0);
2296        assert_eq!(v.get(), 0);
2297
2298        l.pop_front();
2299        assert_eq!(v.get(), 1);
2300
2301        l.front_mut().insert_after(Box::new(obj.clone()));
2302        assert_eq!(v.get(), 1);
2303
2304        drop(l);
2305        assert_eq!(v.get(), 3);
2306    }
2307
2308    macro_rules! test_clone_pointer {
2309        ($ptr: ident, $ptr_import: path) => {
2310            use $ptr_import;
2311
2312            #[derive(Clone)]
2313            struct Obj {
2314                link: Link,
2315                value: usize,
2316            }
2317            intrusive_adapter!(ObjAdapter = $ptr<Obj>: Obj { link: Link });
2318
2319            let a = $ptr::new(Obj {
2320                link: Link::new(),
2321                value: 5,
2322            });
2323            let mut l = XorLinkedList::new(ObjAdapter::new());
2324            l.cursor_mut().insert_before(a.clone());
2325            assert_eq!(2, $ptr::strong_count(&a));
2326
2327            let pointer = l.front().clone_pointer().unwrap();
2328            assert_eq!(pointer.value, 5);
2329            assert_eq!(3, $ptr::strong_count(&a));
2330
2331            l.front_mut().remove();
2332            assert!(l.front().clone_pointer().is_none());
2333        };
2334    }
2335
2336    #[test]
2337    fn test_clone_pointer_rc() {
2338        test_clone_pointer!(Rc, std::rc::Rc);
2339    }
2340
2341    #[test]
2342    fn test_clone_pointer_arc() {
2343        test_clone_pointer!(Arc, std::sync::Arc);
2344    }
2345}