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