#[inline]
fn is_contiguous(&self) -> bool {
+ // FIXME: Should we consider `head == 0` to mean
+ // that `self` is contiguous?
self.tail <= self.head
}
if self.is_contiguous() {
let tail = self.tail;
let head = self.head;
- return unsafe { &mut self.buffer_as_mut_slice()[tail..head] };
+ return unsafe { RingSlices::ring_slices(self.buffer_as_mut_slice(), head, tail).0 };
}
let buf = self.buf.ptr();
self.tail = 0;
self.head = len;
}
- } else if free >= self.head {
+ } else if free > self.head {
+ // FIXME: We currently do not consider ....ABCDEFGH
+ // to be contiguous because `head` would be `0` in this
+ // case. While we probably want to change this it
+ // isn't trivial as a few places expect `is_contiguous`
+ // to mean that we can just slice using `buf[tail..head]`.
+
// there is enough free space to copy the head in one go,
// this means that we first shift the tail forwards, and then
// copy the head to the correct position.
// ...ABCDEFGH.
self.tail = self.head;
- self.head = self.tail + len;
+ self.head = self.wrap_add(self.tail, len);
}
} else {
// free is smaller than both head and tail,
let tail = self.tail;
let head = self.head;
- unsafe { &mut self.buffer_as_mut_slice()[tail..head] }
+ unsafe { RingSlices::ring_slices(self.buffer_as_mut_slice(), head, tail).0 }
}
/// Rotates the double-ended queue `mid` places to the left.
let len = other.len();
// We need to extend the buf if it's not a power of two, too small
- // or doesn't have at least one free space
- if !buf.capacity().is_power_of_two()
+ // or doesn't have at least one free space.
+ // We check if `T` is a ZST in the first condition,
+ // because `usize::MAX` (the capacity returned by `capacity()` for ZST)
+ // is not a power of two and thus it'll always try
+ // to reserve more memory which will panic for ZST (rust-lang/rust#78532)
+ if (!buf.capacity().is_power_of_two() && mem::size_of::<T>() != 0)
|| (buf.capacity() < (MINIMUM_CAPACITY + 1))
|| (buf.capacity() == len)
{
let len = other.len();
let cap = other.cap();
- if other.head != 0 {
+ if other.tail != 0 {
ptr::copy(buf.add(other.tail), buf, len);
}
Vec::from_raw_parts(buf, len, cap)