intrusive_collections/
linked_list.rs

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