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