mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
parent
f27a22c24a
commit
78fb977d6b
@ -559,6 +559,30 @@ impl<T> VecDeque<T> {
|
|||||||
pub fn with_capacity(capacity: usize) -> VecDeque<T> {
|
pub fn with_capacity(capacity: usize) -> VecDeque<T> {
|
||||||
Self::with_capacity_in(capacity, Global)
|
Self::with_capacity_in(capacity, Global)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates an empty deque with space for at least `capacity` elements.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// Returns an error if the capacity exceeds `isize::MAX` _bytes_,
|
||||||
|
/// or if the allocator reports allocation failure.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # #![feature(try_with_capacity)]
|
||||||
|
/// # #[allow(unused)]
|
||||||
|
/// # fn example() -> Result<(), std::collections::TryReserveError> {
|
||||||
|
/// use std::collections::VecDeque;
|
||||||
|
///
|
||||||
|
/// let deque: VecDeque<u32> = VecDeque::try_with_capacity(10)?;
|
||||||
|
/// # Ok(()) }
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "try_with_capacity", issue = "91913")]
|
||||||
|
pub fn try_with_capacity(capacity: usize) -> Result<VecDeque<T>, TryReserveError> {
|
||||||
|
Ok(VecDeque { head: 0, len: 0, buf: RawVec::try_with_capacity_in(capacity, Global)? })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, A: Allocator> VecDeque<T, A> {
|
impl<T, A: Allocator> VecDeque<T, A> {
|
||||||
|
@ -163,6 +163,7 @@
|
|||||||
#![feature(trusted_len)]
|
#![feature(trusted_len)]
|
||||||
#![feature(trusted_random_access)]
|
#![feature(trusted_random_access)]
|
||||||
#![feature(try_trait_v2)]
|
#![feature(try_trait_v2)]
|
||||||
|
#![feature(try_with_capacity)]
|
||||||
#![feature(tuple_trait)]
|
#![feature(tuple_trait)]
|
||||||
#![feature(unchecked_math)]
|
#![feature(unchecked_math)]
|
||||||
#![feature(unicode_internals)]
|
#![feature(unicode_internals)]
|
||||||
|
@ -20,6 +20,7 @@ mod tests;
|
|||||||
enum AllocInit {
|
enum AllocInit {
|
||||||
/// The contents of the new memory are uninitialized.
|
/// The contents of the new memory are uninitialized.
|
||||||
Uninitialized,
|
Uninitialized,
|
||||||
|
#[cfg(not(no_global_oom_handling))]
|
||||||
/// The new memory is guaranteed to be zeroed.
|
/// The new memory is guaranteed to be zeroed.
|
||||||
Zeroed,
|
Zeroed,
|
||||||
}
|
}
|
||||||
@ -146,6 +147,13 @@ impl<T, A: Allocator> RawVec<T, A> {
|
|||||||
handle_reserve(Self::try_allocate_in(capacity, AllocInit::Uninitialized, alloc))
|
handle_reserve(Self::try_allocate_in(capacity, AllocInit::Uninitialized, alloc))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Like `try_with_capacity`, but parameterized over the choice of
|
||||||
|
/// allocator for the returned `RawVec`.
|
||||||
|
#[inline]
|
||||||
|
pub fn try_with_capacity_in(capacity: usize, alloc: A) -> Result<Self, TryReserveError> {
|
||||||
|
Self::try_allocate_in(capacity, AllocInit::Uninitialized, alloc)
|
||||||
|
}
|
||||||
|
|
||||||
/// Like `with_capacity_zeroed`, but parameterized over the choice
|
/// Like `with_capacity_zeroed`, but parameterized over the choice
|
||||||
/// of allocator for the returned `RawVec`.
|
/// of allocator for the returned `RawVec`.
|
||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
@ -203,6 +211,7 @@ impl<T, A: Allocator> RawVec<T, A> {
|
|||||||
|
|
||||||
let result = match init {
|
let result = match init {
|
||||||
AllocInit::Uninitialized => alloc.allocate(layout),
|
AllocInit::Uninitialized => alloc.allocate(layout),
|
||||||
|
#[cfg(not(no_global_oom_handling))]
|
||||||
AllocInit::Zeroed => alloc.allocate_zeroed(layout),
|
AllocInit::Zeroed => alloc.allocate_zeroed(layout),
|
||||||
};
|
};
|
||||||
let ptr = match result {
|
let ptr = match result {
|
||||||
|
@ -492,6 +492,19 @@ impl String {
|
|||||||
String { vec: Vec::with_capacity(capacity) }
|
String { vec: Vec::with_capacity(capacity) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new empty `String` with at least the specified capacity.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// Returns [`Err`] if the capacity exceeds `isize::MAX` bytes,
|
||||||
|
/// or if the memory allocator reports failure.
|
||||||
|
///
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "try_with_capacity", issue = "91913")]
|
||||||
|
pub fn try_with_capacity(capacity: usize) -> Result<String, TryReserveError> {
|
||||||
|
Ok(String { vec: Vec::try_with_capacity(capacity)? })
|
||||||
|
}
|
||||||
|
|
||||||
// HACK(japaric): with cfg(test) the inherent `[T]::to_vec` method, which is
|
// HACK(japaric): with cfg(test) the inherent `[T]::to_vec` method, which is
|
||||||
// required for this method definition, is not available. Since we don't
|
// required for this method definition, is not available. Since we don't
|
||||||
// require this method for testing purposes, I'll just stub it
|
// require this method for testing purposes, I'll just stub it
|
||||||
|
@ -481,6 +481,22 @@ impl<T> Vec<T> {
|
|||||||
Self::with_capacity_in(capacity, Global)
|
Self::with_capacity_in(capacity, Global)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constructs a new, empty `Vec<T>` with at least the specified capacity.
|
||||||
|
///
|
||||||
|
/// The vector will be able to hold at least `capacity` elements without
|
||||||
|
/// reallocating. This method is allowed to allocate for more elements than
|
||||||
|
/// `capacity`. If `capacity` is 0, the vector will not allocate.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// Returns an error if the capacity exceeds `isize::MAX` _bytes_,
|
||||||
|
/// or if the allocator reports allocation failure.
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "try_with_capacity", issue = "91913")]
|
||||||
|
pub fn try_with_capacity(capacity: usize) -> Result<Self, TryReserveError> {
|
||||||
|
Self::try_with_capacity_in(capacity, Global)
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a `Vec<T>` directly from a pointer, a length, and a capacity.
|
/// Creates a `Vec<T>` directly from a pointer, a length, and a capacity.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@ -672,6 +688,24 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||||||
Vec { buf: RawVec::with_capacity_in(capacity, alloc), len: 0 }
|
Vec { buf: RawVec::with_capacity_in(capacity, alloc), len: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constructs a new, empty `Vec<T, A>` with at least the specified capacity
|
||||||
|
/// with the provided allocator.
|
||||||
|
///
|
||||||
|
/// The vector will be able to hold at least `capacity` elements without
|
||||||
|
/// reallocating. This method is allowed to allocate for more elements than
|
||||||
|
/// `capacity`. If `capacity` is 0, the vector will not allocate.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// Returns an error if the capacity exceeds `isize::MAX` _bytes_,
|
||||||
|
/// or if the allocator reports allocation failure.
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
|
// #[unstable(feature = "try_with_capacity", issue = "91913")]
|
||||||
|
pub fn try_with_capacity_in(capacity: usize, alloc: A) -> Result<Self, TryReserveError> {
|
||||||
|
Ok(Vec { buf: RawVec::try_with_capacity_in(capacity, alloc)?, len: 0 })
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a `Vec<T, A>` directly from a pointer, a length, a capacity,
|
/// Creates a `Vec<T, A>` directly from a pointer, a length, a capacity,
|
||||||
/// and an allocator.
|
/// and an allocator.
|
||||||
///
|
///
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#![feature(pattern)]
|
#![feature(pattern)]
|
||||||
#![feature(trusted_len)]
|
#![feature(trusted_len)]
|
||||||
#![feature(try_reserve_kind)]
|
#![feature(try_reserve_kind)]
|
||||||
|
#![feature(try_with_capacity)]
|
||||||
#![feature(unboxed_closures)]
|
#![feature(unboxed_closures)]
|
||||||
#![feature(associated_type_bounds)]
|
#![feature(associated_type_bounds)]
|
||||||
#![feature(binary_heap_into_iter_sorted)]
|
#![feature(binary_heap_into_iter_sorted)]
|
||||||
|
@ -723,6 +723,17 @@ fn test_reserve_exact() {
|
|||||||
assert!(s.capacity() >= 33)
|
assert!(s.capacity() >= 33)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
|
||||||
|
#[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
|
||||||
|
fn test_try_with_capacity() {
|
||||||
|
let string = String::try_with_capacity(1000).unwrap();
|
||||||
|
assert_eq!(0, string.len());
|
||||||
|
assert!(string.capacity() >= 1000 && string.capacity() <= isize::MAX as usize);
|
||||||
|
|
||||||
|
assert!(String::try_with_capacity(usize::MAX).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
|
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
|
||||||
#[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
|
#[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
|
||||||
|
@ -1694,6 +1694,18 @@ fn test_reserve_exact() {
|
|||||||
assert!(v.capacity() >= 33)
|
assert!(v.capacity() >= 33)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
|
||||||
|
#[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
|
||||||
|
fn test_try_with_capacity() {
|
||||||
|
let mut vec: Vec<u32> = Vec::try_with_capacity(5).unwrap();
|
||||||
|
assert_eq!(0, vec.len());
|
||||||
|
assert!(vec.capacity() >= 5 && vec.capacity() <= isize::MAX as usize / 4);
|
||||||
|
assert!(vec.spare_capacity_mut().len() >= 5);
|
||||||
|
|
||||||
|
assert!(Vec::<u16>::try_with_capacity(isize::MAX as usize + 1).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
|
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
|
||||||
#[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
|
#[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
|
||||||
|
@ -1182,6 +1182,17 @@ fn test_reserve_exact_2() {
|
|||||||
assert!(v.capacity() >= 33)
|
assert!(v.capacity() >= 33)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
|
||||||
|
#[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
|
||||||
|
fn test_try_with_capacity() {
|
||||||
|
let vec: VecDeque<u32> = VecDeque::try_with_capacity(5).unwrap();
|
||||||
|
assert_eq!(0, vec.len());
|
||||||
|
assert!(vec.capacity() >= 5 && vec.capacity() <= isize::MAX as usize / 4);
|
||||||
|
|
||||||
|
assert!(VecDeque::<u16>::try_with_capacity(isize::MAX as usize + 1).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
|
#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
|
||||||
#[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
|
#[cfg_attr(target_os = "android", ignore)] // Android used in CI has a broken dlmalloc
|
||||||
|
35
tests/codegen/vec-with-capacity.rs
Normal file
35
tests/codegen/vec-with-capacity.rs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
//@ compile-flags: -O
|
||||||
|
//@ ignore-debug
|
||||||
|
// (with debug assertions turned on, `assert_unchecked` generates a real assertion)
|
||||||
|
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
#![feature(try_with_capacity)]
|
||||||
|
|
||||||
|
// CHECK-LABEL: @with_capacity_does_not_grow1
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn with_capacity_does_not_grow1() -> Vec<u32> {
|
||||||
|
let v = Vec::with_capacity(1234);
|
||||||
|
// CHECK: call {{.*}}__rust_alloc(
|
||||||
|
// CHECK-NOT: call {{.*}}__rust_realloc
|
||||||
|
// CHECK-NOT: call {{.*}}capacity_overflow
|
||||||
|
// CHECK-NOT: call {{.*}}finish_grow
|
||||||
|
// CHECK-NOT: call {{.*}}reserve
|
||||||
|
// CHECK-NOT: memcpy
|
||||||
|
// CHECK-NOT: memset
|
||||||
|
v
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: @try_with_capacity_does_not_grow2
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn try_with_capacity_does_not_grow2() -> Option<Vec<Vec<u8>>> {
|
||||||
|
let v = Vec::try_with_capacity(1234).ok()?;
|
||||||
|
// CHECK: call {{.*}}__rust_alloc(
|
||||||
|
// CHECK-NOT: call {{.*}}__rust_realloc
|
||||||
|
// CHECK-NOT: call {{.*}}capacity_overflow
|
||||||
|
// CHECK-NOT: call {{.*}}finish_grow
|
||||||
|
// CHECK-NOT: call {{.*}}handle_alloc_error
|
||||||
|
// CHECK-NOT: call {{.*}}reserve
|
||||||
|
// CHECK-NOT: memcpy
|
||||||
|
// CHECK-NOT: memset
|
||||||
|
Some(v)
|
||||||
|
}
|
@ -7,9 +7,9 @@ LL | Vec::contains(&vec, &0);
|
|||||||
note: if you're trying to build a new `Vec<_, _>` consider using one of the following associated functions:
|
note: if you're trying to build a new `Vec<_, _>` consider using one of the following associated functions:
|
||||||
Vec::<T>::new
|
Vec::<T>::new
|
||||||
Vec::<T>::with_capacity
|
Vec::<T>::with_capacity
|
||||||
|
Vec::<T>::try_with_capacity
|
||||||
Vec::<T>::from_raw_parts
|
Vec::<T>::from_raw_parts
|
||||||
Vec::<T, A>::new_in
|
and 4 others
|
||||||
and 2 others
|
|
||||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||||
help: the function `contains` is implemented on `[_]`
|
help: the function `contains` is implemented on `[_]`
|
||||||
|
|
|
|
||||||
|
@ -7,9 +7,9 @@ LL | Vec::<Q>::mew()
|
|||||||
note: if you're trying to build a new `Vec<Q>` consider using one of the following associated functions:
|
note: if you're trying to build a new `Vec<Q>` consider using one of the following associated functions:
|
||||||
Vec::<T>::new
|
Vec::<T>::new
|
||||||
Vec::<T>::with_capacity
|
Vec::<T>::with_capacity
|
||||||
|
Vec::<T>::try_with_capacity
|
||||||
Vec::<T>::from_raw_parts
|
Vec::<T>::from_raw_parts
|
||||||
Vec::<T, A>::new_in
|
and 4 others
|
||||||
and 2 others
|
|
||||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||||
help: there is an associated function `new` with a similar name
|
help: there is an associated function `new` with a similar name
|
||||||
|
|
|
|
||||||
|
Loading…
Reference in New Issue
Block a user