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