vec finer capacity controls

This commit is contained in:
cscherr 2025-06-04 17:53:30 +02:00
parent 4270ea7a4c
commit dd51d8d1d1
Signed by: cscherrNT
GPG key ID: 8E2B45BC51A27EA7
2 changed files with 28 additions and 13 deletions

View file

@ -18,19 +18,12 @@ impl<T> RawVec<T> {
}
// See rustonomicon, chapter 9.2
pub(crate) fn grow(&mut self) {
let (new_cap, new_layout) = if self.capacity == 0 {
(1, Layout::array::<T>(1).unwrap())
} else {
// This can't overflow since self.cap <= isize::MAX.
let new_cap = 2 * self.capacity;
// `Layout::array` checks that the number of bytes is <= usize::MAX,
// but this is redundant since old_layout.size() <= isize::MAX,
// so the `unwrap` should never fail.
let new_layout = Layout::array::<T>(new_cap).unwrap();
(new_cap, new_layout)
};
pub(crate) fn grow_by(&mut self, added_capacity: usize) {
let new_cap = self.capacity + added_capacity;
// `Layout::array` checks that the number of bytes is <= usize::MAX,
// but this is redundant since old_layout.size() <= isize::MAX,
// so the `unwrap` should never fail.
let new_layout = Layout::array::<T>(new_cap).unwrap();
// Ensure that the new allocation doesn't exceed `isize::MAX` bytes.
if new_layout.size() > isize::MAX as usize {
@ -52,6 +45,14 @@ impl<T> RawVec<T> {
};
self.capacity = new_cap;
}
pub(crate) fn grow(&mut self) {
if self.capacity == 0 {
self.grow_by(1);
} else {
self.grow_by(self.capacity);
}
}
}
impl<T> Drop for RawVec<T> {

View file

@ -37,6 +37,16 @@ impl<T> Vec<T> {
}
}
pub fn with_capacity(capacity: usize) -> Self {
if mem::size_of::<T>() == 0 {
panic!("We're not ready to handle ZSTs");
}
let mut v = Self::new();
v.reserve(capacity);
v
}
pub fn pop(&mut self) -> Option<T> {
if self.used == 0 {
None
@ -107,6 +117,10 @@ impl<T> Vec<T> {
result
}
}
pub fn reserve(&mut self, added_capacity: usize) {
self.buf.grow_by(added_capacity);
}
}
impl<T> Index<usize> for Vec<T> {