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