Implement in-place iteratation markers for iter::{Copied, Cloned}

This commit is contained in:
The8472 2021-05-20 00:40:55 +02:00 committed by The 8472
parent 3aa73135cf
commit 37d26c719d
3 changed files with 51 additions and 6 deletions

View File

@ -1166,10 +1166,14 @@ fn test_from_iter_partially_drained_in_place_specialization() {
#[test]
fn test_from_iter_specialization_with_iterator_adapters() {
fn assert_in_place_trait<T: InPlaceIterable>(_: &T) {}
let src: Vec<usize> = vec![0usize; 256];
let owned: Vec<usize> = vec![0usize; 256];
let refd: Vec<&usize> = owned.iter().collect();
let src: Vec<&&usize> = refd.iter().collect();
let srcptr = src.as_ptr();
let iter = src
.into_iter()
.copied()
.cloned()
.enumerate()
.map(|i| i.0 + i.1)
.zip(std::iter::repeat(1usize))
@ -1180,7 +1184,7 @@ fn test_from_iter_specialization_with_iterator_adapters() {
assert_in_place_trait(&iter);
let sink = iter.collect::<Result<Vec<_>, _>>().unwrap();
let sinkptr = sink.as_ptr();
assert_eq!(srcptr, sinkptr as *const usize);
assert_eq!(srcptr as *const usize, sinkptr as *const usize);
}
#[test]

View File

@ -1,8 +1,9 @@
use crate::iter::adapters::{
zip::try_get_unchecked, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
zip::try_get_unchecked, SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
};
use crate::iter::{FusedIterator, TrustedLen, UncheckedIterator};
use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen, UncheckedIterator};
use crate::ops::Try;
use core::num::NonZeroUsize;
/// An iterator that clones the elements of an underlying iterator.
///
@ -167,3 +168,23 @@ impl<I: Default> Default for Cloned<I> {
Self::new(Default::default())
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<I> SourceIter for Cloned<I>
where
I: SourceIter,
{
type Source = I::Source;
#[inline]
unsafe fn as_inner(&mut self) -> &mut I::Source {
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
unsafe { SourceIter::as_inner(&mut self.it) }
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable> InPlaceIterable for Cloned<I> {
const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
}

View File

@ -1,7 +1,7 @@
use crate::iter::adapters::{
zip::try_get_unchecked, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
zip::try_get_unchecked, SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
};
use crate::iter::{FusedIterator, TrustedLen};
use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
use crate::mem::MaybeUninit;
use crate::mem::SizedTypeProperties;
use crate::num::NonZeroUsize;
@ -255,3 +255,23 @@ impl<I: Default> Default for Copied<I> {
Self::new(Default::default())
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<I> SourceIter for Copied<I>
where
I: SourceIter,
{
type Source = I::Source;
#[inline]
unsafe fn as_inner(&mut self) -> &mut I::Source {
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
unsafe { SourceIter::as_inner(&mut self.it) }
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable> InPlaceIterable for Copied<I> {
const EXPAND_BY: Option<NonZeroUsize> = I::EXPAND_BY;
const MERGE_BY: Option<NonZeroUsize> = I::MERGE_BY;
}