Skip to main content

embed_dlist/
lib.rs

1#![allow(rustdoc::redundant_explicit_links)]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![cfg_attr(docsrs, allow(unused_attributes))]
4#![cfg_attr(not(feature = "std"), no_std)]
5
6//! An intrusive doubly linked list implementation.
7//!
8//! This module provides `DLinkedList`, a doubly linked list where elements
9//! embed the list nodes themselves. This design offers memory efficiency
10//! and explicit control over allocation, suitable for scenarios like
11//! building LRU caches directly within data structures.
12//!
13//! # Features
14//! - O(1) push and pop from both front and back.
15//! - Generic over pointer types (`Box`, `Arc`, `NonNull`, raw pointers).
16//! - Supports multiple lists for the same item via `Tag`.
17//!
18//! # Example
19//!
20//! ```rust
21//! use embed_dlist::{DLinkedList, DListItem, DListNode};
22//! use core::cell::UnsafeCell;
23//! use std::sync::Arc;
24//! use core::ptr::NonNull;
25//!
26//! struct MyTag ();
27//!
28//! struct MyItem {
29//!     id: u32,
30//!     data: String,
31//!     node: UnsafeCell<DListNode<MyTag>>,
32//! }
33//!
34//! impl MyItem {
35//!     fn new(id: u32, data: &str) -> Self {
36//!         MyItem {
37//!             id,
38//!             data: data.to_string(),
39//!             node: UnsafeCell::new(DListNode::default()),
40//!         }
41//!     }
42//! }
43//!
44//! unsafe impl DListItem<MyTag> for MyItem {
45//!     fn get_node(&self) -> &mut DListNode<MyTag> {
46//!         unsafe { &mut *self.node.get() }
47//!     }
48//! }
49//!
50//! // Using Box<T> (owned pointers)
51//! {
52//!     let mut list = DLinkedList::<Box<MyItem>, MyTag>::new();
53//!     list.push_back(Box::new(MyItem::new(1, "First")));
54//!     list.push_front(Box::new(MyItem::new(2, "Second")));
55//!     list.push_back(Box::new(MyItem::new(3, "Third")));
56//!     assert_eq!(list.len(), 3);
57//!     assert_eq!(list.pop_front().unwrap().id, 2);
58//!     assert_eq!(list.pop_back().unwrap().id, 3);
59//!     assert_eq!(list.pop_front().unwrap().id, 1);
60//!     assert!(list.is_empty());
61//! }
62//!
63//! // Using Arc<T> (shared ownership)
64//! {
65//!     let mut list = DLinkedList::<Arc<MyItem>, MyTag>::new();
66//!     list.push_back(Arc::new(MyItem::new(1, "First")));
67//!     list.push_front(Arc::new(MyItem::new(2, "Second")));
68//!     list.push_back(Arc::new(MyItem::new(3, "Third")));
69//!     assert_eq!(list.len(), 3);
70//!     assert_eq!(list.pop_front().unwrap().id, 2);
71//!     assert_eq!(list.pop_back().unwrap().id, 3);
72//!     assert_eq!(list.pop_front().unwrap().id, 1);
73//!     assert!(list.is_empty());
74//! }
75//!
76//! // Using NonNull<T> (ignore ownership)
77//! {
78//!     let mut list = DLinkedList::<NonNull<MyItem>, MyTag>::new();
79//!     let item1 = Box::into_raw(Box::new(MyItem::new(1, "First")));
80//!     let item2 = Box::into_raw(Box::new(MyItem::new(2, "Second")));
81//!     let item3 = Box::into_raw(Box::new(MyItem::new(3, "Third")));
82//!     list.push_back(unsafe{NonNull::new_unchecked(item1)});
83//!     list.push_front(unsafe{NonNull::new_unchecked(item2)});
84//!     list.push_back(unsafe{NonNull::new_unchecked(item3)});
85//!     assert_eq!(list.len(), 3);
86//!     assert_eq!(unsafe { list.pop_front().unwrap().as_ref().id }, 2);
87//!     assert_eq!(unsafe { list.pop_back().unwrap().as_ref().id }, 3);
88//!     assert_eq!(unsafe { list.pop_front().unwrap().as_ref().id }, 1);
89//!     assert!(list.is_empty());
90//!     unsafe{
91//!         let _ = Box::from_raw(item1);
92//!         let _ = Box::from_raw(item2);
93//!         let _ = Box::from_raw(item3);
94//!     }
95//! }
96//! ```
97//!
98//! # Mixed Types
99//!
100//! This example show mixed multiple types (which have the same DListNode field) in one list,
101//! with custom pointer type.
102//!
103//! ```
104//! use embed_dlist::{DLinkedList, DListItem, DListNode};
105//! use pointers::Pointer;
106//! use core::cell::UnsafeCell;
107//! use std::sync::Arc;
108//!
109//! enum MixedPointer {
110//!     Multi(Arc<ArcNode>),
111//!     One(Box<BoxNode>),
112//! }
113//!
114//! impl MixedPointer {
115//!
116//!     fn as_multi(&self) -> &Arc<ArcNode> {
117//!         if let Self::Multi(inner) = self {
118//!             inner
119//!         } else {
120//!             panic!("not Multi")
121//!         }
122//!     }
123//!
124//!     fn as_one(&self) -> &Box<BoxNode> {
125//!         if let Self::One(inner) = self {
126//!             inner
127//!         } else {
128//!             panic!("not One")
129//!         }
130//!     }
131//! }
132//!
133//! const IS_ARC: usize = 0x1;
134//! const TYPE_MASK: usize = IS_ARC;
135//!
136//! struct ArcNode {
137//!     _node: UnsafeCell<DListNode<()>>,
138//!     v: usize,
139//! }
140//!
141//! struct BoxNode {
142//!     _node: UnsafeCell<DListNode<()>>,
143//!     v: String,
144//! }
145//!
146//! impl ArcNode {
147//!     fn new(v: usize) -> Arc<Self> {
148//!         Arc::new(Self{
149//!             _node: Default::default(),
150//!             v,
151//!         })
152//!     }
153//! }
154//!
155//! impl BoxNode {
156//!     fn new(v: String) -> Box<Self> {
157//!         Box::new(Self{
158//!             _node: Default::default(),
159//!             v,
160//!         })
161//!     }
162//! }
163//!
164//! struct MixedAddr (usize);
165//!
166//! impl Pointer for MixedPointer {
167//!     type Target = MixedAddr;
168//!
169//!     fn as_ref(&self) -> &MixedAddr {
170//!         unreachable!("we don't call as_ref in DLinkedList");
171//!     }
172//!
173//!     /// # Safety
174//!     ///
175//!     /// just a mock
176//!     unsafe fn from_raw(p: *const MixedAddr) -> Self {
177//!         let real_p = (p as usize) & (!TYPE_MASK);
178//!         debug_assert!(real_p != 0);
179//!         let type_flag = (p as usize) & TYPE_MASK;
180//!         if type_flag == IS_ARC {
181//!             Self::Multi(unsafe{Arc::from_raw(real_p as *mut ArcNode)})
182//!         } else {
183//!             Self::One(unsafe{Box::from_raw(real_p as *mut BoxNode)})
184//!         }
185//!     }
186//!
187//!     /// # Safety
188//!     /// the address into_raw cannot be defer directly
189//!     fn into_raw(self) -> *const MixedAddr {
190//!         let addr: usize = match self {
191//!             MixedPointer::Multi(item)=>{Arc::into_raw(item) as usize | IS_ARC},
192//!             MixedPointer::One(item)=>{Box::into_raw(item) as usize},
193//!         };
194//!         addr as *const MixedAddr
195//!     }
196//! }
197//!
198//! unsafe impl DListItem<()> for MixedAddr {
199//!     
200//!     fn get_node(&self) -> &mut DListNode<()> {
201//!         unreachable!();
202//!     }
203//!
204//!     unsafe fn get_node_from_ptr<'a>(p: *mut u8) -> &'a mut DListNode<()>
205//!     where
206//!         Self: 'a,
207//!     {
208//!         let real_p = (p as usize) & (!TYPE_MASK);
209//!         debug_assert!(real_p != 0);
210//!         let type_flag = (p as usize) & TYPE_MASK;
211//!         if type_flag == IS_ARC {
212//!             unsafe{&mut *(*(real_p as *const ArcNode))._node.get()}
213//!         } else {
214//!             unsafe{&mut *(*(real_p as *const BoxNode))._node.get()}
215//!         }
216//!     }
217//! }
218//!
219//! // list operation
220//! let mut l = DLinkedList::<MixedPointer, ()>::new();
221//! l.push_back(MixedPointer::Multi(ArcNode::new(1)));
222//! l.push_back(MixedPointer::One(BoxNode::new("box1".to_string())));
223//! l.push_back(MixedPointer::One(BoxNode::new("box2".to_string())));
224//! l.push_back(MixedPointer::Multi(ArcNode::new(2)));
225//!
226//! let mut iter = l.iter();
227//! assert_eq!(iter.next().unwrap().as_multi().v, 1);
228//! assert_eq!(iter.next().unwrap().as_one().v.as_str(), "box1");
229//! assert_eq!(iter.next().unwrap().as_one().v.as_str(), "box2");
230//! assert_eq!(iter.next().unwrap().as_multi().v, 2);
231//! assert!(iter.next().is_none());
232//!
233//! let mut iter = l.drain();
234//! assert_eq!(iter.next().unwrap().as_multi().v, 1);
235//! assert_eq!(iter.next().unwrap().as_one().v.as_str(), "box1");
236//! assert_eq!(iter.next().unwrap().as_one().v.as_str(), "box2");
237//! assert_eq!(iter.next().unwrap().as_multi().v, 2);
238//! assert!(iter.next().is_none());
239//! ```
240
241extern crate alloc;
242#[cfg(any(feature = "std", test))]
243extern crate std;
244
245use core::marker::PhantomData;
246use core::{
247    borrow::BorrowMut,
248    fmt,
249    mem::{self, MaybeUninit},
250    ptr::{self, null, null_mut},
251};
252use pointers::Pointer;
253
254/// A trait to return internal mutable DListNode for specified list.
255///
256/// The tag is used to distinguish different DListNodes within the same item,
257/// allowing an item to belong to multiple lists simultaneously.
258/// For only one ownership, you can use `()`.
259///
260/// # Safety
261///
262/// Implementors must ensure `get_node` returns a valid reference to the `DListNode`
263/// embedded within `Self`. Users must use `UnsafeCell` to hold `DListNode` to support
264/// interior mutability required by list operations.
265pub unsafe trait DListItem<Tag>: Sized {
266    fn get_node(&self) -> &mut DListNode<Tag>;
267
268    /// # Safety
269    ///
270    /// This is just map from raw pointer to `&mut DListNode`.
271    ///
272    /// You only have to implement this when using custom pointer type with abnormal address.
273    /// Refer to [Mixed Type Example](index.html#mixed-types)
274    #[allow(unsafe_op_in_unsafe_fn)]
275    #[inline(always)]
276    unsafe fn get_node_from_ptr<'a>(p: *mut u8) -> &'a mut DListNode<Tag>
277    where
278        Self: 'a,
279    {
280        debug_assert!(!p.is_null());
281        (*(p as *const Self)).get_node()
282    }
283}
284
285/// The node structure that must be embedded in items to be stored in a `DLinkedList`.
286#[repr(C)]
287pub struct DListNode<Tag> {
288    prev: *mut u8,
289    next: *mut u8,
290    _phan: PhantomData<fn(&Tag)>,
291}
292
293unsafe impl<Tag> Send for DListNode<Tag> {}
294
295impl<Tag> Default for DListNode<Tag> {
296    #[inline(always)]
297    fn default() -> Self {
298        Self { prev: null_mut(), next: null_mut(), _phan: Default::default() }
299    }
300}
301
302impl<Tag> fmt::Debug for DListNode<Tag> {
303    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
304        write!(f, "(")?;
305        if !self.prev.is_null() {
306            write!(f, "prev: {:p} ", self.prev)?;
307        } else {
308            write!(f, "prev: none ")?;
309        }
310        if !self.next.is_null() {
311            write!(f, "next: {:p} ", self.next)?;
312        } else {
313            write!(f, "next: none ")?;
314        }
315        write!(f, ")")
316    }
317}
318
319/// An intrusive doubly linked list.
320///
321/// Supports O(1) insertion and removal at both ends.
322#[repr(C)]
323pub struct DLinkedList<P, Tag>
324where
325    P: Pointer,
326    P::Target: DListItem<Tag>,
327{
328    length: usize,
329    head: *mut u8,
330    tail: *mut u8,
331    _phan: PhantomData<fn(&P, &Tag)>,
332}
333
334unsafe impl<P, Tag> Send for DLinkedList<P, Tag>
335where
336    P: Pointer,
337    P::Target: DListItem<Tag>,
338{
339}
340
341impl<P: fmt::Debug, Tag> fmt::Debug for DLinkedList<P, Tag>
342where
343    P: Pointer,
344    P::Target: DListItem<Tag>,
345{
346    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
347        write!(f, "{{ length: {} ", self.length)?;
348        if !self.head.is_null() {
349            write!(f, "head: {:?} ", self.head)?;
350        } else {
351            write!(f, "head: none ")?;
352        }
353        if !self.tail.is_null() {
354            write!(f, "tail: {:?} ", self.tail)?;
355        } else {
356            write!(f, "tail: none ")?;
357        }
358        write!(f, "}}")
359    }
360}
361
362impl<P, Tag> DLinkedList<P, Tag>
363where
364    P: Pointer,
365    P::Target: DListItem<Tag>,
366{
367    /// Creates a new, empty doubly linked list.
368    #[inline(always)]
369    pub fn new() -> Self {
370        DLinkedList { length: 0, head: null_mut(), tail: null_mut(), _phan: Default::default() }
371    }
372
373    /// Clears the list, dropping all of its elements if the pointer type `P` owns them.
374    #[inline]
375    pub fn clear(&mut self) {
376        // By repeatedly popping from the front, we drop each element.
377        // If P is an owned pointer (like Box), the element is dropped.
378        // If P is a raw pointer, it's a no-op, but the list is still emptied.
379        while self.pop_front().is_some() {}
380    }
381
382    /// Returns the length of the list as `usize`.
383    #[inline(always)]
384    pub fn len(&self) -> usize {
385        self.length
386    }
387
388    /// Returns `true` if the list contains no elements.
389    #[inline(always)]
390    pub fn is_empty(&self) -> bool {
391        self.length == 0
392    }
393
394    #[inline(always)]
395    fn _remove_node(&mut self, item: *mut u8) -> bool {
396        let mut removed = false;
397        unsafe {
398            let node = <P::Target as DListItem<Tag>>::get_node_from_ptr(item);
399            if !node.prev.is_null() {
400                <P::Target as DListItem<Tag>>::get_node_from_ptr(node.prev).next = node.next;
401                removed = true;
402            } else if self.head == item {
403                self.head = node.next;
404                removed = true;
405            }
406            if !node.next.is_null() {
407                <P::Target as DListItem<Tag>>::get_node_from_ptr(node.next).prev = node.prev;
408                removed = true;
409            } else if self.tail == item {
410                self.tail = node.prev;
411                removed = true;
412            }
413            if removed {
414                node.next = null_mut();
415                node.prev = null_mut();
416                self.length -= 1;
417            }
418        }
419        removed
420    }
421
422    /// Remove a node by raw pointer from the middle of the list, and recover P from `item`
423    ///
424    /// - Return Some if the item is in the list.
425    /// - Return None if the item is not in any list.
426    ///
427    /// NOTE: Due to avoid miri stack borrow rule error, `item` is a raw pointer.
428    ///
429    /// # Safety
430    ///
431    /// `item` should point the a valid item. Do not remove item from other list, otherwise will lead to UB.
432    ///
433    /// # Example
434    ///
435    /// ```
436    ///
437    /// use embed_dlist::{DLinkedList, DListItem, DListNode};
438    /// use core::cell::UnsafeCell;
439    /// extern crate alloc;
440    /// use alloc::boxed::Box;
441    ///
442    /// #[derive(Debug)]
443    /// pub struct TestNode {
444    ///     pub value: i64,
445    ///     pub node: UnsafeCell<DListNode<()>>,
446    /// }
447    ///
448    /// unsafe impl Send for TestNode {}
449    ///
450    /// unsafe impl DListItem<()> for TestNode {
451    ///     fn get_node(&self) -> &mut DListNode<()> {
452    ///         unsafe { &mut *self.node.get() }
453    ///     }
454    /// }
455    ///
456    /// fn new_node(v: i64) -> TestNode {
457    ///     TestNode { value: v, node: UnsafeCell::new(DListNode::default()) }
458    /// }
459    ///
460    /// let mut l = DLinkedList::<Box<TestNode>, ()>::new();
461    ///
462    /// let node1 = Box::new(new_node(1));
463    /// l.push_back(node1);
464    /// let node2 = Box::new(new_node(2));
465    ///
466    /// // NOTE: use `node_p = node2.as_ptr()`  will trigger miri stack borrow rule.
467    /// // we use into_raw and then from_raw
468    /// let node2_p = Box::into_raw(node2);
469    /// l.push_back(unsafe{Box::from_raw(node2_p)});
470    ///
471    /// let node3 = Box::new(new_node(3));
472    /// l.push_back(node3);
473    /// assert_eq!(l.len(), 3);
474    ///
475    /// let node2 = unsafe { l.remove_node(node2_p).unwrap() };
476    /// assert_eq!(l.len(), 2);
477    /// assert_eq!(node2.value, 2);
478    /// ```
479    #[inline(always)]
480    pub unsafe fn remove_node(&mut self, item: *const P::Target) -> Option<P> {
481        unsafe { if self._remove_node(item as *mut u8) { Some(P::from_raw(item)) } else { None } }
482    }
483
484    /// Remove the item from the list if it's in the list, but do not recover the removed ptr to P.
485    ///
486    /// # Safety
487    ///
488    /// You have to make sure the returned item ref counter be dropped manually
489    ///
490    /// If the item was in the list, return `item` back; otherwise return `null()`
491    #[inline(always)]
492    pub unsafe fn remove_node_raw(&mut self, item: *const P::Target) -> *const P::Target {
493        if self._remove_node(item as *mut u8) { item } else { null() }
494    }
495
496    /// Moves a node to the front of the list (e.g., for LRU updates).
497    ///
498    /// NOTE: Due to avoid miri stack borrow rule error, `item` is a raw pointer.
499    ///
500    /// # Safety
501    ///
502    /// The item must be in the list, otherwise will lead to UB.
503    #[inline(always)]
504    pub unsafe fn peak(&mut self, item: *const P::Target) {
505        assert!(!self.head.is_null());
506        if !ptr::eq(self.head, item as *mut u8) {
507            assert!(self._remove_node(item as *mut u8), "item is not in the list");
508            self.push_front_ptr(item);
509        }
510    }
511
512    /// Pushes an element to the front of the list.
513    #[inline]
514    pub fn push_front(&mut self, item: P) {
515        let ptr = item.into_raw();
516        self.push_front_ptr(ptr);
517    }
518
519    #[inline]
520    fn push_front_ptr(&mut self, ptr: *const P::Target) {
521        let node = unsafe { <P::Target as DListItem<Tag>>::get_node_from_ptr(ptr as *mut u8) };
522        let head = self.head;
523        node.next = head;
524        node.prev = null_mut();
525
526        if head.is_null() {
527            self.tail = ptr as *mut u8;
528        } else {
529            unsafe {
530                <P::Target as DListItem<Tag>>::get_node_from_ptr(head).prev = ptr as *mut u8;
531            }
532        }
533        self.head = ptr as *mut u8;
534        self.length += 1;
535    }
536
537    /// Pushes an element to the back of the list.
538    #[inline]
539    pub fn push_back(&mut self, item: P) {
540        let tail = self.tail;
541        let ptr = item.into_raw() as *mut u8;
542        unsafe {
543            let node = <P::Target as DListItem<Tag>>::get_node_from_ptr(ptr);
544            node.prev = tail;
545            node.next = null_mut();
546            if tail.is_null() {
547                self.head = ptr;
548            } else {
549                <P::Target as DListItem<Tag>>::get_node_from_ptr(tail).next = ptr;
550            }
551        }
552        self.tail = ptr;
553        self.length += 1;
554    }
555
556    /// Removes and returns the element at the front of the list.
557    pub fn pop_front(&mut self) -> Option<P> {
558        if !self.head.is_null() {
559            let head_ptr = self.head;
560            unsafe {
561                self._remove_node(head_ptr);
562                Some(P::from_raw(head_ptr as *const P::Target))
563            }
564        } else {
565            None
566        }
567    }
568
569    /// Removes and returns the element at the back of the list.
570    #[inline]
571    pub fn pop_back(&mut self) -> Option<P> {
572        if !self.tail.is_null() {
573            let tail_ptr = self.tail;
574            unsafe {
575                self._remove_node(tail_ptr);
576                Some(P::from_raw(tail_ptr as *const P::Target))
577            }
578        } else {
579            None
580        }
581    }
582
583    #[inline]
584    pub fn get_front_ptr(&self) -> *const P::Target {
585        self.head as *const P::Target
586    }
587
588    /// Returns a reference to the front element.
589    #[inline]
590    pub fn get_front(&self) -> Option<&P::Target> {
591        unsafe {
592            if !self.head.is_null() { Some(&(*(self.head as *const P::Target))) } else { None }
593        }
594    }
595
596    #[inline]
597    pub fn get_back_ptr(&self) -> *const P::Target {
598        self.tail as *const P::Target
599    }
600
601    /// Returns a reference to the back element.
602    #[inline]
603    pub fn get_back(&self) -> Option<&P::Target> {
604        unsafe {
605            if !self.tail.is_null() { Some(&(*(self.tail as *const P::Target))) } else { None }
606        }
607    }
608
609    /// Checks if the given node is the head of the list.
610    #[inline(always)]
611    pub fn is_front(&self, node: &P::Target) -> bool {
612        if self.head.is_null() {
613            false
614        } else {
615            // This comparison is tricky because self.head is *mut HrcWrapper<T>
616            // and node is &mut DListNode<T>.
617            // We need to compare the node address or the wrapper address.
618            // Converting head -> node and comparing addresses of DListNode is safer.
619            ptr::eq(self.head, node as *const P::Target as *mut u8)
620        }
621    }
622
623    /// Returns an iterator over the list (borrowed).
624    ///
625    /// # NOTE
626    ///
627    /// If you plan on turn the raw pointer to owned, use drain instead
628    ///
629    /// # Safety
630    ///
631    /// The caller must ensure that the list is not modified in a way that can
632    /// invalidate internal pointers (such as removing elements or dropping
633    /// items) for the duration of the iterator's use.
634    #[inline(always)]
635    pub fn iter<'a>(&'a self) -> DLinkedListIter<'a, P, Tag> {
636        DLinkedListIter {
637            next_p: self.head,
638            len: self.len(),
639            _phan: Default::default(),
640            cur: MaybeUninit::uninit(),
641        }
642    }
643
644    /// Returns a draining iterator that removes items from the list.
645    /// Crucial for cleaning up lists containing owned pointers (like `Box`).
646    ///
647    /// # Note
648    ///
649    /// The iterator removes elements from the **front** of the list (FIFO order),
650    #[inline(always)]
651    pub fn drain<'a>(&'a mut self) -> DLinkedListDrainer<'a, P, Tag> {
652        DLinkedListDrainer { list: self, _phan: Default::default() }
653    }
654}
655
656impl<P, Tag> Drop for DLinkedList<P, Tag>
657where
658    P: Pointer,
659    P::Target: DListItem<Tag>,
660{
661    fn drop(&mut self) {
662        // Calling drain will remove all elements from the list and drop them.
663        // The DLinkedListDrainer iterator returns P, which will be dropped
664        // when the iterator is consumed.
665        if mem::needs_drop::<P>() {
666            self.drain().for_each(drop);
667        }
668    }
669}
670
671pub struct DLinkedListIter<'a, P, Tag>
672where
673    P: Pointer,
674    P::Target: DListItem<Tag>,
675{
676    next_p: *mut u8,
677    cur: MaybeUninit<P>,
678    len: usize,
679    _phan: PhantomData<&'a DLinkedList<P, Tag>>,
680}
681
682unsafe impl<'a, P, Tag> Send for DLinkedListIter<'a, P, Tag>
683where
684    P: Pointer,
685    P::Target: DListItem<Tag>,
686{
687}
688
689impl<'a, P, Tag> Iterator for DLinkedListIter<'a, P, Tag>
690where
691    P: Pointer,
692    P::Target: DListItem<Tag>,
693{
694    type Item = &'a P;
695
696    #[inline]
697    fn next(&mut self) -> Option<&'a P> {
698        if !self.next_p.is_null() {
699            self.len -= 1;
700            let cur = self.next_p;
701            unsafe {
702                self.next_p = <P::Target as DListItem<Tag>>::get_node_from_ptr(cur).next;
703                self.cur.write(P::from_raw(cur as *const P::Target));
704                // use transmute to convert lifetime from '_ to 'a
705                return Some(mem::transmute::<&P, &P>(self.cur.assume_init_ref()));
706            }
707        }
708        None
709    }
710
711    #[inline]
712    fn size_hint(&self) -> (usize, Option<usize>) {
713        (self.len, Some(self.len))
714    }
715}
716
717impl<'a, P, Tag> ExactSizeIterator for DLinkedListIter<'a, P, Tag>
718where
719    P: Pointer,
720    P::Target: DListItem<Tag>,
721{
722}
723
724pub type DLinkedListDrainer<'a, P, Tag> = Drainer<&'a mut DLinkedList<P, Tag>, P, Tag>;
725pub type DLinkedListIntoIter<P, Tag> = Drainer<DLinkedList<P, Tag>, P, Tag>;
726
727pub struct Drainer<L, P, Tag>
728where
729    L: BorrowMut<DLinkedList<P, Tag>>,
730    P: Pointer,
731    P::Target: DListItem<Tag>,
732{
733    list: L,
734    _phan: PhantomData<(P, Tag)>,
735}
736
737impl<L, P, Tag> Iterator for Drainer<L, P, Tag>
738where
739    L: BorrowMut<DLinkedList<P, Tag>>,
740    P: Pointer,
741    P::Target: DListItem<Tag>,
742{
743    type Item = P;
744
745    #[inline]
746    fn next(&mut self) -> Option<P> {
747        self.list.borrow_mut().pop_front()
748    }
749
750    #[inline]
751    fn size_hint(&self) -> (usize, Option<usize>) {
752        let l = self.list.borrow().len();
753        (l, Some(l))
754    }
755}
756
757impl<L, P, Tag> ExactSizeIterator for Drainer<L, P, Tag>
758where
759    L: BorrowMut<DLinkedList<P, Tag>>,
760    P: Pointer,
761    P::Target: DListItem<Tag>,
762{
763}
764
765impl<'a, P, Tag> IntoIterator for &'a DLinkedList<P, Tag>
766where
767    P: Pointer,
768    P::Target: DListItem<Tag>,
769{
770    type Item = &'a P;
771    type IntoIter = DLinkedListIter<'a, P, Tag>;
772
773    #[inline]
774    fn into_iter(self) -> Self::IntoIter {
775        self.iter()
776    }
777}
778
779impl<P, Tag> IntoIterator for DLinkedList<P, Tag>
780where
781    P: Pointer,
782    P::Target: DListItem<Tag>,
783{
784    type Item = P;
785    type IntoIter = DLinkedListIntoIter<P, Tag>;
786
787    #[inline]
788    fn into_iter(self) -> Self::IntoIter {
789        Drainer { list: self, _phan: Default::default() }
790    }
791}
792
793#[cfg(test)]
794mod tests {
795    use super::*;
796    use std::boxed::Box;
797    use std::cell::UnsafeCell;
798    use std::println;
799    use std::ptr::NonNull;
800    use std::sync::Arc;
801    use std::sync::atomic::{AtomicUsize, Ordering};
802
803    pub struct TestTag;
804
805    #[derive(Debug)]
806    pub struct TestNode {
807        pub value: i64,
808        pub node: UnsafeCell<DListNode<TestTag>>,
809    }
810
811    static ACTIVE_NODE_COUNT: AtomicUsize = AtomicUsize::new(0);
812
813    impl Drop for TestNode {
814        fn drop(&mut self) {
815            ACTIVE_NODE_COUNT.fetch_sub(1, Ordering::SeqCst);
816        }
817    }
818
819    unsafe impl Send for TestNode {}
820
821    unsafe impl DListItem<TestTag> for TestNode {
822        fn get_node(&self) -> &mut DListNode<TestTag> {
823            unsafe { &mut *self.node.get() }
824        }
825    }
826
827    fn new_node(v: i64) -> TestNode {
828        ACTIVE_NODE_COUNT.fetch_add(1, Ordering::SeqCst);
829        TestNode { value: v, node: UnsafeCell::new(DListNode::default()) }
830    }
831
832    #[test]
833    fn test_push_back_box() {
834        let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
835
836        let node1 = Box::new(new_node(1));
837        l.push_back(node1);
838
839        let node2 = Box::new(new_node(2));
840        l.push_back(node2);
841
842        let node3 = Box::new(new_node(3));
843        l.push_back(node3);
844
845        assert_eq!(3, l.len());
846
847        let mut iter = l.iter();
848        assert_eq!(iter.next().unwrap().value, 1);
849        assert_eq!(iter.next().unwrap().value, 2);
850        assert_eq!(iter.next().unwrap().value, 3);
851        assert!(iter.next().is_none());
852
853        {
854            let mut drain = l.drain();
855            assert_eq!(drain.next().unwrap().value, 1);
856            assert_eq!(drain.next().unwrap().value, 2);
857            assert_eq!(drain.next().unwrap().value, 3);
858            assert!(drain.next().is_none());
859        }
860        assert_eq!(l.len(), 0);
861    }
862
863    #[test]
864    fn test_push_back_arc() {
865        let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
866
867        let node1 = Arc::new(new_node(1));
868        l.push_back(node1);
869
870        let node2 = Arc::new(new_node(2));
871        l.push_back(node2);
872
873        let node3 = Arc::new(new_node(3));
874        l.push_back(node3);
875
876        assert_eq!(3, l.len());
877
878        let mut iter = l.iter();
879        assert_eq!(iter.next().unwrap().value, 1);
880        assert_eq!(iter.next().unwrap().value, 2);
881        assert_eq!(iter.next().unwrap().value, 3);
882        assert!(iter.next().is_none());
883
884        {
885            let mut drain = l.drain();
886            assert_eq!(drain.next().unwrap().value, 1);
887            assert_eq!(drain.next().unwrap().value, 2);
888            assert_eq!(drain.next().unwrap().value, 3);
889            assert!(drain.next().is_none());
890        }
891        assert_eq!(l.len(), 0);
892    }
893
894    #[test]
895    fn test_push_front_box() {
896        let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
897
898        let node3 = Box::new(new_node(3));
899        l.push_front(node3);
900
901        let node2 = Box::new(new_node(2));
902        l.push_front(node2);
903
904        let node1 = Box::new(new_node(1));
905        l.push_front(node1);
906
907        assert_eq!(3, l.len());
908
909        let mut iter = l.iter();
910        assert_eq!(iter.next().unwrap().value, 1);
911        assert_eq!(iter.next().unwrap().value, 2);
912        assert_eq!(iter.next().unwrap().value, 3);
913        assert!(iter.next().is_none());
914
915        {
916            let mut drain = l.drain();
917            assert_eq!(drain.next().unwrap().value, 1);
918            assert_eq!(drain.next().unwrap().value, 2);
919            assert_eq!(drain.next().unwrap().value, 3);
920            assert!(drain.next().is_none());
921        }
922        assert_eq!(l.len(), 0);
923    }
924
925    #[test]
926    fn test_push_front_arc() {
927        let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
928
929        let node3 = Arc::new(new_node(3));
930        l.push_front(node3);
931
932        let node2 = Arc::new(new_node(2));
933        l.push_front(node2);
934
935        let node1 = Arc::new(new_node(1));
936        l.push_front(node1);
937
938        assert_eq!(3, l.len());
939
940        let mut iter = l.iter();
941        assert_eq!(iter.next().unwrap().value, 1);
942        assert_eq!(iter.next().unwrap().value, 2);
943        assert_eq!(iter.next().unwrap().value, 3);
944        assert!(iter.next().is_none());
945
946        {
947            let mut drain = l.drain();
948            assert_eq!(drain.next().unwrap().value, 1);
949            assert_eq!(drain.next().unwrap().value, 2);
950            assert_eq!(drain.next().unwrap().value, 3);
951            assert!(drain.next().is_none());
952        }
953        assert_eq!(l.len(), 0);
954    }
955
956    #[test]
957    fn test_pop_back_box() {
958        let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
959
960        let node1 = Box::new(new_node(1));
961        l.push_back(node1);
962
963        let node2 = Box::new(new_node(2));
964        l.push_back(node2);
965
966        let node3 = Box::new(new_node(3));
967        l.push_back(node3);
968
969        let mut iter = l.iter();
970        assert_eq!(iter.next().unwrap().value, 1);
971        assert_eq!(iter.next().unwrap().value, 2);
972        assert_eq!(iter.next().unwrap().value, 3);
973        assert!(iter.next().is_none());
974
975        let del_node = l.pop_back();
976        assert_eq!(2, l.len());
977        assert!(del_node.is_some());
978        assert_eq!(del_node.unwrap().value, 3);
979
980        let mut iter_remaining = l.iter();
981        assert_eq!(iter_remaining.next().unwrap().value, 1);
982        assert_eq!(iter_remaining.next().unwrap().value, 2);
983        assert!(iter_remaining.next().is_none());
984
985        {
986            let mut drain = l.drain();
987            assert_eq!(drain.next().unwrap().value, 1);
988            assert_eq!(drain.next().unwrap().value, 2);
989            assert!(drain.next().is_none());
990        }
991        assert_eq!(l.len(), 0);
992    }
993
994    #[test]
995    fn test_pop_back_arc() {
996        let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
997
998        let node1 = Arc::new(new_node(1));
999        l.push_back(node1);
1000
1001        let node2 = Arc::new(new_node(2));
1002        l.push_back(node2);
1003
1004        let node3 = Arc::new(new_node(3));
1005        l.push_back(node3);
1006
1007        let mut iter = l.iter();
1008        assert_eq!(iter.next().unwrap().value, 1);
1009        assert_eq!(iter.next().unwrap().value, 2);
1010        assert_eq!(iter.next().unwrap().value, 3);
1011        assert!(iter.next().is_none());
1012
1013        let del_node = l.pop_back();
1014        assert_eq!(2, l.len());
1015        assert!(del_node.is_some());
1016        // Note: The value returned by Arc::from_raw must still be used.
1017        assert!(del_node.is_some());
1018
1019        // Check the order of remaining elements
1020        let mut iter = l.iter();
1021        assert_eq!(iter.next().unwrap().value, 1);
1022        assert_eq!(iter.next().unwrap().value, 2);
1023        assert!(iter.next().is_none());
1024
1025        {
1026            let mut drain = l.drain();
1027            assert_eq!(drain.next().unwrap().value, 1);
1028            assert_eq!(drain.next().unwrap().value, 2);
1029            assert!(drain.next().is_none());
1030        }
1031        assert_eq!(l.len(), 0);
1032    }
1033
1034    #[test]
1035    fn test_pop_front_arc() {
1036        let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
1037
1038        let node1 = Arc::new(new_node(1));
1039        l.push_front(node1);
1040
1041        let node2 = Arc::new(new_node(2));
1042        l.push_front(node2);
1043
1044        let node3 = Arc::new(new_node(3));
1045        l.push_front(node3);
1046
1047        let mut iter = l.iter();
1048        assert_eq!(iter.next().unwrap().value, 3);
1049        assert_eq!(iter.next().unwrap().value, 2);
1050        assert_eq!(iter.next().unwrap().value, 1);
1051        assert!(iter.next().is_none());
1052
1053        let del_node = l.pop_front();
1054        assert_eq!(2, l.len());
1055        assert!(del_node.is_some());
1056        // Note: The value returned by Arc::from_raw must still be used.
1057        assert!(del_node.is_some());
1058
1059        // Check the order of remaining elements
1060        let mut iter = l.iter();
1061        assert_eq!(iter.next().unwrap().value, 2);
1062        assert_eq!(iter.next().unwrap().value, 1);
1063        assert!(iter.next().is_none());
1064
1065        {
1066            assert_eq!(l.pop_front().unwrap().value, 2);
1067            assert_eq!(l.pop_front().unwrap().value, 1);
1068            assert!(l.pop_front().is_none());
1069            assert!(l.pop_back().is_none());
1070        }
1071        assert_eq!(l.len(), 0);
1072    }
1073
1074    #[test]
1075    fn test_iter_box() {
1076        let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
1077
1078        let mut count = 0;
1079        for _item in l.iter() {
1080            count += 1;
1081        }
1082        assert_eq!(count, 0);
1083
1084        let node1 = Box::new(new_node(1));
1085        l.push_back(node1);
1086
1087        let node2 = Box::new(new_node(2));
1088        l.push_back(node2);
1089
1090        let node3 = Box::new(new_node(3));
1091        l.push_back(node3);
1092
1093        count = 0;
1094        for item in l.iter() {
1095            count += 1;
1096            println!("{}", item.value);
1097        }
1098        assert_eq!(count, 3);
1099
1100        {
1101            let mut drain = l.drain();
1102            assert_eq!(drain.next().unwrap().value, 1);
1103            assert_eq!(drain.next().unwrap().value, 2);
1104            assert_eq!(drain.next().unwrap().value, 3);
1105            assert!(drain.next().is_none());
1106        }
1107        assert_eq!(l.len(), 0);
1108    }
1109
1110    #[test]
1111    fn test_iter_arc() {
1112        let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
1113
1114        let mut count = 0;
1115        for _item in l.iter() {
1116            count += 1;
1117        }
1118        assert_eq!(count, 0);
1119
1120        let node1 = Arc::new(new_node(1));
1121        l.push_back(node1);
1122
1123        let node2 = Arc::new(new_node(2));
1124        l.push_back(node2);
1125
1126        let node3 = Arc::new(new_node(3));
1127        l.push_back(node3);
1128
1129        // Check order
1130        let mut iter = l.iter();
1131        assert_eq!(iter.next().unwrap().value, 1);
1132        assert_eq!(iter.next().unwrap().value, 2);
1133        assert_eq!(iter.next().unwrap().value, 3);
1134        assert!(iter.next().is_none());
1135
1136        {
1137            let mut drain = l.drain();
1138            assert_eq!(drain.next().unwrap().value, 1);
1139            assert_eq!(drain.next().unwrap().value, 2);
1140            assert_eq!(drain.next().unwrap().value, 3);
1141            assert!(drain.next().is_none());
1142        }
1143        assert_eq!(l.len(), 0);
1144    }
1145
1146    #[test]
1147    fn test_single_element_box() {
1148        let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
1149        let node1 = Box::new(new_node(1));
1150        l.push_front(node1);
1151        let del_node = l.pop_back();
1152        assert!(del_node.is_some());
1153        assert_eq!(del_node.unwrap().value, 1);
1154        assert_eq!(0, l.len());
1155        assert!(l.pop_back().is_none());
1156
1157        let mut l2 = DLinkedList::<Box<TestNode>, TestTag>::new();
1158        let node2 = Box::new(new_node(2));
1159        l2.push_back(node2);
1160        let del_node2 = l2.pop_back();
1161        assert!(del_node2.is_some());
1162        assert_eq!(del_node2.unwrap().value, 2);
1163        assert_eq!(0, l2.len());
1164        assert!(l2.pop_back().is_none());
1165
1166        {
1167            let mut drain = l.drain();
1168            assert!(drain.next().is_none());
1169        }
1170        assert_eq!(l.len(), 0);
1171
1172        {
1173            let mut drain = l2.drain();
1174            assert!(drain.next().is_none());
1175        }
1176        assert_eq!(l2.len(), 0);
1177    }
1178
1179    #[test]
1180    fn test_single_element_arc() {
1181        let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
1182        let node1 = Arc::new(new_node(1));
1183        l.push_front(node1);
1184        let del_node = l.pop_back();
1185        assert!(del_node.is_some());
1186        assert_eq!(0, l.len());
1187        assert!(l.pop_back().is_none());
1188
1189        let mut l2 = DLinkedList::<Arc<TestNode>, TestTag>::new();
1190        let node2 = Arc::new(new_node(2));
1191        l2.push_back(node2);
1192        let del_node2 = l2.pop_back();
1193        assert!(del_node2.is_some());
1194        assert_eq!(0, l2.len());
1195        assert!(l2.pop_back().is_none());
1196
1197        {
1198            let mut drain = l.drain();
1199            assert!(drain.next().is_none());
1200        }
1201        assert_eq!(l.len(), 0);
1202
1203        {
1204            let mut drain = l2.drain();
1205            assert!(drain.next().is_none());
1206        }
1207        assert_eq!(l2.len(), 0);
1208    }
1209
1210    #[test]
1211    fn test_drop_box_implementation() {
1212        // Reset the counter before the test
1213        ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
1214
1215        {
1216            let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
1217
1218            let node1 = Box::new(new_node(1));
1219            l.push_back(node1);
1220
1221            let node2 = Box::new(new_node(2));
1222            l.push_back(node2);
1223
1224            let node3 = Box::new(new_node(3));
1225            l.push_back(node3);
1226
1227            assert_eq!(l.len(), 3);
1228            assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 3);
1229        } // `l` goes out of scope here, triggering DLinkedList's Drop, which drains and drops nodes.
1230
1231        // All nodes should have been dropped
1232        assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
1233    }
1234
1235    #[test]
1236    fn test_raw_pointer_list() {
1237        // Reset the counter before the test
1238        ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
1239
1240        // Manually create nodes as raw pointers
1241        let node1 = Box::into_raw(Box::new(new_node(10)));
1242        let node2 = Box::into_raw(Box::new(new_node(20)));
1243
1244        assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
1245
1246        unsafe {
1247            let mut l = DLinkedList::<*const TestNode, TestTag>::new();
1248            l.push_back(node1);
1249            l.push_back(node2);
1250
1251            let mut iter = l.iter();
1252            let item = iter.next().unwrap();
1253            assert_eq!((**item).value, 10);
1254            let item = iter.next().unwrap();
1255            assert_eq!((**item).value, 20);
1256            assert!(iter.next().is_none());
1257        } // l dropped here. Because P is *const TestNode, needs_drop is false, so drain is NOT called.
1258
1259        // Nodes should still exist
1260        assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
1261
1262        unsafe {
1263            // Check values
1264            assert_eq!((*node1).value, 10);
1265            assert_eq!((*node2).value, 20);
1266
1267            // Clean up
1268            drop(Box::from_raw(node1));
1269            drop(Box::from_raw(node2));
1270        }
1271        assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
1272    }
1273
1274    #[test]
1275    fn test_non_null_list() {
1276        // Reset the counter before the test
1277        ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
1278
1279        // Manually create nodes
1280        // Box::leak returns &mut T, which helps creating NonNull
1281        let node1 = Box::leak(Box::new(new_node(100)));
1282        let node2 = Box::leak(Box::new(new_node(200)));
1283
1284        let ptr1 = NonNull::from(node1);
1285        let ptr2 = NonNull::from(node2);
1286
1287        assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
1288
1289        unsafe {
1290            let mut l = DLinkedList::<NonNull<TestNode>, TestTag>::new();
1291            l.push_back(ptr1);
1292            l.push_back(ptr2);
1293
1294            let mut iter = l.iter();
1295            assert_eq!(iter.next().unwrap().as_ref().value, 100);
1296            assert_eq!(iter.next().unwrap().as_ref().value, 200);
1297            assert!(iter.next().is_none());
1298        } // l dropped here. NonNull doesn't need drop, so no drain.
1299
1300        // Nodes should still exist
1301        assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
1302
1303        unsafe {
1304            // Clean up
1305            drop(Box::from_raw(ptr1.as_ptr()));
1306            drop(Box::from_raw(ptr2.as_ptr()));
1307        }
1308
1309        assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
1310    }
1311
1312    #[test]
1313    fn test_clear() {
1314        ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
1315        let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
1316
1317        l.push_back(Box::new(new_node(1)));
1318        l.push_back(Box::new(new_node(2)));
1319        assert_eq!(l.len(), 2);
1320        assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
1321
1322        l.clear();
1323
1324        assert!(l.is_empty());
1325        assert_eq!(l.len(), 0);
1326        assert!(l.get_front().is_none());
1327        assert!(l.get_back().is_none());
1328        assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
1329
1330        // Can still push to the list
1331        l.push_back(Box::new(new_node(3)));
1332        assert_eq!(l.len(), 1);
1333        assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 1);
1334    }
1335
1336    #[test]
1337    fn test_remove_middle() {
1338        // Reset the counter before the test
1339        ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
1340        {
1341            let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
1342
1343            let node1 = Box::new(new_node(1));
1344            l.push_back(node1);
1345
1346            let node2 = Box::new(new_node(2));
1347
1348            // NOTE: use `node_p = node2.as_ptr()`  will trigger miri stack borrow rule.
1349            // we use into_raw and then from_raw
1350            let node2_p = Box::into_raw(node2);
1351            l.push_back(unsafe { Box::from_raw(node2_p) });
1352
1353            let node3 = Box::new(new_node(3));
1354            l.push_back(node3);
1355
1356            assert_eq!(l.len(), 3);
1357            assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 3);
1358
1359            let node2 = unsafe { l.remove_node(node2_p).unwrap() };
1360            assert_eq!(l.len(), 2);
1361            assert_eq!(node2.value, 2);
1362
1363            let node4 = Box::new(new_node(4));
1364
1365            let node4_p = Box::into_raw(node4);
1366            assert!(unsafe { l.remove_node(node4_p) }.is_none());
1367            unsafe {
1368                let _ = Box::from_raw(node4_p);
1369            }
1370        } // `l` goes out of scope here, triggering DLinkedList's Drop, which drains and drops nodes.
1371
1372        // All nodes should have been dropped
1373        assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
1374    }
1375
1376    #[test]
1377    fn test_peak_arc() {
1378        let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
1379
1380        let node1 = Arc::new(new_node(1));
1381        l.push_back(node1);
1382
1383        let node2 = Arc::new(new_node(2));
1384        l.push_back(node2);
1385
1386        let node3 = Arc::new(new_node(3));
1387        l.push_back(node3.clone());
1388
1389        let mut iter = l.iter();
1390        assert_eq!(iter.next().unwrap().value, 1);
1391        assert_eq!(iter.next().unwrap().value, 2);
1392        assert_eq!(iter.next().unwrap().value, 3);
1393        assert!(iter.next().is_none());
1394
1395        let node3_p = Arc::as_ptr(&node3);
1396
1397        unsafe { l.peak(node3_p) };
1398
1399        // Check the order of remaining elements
1400        let mut iter = l.iter();
1401        assert_eq!(iter.next().unwrap().value, 3);
1402        assert_eq!(iter.next().unwrap().value, 1);
1403        assert_eq!(iter.next().unwrap().value, 2);
1404        assert!(iter.next().is_none());
1405
1406        {
1407            let mut drain = l.drain();
1408            assert_eq!(drain.next().unwrap().value, 3);
1409            assert_eq!(drain.next().unwrap().value, 1);
1410            assert_eq!(drain.next().unwrap().value, 2);
1411            assert!(drain.next().is_none());
1412        }
1413        assert_eq!(l.len(), 0);
1414    }
1415}