1 use crate::alloc
::{Allocator, Global}
;
3 use core
::iter
::{FusedIterator, TrustedLen}
;
5 use core
::ptr
::{self, NonNull}
;
6 use core
::slice
::{self}
;
10 /// A draining iterator for `Vec<T>`.
12 /// This `struct` is created by [`Vec::drain`].
13 /// See its documentation for more.
18 /// let mut v = vec![0, 1, 2];
19 /// let iter: std::vec::Drain<_> = v.drain(..);
21 #[stable(feature = "drain", since = "1.6.0")]
25 #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + 'a = Global,
27 /// Index of tail to preserve
28 pub(super) tail_start
: usize,
30 pub(super) tail_len
: usize,
31 /// Current remaining range to remove
32 pub(super) iter
: slice
::Iter
<'a
, T
>,
33 pub(super) vec
: NonNull
<Vec
<T
, A
>>,
36 #[stable(feature = "collection_debug", since = "1.17.0")]
37 impl<T
: fmt
::Debug
, A
: Allocator
> fmt
::Debug
for Drain
<'_
, T
, A
> {
38 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
39 f
.debug_tuple("Drain").field(&self.iter
.as_slice()).finish()
43 impl<'a
, T
, A
: Allocator
> Drain
<'a
, T
, A
> {
44 /// Returns the remaining items of this iterator as a slice.
49 /// let mut vec = vec!['a', 'b', 'c'];
50 /// let mut drain = vec.drain(..);
51 /// assert_eq!(drain.as_slice(), &['a', 'b', 'c']);
52 /// let _ = drain.next().unwrap();
53 /// assert_eq!(drain.as_slice(), &['b', 'c']);
55 #[stable(feature = "vec_drain_as_slice", since = "1.46.0")]
56 pub fn as_slice(&self) -> &[T
] {
60 /// Returns a reference to the underlying allocator.
61 #[unstable(feature = "allocator_api", issue = "32838")]
63 pub fn allocator(&self) -> &A
{
64 unsafe { self.vec.as_ref().allocator() }
68 #[stable(feature = "vec_drain_as_slice", since = "1.46.0")]
69 impl<'a
, T
, A
: Allocator
> AsRef
<[T
]> for Drain
<'a
, T
, A
> {
70 fn as_ref(&self) -> &[T
] {
75 #[stable(feature = "drain", since = "1.6.0")]
76 unsafe impl<T
: Sync
, A
: Sync
+ Allocator
> Sync
for Drain
<'_
, T
, A
> {}
77 #[stable(feature = "drain", since = "1.6.0")]
78 unsafe impl<T
: Send
, A
: Send
+ Allocator
> Send
for Drain
<'_
, T
, A
> {}
80 #[stable(feature = "drain", since = "1.6.0")]
81 impl<T
, A
: Allocator
> Iterator
for Drain
<'_
, T
, A
> {
85 fn next(&mut self) -> Option
<T
> {
86 self.iter
.next().map(|elt
| unsafe { ptr::read(elt as *const _) }
)
89 fn size_hint(&self) -> (usize, Option
<usize>) {
94 #[stable(feature = "drain", since = "1.6.0")]
95 impl<T
, A
: Allocator
> DoubleEndedIterator
for Drain
<'_
, T
, A
> {
97 fn next_back(&mut self) -> Option
<T
> {
98 self.iter
.next_back().map(|elt
| unsafe { ptr::read(elt as *const _) }
)
102 #[stable(feature = "drain", since = "1.6.0")]
103 impl<T
, A
: Allocator
> Drop
for Drain
<'_
, T
, A
> {
105 /// Continues dropping the remaining elements in the `Drain`, then moves back the
106 /// un-`Drain`ed elements to restore the original `Vec`.
107 struct DropGuard
<'r
, 'a
, T
, A
: Allocator
>(&'r
mut Drain
<'a
, T
, A
>);
109 impl<'r
, 'a
, T
, A
: Allocator
> Drop
for DropGuard
<'r
, 'a
, T
, A
> {
111 // Continue the same loop we have below. If the loop already finished, this does
113 self.0.for_each
(drop
);
115 if self.0.tail_len
> 0 {
117 let source_vec
= self.0.vec
.as_mut();
118 // memmove back untouched tail, update to new length
119 let start
= source_vec
.len();
120 let tail
= self.0.tail_start
;
122 let src
= source_vec
.as_ptr().add(tail
);
123 let dst
= source_vec
.as_mut_ptr().add(start
);
124 ptr
::copy(src
, dst
, self.0.tail_len
);
126 source_vec
.set_len(start
+ self.0.tail_len
);
132 // exhaust self first
133 while let Some(item
) = self.next() {
134 let guard
= DropGuard(self);
139 // Drop a `DropGuard` to move back the non-drained tail of `self`.
144 #[stable(feature = "drain", since = "1.6.0")]
145 impl<T
, A
: Allocator
> ExactSizeIterator
for Drain
<'_
, T
, A
> {
146 fn is_empty(&self) -> bool
{
151 #[unstable(feature = "trusted_len", issue = "37572")]
152 unsafe impl<T
, A
: Allocator
> TrustedLen
for Drain
<'_
, T
, A
> {}
154 #[stable(feature = "fused", since = "1.26.0")]
155 impl<T
, A
: Allocator
> FusedIterator
for Drain
<'_
, T
, A
> {}