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:
bors 2015-09-19 14:23:46 +00:00
commit 0b5b029da1

View File

@ -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();
}
}
}
}