Skip to content

Commit da0ceef

Browse files
committed
Introduce Vec::resize_with method (see #41758)
1 parent 135f334 commit da0ceef

File tree

1 file changed

+57
-7
lines changed

1 file changed

+57
-7
lines changed

Diff for: src/liballoc/vec.rs

+57-7
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,49 @@ impl<T> Vec<T> {
13061306
}
13071307
other
13081308
}
1309+
1310+
/// Resizes the `Vec` in-place so that `len` is equal to `new_len`.
1311+
///
1312+
/// If `new_len` is greater than `len`, the `Vec` is extended by the
1313+
/// difference, with each additional slot filled with the result of
1314+
/// calling the closure `f`. The return values from `f` will end up
1315+
/// in the `Vec` in the order they have been generated.
1316+
///
1317+
/// If `new_len` is less than `len`, the `Vec` is simply truncated.
1318+
///
1319+
/// This method uses a closure to create new values on every push. If
1320+
/// you'd rather [`Clone`] a given value, use [`resize`]. If you want
1321+
/// to use the [`Default`] trait to generate values, you can pass
1322+
/// [`Default::default()`] as the second argument..
1323+
///
1324+
/// # Examples
1325+
///
1326+
/// ```
1327+
/// #![feature(vec_resize_with)]
1328+
///
1329+
/// let mut vec = vec![1, 2, 3];
1330+
/// vec.resize_with(5, Default::default);
1331+
/// assert_eq!(vec, [1, 2, 3, 0, 0]);
1332+
///
1333+
/// let mut vec = vec![];
1334+
/// let mut p = 1;
1335+
/// vec.resize_with(4, || { p *= 2; p });
1336+
/// assert_eq!(vec, [2, 4, 8, 16]);
1337+
/// ```
1338+
///
1339+
/// [`resize`]: #method.resize
1340+
/// [`Clone`]: ../../std/clone/trait.Clone.html
1341+
#[unstable(feature = "vec_resize_with", issue = "41758")]
1342+
pub fn resize_with<F>(&mut self, new_len: usize, f: F)
1343+
where F: FnMut() -> T
1344+
{
1345+
let len = self.len();
1346+
if new_len > len {
1347+
self.extend_with(new_len - len, ExtendFunc(f));
1348+
} else {
1349+
self.truncate(new_len);
1350+
}
1351+
}
13091352
}
13101353

13111354
impl<T: Clone> Vec<T> {
@@ -1316,8 +1359,8 @@ impl<T: Clone> Vec<T> {
13161359
/// If `new_len` is less than `len`, the `Vec` is simply truncated.
13171360
///
13181361
/// This method requires [`Clone`] to be able clone the passed value. If
1319-
/// you'd rather create a value with [`Default`] instead, see
1320-
/// [`resize_default`].
1362+
/// you need more flexibility (or want to rely on [`Default`] instead of
1363+
/// [`Clone`]), use [`resize_with`].
13211364
///
13221365
/// # Examples
13231366
///
@@ -1333,7 +1376,7 @@ impl<T: Clone> Vec<T> {
13331376
///
13341377
/// [`Clone`]: ../../std/clone/trait.Clone.html
13351378
/// [`Default`]: ../../std/default/trait.Default.html
1336-
/// [`resize_default`]: #method.resize_default
1379+
/// [`resize_with`]: #method.resize_with
13371380
#[stable(feature = "vec_resize", since = "1.5.0")]
13381381
pub fn resize(&mut self, new_len: usize, value: T) {
13391382
let len = self.len();
@@ -1412,24 +1455,31 @@ impl<T: Default> Vec<T> {
14121455

14131456
// This code generalises `extend_with_{element,default}`.
14141457
trait ExtendWith<T> {
1415-
fn next(&self) -> T;
1458+
fn next(&mut self) -> T;
14161459
fn last(self) -> T;
14171460
}
14181461

14191462
struct ExtendElement<T>(T);
14201463
impl<T: Clone> ExtendWith<T> for ExtendElement<T> {
1421-
fn next(&self) -> T { self.0.clone() }
1464+
fn next(&mut self) -> T { self.0.clone() }
14221465
fn last(self) -> T { self.0 }
14231466
}
14241467

14251468
struct ExtendDefault;
14261469
impl<T: Default> ExtendWith<T> for ExtendDefault {
1427-
fn next(&self) -> T { Default::default() }
1470+
fn next(&mut self) -> T { Default::default() }
14281471
fn last(self) -> T { Default::default() }
14291472
}
1473+
1474+
struct ExtendFunc<F>(F);
1475+
impl<T, F: FnMut() -> T> ExtendWith<T> for ExtendFunc<F> {
1476+
fn next(&mut self) -> T { (self.0)() }
1477+
fn last(mut self) -> T { (self.0)() }
1478+
}
1479+
14301480
impl<T> Vec<T> {
14311481
/// Extend the vector by `n` values, using the given generator.
1432-
fn extend_with<E: ExtendWith<T>>(&mut self, n: usize, value: E) {
1482+
fn extend_with<E: ExtendWith<T>>(&mut self, n: usize, mut value: E) {
14331483
self.reserve(n);
14341484

14351485
unsafe {

0 commit comments

Comments
 (0)