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