reusable_memory/borrow/
drain.rs1use std::{
2 fmt,
3 ops::{Bound, Range, RangeBounds}
4};
5
6use super::ReusableMemoryBorrow;
7
8pub struct BorrowDrainIter<'bor, 'mem, T: 'mem> {
11 borrow: &'bor mut ReusableMemoryBorrow<'mem, T>,
12 drain_range: Range<usize>,
13
14 tail_start: usize,
16 tail_len: usize
18}
19impl<'bor, 'mem: 'bor, T: 'mem> BorrowDrainIter<'bor, 'mem, T> {
20 pub(super) fn new(
21 borrow: &'bor mut ReusableMemoryBorrow<'mem, T>, range: impl RangeBounds<usize>
22 ) -> Self {
23 let len = borrow.len();
24 let start = match range.start_bound() {
25 Bound::Included(&n) => n,
26 Bound::Excluded(&n) => n + 1,
27 Bound::Unbounded => 0
28 };
29 let end = match range.end_bound() {
30 Bound::Included(&n) => n + 1,
31 Bound::Excluded(&n) => n,
32 Bound::Unbounded => len
33 };
34 assert!(start <= end);
35 assert!(end <= len);
36
37 unsafe {
38 borrow.set_len(start);
40
41 Self { borrow, drain_range: start .. end, tail_start: end, tail_len: len - end }
42 }
43 }
44}
45impl<T: fmt::Debug> fmt::Debug for BorrowDrainIter<'_, '_, T> {
46 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47 f.debug_tuple("BorrowDrainIter")
48 .field(unsafe {
49 &std::slice::from_raw_parts(
50 self.borrow.as_ptr().add(self.drain_range.start),
51 self.drain_range.end - self.drain_range.start
52 )
53 })
54 .finish()
55 }
56}
57impl<T> Iterator for BorrowDrainIter<'_, '_, T> {
58 type Item = T;
59
60 fn next(&mut self) -> Option<T> {
61 self.drain_range
62 .next()
63 .map(|offset| unsafe { std::ptr::read(self.borrow.as_ptr().add(offset)) })
64 }
65
66 fn size_hint(&self) -> (usize, Option<usize>) { self.drain_range.size_hint() }
67}
68impl<T> DoubleEndedIterator for BorrowDrainIter<'_, '_, T> {
69 fn next_back(&mut self) -> Option<T> {
70 self.drain_range
71 .next_back()
72 .map(|offset| unsafe { std::ptr::read(self.borrow.as_ptr().add(offset)) })
73 }
74}
75impl<T> ExactSizeIterator for BorrowDrainIter<'_, '_, T> {}
76impl<T> Drop for BorrowDrainIter<'_, '_, T> {
77 fn drop(&mut self) {
78 self.for_each(drop);
80
81 if self.tail_len > 0 {
82 unsafe {
83 let start = self.borrow.len();
84 let tail = self.tail_start;
85 if start != tail {
87 let src = self.borrow.as_ptr().add(tail);
88 let dst = self.borrow.as_mut_ptr().add(start);
89 std::ptr::copy(src, dst, self.tail_len);
90 }
91
92 self.borrow.set_len(start + self.tail_len);
93 }
94 }
95 }
96}