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 
14 use core::cell::Cell;
15 use core::fmt;
16 use core::ptr::NonNull;
17 use core::sync::atomic::{AtomicUsize, Ordering};
18 
19 use crate::link_ops::{self, DefaultLinkOps};
20 use crate::pointer_ops::PointerOps;
21 use crate::singly_linked_list::SinglyLinkedListOps;
22 use crate::Adapter;
23 // Necessary for Rust 1.56 compatability
24 #[allow(unused_imports)]
25 use crate::unchecked_option::UncheckedOptionExt;
26 
27 // =============================================================================
28 // XorLinkedListOps
29 // =============================================================================
30 
31 /// Link operations for `XorLinkedList`.
32 pub 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
next(&self, ptr: Self::LinkPtr, prev: Option<Self::LinkPtr>) -> Option<Self::LinkPtr>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
prev(&self, ptr: Self::LinkPtr, next: Option<Self::LinkPtr>) -> Option<Self::LinkPtr>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.
set( &mut self, ptr: Self::LinkPtr, prev: Option<Self::LinkPtr>, next: Option<Self::LinkPtr>, )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
replace_next_or_prev( &mut self, ptr: Self::LinkPtr, old: Option<Self::LinkPtr>, new: Option<Self::LinkPtr>, )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))]
94 pub struct Link {
95     packed: Cell<usize>,
96 }
97 
98 // Use a special value to indicate an unlinked node
99 const UNLINKED_MARKER: usize = 1_usize;
100 
101 impl Link {
102     /// Creates a new `Link`.
103     #[inline]
new() -> Link104     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]
is_linked(&self) -> bool112     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]
force_unlink(&self)125     pub unsafe fn force_unlink(&self) {
126         self.packed.set(UNLINKED_MARKER);
127     }
128 }
129 
130 impl 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.
137 unsafe 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.
141 impl Clone for Link {
142     #[inline]
clone(&self) -> Link143     fn clone(&self) -> Link {
144         Link::new()
145     }
146 }
147 
148 // Same as above
149 impl Default for Link {
150     #[inline]
default() -> Link151     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.
158 impl fmt::Debug for Link {
159     #[inline]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result160     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)]
177 pub struct LinkOps;
178 
179 unsafe impl link_ops::LinkOps for LinkOps {
180     type LinkPtr = NonNull<Link>;
181 
182     #[inline]
acquire_link(&mut self, ptr: Self::LinkPtr) -> bool183     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]
release_link(&mut self, ptr: Self::LinkPtr)193     unsafe fn release_link(&mut self, ptr: Self::LinkPtr) {
194         ptr.as_ref().packed.set(UNLINKED_MARKER);
195     }
196 }
197 
198 unsafe impl XorLinkedListOps for LinkOps {
199     #[inline]
next( &self, ptr: Self::LinkPtr, prev: Option<Self::LinkPtr>, ) -> Option<Self::LinkPtr>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]
prev( &self, ptr: Self::LinkPtr, next: Option<Self::LinkPtr>, ) -> Option<Self::LinkPtr>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]
set( &mut self, ptr: Self::LinkPtr, prev: Option<Self::LinkPtr>, next: Option<Self::LinkPtr>, )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]
replace_next_or_prev( &mut self, ptr: Self::LinkPtr, old: Option<Self::LinkPtr>, new: Option<Self::LinkPtr>, )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 
246 unsafe impl SinglyLinkedListOps for LinkOps {
247     #[inline]
next(&self, ptr: Self::LinkPtr) -> Option<Self::LinkPtr>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]
set_next(&mut self, ptr: Self::LinkPtr, next: Option<Self::LinkPtr>)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))]
268 pub struct AtomicLink {
269     packed: AtomicUsize,
270 }
271 
272 impl AtomicLink {
273     /// Creates a new `Link`.
274     #[inline]
new() -> AtomicLink275     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]
is_linked(&self) -> bool283     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]
force_unlink(&self)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]
packed_exclusive(&self) -> &Cell<usize>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 
312 impl 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.
319 unsafe impl Send for AtomicLink {}
320 
321 // An object containing a link can be shared between threads since `acquire_link` is atomic.
322 unsafe impl Sync for AtomicLink {}
323 
324 impl Clone for AtomicLink {
325     #[inline]
clone(&self) -> AtomicLink326     fn clone(&self) -> AtomicLink {
327         AtomicLink::new()
328     }
329 }
330 
331 impl Default for AtomicLink {
332     #[inline]
default() -> AtomicLink333     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.
340 impl fmt::Debug for AtomicLink {
341     #[inline]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result342     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)]
359 pub struct AtomicLinkOps;
360 
361 const LINKED_DEFAULT_VALUE: usize = 0;
362 
363 unsafe impl link_ops::LinkOps for AtomicLinkOps {
364     type LinkPtr = NonNull<AtomicLink>;
365 
366     #[inline]
acquire_link(&mut self, ptr: Self::LinkPtr) -> bool367     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]
release_link(&mut self, ptr: Self::LinkPtr)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 
387 unsafe impl XorLinkedListOps for AtomicLinkOps {
388     #[inline]
next( &self, ptr: Self::LinkPtr, prev: Option<Self::LinkPtr>, ) -> Option<Self::LinkPtr>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]
prev( &self, ptr: Self::LinkPtr, next: Option<Self::LinkPtr>, ) -> Option<Self::LinkPtr>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]
set( &mut self, ptr: Self::LinkPtr, prev: Option<Self::LinkPtr>, next: Option<Self::LinkPtr>, )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]
replace_next_or_prev( &mut self, ptr: Self::LinkPtr, old: Option<Self::LinkPtr>, new: Option<Self::LinkPtr>, )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 
437 unsafe impl SinglyLinkedListOps for AtomicLinkOps {
438     #[inline]
next(&self, ptr: Self::LinkPtr) -> Option<Self::LinkPtr>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]
set_next(&mut self, ptr: Self::LinkPtr, next: Option<Self::LinkPtr>)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]
link_between<T: XorLinkedListOps>( link_ops: &mut T, ptr: T::LinkPtr, prev: Option<T::LinkPtr>, next: Option<T::LinkPtr>, )453 unsafe 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`.
475 pub struct Cursor<'a, A: Adapter>
476 where
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 
485 impl<'a, A: Adapter> Clone for Cursor<'a, A>
486 where
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 
500 impl<'a, A: Adapter> Cursor<'a, A>
501 where
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`.
603 pub struct CursorMut<'a, A: Adapter>
604 where
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 
613 impl<'a, A: Adapter> CursorMut<'a, A>
614 where
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.
1088 pub struct CursorOwning<A: Adapter>
1089 where
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 
1098 impl<A: Adapter> CursorOwning<A>
1099 where
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 }
1146 unsafe impl<A: Adapter> Send for CursorOwning<A>
1147 where
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.
1164 pub struct XorLinkedList<A: Adapter>
1165 where
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 
1173 impl<A: Adapter> XorLinkedList<A>
1174 where
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
1587 unsafe impl<A: Adapter + Sync> Sync for XorLinkedList<A>
1588 where
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.
1596 unsafe impl<A: Adapter + Send> Send for XorLinkedList<A>
1597 where
1598     <A::PointerOps as PointerOps>::Pointer: Send,
1599     A::LinkOps: XorLinkedListOps,
1600 {
1601 }
1602 
1603 // Drop all owned pointers if the collection is dropped
1604 impl<A: Adapter> Drop for XorLinkedList<A>
1605 where
1606     A::LinkOps: XorLinkedListOps,
1607 {
1608     #[inline]
1609     fn drop(&mut self) {
1610         self.clear();
1611     }
1612 }
1613 
1614 impl<A: Adapter> IntoIterator for XorLinkedList<A>
1615 where
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 
1627 impl<'a, A: Adapter + 'a> IntoIterator for &'a XorLinkedList<A>
1628 where
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 
1640 impl<A: Adapter + Default> Default for XorLinkedList<A>
1641 where
1642     A::LinkOps: XorLinkedListOps,
1643 {
1644     fn default() -> XorLinkedList<A> {
1645         XorLinkedList::new(A::default())
1646     }
1647 }
1648 
1649 impl<A: Adapter> fmt::Debug for XorLinkedList<A>
1650 where
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`.
1664 pub struct Iter<'a, A: Adapter>
1665 where
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 }
1674 impl<'a, A: Adapter + 'a> Iterator for Iter<'a, A>
1675 where
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 }
1697 impl<'a, A: Adapter + 'a> DoubleEndedIterator for Iter<'a, A>
1698 where
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 }
1718 impl<'a, A: Adapter + 'a> Clone for Iter<'a, A>
1719 where
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`.
1739 pub struct IntoIter<A: Adapter>
1740 where
1741     A::LinkOps: XorLinkedListOps,
1742 {
1743     list: XorLinkedList<A>,
1744 }
1745 impl<A: Adapter> Iterator for IntoIter<A>
1746 where
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 }
1756 impl<A: Adapter> DoubleEndedIterator for IntoIter<A>
1757 where
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)]
1771 mod 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 }
2346