提交 5058e586 编写于 作者: U Ulrik Sverdrup

vec: Write the .extend() specialization in cleaner style

As far as possible, use regular `default fn` specialization in favour of
ad-hoc conditionals.
上级 c9f16bbc
......@@ -1586,36 +1586,34 @@ fn into_iter(mut self) -> slice::IterMut<'a, T> {
impl<T> Extend<T> for Vec<T> {
#[inline]
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
self.extend_desugared(iter.into_iter())
self.spec_extend(iter.into_iter())
}
}
trait IsTrustedLen : Iterator {
fn trusted_len(&self) -> Option<usize> { None }
trait SpecExtend<I> {
fn spec_extend(&mut self, iter: I);
}
impl<I> IsTrustedLen for I where I: Iterator { }
impl<I> IsTrustedLen for I where I: TrustedLen
impl<I, T> SpecExtend<I> for Vec<T>
where I: Iterator<Item=T>,
{
fn trusted_len(&self) -> Option<usize> {
let (low, high) = self.size_hint();
default fn spec_extend(&mut self, iter: I) {
self.extend_desugared(iter)
}
}
impl<I, T> SpecExtend<I> for Vec<T>
where I: TrustedLen<Item=T>,
{
fn spec_extend(&mut self, iterator: I) {
// This is the case for a TrustedLen iterator.
let (low, high) = iterator.size_hint();
if let Some(high_value) = high {
debug_assert_eq!(low, high_value,
"TrustedLen iterator's size hint is not exact: {:?}",
(low, high));
}
high
}
}
impl<T> Vec<T> {
fn extend_desugared<I: Iterator<Item = T>>(&mut self, mut iterator: I) {
// This function should be the moral equivalent of:
//
// for item in iterator {
// self.push(item);
// }
if let Some(additional) = iterator.trusted_len() {
if let Some(additional) = high {
self.reserve(additional);
unsafe {
let mut ptr = self.as_mut_ptr().offset(self.len() as isize);
......@@ -1628,17 +1626,30 @@ fn extend_desugared<I: Iterator<Item = T>>(&mut self, mut iterator: I) {
}
}
} else {
while let Some(element) = iterator.next() {
let len = self.len();
if len == self.capacity() {
let (lower, _) = iterator.size_hint();
self.reserve(lower.saturating_add(1));
}
unsafe {
ptr::write(self.get_unchecked_mut(len), element);
// NB can't overflow since we would have had to alloc the address space
self.set_len(len + 1);
}
self.extend_desugared(iterator)
}
}
}
impl<T> Vec<T> {
fn extend_desugared<I: Iterator<Item = T>>(&mut self, mut iterator: I) {
// This is the case for a general iterator.
//
// This function should be the moral equivalent of:
//
// for item in iterator {
// self.push(item);
// }
while let Some(element) = iterator.next() {
let len = self.len();
if len == self.capacity() {
let (lower, _) = iterator.size_hint();
self.reserve(lower.saturating_add(1));
}
unsafe {
ptr::write(self.get_unchecked_mut(len), element);
// NB can't overflow since we would have had to alloc the address space
self.set_len(len + 1);
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册