Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: removing alloc::collections::vec_deque ignore-tidy-filelength #78590

Merged
merged 1 commit into from
Nov 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions library/alloc/src/collections/vec_deque/into_iter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use core::fmt;
use core::iter::FusedIterator;

use super::VecDeque;

/// An owning iterator over the elements of a `VecDeque`.
///
/// This `struct` is created by the [`into_iter`] method on [`VecDeque`]
/// (provided by the `IntoIterator` trait). See its documentation for more.
///
/// [`into_iter`]: VecDeque::into_iter
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IntoIter<T> {
pub(crate) inner: VecDeque<T>,
}

#[stable(feature = "collection_debug", since = "1.17.0")]
impl<T: fmt::Debug> fmt::Debug for IntoIter<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("IntoIter").field(&self.inner).finish()
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Iterator for IntoIter<T> {
type Item = T;

#[inline]
fn next(&mut self) -> Option<T> {
self.inner.pop_front()
}

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.inner.len();
(len, Some(len))
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> DoubleEndedIterator for IntoIter<T> {
#[inline]
fn next_back(&mut self) -> Option<T> {
self.inner.pop_back()
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ExactSizeIterator for IntoIter<T> {
fn is_empty(&self) -> bool {
self.inner.is_empty()
}
}

#[stable(feature = "fused", since = "1.26.0")]
impl<T> FusedIterator for IntoIter<T> {}
159 changes: 159 additions & 0 deletions library/alloc/src/collections/vec_deque/iter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
use core::fmt;
use core::iter::FusedIterator;
use core::ops::Try;

use super::{count, wrap_index, RingSlices};

/// An iterator over the elements of a `VecDeque`.
///
/// This `struct` is created by the [`iter`] method on [`super::VecDeque`]. See its
/// documentation for more.
///
/// [`iter`]: super::VecDeque::iter
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Iter<'a, T: 'a> {
pub(crate) ring: &'a [T],
pub(crate) tail: usize,
pub(crate) head: usize,
}

#[stable(feature = "collection_debug", since = "1.17.0")]
impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
f.debug_tuple("Iter").field(&front).field(&back).finish()
}
}

// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Clone for Iter<'_, T> {
fn clone(&self) -> Self {
Iter { ring: self.ring, tail: self.tail, head: self.head }
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;

#[inline]
fn next(&mut self) -> Option<&'a T> {
if self.tail == self.head {
return None;
}
let tail = self.tail;
self.tail = wrap_index(self.tail.wrapping_add(1), self.ring.len());
unsafe { Some(self.ring.get_unchecked(tail)) }
}

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = count(self.tail, self.head, self.ring.len());
(len, Some(len))
}

fn fold<Acc, F>(self, mut accum: Acc, mut f: F) -> Acc
where
F: FnMut(Acc, Self::Item) -> Acc,
{
let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
accum = front.iter().fold(accum, &mut f);
back.iter().fold(accum, &mut f)
}

fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
where
Self: Sized,
F: FnMut(B, Self::Item) -> R,
R: Try<Ok = B>,
{
let (mut iter, final_res);
if self.tail <= self.head {
// single slice self.ring[self.tail..self.head]
iter = self.ring[self.tail..self.head].iter();
final_res = iter.try_fold(init, &mut f);
} else {
// two slices: self.ring[self.tail..], self.ring[..self.head]
let (front, back) = self.ring.split_at(self.tail);
let mut back_iter = back.iter();
let res = back_iter.try_fold(init, &mut f);
let len = self.ring.len();
self.tail = (self.ring.len() - back_iter.len()) & (len - 1);
iter = front[..self.head].iter();
final_res = iter.try_fold(res?, &mut f);
}
self.tail = self.head - iter.len();
final_res
}

fn nth(&mut self, n: usize) -> Option<Self::Item> {
if n >= count(self.tail, self.head, self.ring.len()) {
self.tail = self.head;
None
} else {
self.tail = wrap_index(self.tail.wrapping_add(n), self.ring.len());
self.next()
}
}

#[inline]
fn last(mut self) -> Option<&'a T> {
self.next_back()
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<&'a T> {
if self.tail == self.head {
return None;
}
self.head = wrap_index(self.head.wrapping_sub(1), self.ring.len());
unsafe { Some(self.ring.get_unchecked(self.head)) }
}

fn rfold<Acc, F>(self, mut accum: Acc, mut f: F) -> Acc
where
F: FnMut(Acc, Self::Item) -> Acc,
{
let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
accum = back.iter().rfold(accum, &mut f);
front.iter().rfold(accum, &mut f)
}

fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
where
Self: Sized,
F: FnMut(B, Self::Item) -> R,
R: Try<Ok = B>,
{
let (mut iter, final_res);
if self.tail <= self.head {
// single slice self.ring[self.tail..self.head]
iter = self.ring[self.tail..self.head].iter();
final_res = iter.try_rfold(init, &mut f);
} else {
// two slices: self.ring[self.tail..], self.ring[..self.head]
let (front, back) = self.ring.split_at(self.tail);
let mut front_iter = front[..self.head].iter();
let res = front_iter.try_rfold(init, &mut f);
self.head = front_iter.len();
iter = back.iter();
final_res = iter.try_rfold(res?, &mut f);
}
self.head = self.tail + iter.len();
final_res
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ExactSizeIterator for Iter<'_, T> {
fn is_empty(&self) -> bool {
self.head == self.tail
}
}

#[stable(feature = "fused", since = "1.26.0")]
impl<T> FusedIterator for Iter<'_, T> {}
128 changes: 128 additions & 0 deletions library/alloc/src/collections/vec_deque/iter_mut.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
use core::fmt;
use core::iter::FusedIterator;
use core::marker::PhantomData;

use super::{count, wrap_index, RingSlices};

/// A mutable iterator over the elements of a `VecDeque`.
///
/// This `struct` is created by the [`iter_mut`] method on [`super::VecDeque`]. See its
/// documentation for more.
///
/// [`iter_mut`]: super::VecDeque::iter_mut
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IterMut<'a, T: 'a> {
// Internal safety invariant: the entire slice is dereferencable.
pub(crate) ring: *mut [T],
pub(crate) tail: usize,
pub(crate) head: usize,
pub(crate) phantom: PhantomData<&'a mut [T]>,
}

// SAFETY: we do nothing thread-local and there is no interior mutability,
// so the usual structural `Send`/`Sync` apply.
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<T: Send> Send for IterMut<'_, T> {}
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<T: Sync> Sync for IterMut<'_, T> {}

#[stable(feature = "collection_debug", since = "1.17.0")]
impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
// SAFETY: these are the elements we have not handed out yet, so aliasing is fine.
// The `IterMut` invariant also ensures everything is dereferencable.
let (front, back) = unsafe { (&*front, &*back) };
f.debug_tuple("IterMut").field(&front).field(&back).finish()
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;

#[inline]
fn next(&mut self) -> Option<&'a mut T> {
if self.tail == self.head {
return None;
}
let tail = self.tail;
self.tail = wrap_index(self.tail.wrapping_add(1), self.ring.len());

unsafe {
let elem = self.ring.get_unchecked_mut(tail);
Some(&mut *elem)
}
}

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = count(self.tail, self.head, self.ring.len());
(len, Some(len))
}

fn fold<Acc, F>(self, mut accum: Acc, mut f: F) -> Acc
where
F: FnMut(Acc, Self::Item) -> Acc,
{
let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
// SAFETY: these are the elements we have not handed out yet, so aliasing is fine.
// The `IterMut` invariant also ensures everything is dereferencable.
let (front, back) = unsafe { (&mut *front, &mut *back) };
accum = front.iter_mut().fold(accum, &mut f);
back.iter_mut().fold(accum, &mut f)
}

fn nth(&mut self, n: usize) -> Option<Self::Item> {
if n >= count(self.tail, self.head, self.ring.len()) {
self.tail = self.head;
None
} else {
self.tail = wrap_index(self.tail.wrapping_add(n), self.ring.len());
self.next()
}
}

#[inline]
fn last(mut self) -> Option<&'a mut T> {
self.next_back()
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<&'a mut T> {
if self.tail == self.head {
return None;
}
self.head = wrap_index(self.head.wrapping_sub(1), self.ring.len());

unsafe {
let elem = self.ring.get_unchecked_mut(self.head);
Some(&mut *elem)
}
}

fn rfold<Acc, F>(self, mut accum: Acc, mut f: F) -> Acc
where
F: FnMut(Acc, Self::Item) -> Acc,
{
let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail);
// SAFETY: these are the elements we have not handed out yet, so aliasing is fine.
// The `IterMut` invariant also ensures everything is dereferencable.
let (front, back) = unsafe { (&mut *front, &mut *back) };
accum = back.iter_mut().rfold(accum, &mut f);
front.iter_mut().rfold(accum, &mut f)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ExactSizeIterator for IterMut<'_, T> {
fn is_empty(&self) -> bool {
self.head == self.tail
}
}

#[stable(feature = "fused", since = "1.26.0")]
impl<T> FusedIterator for IterMut<'_, T> {}
19 changes: 19 additions & 0 deletions library/alloc/src/collections/vec_deque/macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
macro_rules! __impl_slice_eq1 {
([$($vars:tt)*] $lhs:ty, $rhs:ty, $($constraints:tt)*) => {
#[stable(feature = "vec_deque_partial_eq_slice", since = "1.17.0")]
impl<A, B, $($vars)*> PartialEq<$rhs> for $lhs
where
A: PartialEq<B>,
$($constraints)*
{
fn eq(&self, other: &$rhs) -> bool {
if self.len() != other.len() {
return false;
}
let (sa, sb) = self.as_slices();
let (oa, ob) = other[..].split_at(sa.len());
sa == oa && sb == ob
}
}
}
}
Loading