rollup merge of #22455: msiemens/add-vec-from_elem
Implement `Vec::from_elem` by making the `vec![element; len]` macro more powerful (see rust-lang/rfcs#832). Closes #22414 r? @Gankro
This commit is contained in:
commit
6d7a5e7094
@ -9,12 +9,34 @@
|
||||
// except according to those terms.
|
||||
|
||||
/// Creates a `Vec` containing the arguments.
|
||||
///
|
||||
/// `vec!` allows `Vec`s to be defined with the same syntax as array expressions.
|
||||
/// There are two forms of this macro:
|
||||
///
|
||||
/// - Create a `Vec` containing a given list of elements:
|
||||
///
|
||||
/// ```
|
||||
/// let v = vec![1, 2, 3];
|
||||
/// assert_eq!(v[0], 1);
|
||||
/// assert_eq!(v[1], 2);
|
||||
/// assert_eq!(v[2], 3);
|
||||
/// ```
|
||||
///
|
||||
/// - Create a `Vec` from a given element and size:
|
||||
///
|
||||
/// ```
|
||||
/// let v = vec![1; 3];
|
||||
/// assert_eq!(v, vec![1, 1, 1]);
|
||||
/// ```
|
||||
///
|
||||
/// Note that unlike array expressions this syntax supports all elements
|
||||
/// which implement `Clone` and the number of elements doesn't have to be
|
||||
/// a constant.
|
||||
#[macro_export]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
macro_rules! vec {
|
||||
($x:expr; $y:expr) => (
|
||||
<[_] as $crate::slice::SliceExt>::into_vec(
|
||||
$crate::boxed::Box::new([$x; $y]))
|
||||
($elem:expr; $n:expr) => (
|
||||
$crate::vec::from_elem($elem, $n)
|
||||
);
|
||||
($($x:expr),*) => (
|
||||
<[_] as $crate::slice::SliceExt>::into_vec(
|
||||
|
@ -1252,6 +1252,30 @@ unsafe fn dealloc<T>(ptr: *mut T, len: usize) {
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn from_elem<T: Clone>(elem: T, n: usize) -> Vec<T> {
|
||||
unsafe {
|
||||
let mut v = Vec::with_capacity(n);
|
||||
let mut ptr = v.as_mut_ptr();
|
||||
|
||||
// Write all elements except the last one
|
||||
for i in 1..n {
|
||||
ptr::write(ptr, Clone::clone(&elem));
|
||||
ptr = ptr.offset(1);
|
||||
v.set_len(i); // Increment the length in every step in case Clone::clone() panics
|
||||
}
|
||||
|
||||
if n > 0 {
|
||||
// We can write the last element directly without cloning needlessly
|
||||
ptr::write(ptr, elem);
|
||||
v.set_len(n);
|
||||
}
|
||||
|
||||
v
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Common trait implementations for Vec
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -14,4 +14,9 @@ pub fn main() {
|
||||
assert_eq!(vec![1; 2], vec![1, 1]);
|
||||
assert_eq!(vec![1; 1], vec![1]);
|
||||
assert_eq!(vec![1; 0], vec![]);
|
||||
|
||||
// from_elem syntax (see RFC 832)
|
||||
let el = Box::new(1);
|
||||
let n = 3;
|
||||
assert_eq!(vec![el; n], vec![Box::new(1), Box::new(1), Box::new(1)]);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user