1use std::{marker::PhantomData, ptr::NonNull};
16
17use super::CacheRegion;
18
19#[cfg(feature = "unstable-debug-counters")]
20use crate::common::concurrent::debug_counters;
21
22#[repr(align(4))]
27#[derive(PartialEq, Eq)]
28pub(crate) struct DeqNode<T> {
29 next: Option<NonNull<DeqNode<T>>>,
30 prev: Option<NonNull<DeqNode<T>>>,
31 pub(crate) element: T,
32}
33
34impl<T> std::fmt::Debug for DeqNode<T> {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 f.debug_struct("DeqNode")
37 .field("next", &self.next)
38 .field("prev", &self.prev)
39 .finish()
40 }
41}
42
43impl<T> DeqNode<T> {
44 pub(crate) fn new(element: T) -> Self {
45 #[cfg(feature = "unstable-debug-counters")]
46 debug_counters::InternalGlobalDebugCounters::deq_node_created();
47
48 Self {
49 next: None,
50 prev: None,
51 element,
52 }
53 }
54
55 pub(crate) fn next_node_ptr(this: NonNull<Self>) -> Option<NonNull<DeqNode<T>>> {
56 unsafe { this.as_ref() }.next
57 }
58}
59
60#[cfg(feature = "unstable-debug-counters")]
61impl<T> Drop for DeqNode<T> {
62 fn drop(&mut self) {
63 debug_counters::InternalGlobalDebugCounters::deq_node_dropped();
64 }
65}
66
67enum DeqCursor<T> {
69 Node(NonNull<DeqNode<T>>),
70 Done,
71}
72
73pub(crate) struct Deque<T> {
74 region: CacheRegion,
75 len: usize,
76 head: Option<NonNull<DeqNode<T>>>,
77 tail: Option<NonNull<DeqNode<T>>>,
78 cursor: Option<DeqCursor<T>>,
79 marker: PhantomData<Box<DeqNode<T>>>,
80}
81
82impl<T> Drop for Deque<T> {
83 fn drop(&mut self) {
84 struct DropGuard<'a, T>(&'a mut Deque<T>);
85
86 impl<T> Drop for DropGuard<'_, T> {
87 fn drop(&mut self) {
88 while self.0.pop_front().is_some() {}
91 }
92 }
93
94 while let Some(node) = self.pop_front() {
95 let guard = DropGuard(self);
96 drop(node);
97 std::mem::forget(guard);
98 }
99 }
100}
101
102impl<T> Deque<T> {
104 pub(crate) fn new(region: CacheRegion) -> Self {
105 Self {
106 region,
107 len: 0,
108 head: None,
109 tail: None,
110 cursor: None,
111 marker: PhantomData,
112 }
113 }
114
115 pub(crate) fn region(&self) -> CacheRegion {
116 self.region
117 }
118
119 pub(crate) fn len(&self) -> usize {
120 self.len
121 }
122
123 pub(crate) fn contains(&self, node: &DeqNode<T>) -> bool {
124 node.prev.is_some() || self.is_head(node)
125 }
126
127 pub(crate) fn peek_front(&self) -> Option<&DeqNode<T>> {
128 self.head.as_ref().map(|node| unsafe { node.as_ref() })
129 }
130
131 pub(crate) fn peek_front_ptr(&self) -> Option<NonNull<DeqNode<T>>> {
132 self.head.as_ref().copied()
133 }
134
135 pub(crate) fn pop_front(&mut self) -> Option<Box<DeqNode<T>>> {
137 self.head.map(|node| unsafe {
140 if self.is_at_cursor(node.as_ref()) {
141 self.advance_cursor();
142 }
143
144 let mut node = Box::from_raw(node.as_ptr());
145 self.head = node.next;
146
147 match self.head {
148 None => self.tail = None,
149 Some(head) => (*head.as_ptr()).prev = None,
151 }
152
153 self.len -= 1;
154
155 node.prev = None;
156 node.next = None;
157 node
158 })
159 }
160
161 pub(crate) fn peek_back(&self) -> Option<&DeqNode<T>> {
162 self.tail.as_ref().map(|node| unsafe { node.as_ref() })
163 }
164
165 pub(crate) fn push_back(&mut self, mut node: Box<DeqNode<T>>) -> NonNull<DeqNode<T>> {
167 unsafe {
170 node.next = None;
171 node.prev = self.tail;
172 let node = NonNull::new(Box::into_raw(node)).expect("Got a null ptr");
173
174 match self.tail {
175 None => self.head = Some(node),
176 Some(tail) => (*tail.as_ptr()).next = Some(node),
178 }
179
180 self.tail = Some(node);
181 self.len += 1;
182 node
183 }
184 }
185
186 pub(crate) unsafe fn move_to_back(&mut self, mut node: NonNull<DeqNode<T>>) {
187 if self.is_tail(node.as_ref()) {
188 return;
190 }
191
192 if self.is_at_cursor(node.as_ref()) {
193 self.advance_cursor();
194 }
195
196 let node = node.as_mut(); match node.prev {
200 Some(prev) if node.next.is_some() => (*prev.as_ptr()).next = node.next,
201 Some(..) => (),
202 None => self.head = node.next,
204 };
205
206 if let Some(next) = node.next.take() {
208 (*next.as_ptr()).prev = node.prev;
209
210 let mut node = NonNull::from(node);
211 match self.tail {
212 Some(tail) => {
214 node.as_mut().prev = Some(tail);
215 (*tail.as_ptr()).next = Some(node);
216 }
217 None => unreachable!(),
218 }
219 self.tail = Some(node);
220 }
221 }
222
223 pub(crate) fn move_front_to_back(&mut self) {
224 if let Some(node) = self.head {
225 unsafe { self.move_to_back(node) };
226 }
227 }
228
229 pub(crate) unsafe fn unlink(&mut self, mut node: NonNull<DeqNode<T>>) {
238 if self.is_at_cursor(node.as_ref()) {
239 self.advance_cursor();
240 }
241
242 let node = node.as_mut(); match node.prev {
246 Some(prev) => (*prev.as_ptr()).next = node.next,
247 None => self.head = node.next,
249 };
250
251 match node.next {
252 Some(next) => (*next.as_ptr()).prev = node.prev,
253 None => self.tail = node.prev,
255 };
256
257 node.prev = None;
258 node.next = None;
259
260 self.len -= 1;
261 }
262
263 pub(crate) unsafe fn unlink_and_drop(&mut self, node: NonNull<DeqNode<T>>) {
270 self.unlink(node);
271 std::mem::drop(Box::from_raw(node.as_ptr()));
272 }
273
274 pub(crate) fn reset_cursor(&mut self) {
275 self.cursor = None;
276 }
277}
278
279impl<'a, T> Iterator for &'a mut Deque<T> {
280 type Item = &'a T;
281
282 fn next(&mut self) -> Option<Self::Item> {
283 if self.cursor.is_none() {
284 if let Some(head) = self.head {
285 self.cursor = Some(DeqCursor::Node(head));
286 }
287 }
288 let elem = if let Some(DeqCursor::Node(node)) = self.cursor {
289 unsafe { Some(&(*node.as_ptr()).element) }
290 } else {
291 None
292 };
293 self.advance_cursor();
294 elem
295 }
296}
297
298impl<T> Deque<T> {
300 fn is_head(&self, node: &DeqNode<T>) -> bool {
301 if let Some(head) = self.head {
302 std::ptr::eq(unsafe { head.as_ref() }, node)
303 } else {
304 false
305 }
306 }
307
308 fn is_tail(&self, node: &DeqNode<T>) -> bool {
309 if let Some(tail) = self.tail {
310 std::ptr::eq(unsafe { tail.as_ref() }, node)
311 } else {
312 false
313 }
314 }
315
316 fn is_at_cursor(&self, node: &DeqNode<T>) -> bool {
317 if let Some(DeqCursor::Node(cur_node)) = self.cursor {
318 std::ptr::eq(unsafe { cur_node.as_ref() }, node)
319 } else {
320 false
321 }
322 }
323
324 fn advance_cursor(&mut self) {
325 match self.cursor.take() {
326 None => (),
327 Some(DeqCursor::Node(node)) => unsafe {
328 if let Some(next) = (*node.as_ptr()).next {
329 self.cursor = Some(DeqCursor::Node(next));
330 } else {
331 self.cursor = Some(DeqCursor::Done);
332 }
333 },
334 Some(DeqCursor::Done) => {
335 self.cursor = None;
336 }
337 }
338 }
339}
340
341#[cfg(test)]
342mod tests {
343 use super::{CacheRegion::MainProbation, DeqNode, Deque};
344
345 #[test]
346 #[allow(clippy::cognitive_complexity)]
347 fn basics() {
348 let mut deque: Deque<String> = Deque::new(MainProbation);
349 assert_eq!(deque.len(), 0);
350 assert!(deque.peek_front().is_none());
351 assert!(deque.peek_back().is_none());
352
353 let node1 = DeqNode::new("a".to_string());
355 assert!(!deque.contains(&node1));
356 let node1 = Box::new(node1);
357 let node1_ptr = deque.push_back(node1);
358 assert_eq!(deque.len(), 1);
359
360 let head_a = deque.peek_front().unwrap();
362 assert!(deque.contains(head_a));
363 assert!(deque.is_head(head_a));
364 assert!(deque.is_tail(head_a));
365 assert_eq!(head_a.element, "a".to_string());
366
367 unsafe { deque.move_to_back(node1_ptr) };
369 assert_eq!(deque.len(), 1);
370
371 let head_b = deque.peek_front().unwrap();
373 assert!(deque.contains(head_b));
374 assert!(deque.is_head(head_b));
375 assert!(deque.is_tail(head_b));
376 assert!(std::ptr::eq(head_b, node1_ptr.as_ptr()));
377 assert!(head_b.prev.is_none());
378 assert!(head_b.next.is_none());
379
380 let tail_a = deque.peek_back().unwrap();
382 assert!(deque.contains(tail_a));
383 assert!(deque.is_head(tail_a));
384 assert!(deque.is_tail(tail_a));
385 assert!(std::ptr::eq(tail_a, node1_ptr.as_ptr()));
386 assert!(tail_a.prev.is_none());
387 assert!(tail_a.next.is_none());
388
389 let node2 = DeqNode::new("b".to_string());
391 assert!(!deque.contains(&node2));
392 let node2_ptr = deque.push_back(Box::new(node2));
393 assert_eq!(deque.len(), 2);
394
395 let head_c = deque.peek_front().unwrap();
397 assert!(deque.contains(head_c));
398 assert!(deque.is_head(head_c));
399 assert!(!deque.is_tail(head_c));
400 assert!(std::ptr::eq(head_c, node1_ptr.as_ptr()));
401 assert!(head_c.prev.is_none());
402 assert!(std::ptr::eq(
403 head_c.next.unwrap().as_ptr(),
404 node2_ptr.as_ptr()
405 ));
406
407 unsafe { deque.move_to_back(node2_ptr) };
409 assert_eq!(deque.len(), 2);
410
411 let head_d = deque.peek_front().unwrap();
413 assert!(deque.contains(head_d));
414 assert!(deque.is_head(head_d));
415 assert!(!deque.is_tail(head_d));
416 assert!(std::ptr::eq(head_d, node1_ptr.as_ptr()));
417 assert!(head_d.prev.is_none());
418 assert!(std::ptr::eq(
419 head_d.next.unwrap().as_ptr(),
420 node2_ptr.as_ptr()
421 ));
422
423 let tail_b = deque.peek_back().unwrap();
425 assert!(deque.contains(tail_b));
426 assert!(!deque.is_head(tail_b));
427 assert!(deque.is_tail(tail_b));
428 assert!(std::ptr::eq(tail_b, node2_ptr.as_ptr()));
429 assert!(std::ptr::eq(
430 tail_b.prev.unwrap().as_ptr(),
431 node1_ptr.as_ptr()
432 ));
433 assert_eq!(tail_b.element, "b".to_string());
434 assert!(tail_b.next.is_none());
435
436 unsafe { deque.move_to_back(node1_ptr) };
438 assert_eq!(deque.len(), 2);
439
440 let head_e = deque.peek_front().unwrap();
442 assert!(deque.contains(head_e));
443 assert!(deque.is_head(head_e));
444 assert!(!deque.is_tail(head_e));
445 assert!(std::ptr::eq(head_e, node2_ptr.as_ptr()));
446 assert!(head_e.prev.is_none());
447 assert!(std::ptr::eq(
448 head_e.next.unwrap().as_ptr(),
449 node1_ptr.as_ptr()
450 ));
451
452 let tail_c = deque.peek_back().unwrap();
454 assert!(deque.contains(tail_c));
455 assert!(!deque.is_head(tail_c));
456 assert!(deque.is_tail(tail_c));
457 assert!(std::ptr::eq(tail_c, node1_ptr.as_ptr()));
458 assert!(std::ptr::eq(
459 tail_c.prev.unwrap().as_ptr(),
460 node2_ptr.as_ptr()
461 ));
462 assert!(tail_c.next.is_none());
463
464 let node3 = DeqNode::new("c".to_string());
466 assert!(!deque.contains(&node3));
467 let node3_ptr = deque.push_back(Box::new(node3));
468 assert_eq!(deque.len(), 3);
469
470 let head_f = deque.peek_front().unwrap();
472 assert!(deque.contains(head_f));
473 assert!(deque.is_head(head_f));
474 assert!(!deque.is_tail(head_f));
475 assert!(std::ptr::eq(head_f, node2_ptr.as_ptr()));
476 assert!(head_f.prev.is_none());
477 assert!(std::ptr::eq(
478 head_f.next.unwrap().as_ptr(),
479 node1_ptr.as_ptr()
480 ));
481
482 let tail_d = deque.peek_back().unwrap();
484 assert!(std::ptr::eq(tail_d, node3_ptr.as_ptr()));
485 assert_eq!(tail_d.element, "c".to_string());
486 assert!(deque.contains(tail_d));
487 assert!(!deque.is_head(tail_d));
488 assert!(deque.is_tail(tail_d));
489 assert!(std::ptr::eq(tail_d, node3_ptr.as_ptr()));
490 assert!(std::ptr::eq(
491 tail_d.prev.unwrap().as_ptr(),
492 node1_ptr.as_ptr()
493 ));
494 assert!(tail_d.next.is_none());
495
496 unsafe { deque.move_to_back(node1_ptr) };
498 assert_eq!(deque.len(), 3);
499
500 let head_g = deque.peek_front().unwrap();
502 assert!(deque.contains(head_g));
503 assert!(deque.is_head(head_g));
504 assert!(!deque.is_tail(head_g));
505 assert!(std::ptr::eq(head_g, node2_ptr.as_ptr()));
506 assert!(head_g.prev.is_none());
507 assert!(std::ptr::eq(
508 head_g.next.unwrap().as_ptr(),
509 node3_ptr.as_ptr()
510 ));
511
512 let tail_e = deque.peek_back().unwrap();
514 assert!(deque.contains(tail_e));
515 assert!(!deque.is_head(tail_e));
516 assert!(deque.is_tail(tail_e));
517 assert!(std::ptr::eq(tail_e, node1_ptr.as_ptr()));
518 assert!(std::ptr::eq(
519 tail_e.prev.unwrap().as_ptr(),
520 node3_ptr.as_ptr()
521 ));
522 assert!(tail_e.next.is_none());
523
524 unsafe { deque.unlink(node3_ptr) };
526 assert_eq!(deque.len(), 2);
527 let node3_ref = unsafe { node3_ptr.as_ref() };
528 assert!(!deque.contains(node3_ref));
529 assert!(node3_ref.next.is_none());
530 assert!(node3_ref.next.is_none());
531 std::mem::drop(unsafe { Box::from_raw(node3_ptr.as_ptr()) });
532
533 let head_h = deque.peek_front().unwrap();
535 assert!(deque.contains(head_h));
536 assert!(deque.is_head(head_h));
537 assert!(!deque.is_tail(head_h));
538 assert!(std::ptr::eq(head_h, node2_ptr.as_ptr()));
539 assert!(head_h.prev.is_none());
540 assert!(std::ptr::eq(
541 head_h.next.unwrap().as_ptr(),
542 node1_ptr.as_ptr()
543 ));
544
545 let tail_f = deque.peek_back().unwrap();
547 assert!(deque.contains(tail_f));
548 assert!(!deque.is_head(tail_f));
549 assert!(deque.is_tail(tail_f));
550 assert!(std::ptr::eq(tail_f, node1_ptr.as_ptr()));
551 assert!(std::ptr::eq(
552 tail_f.prev.unwrap().as_ptr(),
553 node2_ptr.as_ptr()
554 ));
555 assert!(tail_f.next.is_none());
556
557 unsafe { deque.unlink(node2_ptr) };
559 assert_eq!(deque.len(), 1);
560 let node2_ref = unsafe { node2_ptr.as_ref() };
561 assert!(!deque.contains(node2_ref));
562 assert!(node2_ref.next.is_none());
563 assert!(node2_ref.next.is_none());
564 std::mem::drop(unsafe { Box::from_raw(node2_ptr.as_ptr()) });
565
566 let head_g = deque.peek_front().unwrap();
568 assert!(deque.contains(head_g));
569 assert!(deque.is_head(head_g));
570 assert!(deque.is_tail(head_g));
571 assert!(std::ptr::eq(head_g, node1_ptr.as_ptr()));
572 assert!(head_g.prev.is_none());
573 assert!(head_g.next.is_none());
574
575 let tail_g = deque.peek_back().unwrap();
577 assert!(deque.contains(tail_g));
578 assert!(deque.is_head(tail_g));
579 assert!(deque.is_tail(tail_g));
580 assert!(std::ptr::eq(tail_g, node1_ptr.as_ptr()));
581 assert!(tail_g.next.is_none());
582 assert!(tail_g.next.is_none());
583
584 unsafe { deque.unlink(node1_ptr) };
586 assert_eq!(deque.len(), 0);
587 let node1_ref = unsafe { node1_ptr.as_ref() };
588 assert!(!deque.contains(node1_ref));
589 assert!(node1_ref.next.is_none());
590 assert!(node1_ref.next.is_none());
591 std::mem::drop(unsafe { Box::from_raw(node1_ptr.as_ptr()) });
592
593 let head_h = deque.peek_front();
595 assert!(head_h.is_none());
596
597 let tail_e = deque.peek_back();
599 assert!(tail_e.is_none());
600 }
601
602 #[test]
603 fn iter() {
604 let mut deque: Deque<String> = Deque::new(MainProbation);
605 assert!((&mut deque).next().is_none());
606
607 let node1 = DeqNode::new("a".into());
608 deque.push_back(Box::new(node1));
609 let node2 = DeqNode::new("b".into());
610 let node2_ptr = deque.push_back(Box::new(node2));
611 let node3 = DeqNode::new("c".into());
612 let node3_ptr = deque.push_back(Box::new(node3));
613
614 assert_eq!((&mut deque).next(), Some(&"a".into()));
617 assert_eq!((&mut deque).next(), Some(&"b".into()));
618 assert_eq!((&mut deque).next(), Some(&"c".into()));
619 assert!((&mut deque).next().is_none());
620
621 assert_eq!((&mut deque).next(), Some(&"a".into()));
624 assert_eq!((&mut deque).next(), Some(&"b".into()));
625 assert_eq!((&mut deque).next(), Some(&"c".into()));
626 assert!((&mut deque).next().is_none());
627
628 assert_eq!((&mut deque).next(), Some(&"a".into()));
631 assert_eq!((&mut deque).next(), Some(&"b".into()));
632 deque.reset_cursor();
633 assert_eq!((&mut deque).next(), Some(&"a".into()));
634 assert_eq!((&mut deque).next(), Some(&"b".into()));
635 assert_eq!((&mut deque).next(), Some(&"c".into()));
636 assert!((&mut deque).next().is_none());
637
638 assert_eq!((&mut deque).next(), Some(&"a".into()));
641 unsafe { deque.move_to_back(node2_ptr) };
643 assert_eq!((&mut deque).next(), Some(&"c".into()));
645 assert_eq!((&mut deque).next(), Some(&"b".into()));
646 assert!((&mut deque).next().is_none());
647
648 assert_eq!((&mut deque).next(), Some(&"a".into()));
651 unsafe { deque.unlink_and_drop(node3_ptr) };
653 assert_eq!((&mut deque).next(), Some(&"b".into()));
655 assert!((&mut deque).next().is_none());
656
657 let node3 = DeqNode::new("c".into());
660 deque.push_back(Box::new(node3));
661
662 assert_eq!((&mut deque).next(), Some(&"a".into()));
663 deque.pop_front(); deque.pop_front(); assert_eq!((&mut deque).next(), Some(&"c".into()));
668 assert!((&mut deque).next().is_none());
669
670 deque.pop_front(); assert!((&mut deque).next().is_none());
674 assert!((&mut deque).next().is_none());
675 }
676
677 #[test]
678 fn next_node() {
679 let mut deque: Deque<String> = Deque::new(MainProbation);
680
681 let node1 = DeqNode::new("a".into());
682 deque.push_back(Box::new(node1));
683 let node2 = DeqNode::new("b".into());
684 let node2_ptr = deque.push_back(Box::new(node2));
685 let node3 = DeqNode::new("c".into());
686 let node3_ptr = deque.push_back(Box::new(node3));
687
688 let node1a = deque.peek_front_ptr().unwrap();
692 assert_eq!(unsafe { node1a.as_ref() }.element, "a".to_string());
693 let node2a = DeqNode::next_node_ptr(node1a).unwrap();
694 assert_eq!(unsafe { node2a.as_ref() }.element, "b".to_string());
695 let node3a = DeqNode::next_node_ptr(node2a).unwrap();
696 assert_eq!(unsafe { node3a.as_ref() }.element, "c".to_string());
697 assert!(DeqNode::next_node_ptr(node3a).is_none());
698
699 unsafe { deque.move_to_back(node2_ptr) };
703 let node1a = deque.peek_front_ptr().unwrap();
704 assert_eq!(unsafe { node1a.as_ref() }.element, "a".to_string());
705 let node3a = DeqNode::next_node_ptr(node1a).unwrap();
706 assert_eq!(unsafe { node3a.as_ref() }.element, "c".to_string());
707 let node2a = DeqNode::next_node_ptr(node3a).unwrap();
708 assert_eq!(unsafe { node2a.as_ref() }.element, "b".to_string());
709 assert!(DeqNode::next_node_ptr(node2a).is_none());
710
711 unsafe { deque.unlink_and_drop(node3_ptr) };
715 let node1a = deque.peek_front_ptr().unwrap();
716 assert_eq!(unsafe { node1a.as_ref() }.element, "a".to_string());
717 let node2a = DeqNode::next_node_ptr(node1a).unwrap();
718 assert_eq!(unsafe { node2a.as_ref() }.element, "b".to_string());
719 assert!(DeqNode::next_node_ptr(node2a).is_none());
720 }
721
722 #[test]
723 fn peek_and_move_to_back() {
724 let mut deque: Deque<String> = Deque::new(MainProbation);
725
726 let node1 = DeqNode::new("a".into());
727 deque.push_back(Box::new(node1));
728 let node2 = DeqNode::new("b".into());
729 let _ = deque.push_back(Box::new(node2));
730 let node3 = DeqNode::new("c".into());
731 let _ = deque.push_back(Box::new(node3));
732 let node1a = deque.peek_front_ptr().unwrap();
735 assert_eq!(unsafe { node1a.as_ref() }.element, "a".to_string());
736 unsafe { deque.move_to_back(node1a) };
737 let node2a = deque.peek_front_ptr().unwrap();
740 assert_eq!(unsafe { node2a.as_ref() }.element, "b".to_string());
741
742 let node3a = DeqNode::next_node_ptr(node2a).unwrap();
743 assert_eq!(unsafe { node3a.as_ref() }.element, "c".to_string());
744 unsafe { deque.move_to_back(node3a) };
745 deque.move_front_to_back();
748 let node1b = deque.peek_front().unwrap();
751 assert_eq!(node1b.element, "a".to_string());
752 }
753
754 #[test]
755 fn drop() {
756 use std::{cell::RefCell, rc::Rc};
757
758 struct X(u32, Rc<RefCell<Vec<u32>>>);
759
760 impl Drop for X {
761 fn drop(&mut self) {
762 self.1.borrow_mut().push(self.0)
763 }
764 }
765
766 let mut deque: Deque<X> = Deque::new(MainProbation);
767 let dropped = Rc::new(RefCell::new(Vec::default()));
768
769 let node1 = DeqNode::new(X(1, Rc::clone(&dropped)));
770 let node2 = DeqNode::new(X(2, Rc::clone(&dropped)));
771 let node3 = DeqNode::new(X(3, Rc::clone(&dropped)));
772 let node4 = DeqNode::new(X(4, Rc::clone(&dropped)));
773 deque.push_back(Box::new(node1));
774 deque.push_back(Box::new(node2));
775 deque.push_back(Box::new(node3));
776 deque.push_back(Box::new(node4));
777 assert_eq!(deque.len(), 4);
778
779 std::mem::drop(deque);
780
781 assert_eq!(*dropped.borrow(), &[1, 2, 3, 4]);
782 }
783}