#[inline]
fn is_contiguous(&self) -> bool {
+ // FIXME: Should we consider `head == 0` to mean
+ // that `self` is contiguous?
self.tail <= self.head
}
/// ```
/// use std::collections::VecDeque;
///
- /// let mut buf: VecDeque<_> = vec![1,2,3].into_iter().collect();
+ /// let mut buf: VecDeque<_> = vec![1, 2, 3].into_iter().collect();
/// let buf2 = buf.split_off(1);
/// assert_eq!(buf, [1]);
/// assert_eq!(buf2, [2, 3]);
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.
/// (3, 1), (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
/// (1, 21), (2, 34), (4, 55)].into();
///
- /// assert_eq!(deque.binary_search_by_key(&13, |&(a,b)| b), Ok(9));
- /// assert_eq!(deque.binary_search_by_key(&4, |&(a,b)| b), Err(7));
- /// assert_eq!(deque.binary_search_by_key(&100, |&(a,b)| b), Err(13));
- /// let r = deque.binary_search_by_key(&1, |&(a,b)| b);
+ /// assert_eq!(deque.binary_search_by_key(&13, |&(a, b)| b), Ok(9));
+ /// assert_eq!(deque.binary_search_by_key(&4, |&(a, b)| b), Err(7));
+ /// assert_eq!(deque.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+ /// let r = deque.binary_search_by_key(&1, |&(a, b)| b);
/// assert!(matches!(r, Ok(1..=4)));
/// ```
#[unstable(feature = "vecdeque_binary_search", issue = "78021")]
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)