-
Notifications
You must be signed in to change notification settings - Fork 13k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of #78590 - DeveloperC286:issue_60302, r=varkor
refactor: removing alloc::collections::vec_deque ignore-tidy-filelength This PR removes the need for ignore-tidy-filelength for alloc::collections::vec_deque which is part of the issue #60302 It is probably easiest to review this PR by looking at it commit by commit rather than looking at the overall diff.
- Loading branch information
Showing
8 changed files
with
515 additions
and
473 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.