}
}
+ /// Copies all values from `src` to `dst`, wrapping around if needed.
+ /// Assumes capacity is sufficient.
+ #[inline]
+ unsafe fn copy_slice(&mut self, dst: usize, src: &[T]) {
+ debug_assert!(src.len() <= self.cap());
+ let head_room = self.cap() - dst;
+ if src.len() <= head_room {
+ unsafe {
+ ptr::copy_nonoverlapping(src.as_ptr(), self.ptr().add(dst), src.len());
+ }
+ } else {
+ let (left, right) = src.split_at(head_room);
+ unsafe {
+ ptr::copy_nonoverlapping(left.as_ptr(), self.ptr().add(dst), left.len());
+ ptr::copy_nonoverlapping(right.as_ptr(), self.ptr(), right.len());
+ }
+ }
+ }
+
/// Frobs the head and tail sections around to handle the fact that we
/// just reallocated. Unsafe because it trusts old_capacity.
#[inline]
/// ```
#[unstable(feature = "allocator_api", issue = "32838")]
pub fn with_capacity_in(capacity: usize, alloc: A) -> VecDeque<T, A> {
+ assert!(capacity < 1_usize << usize::BITS - 1, "capacity overflow");
// +1 since the ringbuffer always leaves one space empty
let cap = cmp::max(capacity + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
- assert!(cap > capacity, "capacity overflow");
VecDeque { tail: 0, head: 0, buf: RawVec::with_capacity_in(cap, alloc) }
}
#[inline]
#[stable(feature = "append", since = "1.4.0")]
pub fn append(&mut self, other: &mut Self) {
- // naive impl
- self.extend(other.drain(..));
+ self.reserve(other.len());
+ unsafe {
+ let (left, right) = other.as_slices();
+ self.copy_slice(self.head, left);
+ self.copy_slice(self.wrap_add(self.head, left.len()), right);
+ }
+ // SAFETY: Update pointers after copying to avoid leaving doppelganger
+ // in case of panics.
+ self.head = self.wrap_add(self.head, other.len());
+ // Silently drop values in `other`.
+ other.tail = other.head;
}
/// Retains only the elements specified by the predicate.