Skip to content

Commit 0cccf81

Browse files
authored
Rollup merge of rust-lang#49559 - djc:resize-with, r=TimNN
Introduce Vec::resize_with method (see rust-lang#41758) In rust-lang#41758, the libs team decided they preferred `Vec::resize_with` over `Vec::resize_default()`. Here is an implementation to get this moving forward. I don't know what the removal process for `Vec::resize_default()` should be, so I've left it in place for now. Would be happy to follow up with its removal.
2 parents b5ceda8 + da0ceef commit 0cccf81

File tree

1 file changed

+57
-7
lines changed

1 file changed

+57
-7
lines changed

src/liballoc/vec.rs

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,6 +1283,49 @@ impl<T> Vec<T> {
12831283
}
12841284
other
12851285
}
1286+
1287+
/// Resizes the `Vec` in-place so that `len` is equal to `new_len`.
1288+
///
1289+
/// If `new_len` is greater than `len`, the `Vec` is extended by the
1290+
/// difference, with each additional slot filled with the result of
1291+
/// calling the closure `f`. The return values from `f` will end up
1292+
/// in the `Vec` in the order they have been generated.
1293+
///
1294+
/// If `new_len` is less than `len`, the `Vec` is simply truncated.
1295+
///
1296+
/// This method uses a closure to create new values on every push. If
1297+
/// you'd rather [`Clone`] a given value, use [`resize`]. If you want
1298+
/// to use the [`Default`] trait to generate values, you can pass
1299+
/// [`Default::default()`] as the second argument..
1300+
///
1301+
/// # Examples
1302+
///
1303+
/// ```
1304+
/// #![feature(vec_resize_with)]
1305+
///
1306+
/// let mut vec = vec![1, 2, 3];
1307+
/// vec.resize_with(5, Default::default);
1308+
/// assert_eq!(vec, [1, 2, 3, 0, 0]);
1309+
///
1310+
/// let mut vec = vec![];
1311+
/// let mut p = 1;
1312+
/// vec.resize_with(4, || { p *= 2; p });
1313+
/// assert_eq!(vec, [2, 4, 8, 16]);
1314+
/// ```
1315+
///
1316+
/// [`resize`]: #method.resize
1317+
/// [`Clone`]: ../../std/clone/trait.Clone.html
1318+
#[unstable(feature = "vec_resize_with", issue = "41758")]
1319+
pub fn resize_with<F>(&mut self, new_len: usize, f: F)
1320+
where F: FnMut() -> T
1321+
{
1322+
let len = self.len();
1323+
if new_len > len {
1324+
self.extend_with(new_len - len, ExtendFunc(f));
1325+
} else {
1326+
self.truncate(new_len);
1327+
}
1328+
}
12861329
}
12871330

12881331
impl<T: Clone> Vec<T> {
@@ -1293,8 +1336,8 @@ impl<T: Clone> Vec<T> {
12931336
/// If `new_len` is less than `len`, the `Vec` is simply truncated.
12941337
///
12951338
/// This method requires [`Clone`] to be able clone the passed value. If
1296-
/// you'd rather create a value with [`Default`] instead, see
1297-
/// [`resize_default`].
1339+
/// you need more flexibility (or want to rely on [`Default`] instead of
1340+
/// [`Clone`]), use [`resize_with`].
12981341
///
12991342
/// # Examples
13001343
///
@@ -1310,7 +1353,7 @@ impl<T: Clone> Vec<T> {
13101353
///
13111354
/// [`Clone`]: ../../std/clone/trait.Clone.html
13121355
/// [`Default`]: ../../std/default/trait.Default.html
1313-
/// [`resize_default`]: #method.resize_default
1356+
/// [`resize_with`]: #method.resize_with
13141357
#[stable(feature = "vec_resize", since = "1.5.0")]
13151358
pub fn resize(&mut self, new_len: usize, value: T) {
13161359
let len = self.len();
@@ -1389,24 +1432,31 @@ impl<T: Default> Vec<T> {
13891432

13901433
// This code generalises `extend_with_{element,default}`.
13911434
trait ExtendWith<T> {
1392-
fn next(&self) -> T;
1435+
fn next(&mut self) -> T;
13931436
fn last(self) -> T;
13941437
}
13951438

13961439
struct ExtendElement<T>(T);
13971440
impl<T: Clone> ExtendWith<T> for ExtendElement<T> {
1398-
fn next(&self) -> T { self.0.clone() }
1441+
fn next(&mut self) -> T { self.0.clone() }
13991442
fn last(self) -> T { self.0 }
14001443
}
14011444

14021445
struct ExtendDefault;
14031446
impl<T: Default> ExtendWith<T> for ExtendDefault {
1404-
fn next(&self) -> T { Default::default() }
1447+
fn next(&mut self) -> T { Default::default() }
14051448
fn last(self) -> T { Default::default() }
14061449
}
1450+
1451+
struct ExtendFunc<F>(F);
1452+
impl<T, F: FnMut() -> T> ExtendWith<T> for ExtendFunc<F> {
1453+
fn next(&mut self) -> T { (self.0)() }
1454+
fn last(mut self) -> T { (self.0)() }
1455+
}
1456+
14071457
impl<T> Vec<T> {
14081458
/// Extend the vector by `n` values, using the given generator.
1409-
fn extend_with<E: ExtendWith<T>>(&mut self, n: usize, value: E) {
1459+
fn extend_with<E: ExtendWith<T>>(&mut self, n: usize, mut value: E) {
14101460
self.reserve(n);
14111461

14121462
unsafe {

0 commit comments

Comments
 (0)