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