// SPDX-License-Identifier: Apache-2.0 OR MIT // // Modifications Copyright Kani Contributors // See GitHub history for details. //! This is a modified version of std collections/vec_deque/mod.rs //! A double-ended queue (deque) implemented with a growable ring buffer. //! //! This queue has *O*(1) amortized inserts and removals from both ends of the //! container. It also has *O*(1) indexing like a vector. The contained elements //! are not required to be copyable, and the queue will be sendable if the //! contained type is sendable. #[allow(unsafe_op_in_unsafe_fn)] use core::slice; use crate::raw_vec::RawVec; use std::alloc::{Allocator, Global}; pub use std::collections::vec_deque::*; use std::{cmp, mem, ptr}; 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 /// A double-ended queue implemented with a growable ring buffer. /// /// The "default" usage of this type as a queue is to use [`push_back`] to add to /// the queue, and [`pop_front`] to remove from the queue. [`extend`] and [`append`] /// push onto the back in this manner, and iterating over `VecDeque` goes front /// to back. /// /// A `VecDeque` with a known list of items can be initialized from an array: /// /// ``` /// use std::collections::VecDeque; /// /// let deq = VecDeque::from([-1, 0, 1]); /// ``` /// /// Since `VecDeque` is a ring buffer, its elements are not necessarily contiguous /// in memory. If you want to access the elements as a single slice, such as for /// efficient sorting, you can use [`make_contiguous`]. It rotates the `VecDeque` /// so that its elements do not wrap, and returns a mutable slice to the /// now-contiguous element sequence. /// /// [`push_back`]: VecDeque::push_back /// [`pop_front`]: VecDeque::pop_front /// [`extend`]: VecDeque::extend /// [`append`]: VecDeque::append /// [`make_contiguous`]: VecDeque::make_contiguous //#[cfg_attr(not(test), rustc_diagnostic_item = "VecDeque")] //#[stable(feature = "rust1", since = "1.0.0")] #[rustc_insignificant_dtor] pub struct VecDeque< T, //#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, > { // tail and head are pointers into the buffer. Tail always points // to the first element that could be read, Head always points // to where data should be written. // If tail == head the buffer is empty. The length of the ringbuffer // is defined as the distance between the two. tail: usize, head: usize, buf: RawVec, } //#[stable(feature = "rust1", since = "1.0.0")] impl Default for VecDeque { /// Creates an empty deque. #[inline] fn default() -> VecDeque { VecDeque::new() } } impl VecDeque { /// Marginally more convenient #[inline] fn ptr(&self) -> *mut T { self.buf.ptr() } /// Marginally more convenient #[inline] fn cap(&self) -> usize { if mem::size_of::() == 0 { // For zero sized types, we are always at maximum capacity MAXIMUM_ZST_CAPACITY } else { self.buf.capacity() } } /// Writes an element into the buffer, moving it. #[inline] unsafe fn buffer_write(&mut self, off: usize, value: T) { unsafe { ptr::write(self.ptr().add(off), value); } } /// Returns `true` if the buffer is at full capacity. #[inline] fn is_full(&self) -> bool { self.cap() - self.len() == 1 } /// Returns the index in the underlying buffer for a given logical element /// index + addend. #[inline] fn wrap_add(&self, idx: usize, addend: usize) -> usize { wrap_index(idx.wrapping_add(addend), self.cap()) } /// Returns the index in the underlying buffer for a given logical element /// index - subtrahend. #[inline] fn wrap_sub(&self, idx: usize, subtrahend: usize) -> usize { wrap_index(idx.wrapping_sub(subtrahend), self.cap()) } /// Copies a contiguous block of memory len long from src to dst #[inline] unsafe fn copy_nonoverlapping(&self, dst: usize, src: usize, len: usize) { debug_assert!( dst + len <= self.cap(), "cno dst={} src={} len={} cap={}", dst, src, len, self.cap() ); debug_assert!( src + len <= self.cap(), "cno dst={} src={} len={} cap={}", dst, src, len, self.cap() ); unsafe { ptr::copy_nonoverlapping(self.ptr().add(src), self.ptr().add(dst), len); } } /// Frobs the head and tail sections around to handle the fact that we /// just reallocated. Unsafe because it trusts old_capacity. #[inline] unsafe fn handle_capacity_increase(&mut self, old_capacity: usize) { let new_capacity = self.cap(); // Move the shortest contiguous section of the ring buffer // T H // [o o o o o o o . ] // T H // A [o o o o o o o . . . . . . . . . ] // H T // [o o . o o o o o ] // T H // B [. . . o o o o o o o . . . . . . ] // H T // [o o o o o . o o ] // H T // C [o o o o o . . . . . . . . . o o ] if self.tail <= self.head { // A // Nop } else if self.head < old_capacity - self.tail { // B unsafe { self.copy_nonoverlapping(old_capacity, 0, self.head); } self.head += old_capacity; debug_assert!(self.head > self.tail); } else { // C let new_tail = new_capacity - (old_capacity - self.tail); unsafe { self.copy_nonoverlapping(new_tail, self.tail, old_capacity - self.tail); } self.tail = new_tail; debug_assert!(self.head < self.tail); } debug_assert!(self.head < self.cap()); debug_assert!(self.tail < self.cap()); debug_assert!(self.cap().count_ones() == 1); } } impl VecDeque { /// Creates an empty deque. /// /// # Examples /// /// ``` /// use std::collections::VecDeque; /// /// let deque: VecDeque = VecDeque::new(); /// ``` #[inline] //#[stable(feature = "rust1", since = "1.0.0")] #[must_use] pub fn new() -> VecDeque { VecDeque::new_in(Global) } /// Creates an empty deque with space for at least `capacity` elements. /// /// # Examples /// /// ``` /// use std::collections::VecDeque; /// /// let deque: VecDeque = VecDeque::with_capacity(10); /// ``` #[inline] //#[stable(feature = "rust1", since = "1.0.0")] #[must_use] pub fn with_capacity(capacity: usize) -> VecDeque { Self::with_capacity_in(capacity, Global) } } impl VecDeque { /// Creates an empty deque. /// /// # Examples /// /// ``` /// use std::collections::VecDeque; /// /// let deque: VecDeque = VecDeque::new(); /// ``` #[inline] //#[unstable(feature = "allocator_api", issue = "32838")] fn new_in(alloc: A) -> VecDeque { VecDeque::with_capacity_in(INITIAL_CAPACITY, alloc) } /// Creates an empty deque with space for at least `capacity` elements. /// /// # Examples /// /// ``` /// use std::collections::VecDeque; /// /// let deque: VecDeque = VecDeque::with_capacity(10); /// ``` //#[unstable(feature = "allocator_api", issue = "32838")] fn with_capacity_in(capacity: usize, alloc: A) -> VecDeque { 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(); VecDeque { tail: 0, head: 0, buf: RawVec::with_capacity_in(cap, alloc) } } /// Provides a reference to the element at the given index. /// /// Element at index 0 is the front of the queue. /// /// # Examples /// /// ``` /// use std::collections::VecDeque; /// /// let mut buf = VecDeque::new(); /// buf.push_back(3); /// buf.push_back(4); /// buf.push_back(5); /// assert_eq!(buf.get(1), Some(&4)); /// ``` //#[stable(feature = "rust1", since = "1.0.0")] pub fn get(&self, index: usize) -> Option<&T> { if index < self.len() { let idx = self.wrap_add(self.tail, index); unsafe { Some(&*self.ptr().add(idx)) } } else { None } } /// Provides a mutable reference to the element at the given index. /// /// Element at index 0 is the front of the queue. /// /// # Examples /// /// ``` /// use std::collections::VecDeque; /// /// let mut buf = VecDeque::new(); /// buf.push_back(3); /// buf.push_back(4); /// buf.push_back(5); /// if let Some(elem) = buf.get_mut(1) { /// *elem = 7; /// } /// /// assert_eq!(buf[1], 7); /// ``` //#[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self, index: usize) -> Option<&mut T> { if index < self.len() { let idx = self.wrap_add(self.tail, index); unsafe { Some(&mut *self.ptr().add(idx)) } } else { None } } /// Returns the number of elements the deque can hold without /// reallocating. /// /// # Examples /// /// ``` /// use std::collections::VecDeque; /// /// let buf: VecDeque = VecDeque::with_capacity(10); /// assert!(buf.capacity() >= 10); /// ``` #[inline] //#[stable(feature = "rust1", since = "1.0.0")] pub fn capacity(&self) -> usize { self.cap() - 1 } /// Reserves capacity for at least `additional` more elements to be inserted in the given /// deque. The collection may reserve more space to avoid frequent reallocations. /// /// # Panics /// /// Panics if the new capacity overflows `usize`. /// /// # Examples /// /// ``` /// use std::collections::VecDeque; /// /// let mut buf: VecDeque = [1].into(); /// buf.reserve(10); /// assert!(buf.capacity() >= 11); /// ``` //#[stable(feature = "rust1", since = "1.0.0")] pub fn reserve(&mut self, additional: usize) { let old_cap = self.cap(); let used_cap = self.len() + 1; let new_cap = used_cap .checked_add(additional) .and_then(|needed_cap| needed_cap.checked_next_power_of_two()) .expect("capacity overflow"); if new_cap > old_cap { self.buf.reserve_exact(used_cap, new_cap - used_cap); unsafe { self.handle_capacity_increase(old_cap); } } } /// Returns the number of elements in the deque. /// /// # Examples /// /// ``` /// use std::collections::VecDeque; /// /// let mut deque = VecDeque::new(); /// assert_eq!(deque.len(), 0); /// deque.push_back(1); /// assert_eq!(deque.len(), 1); /// ``` //#[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> usize { count(self.tail, self.head, self.cap()) } /// Returns `true` if the deque is empty. /// /// # Examples /// /// ``` /// use std::collections::VecDeque; /// /// let mut deque = VecDeque::new(); /// assert!(deque.is_empty()); /// deque.push_front(1); /// assert!(!deque.is_empty()); /// ``` //#[stable(feature = "rust1", since = "1.0.0")] pub fn is_empty(&self) -> bool { self.tail == self.head } /// Provides a reference to the front element, or `None` if the deque is /// empty. /// /// # Examples /// /// ``` /// use std::collections::VecDeque; /// /// let mut d = VecDeque::new(); /// assert_eq!(d.front(), None); /// /// d.push_back(1); /// d.push_back(2); /// assert_eq!(d.front(), Some(&1)); /// ``` //#[stable(feature = "rust1", since = "1.0.0")] pub fn front(&self) -> Option<&T> { self.get(0) } /// Provides a mutable reference to the front element, or `None` if the /// deque is empty. /// /// # Examples /// /// ``` /// use std::collections::VecDeque; /// /// let mut d = VecDeque::new(); /// assert_eq!(d.front_mut(), None); /// /// d.push_back(1); /// d.push_back(2); /// match d.front_mut() { /// Some(x) => *x = 9, /// None => (), /// } /// assert_eq!(d.front(), Some(&9)); /// ``` //#[stable(feature = "rust1", since = "1.0.0")] pub fn front_mut(&mut self) -> Option<&mut T> { self.get_mut(0) } /// Provides a reference to the back element, or `None` if the deque is /// empty. /// /// # Examples /// /// ``` /// use std::collections::VecDeque; /// /// let mut d = VecDeque::new(); /// assert_eq!(d.back(), None); /// /// d.push_back(1); /// d.push_back(2); /// assert_eq!(d.back(), Some(&2)); /// ``` //#[stable(feature = "rust1", since = "1.0.0")] pub fn back(&self) -> Option<&T> { self.get(self.len().wrapping_sub(1)) } /// Prepends an element to the deque. /// /// # Examples /// /// ``` /// use std::collections::VecDeque; /// /// let mut d = VecDeque::new(); /// d.push_front(1); /// d.push_front(2); /// assert_eq!(d.front(), Some(&2)); /// ``` //#[stable(feature = "rust1", since = "1.0.0")] pub fn push_front(&mut self, value: T) { if self.is_full() { self.grow(); } self.tail = self.wrap_sub(self.tail, 1); let tail = self.tail; unsafe { self.buffer_write(tail, value); } } /// Appends an element to the back of the deque. /// /// # Examples /// /// ``` /// use std::collections::VecDeque; /// /// let mut buf = VecDeque::new(); /// buf.push_back(1); /// buf.push_back(3); /// assert_eq!(3, *buf.back().unwrap()); /// ``` //#[stable(feature = "rust1", since = "1.0.0")] pub fn push_back(&mut self, value: T) { if self.is_full() { self.grow(); } let head = self.head; self.head = self.wrap_add(self.head, 1); unsafe { self.buffer_write(head, value) } } // Double the buffer size. This method is inline(never), so we expect it to only // be called in cold paths. // This may panic or abort #[inline(never)] fn grow(&mut self) { // Extend or possibly remove this assertion when valid use-cases for growing the // buffer without it being full emerge debug_assert!(self.is_full()); let old_cap = self.cap(); self.buf.reserve_exact(old_cap, old_cap); assert!(self.cap() == old_cap * 2); unsafe { self.handle_capacity_increase(old_cap); } debug_assert!(!self.is_full()); } } /// Returns the index in the underlying buffer for a given logical element index. #[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) } /// Calculate the number of elements left to be read in the buffer #[inline] fn count(tail: usize, head: usize, size: usize) -> usize { // size is always a power of 2 (head.wrapping_sub(tail)) & (size - 1) }