Skip to content

Commit bd49a60

Browse files
committed
refactor: moved SpecExtend into spec_extend.rs
1 parent d24a277 commit bd49a60

File tree

2 files changed

+87
-79
lines changed

2 files changed

+87
-79
lines changed

library/alloc/src/vec/mod.rs

Lines changed: 5 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,7 @@ use core::convert::TryFrom;
5959
use core::fmt;
6060
use core::hash::{Hash, Hasher};
6161
use core::intrinsics::{arith_offset, assume};
62-
use core::iter::{
63-
FromIterator, TrustedLen,
64-
};
62+
use core::iter::{FromIterator};
6563
use core::marker::PhantomData;
6664
use core::mem::{self, ManuallyDrop, MaybeUninit};
6765
use core::ops::{self, Index, IndexMut, Range, RangeBounds};
@@ -125,6 +123,10 @@ use self::spec_from_iter::SpecFromIter;
125123

126124
mod spec_from_iter;
127125

126+
use self::spec_extend::SpecExtend;
127+
128+
mod spec_extend;
129+
128130
/// A contiguous growable array type, written `Vec<T>` but pronounced 'vector'.
129131
///
130132
/// # Examples
@@ -2160,82 +2162,6 @@ impl<T, A: Allocator> Extend<T> for Vec<T, A> {
21602162
}
21612163
}
21622164

2163-
// Specialization trait used for Vec::extend
2164-
trait SpecExtend<T, I> {
2165-
fn spec_extend(&mut self, iter: I);
2166-
}
2167-
2168-
impl<T, I, A: Allocator> SpecExtend<T, I> for Vec<T, A>
2169-
where
2170-
I: Iterator<Item = T>,
2171-
{
2172-
default fn spec_extend(&mut self, iter: I) {
2173-
self.extend_desugared(iter)
2174-
}
2175-
}
2176-
2177-
impl<T, I, A: Allocator> SpecExtend<T, I> for Vec<T, A>
2178-
where
2179-
I: TrustedLen<Item = T>,
2180-
{
2181-
default fn spec_extend(&mut self, iterator: I) {
2182-
// This is the case for a TrustedLen iterator.
2183-
let (low, high) = iterator.size_hint();
2184-
if let Some(high_value) = high {
2185-
debug_assert_eq!(
2186-
low,
2187-
high_value,
2188-
"TrustedLen iterator's size hint is not exact: {:?}",
2189-
(low, high)
2190-
);
2191-
}
2192-
if let Some(additional) = high {
2193-
self.reserve(additional);
2194-
unsafe {
2195-
let mut ptr = self.as_mut_ptr().add(self.len());
2196-
let mut local_len = SetLenOnDrop::new(&mut self.len);
2197-
iterator.for_each(move |element| {
2198-
ptr::write(ptr, element);
2199-
ptr = ptr.offset(1);
2200-
// NB can't overflow since we would have had to alloc the address space
2201-
local_len.increment_len(1);
2202-
});
2203-
}
2204-
} else {
2205-
self.extend_desugared(iterator)
2206-
}
2207-
}
2208-
}
2209-
2210-
impl<T, A: Allocator> SpecExtend<T, IntoIter<T>> for Vec<T, A> {
2211-
fn spec_extend(&mut self, mut iterator: IntoIter<T>) {
2212-
unsafe {
2213-
self.append_elements(iterator.as_slice() as _);
2214-
}
2215-
iterator.ptr = iterator.end;
2216-
}
2217-
}
2218-
2219-
impl<'a, T: 'a, I, A: Allocator + 'a> SpecExtend<&'a T, I> for Vec<T, A>
2220-
where
2221-
I: Iterator<Item = &'a T>,
2222-
T: Clone,
2223-
{
2224-
default fn spec_extend(&mut self, iterator: I) {
2225-
self.spec_extend(iterator.cloned())
2226-
}
2227-
}
2228-
2229-
impl<'a, T: 'a, A: Allocator + 'a> SpecExtend<&'a T, slice::Iter<'a, T>> for Vec<T, A>
2230-
where
2231-
T: Copy,
2232-
{
2233-
fn spec_extend(&mut self, iterator: slice::Iter<'a, T>) {
2234-
let slice = iterator.as_slice();
2235-
unsafe { self.append_elements(slice) };
2236-
}
2237-
}
2238-
22392165
impl<T, A: Allocator> Vec<T, A> {
22402166
// leaf method to which various SpecFrom/SpecExtend implementations delegate when
22412167
// they have no further optimizations to apply

library/alloc/src/vec/spec_extend.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
use crate::alloc::{Allocator};
2+
use core::iter::{TrustedLen};
3+
use core::slice::{self};
4+
use core::ptr::{self};
5+
6+
use super::{Vec, IntoIter, SetLenOnDrop};
7+
8+
// Specialization trait used for Vec::extend
9+
pub(super) trait SpecExtend<T, I> {
10+
fn spec_extend(&mut self, iter: I);
11+
}
12+
13+
impl<T, I, A: Allocator> SpecExtend<T, I> for Vec<T, A>
14+
where
15+
I: Iterator<Item = T>,
16+
{
17+
default fn spec_extend(&mut self, iter: I) {
18+
self.extend_desugared(iter)
19+
}
20+
}
21+
22+
impl<T, I, A: Allocator> SpecExtend<T, I> for Vec<T, A>
23+
where
24+
I: TrustedLen<Item = T>,
25+
{
26+
default fn spec_extend(&mut self, iterator: I) {
27+
// This is the case for a TrustedLen iterator.
28+
let (low, high) = iterator.size_hint();
29+
if let Some(high_value) = high {
30+
debug_assert_eq!(
31+
low,
32+
high_value,
33+
"TrustedLen iterator's size hint is not exact: {:?}",
34+
(low, high)
35+
);
36+
}
37+
if let Some(additional) = high {
38+
self.reserve(additional);
39+
unsafe {
40+
let mut ptr = self.as_mut_ptr().add(self.len());
41+
let mut local_len = SetLenOnDrop::new(&mut self.len);
42+
iterator.for_each(move |element| {
43+
ptr::write(ptr, element);
44+
ptr = ptr.offset(1);
45+
// NB can't overflow since we would have had to alloc the address space
46+
local_len.increment_len(1);
47+
});
48+
}
49+
} else {
50+
self.extend_desugared(iterator)
51+
}
52+
}
53+
}
54+
55+
impl<T, A: Allocator> SpecExtend<T, IntoIter<T>> for Vec<T, A> {
56+
fn spec_extend(&mut self, mut iterator: IntoIter<T>) {
57+
unsafe {
58+
self.append_elements(iterator.as_slice() as _);
59+
}
60+
iterator.ptr = iterator.end;
61+
}
62+
}
63+
64+
impl<'a, T: 'a, I, A: Allocator + 'a> SpecExtend<&'a T, I> for Vec<T, A>
65+
where
66+
I: Iterator<Item = &'a T>,
67+
T: Clone,
68+
{
69+
default fn spec_extend(&mut self, iterator: I) {
70+
self.spec_extend(iterator.cloned())
71+
}
72+
}
73+
74+
impl<'a, T: 'a, A: Allocator + 'a> SpecExtend<&'a T, slice::Iter<'a, T>> for Vec<T, A>
75+
where
76+
T: Copy,
77+
{
78+
fn spec_extend(&mut self, iterator: slice::Iter<'a, T>) {
79+
let slice = iterator.as_slice();
80+
unsafe { self.append_elements(slice) };
81+
}
82+
}

0 commit comments

Comments
 (0)