Skip to content

Commit 4d09a0e

Browse files
committed
Auto merge of #41771 - clarcharr:resize_default, r=nikomatsakis
Add Vec::resize_default. As suggested by #41758.
2 parents fa78d5b + c2c0641 commit 4d09a0e

File tree

3 files changed

+103
-33
lines changed

3 files changed

+103
-33
lines changed

src/doc/unstable-book/src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@
217217
- [unique](library-features/unique.md)
218218
- [unsize](library-features/unsize.md)
219219
- [utf8_error_error_len](library-features/utf8-error-error-len.md)
220+
- [vec_resize_default](library-features/vec-resize-default.md)
220221
- [vec_remove_item](library-features/vec-remove-item.md)
221222
- [windows_c](library-features/windows-c.md)
222223
- [windows_handle](library-features/windows-handle.md)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# `vec_resize_default`
2+
3+
The tracking issue for this feature is: [#41758]
4+
5+
[#41758]: https://github.com/rust-lang/rust/issues/41758
6+
7+
------------------------

src/libcollections/vec.rs

+95-33
Original file line numberDiff line numberDiff line change
@@ -1220,11 +1220,14 @@ impl<T> Vec<T> {
12201220
}
12211221

12221222
impl<T: Clone> Vec<T> {
1223-
/// Resizes the `Vec` in-place so that `len()` is equal to `new_len`.
1223+
/// Resizes the `Vec` in-place so that `len` is equal to `new_len`.
12241224
///
1225-
/// If `new_len` is greater than `len()`, the `Vec` is extended by the
1225+
/// If `new_len` is greater than `len`, the `Vec` is extended by the
12261226
/// difference, with each additional slot filled with `value`.
1227-
/// If `new_len` is less than `len()`, the `Vec` is simply truncated.
1227+
/// If `new_len` is less than `len`, the `Vec` is simply truncated.
1228+
///
1229+
/// This method requires `Clone` to clone the passed value. If you'd
1230+
/// rather create a value with `Default` instead, see [`resize_default`].
12281231
///
12291232
/// # Examples
12301233
///
@@ -1237,19 +1240,100 @@ impl<T: Clone> Vec<T> {
12371240
/// vec.resize(2, 0);
12381241
/// assert_eq!(vec, [1, 2]);
12391242
/// ```
1243+
///
1244+
/// [`resize_default`]: #method.resize_default
12401245
#[stable(feature = "vec_resize", since = "1.5.0")]
12411246
pub fn resize(&mut self, new_len: usize, value: T) {
12421247
let len = self.len();
12431248

12441249
if new_len > len {
1245-
self.extend_with_element(new_len - len, value);
1250+
self.extend_with(new_len - len, ExtendElement(value))
1251+
} else {
1252+
self.truncate(new_len);
1253+
}
1254+
}
1255+
1256+
/// Clones and appends all elements in a slice to the `Vec`.
1257+
///
1258+
/// Iterates over the slice `other`, clones each element, and then appends
1259+
/// it to this `Vec`. The `other` vector is traversed in-order.
1260+
///
1261+
/// Note that this function is same as `extend` except that it is
1262+
/// specialized to work with slices instead. If and when Rust gets
1263+
/// specialization this function will likely be deprecated (but still
1264+
/// available).
1265+
///
1266+
/// # Examples
1267+
///
1268+
/// ```
1269+
/// let mut vec = vec![1];
1270+
/// vec.extend_from_slice(&[2, 3, 4]);
1271+
/// assert_eq!(vec, [1, 2, 3, 4]);
1272+
/// ```
1273+
#[stable(feature = "vec_extend_from_slice", since = "1.6.0")]
1274+
pub fn extend_from_slice(&mut self, other: &[T]) {
1275+
self.spec_extend(other.iter())
1276+
}
1277+
}
1278+
1279+
impl<T: Default> Vec<T> {
1280+
/// Resizes the `Vec` in-place so that `len` is equal to `new_len`.
1281+
///
1282+
/// If `new_len` is greater than `len`, the `Vec` is extended by the
1283+
/// difference, with each additional slot filled with `Default::default()`.
1284+
/// If `new_len` is less than `len`, the `Vec` is simply truncated.
1285+
///
1286+
/// This method uses `Default` to create new values on every push. If
1287+
/// you'd rather `Clone` a given value, use [`resize`].
1288+
///
1289+
///
1290+
/// # Examples
1291+
///
1292+
/// ```
1293+
/// #![feature(vec_resize_default)]
1294+
///
1295+
/// let mut vec = vec![1, 2, 3];
1296+
/// vec.resize_default(5);
1297+
/// assert_eq!(vec, [1, 2, 3, 0, 0]);
1298+
///
1299+
/// let mut vec = vec![1, 2, 3, 4];
1300+
/// vec.resize_default(2);
1301+
/// assert_eq!(vec, [1, 2]);
1302+
/// ```
1303+
///
1304+
/// [`resize`]: #method.resize
1305+
#[unstable(feature = "vec_resize_default", issue = "41758")]
1306+
pub fn resize_default(&mut self, new_len: usize) {
1307+
let len = self.len();
1308+
1309+
if new_len > len {
1310+
self.extend_with(new_len - len, ExtendDefault);
12461311
} else {
12471312
self.truncate(new_len);
12481313
}
12491314
}
1315+
}
12501316

1251-
/// Extend the vector by `n` additional clones of `value`.
1252-
fn extend_with_element(&mut self, n: usize, value: T) {
1317+
// This code generalises `extend_with_{element,default}`.
1318+
trait ExtendWith<T> {
1319+
fn next(&self) -> T;
1320+
fn last(self) -> T;
1321+
}
1322+
1323+
struct ExtendElement<T>(T);
1324+
impl<T: Clone> ExtendWith<T> for ExtendElement<T> {
1325+
fn next(&self) -> T { self.0.clone() }
1326+
fn last(self) -> T { self.0 }
1327+
}
1328+
1329+
struct ExtendDefault;
1330+
impl<T: Default> ExtendWith<T> for ExtendDefault {
1331+
fn next(&self) -> T { Default::default() }
1332+
fn last(self) -> T { Default::default() }
1333+
}
1334+
impl<T> Vec<T> {
1335+
/// Extend the vector by `n` values, using the given generator.
1336+
fn extend_with<E: ExtendWith<T>>(&mut self, n: usize, value: E) {
12531337
self.reserve(n);
12541338

12551339
unsafe {
@@ -1261,43 +1345,21 @@ impl<T: Clone> Vec<T> {
12611345

12621346
// Write all elements except the last one
12631347
for _ in 1..n {
1264-
ptr::write(ptr, value.clone());
1348+
ptr::write(ptr, value.next());
12651349
ptr = ptr.offset(1);
1266-
// Increment the length in every step in case clone() panics
1350+
// Increment the length in every step in case next() panics
12671351
local_len.increment_len(1);
12681352
}
12691353

12701354
if n > 0 {
12711355
// We can write the last element directly without cloning needlessly
1272-
ptr::write(ptr, value);
1356+
ptr::write(ptr, value.last());
12731357
local_len.increment_len(1);
12741358
}
12751359

12761360
// len set by scope guard
12771361
}
12781362
}
1279-
1280-
/// Clones and appends all elements in a slice to the `Vec`.
1281-
///
1282-
/// Iterates over the slice `other`, clones each element, and then appends
1283-
/// it to this `Vec`. The `other` vector is traversed in-order.
1284-
///
1285-
/// Note that this function is same as `extend` except that it is
1286-
/// specialized to work with slices instead. If and when Rust gets
1287-
/// specialization this function will likely be deprecated (but still
1288-
/// available).
1289-
///
1290-
/// # Examples
1291-
///
1292-
/// ```
1293-
/// let mut vec = vec![1];
1294-
/// vec.extend_from_slice(&[2, 3, 4]);
1295-
/// assert_eq!(vec, [1, 2, 3, 4]);
1296-
/// ```
1297-
#[stable(feature = "vec_extend_from_slice", since = "1.6.0")]
1298-
pub fn extend_from_slice(&mut self, other: &[T]) {
1299-
self.spec_extend(other.iter())
1300-
}
13011363
}
13021364

13031365
// Set the length of the vec when the `SetLenOnDrop` value goes out of scope.
@@ -1389,7 +1451,7 @@ trait SpecFromElem: Sized {
13891451
impl<T: Clone> SpecFromElem for T {
13901452
default fn from_elem(elem: Self, n: usize) -> Vec<Self> {
13911453
let mut v = Vec::with_capacity(n);
1392-
v.extend_with_element(n, elem);
1454+
v.extend_with(n, ExtendElement(elem));
13931455
v
13941456
}
13951457
}
@@ -1424,7 +1486,7 @@ macro_rules! impl_spec_from_elem {
14241486
}
14251487
}
14261488
let mut v = Vec::with_capacity(n);
1427-
v.extend_with_element(n, elem);
1489+
v.extend_with(n, ExtendElement(elem));
14281490
v
14291491
}
14301492
}

0 commit comments

Comments
 (0)