Rollup merge of #81619 - SkiFire13:resultshunt-inplace, r=the8472

Implement `SourceIterator` and `InPlaceIterable` for `ResultShunt`
This commit is contained in:
Dylan DPC 2021-04-04 19:19:59 +02:00 committed by GitHub
commit 869726d335
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 2 deletions

View File

@ -1004,9 +1004,9 @@ fn test_from_iter_specialization_with_iterator_adapters() {
.map_while(Option::Some)
.peekable()
.skip(1)
.map(|e| std::num::NonZeroUsize::new(e));
.map(|e| if e != usize::MAX { Ok(std::num::NonZeroUsize::new(e)) } else { Err(()) });
assert_in_place_trait(&iter);
let sink = iter.collect::<Vec<_>>();
let sink = iter.collect::<Result<Vec<_>, _>>().unwrap();
let sinkptr = sink.as_ptr();
assert_eq!(srcptr, sinkptr as *const usize);
}

View File

@ -194,3 +194,26 @@ where
self.try_fold(init, ok(fold)).unwrap()
}
}
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<S: Iterator, I, E> SourceIter for ResultShunt<'_, I, E>
where
I: SourceIter<Source = S>,
{
type Source = S;
#[inline]
unsafe fn as_inner(&mut self) -> &mut S {
// SAFETY: unsafe function forwarding to unsafe function with the same requirements
unsafe { SourceIter::as_inner(&mut self.iter) }
}
}
// SAFETY: ResultShunt::next calls I::find, which has to advance `iter` in order to
// return `Some(_)`. Since `iter` has type `I: InPlaceIterable` it's guaranteed that
// at least one item will be moved out from the underlying source.
#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<I, T, E> InPlaceIterable for ResultShunt<'_, I, E> where
I: Iterator<Item = Result<T, E>> + InPlaceIterable
{
}