Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 6bf9608

Browse files
committed
refactor: moving Drain into drain.rs
1 parent 17593f2 commit 6bf9608

File tree

2 files changed

+162
-147
lines changed

2 files changed

+162
-147
lines changed

library/alloc/src/vec/drain.rs

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
use crate::alloc::{Allocator, Global};
2+
use core::iter::{
3+
FusedIterator, TrustedLen,
4+
};
5+
use core::mem::{self};
6+
use core::ptr::{self, NonNull};
7+
use core::slice::{self};
8+
use core::fmt;
9+
10+
use super::{Vec};
11+
12+
/// A draining iterator for `Vec<T>`.
13+
///
14+
/// This `struct` is created by [`Vec::drain`].
15+
/// See its documentation for more.
16+
///
17+
/// # Example
18+
///
19+
/// ```
20+
/// let mut v = vec![0, 1, 2];
21+
/// let iter: std::vec::Drain<_> = v.drain(..);
22+
/// ```
23+
#[stable(feature = "drain", since = "1.6.0")]
24+
pub struct Drain<
25+
'a,
26+
T: 'a,
27+
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + 'a = Global,
28+
> {
29+
/// Index of tail to preserve
30+
pub(super) tail_start: usize,
31+
/// Length of tail
32+
pub(super) tail_len: usize,
33+
/// Current remaining range to remove
34+
pub(super) iter: slice::Iter<'a, T>,
35+
pub(super) vec: NonNull<Vec<T, A>>,
36+
}
37+
38+
#[stable(feature = "collection_debug", since = "1.17.0")]
39+
impl<T: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, T, A> {
40+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41+
f.debug_tuple("Drain").field(&self.iter.as_slice()).finish()
42+
}
43+
}
44+
45+
impl<'a, T, A: Allocator> Drain<'a, T, A> {
46+
/// Returns the remaining items of this iterator as a slice.
47+
///
48+
/// # Examples
49+
///
50+
/// ```
51+
/// let mut vec = vec!['a', 'b', 'c'];
52+
/// let mut drain = vec.drain(..);
53+
/// assert_eq!(drain.as_slice(), &['a', 'b', 'c']);
54+
/// let _ = drain.next().unwrap();
55+
/// assert_eq!(drain.as_slice(), &['b', 'c']);
56+
/// ```
57+
#[stable(feature = "vec_drain_as_slice", since = "1.46.0")]
58+
pub fn as_slice(&self) -> &[T] {
59+
self.iter.as_slice()
60+
}
61+
62+
/// Returns a reference to the underlying allocator.
63+
#[unstable(feature = "allocator_api", issue = "32838")]
64+
#[inline]
65+
pub fn allocator(&self) -> &A {
66+
unsafe { self.vec.as_ref().allocator() }
67+
}
68+
}
69+
70+
#[stable(feature = "vec_drain_as_slice", since = "1.46.0")]
71+
impl<'a, T, A: Allocator> AsRef<[T]> for Drain<'a, T, A> {
72+
fn as_ref(&self) -> &[T] {
73+
self.as_slice()
74+
}
75+
}
76+
77+
#[stable(feature = "drain", since = "1.6.0")]
78+
unsafe impl<T: Sync, A: Sync + Allocator> Sync for Drain<'_, T, A> {}
79+
#[stable(feature = "drain", since = "1.6.0")]
80+
unsafe impl<T: Send, A: Send + Allocator> Send for Drain<'_, T, A> {}
81+
82+
#[stable(feature = "drain", since = "1.6.0")]
83+
impl<T, A: Allocator> Iterator for Drain<'_, T, A> {
84+
type Item = T;
85+
86+
#[inline]
87+
fn next(&mut self) -> Option<T> {
88+
self.iter.next().map(|elt| unsafe { ptr::read(elt as *const _) })
89+
}
90+
91+
fn size_hint(&self) -> (usize, Option<usize>) {
92+
self.iter.size_hint()
93+
}
94+
}
95+
96+
#[stable(feature = "drain", since = "1.6.0")]
97+
impl<T, A: Allocator> DoubleEndedIterator for Drain<'_, T, A> {
98+
#[inline]
99+
fn next_back(&mut self) -> Option<T> {
100+
self.iter.next_back().map(|elt| unsafe { ptr::read(elt as *const _) })
101+
}
102+
}
103+
104+
#[stable(feature = "drain", since = "1.6.0")]
105+
impl<T, A: Allocator> Drop for Drain<'_, T, A> {
106+
fn drop(&mut self) {
107+
/// Continues dropping the remaining elements in the `Drain`, then moves back the
108+
/// un-`Drain`ed elements to restore the original `Vec`.
109+
struct DropGuard<'r, 'a, T, A: Allocator>(&'r mut Drain<'a, T, A>);
110+
111+
impl<'r, 'a, T, A: Allocator> Drop for DropGuard<'r, 'a, T, A> {
112+
fn drop(&mut self) {
113+
// Continue the same loop we have below. If the loop already finished, this does
114+
// nothing.
115+
self.0.for_each(drop);
116+
117+
if self.0.tail_len > 0 {
118+
unsafe {
119+
let source_vec = self.0.vec.as_mut();
120+
// memmove back untouched tail, update to new length
121+
let start = source_vec.len();
122+
let tail = self.0.tail_start;
123+
if tail != start {
124+
let src = source_vec.as_ptr().add(tail);
125+
let dst = source_vec.as_mut_ptr().add(start);
126+
ptr::copy(src, dst, self.0.tail_len);
127+
}
128+
source_vec.set_len(start + self.0.tail_len);
129+
}
130+
}
131+
}
132+
}
133+
134+
// exhaust self first
135+
while let Some(item) = self.next() {
136+
let guard = DropGuard(self);
137+
drop(item);
138+
mem::forget(guard);
139+
}
140+
141+
// Drop a `DropGuard` to move back the non-drained tail of `self`.
142+
DropGuard(self);
143+
}
144+
}
145+
146+
#[stable(feature = "drain", since = "1.6.0")]
147+
impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {
148+
fn is_empty(&self) -> bool {
149+
self.iter.is_empty()
150+
}
151+
}
152+
153+
#[unstable(feature = "trusted_len", issue = "37572")]
154+
unsafe impl<T, A: Allocator> TrustedLen for Drain<'_, T, A> {}
155+
156+
#[stable(feature = "fused", since = "1.26.0")]
157+
impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}

library/alloc/src/vec/mod.rs

Lines changed: 5 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ pub use self::splice::Splice;
8484

8585
mod splice;
8686

87+
#[stable(feature = "drain", since = "1.6.0")]
88+
pub use self::drain::Drain;
89+
90+
mod drain;
91+
8792
/// A contiguous growable array type, written `Vec<T>` but pronounced 'vector'.
8893
///
8994
/// # Examples
@@ -3320,150 +3325,3 @@ impl<T> AsIntoIter for IntoIter<T> {
33203325
self
33213326
}
33223327
}
3323-
3324-
/// A draining iterator for `Vec<T>`.
3325-
///
3326-
/// This `struct` is created by [`Vec::drain`].
3327-
/// See its documentation for more.
3328-
///
3329-
/// # Example
3330-
///
3331-
/// ```
3332-
/// let mut v = vec![0, 1, 2];
3333-
/// let iter: std::vec::Drain<_> = v.drain(..);
3334-
/// ```
3335-
#[stable(feature = "drain", since = "1.6.0")]
3336-
pub struct Drain<
3337-
'a,
3338-
T: 'a,
3339-
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + 'a = Global,
3340-
> {
3341-
/// Index of tail to preserve
3342-
tail_start: usize,
3343-
/// Length of tail
3344-
tail_len: usize,
3345-
/// Current remaining range to remove
3346-
iter: slice::Iter<'a, T>,
3347-
vec: NonNull<Vec<T, A>>,
3348-
}
3349-
3350-
#[stable(feature = "collection_debug", since = "1.17.0")]
3351-
impl<T: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, T, A> {
3352-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3353-
f.debug_tuple("Drain").field(&self.iter.as_slice()).finish()
3354-
}
3355-
}
3356-
3357-
impl<'a, T, A: Allocator> Drain<'a, T, A> {
3358-
/// Returns the remaining items of this iterator as a slice.
3359-
///
3360-
/// # Examples
3361-
///
3362-
/// ```
3363-
/// let mut vec = vec!['a', 'b', 'c'];
3364-
/// let mut drain = vec.drain(..);
3365-
/// assert_eq!(drain.as_slice(), &['a', 'b', 'c']);
3366-
/// let _ = drain.next().unwrap();
3367-
/// assert_eq!(drain.as_slice(), &['b', 'c']);
3368-
/// ```
3369-
#[stable(feature = "vec_drain_as_slice", since = "1.46.0")]
3370-
pub fn as_slice(&self) -> &[T] {
3371-
self.iter.as_slice()
3372-
}
3373-
3374-
/// Returns a reference to the underlying allocator.
3375-
#[unstable(feature = "allocator_api", issue = "32838")]
3376-
#[inline]
3377-
pub fn allocator(&self) -> &A {
3378-
unsafe { self.vec.as_ref().allocator() }
3379-
}
3380-
}
3381-
3382-
#[stable(feature = "vec_drain_as_slice", since = "1.46.0")]
3383-
impl<'a, T, A: Allocator> AsRef<[T]> for Drain<'a, T, A> {
3384-
fn as_ref(&self) -> &[T] {
3385-
self.as_slice()
3386-
}
3387-
}
3388-
3389-
#[stable(feature = "drain", since = "1.6.0")]
3390-
unsafe impl<T: Sync, A: Sync + Allocator> Sync for Drain<'_, T, A> {}
3391-
#[stable(feature = "drain", since = "1.6.0")]
3392-
unsafe impl<T: Send, A: Send + Allocator> Send for Drain<'_, T, A> {}
3393-
3394-
#[stable(feature = "drain", since = "1.6.0")]
3395-
impl<T, A: Allocator> Iterator for Drain<'_, T, A> {
3396-
type Item = T;
3397-
3398-
#[inline]
3399-
fn next(&mut self) -> Option<T> {
3400-
self.iter.next().map(|elt| unsafe { ptr::read(elt as *const _) })
3401-
}
3402-
3403-
fn size_hint(&self) -> (usize, Option<usize>) {
3404-
self.iter.size_hint()
3405-
}
3406-
}
3407-
3408-
#[stable(feature = "drain", since = "1.6.0")]
3409-
impl<T, A: Allocator> DoubleEndedIterator for Drain<'_, T, A> {
3410-
#[inline]
3411-
fn next_back(&mut self) -> Option<T> {
3412-
self.iter.next_back().map(|elt| unsafe { ptr::read(elt as *const _) })
3413-
}
3414-
}
3415-
3416-
#[stable(feature = "drain", since = "1.6.0")]
3417-
impl<T, A: Allocator> Drop for Drain<'_, T, A> {
3418-
fn drop(&mut self) {
3419-
/// Continues dropping the remaining elements in the `Drain`, then moves back the
3420-
/// un-`Drain`ed elements to restore the original `Vec`.
3421-
struct DropGuard<'r, 'a, T, A: Allocator>(&'r mut Drain<'a, T, A>);
3422-
3423-
impl<'r, 'a, T, A: Allocator> Drop for DropGuard<'r, 'a, T, A> {
3424-
fn drop(&mut self) {
3425-
// Continue the same loop we have below. If the loop already finished, this does
3426-
// nothing.
3427-
self.0.for_each(drop);
3428-
3429-
if self.0.tail_len > 0 {
3430-
unsafe {
3431-
let source_vec = self.0.vec.as_mut();
3432-
// memmove back untouched tail, update to new length
3433-
let start = source_vec.len();
3434-
let tail = self.0.tail_start;
3435-
if tail != start {
3436-
let src = source_vec.as_ptr().add(tail);
3437-
let dst = source_vec.as_mut_ptr().add(start);
3438-
ptr::copy(src, dst, self.0.tail_len);
3439-
}
3440-
source_vec.set_len(start + self.0.tail_len);
3441-
}
3442-
}
3443-
}
3444-
}
3445-
3446-
// exhaust self first
3447-
while let Some(item) = self.next() {
3448-
let guard = DropGuard(self);
3449-
drop(item);
3450-
mem::forget(guard);
3451-
}
3452-
3453-
// Drop a `DropGuard` to move back the non-drained tail of `self`.
3454-
DropGuard(self);
3455-
}
3456-
}
3457-
3458-
#[stable(feature = "drain", since = "1.6.0")]
3459-
impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {
3460-
fn is_empty(&self) -> bool {
3461-
self.iter.is_empty()
3462-
}
3463-
}
3464-
3465-
#[unstable(feature = "trusted_len", issue = "37572")]
3466-
unsafe impl<T, A: Allocator> TrustedLen for Drain<'_, T, A> {}
3467-
3468-
#[stable(feature = "fused", since = "1.26.0")]
3469-
impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}

0 commit comments

Comments
 (0)