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

Commit 17593f2

Browse files
committed
refactor: moving Splice into splice.rs
1 parent 434e5d1 commit 17593f2

File tree

2 files changed

+138
-128
lines changed

2 files changed

+138
-128
lines changed

library/alloc/src/vec/mod.rs

Lines changed: 5 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ pub use self::drain_filter::DrainFilter;
7979

8080
mod drain_filter;
8181

82+
#[stable(feature = "vec_splice", since = "1.21.0")]
83+
pub use self::splice::Splice;
84+
85+
mod splice;
86+
8287
/// A contiguous growable array type, written `Vec<T>` but pronounced 'vector'.
8388
///
8489
/// # Examples
@@ -3462,131 +3467,3 @@ unsafe impl<T, A: Allocator> TrustedLen for Drain<'_, T, A> {}
34623467

34633468
#[stable(feature = "fused", since = "1.26.0")]
34643469
impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}
3465-
3466-
/// A splicing iterator for `Vec`.
3467-
///
3468-
/// This struct is created by [`Vec::splice()`].
3469-
/// See its documentation for more.
3470-
///
3471-
/// # Example
3472-
///
3473-
/// ```
3474-
/// let mut v = vec![0, 1, 2];
3475-
/// let new = [7, 8];
3476-
/// let iter: std::vec::Splice<_> = v.splice(1.., new.iter().cloned());
3477-
/// ```
3478-
#[derive(Debug)]
3479-
#[stable(feature = "vec_splice", since = "1.21.0")]
3480-
pub struct Splice<
3481-
'a,
3482-
I: Iterator + 'a,
3483-
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + 'a = Global,
3484-
> {
3485-
drain: Drain<'a, I::Item, A>,
3486-
replace_with: I,
3487-
}
3488-
3489-
#[stable(feature = "vec_splice", since = "1.21.0")]
3490-
impl<I: Iterator, A: Allocator> Iterator for Splice<'_, I, A> {
3491-
type Item = I::Item;
3492-
3493-
fn next(&mut self) -> Option<Self::Item> {
3494-
self.drain.next()
3495-
}
3496-
3497-
fn size_hint(&self) -> (usize, Option<usize>) {
3498-
self.drain.size_hint()
3499-
}
3500-
}
3501-
3502-
#[stable(feature = "vec_splice", since = "1.21.0")]
3503-
impl<I: Iterator, A: Allocator> DoubleEndedIterator for Splice<'_, I, A> {
3504-
fn next_back(&mut self) -> Option<Self::Item> {
3505-
self.drain.next_back()
3506-
}
3507-
}
3508-
3509-
#[stable(feature = "vec_splice", since = "1.21.0")]
3510-
impl<I: Iterator, A: Allocator> ExactSizeIterator for Splice<'_, I, A> {}
3511-
3512-
#[stable(feature = "vec_splice", since = "1.21.0")]
3513-
impl<I: Iterator, A: Allocator> Drop for Splice<'_, I, A> {
3514-
fn drop(&mut self) {
3515-
self.drain.by_ref().for_each(drop);
3516-
3517-
unsafe {
3518-
if self.drain.tail_len == 0 {
3519-
self.drain.vec.as_mut().extend(self.replace_with.by_ref());
3520-
return;
3521-
}
3522-
3523-
// First fill the range left by drain().
3524-
if !self.drain.fill(&mut self.replace_with) {
3525-
return;
3526-
}
3527-
3528-
// There may be more elements. Use the lower bound as an estimate.
3529-
// FIXME: Is the upper bound a better guess? Or something else?
3530-
let (lower_bound, _upper_bound) = self.replace_with.size_hint();
3531-
if lower_bound > 0 {
3532-
self.drain.move_tail(lower_bound);
3533-
if !self.drain.fill(&mut self.replace_with) {
3534-
return;
3535-
}
3536-
}
3537-
3538-
// Collect any remaining elements.
3539-
// This is a zero-length vector which does not allocate if `lower_bound` was exact.
3540-
let mut collected = self.replace_with.by_ref().collect::<Vec<I::Item>>().into_iter();
3541-
// Now we have an exact count.
3542-
if collected.len() > 0 {
3543-
self.drain.move_tail(collected.len());
3544-
let filled = self.drain.fill(&mut collected);
3545-
debug_assert!(filled);
3546-
debug_assert_eq!(collected.len(), 0);
3547-
}
3548-
}
3549-
// Let `Drain::drop` move the tail back if necessary and restore `vec.len`.
3550-
}
3551-
}
3552-
3553-
/// Private helper methods for `Splice::drop`
3554-
impl<T, A: Allocator> Drain<'_, T, A> {
3555-
/// The range from `self.vec.len` to `self.tail_start` contains elements
3556-
/// that have been moved out.
3557-
/// Fill that range as much as possible with new elements from the `replace_with` iterator.
3558-
/// Returns `true` if we filled the entire range. (`replace_with.next()` didn’t return `None`.)
3559-
unsafe fn fill<I: Iterator<Item = T>>(&mut self, replace_with: &mut I) -> bool {
3560-
let vec = unsafe { self.vec.as_mut() };
3561-
let range_start = vec.len;
3562-
let range_end = self.tail_start;
3563-
let range_slice = unsafe {
3564-
slice::from_raw_parts_mut(vec.as_mut_ptr().add(range_start), range_end - range_start)
3565-
};
3566-
3567-
for place in range_slice {
3568-
if let Some(new_item) = replace_with.next() {
3569-
unsafe { ptr::write(place, new_item) };
3570-
vec.len += 1;
3571-
} else {
3572-
return false;
3573-
}
3574-
}
3575-
true
3576-
}
3577-
3578-
/// Makes room for inserting more elements before the tail.
3579-
unsafe fn move_tail(&mut self, additional: usize) {
3580-
let vec = unsafe { self.vec.as_mut() };
3581-
let len = self.tail_start + self.tail_len;
3582-
vec.buf.reserve(len, additional);
3583-
3584-
let new_tail_start = self.tail_start + additional;
3585-
unsafe {
3586-
let src = vec.as_ptr().add(self.tail_start);
3587-
let dst = vec.as_mut_ptr().add(new_tail_start);
3588-
ptr::copy(src, dst, self.tail_len);
3589-
}
3590-
self.tail_start = new_tail_start;
3591-
}
3592-
}

library/alloc/src/vec/splice.rs

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
use crate::alloc::{Allocator, Global};
2+
use core::ptr::{self};
3+
use core::slice::{self};
4+
5+
use super::{Vec, Drain};
6+
7+
/// A splicing iterator for `Vec`.
8+
///
9+
/// This struct is created by [`Vec::splice()`].
10+
/// See its documentation for more.
11+
///
12+
/// # Example
13+
///
14+
/// ```
15+
/// let mut v = vec![0, 1, 2];
16+
/// let new = [7, 8];
17+
/// let iter: std::vec::Splice<_> = v.splice(1.., new.iter().cloned());
18+
/// ```
19+
#[derive(Debug)]
20+
#[stable(feature = "vec_splice", since = "1.21.0")]
21+
pub struct Splice<
22+
'a,
23+
I: Iterator + 'a,
24+
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + 'a = Global,
25+
> {
26+
pub(super) drain: Drain<'a, I::Item, A>,
27+
pub(super) replace_with: I,
28+
}
29+
30+
#[stable(feature = "vec_splice", since = "1.21.0")]
31+
impl<I: Iterator, A: Allocator> Iterator for Splice<'_, I, A> {
32+
type Item = I::Item;
33+
34+
fn next(&mut self) -> Option<Self::Item> {
35+
self.drain.next()
36+
}
37+
38+
fn size_hint(&self) -> (usize, Option<usize>) {
39+
self.drain.size_hint()
40+
}
41+
}
42+
43+
#[stable(feature = "vec_splice", since = "1.21.0")]
44+
impl<I: Iterator, A: Allocator> DoubleEndedIterator for Splice<'_, I, A> {
45+
fn next_back(&mut self) -> Option<Self::Item> {
46+
self.drain.next_back()
47+
}
48+
}
49+
50+
#[stable(feature = "vec_splice", since = "1.21.0")]
51+
impl<I: Iterator, A: Allocator> ExactSizeIterator for Splice<'_, I, A> {}
52+
53+
#[stable(feature = "vec_splice", since = "1.21.0")]
54+
impl<I: Iterator, A: Allocator> Drop for Splice<'_, I, A> {
55+
fn drop(&mut self) {
56+
self.drain.by_ref().for_each(drop);
57+
58+
unsafe {
59+
if self.drain.tail_len == 0 {
60+
self.drain.vec.as_mut().extend(self.replace_with.by_ref());
61+
return;
62+
}
63+
64+
// First fill the range left by drain().
65+
if !self.drain.fill(&mut self.replace_with) {
66+
return;
67+
}
68+
69+
// There may be more elements. Use the lower bound as an estimate.
70+
// FIXME: Is the upper bound a better guess? Or something else?
71+
let (lower_bound, _upper_bound) = self.replace_with.size_hint();
72+
if lower_bound > 0 {
73+
self.drain.move_tail(lower_bound);
74+
if !self.drain.fill(&mut self.replace_with) {
75+
return;
76+
}
77+
}
78+
79+
// Collect any remaining elements.
80+
// This is a zero-length vector which does not allocate if `lower_bound` was exact.
81+
let mut collected = self.replace_with.by_ref().collect::<Vec<I::Item>>().into_iter();
82+
// Now we have an exact count.
83+
if collected.len() > 0 {
84+
self.drain.move_tail(collected.len());
85+
let filled = self.drain.fill(&mut collected);
86+
debug_assert!(filled);
87+
debug_assert_eq!(collected.len(), 0);
88+
}
89+
}
90+
// Let `Drain::drop` move the tail back if necessary and restore `vec.len`.
91+
}
92+
}
93+
94+
/// Private helper methods for `Splice::drop`
95+
impl<T, A: Allocator> Drain<'_, T, A> {
96+
/// The range from `self.vec.len` to `self.tail_start` contains elements
97+
/// that have been moved out.
98+
/// Fill that range as much as possible with new elements from the `replace_with` iterator.
99+
/// Returns `true` if we filled the entire range. (`replace_with.next()` didn’t return `None`.)
100+
unsafe fn fill<I: Iterator<Item = T>>(&mut self, replace_with: &mut I) -> bool {
101+
let vec = unsafe { self.vec.as_mut() };
102+
let range_start = vec.len;
103+
let range_end = self.tail_start;
104+
let range_slice = unsafe {
105+
slice::from_raw_parts_mut(vec.as_mut_ptr().add(range_start), range_end - range_start)
106+
};
107+
108+
for place in range_slice {
109+
if let Some(new_item) = replace_with.next() {
110+
unsafe { ptr::write(place, new_item) };
111+
vec.len += 1;
112+
} else {
113+
return false;
114+
}
115+
}
116+
true
117+
}
118+
119+
/// Makes room for inserting more elements before the tail.
120+
unsafe fn move_tail(&mut self, additional: usize) {
121+
let vec = unsafe { self.vec.as_mut() };
122+
let len = self.tail_start + self.tail_len;
123+
vec.buf.reserve(len, additional);
124+
125+
let new_tail_start = self.tail_start + additional;
126+
unsafe {
127+
let src = vec.as_ptr().add(self.tail_start);
128+
let dst = vec.as_mut_ptr().add(new_tail_start);
129+
ptr::copy(src, dst, self.tail_len);
130+
}
131+
self.tail_start = new_tail_start;
132+
}
133+
}

0 commit comments

Comments
 (0)