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