Auto merge of #28494 - bluss:vecdeque-zst, r=eddyb
VecDeque: Use power of two capacity even for zero sized types VecDeque depends on using a power of two capacity. Use the largest possible power of two capacity for ZSTs. Fixes #28488
This commit is contained in:
commit
0b5b029da1
@ -21,9 +21,11 @@
|
||||
use core::cmp::Ordering;
|
||||
use core::fmt;
|
||||
use core::iter::{repeat, FromIterator};
|
||||
use core::mem;
|
||||
use core::ops::{Index, IndexMut};
|
||||
use core::ptr;
|
||||
use core::slice;
|
||||
use core::usize;
|
||||
|
||||
use core::hash::{Hash, Hasher};
|
||||
use core::cmp;
|
||||
@ -32,6 +34,7 @@
|
||||
|
||||
const INITIAL_CAPACITY: usize = 7; // 2^3 - 1
|
||||
const MINIMUM_CAPACITY: usize = 1; // 2 - 1
|
||||
const MAXIMUM_ZST_CAPACITY: usize = 1 << (usize::BITS - 1); // Largest possible power of two
|
||||
|
||||
/// `VecDeque` is a growable ring buffer, which can be used as a
|
||||
/// double-ended queue efficiently.
|
||||
@ -83,7 +86,12 @@ fn ptr(&self) -> *mut T {
|
||||
/// Marginally more convenient
|
||||
#[inline]
|
||||
fn cap(&self) -> usize {
|
||||
self.buf.cap()
|
||||
if mem::size_of::<T>() == 0 {
|
||||
// For zero sized types, we are always at maximum capacity
|
||||
MAXIMUM_ZST_CAPACITY
|
||||
} else {
|
||||
self.buf.cap()
|
||||
}
|
||||
}
|
||||
|
||||
/// Turn ptr into a slice
|
||||
@ -1465,6 +1473,7 @@ pub fn resize(&mut self, new_len: usize, value: T) {
|
||||
#[inline]
|
||||
fn wrap_index(index: usize, size: usize) -> usize {
|
||||
// size is always a power of 2
|
||||
debug_assert!(size.is_power_of_two());
|
||||
index & (size - 1)
|
||||
}
|
||||
|
||||
@ -2032,4 +2041,34 @@ fn test_split_off() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zst_push() {
|
||||
const N: usize = 8;
|
||||
|
||||
// Zero sized type
|
||||
struct Zst;
|
||||
|
||||
// Test that for all possible sequences of push_front / push_back,
|
||||
// we end up with a deque of the correct size
|
||||
|
||||
for len in 0..N {
|
||||
let mut tester = VecDeque::with_capacity(len);
|
||||
assert_eq!(tester.len(), 0);
|
||||
assert!(tester.capacity() >= len);
|
||||
for case in 0..(1 << len) {
|
||||
assert_eq!(tester.len(), 0);
|
||||
for bit in 0..len {
|
||||
if case & (1 << bit) != 0 {
|
||||
tester.push_front(Zst);
|
||||
} else {
|
||||
tester.push_back(Zst);
|
||||
}
|
||||
}
|
||||
assert_eq!(tester.len(), len);
|
||||
assert_eq!(tester.iter().count(), len);
|
||||
tester.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user