Skip to content

Commit cb7f7ee

Browse files
author
sarah
committed
feat: impl internal iteration for &mut I
1 parent 9bbbf60 commit cb7f7ee

File tree

3 files changed

+117
-1
lines changed

3 files changed

+117
-1
lines changed

library/core/src/iter/traits/double_ended.rs

+55
Original file line numberDiff line numberDiff line change
@@ -362,13 +362,68 @@ pub trait DoubleEndedIterator: Iterator {
362362

363363
#[stable(feature = "rust1", since = "1.0.0")]
364364
impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I {
365+
#[inline]
365366
fn next_back(&mut self) -> Option<I::Item> {
366367
(**self).next_back()
367368
}
369+
#[inline]
368370
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
369371
(**self).advance_back_by(n)
370372
}
373+
#[inline]
371374
fn nth_back(&mut self, n: usize) -> Option<I::Item> {
372375
(**self).nth_back(n)
373376
}
377+
#[inline]
378+
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
379+
where
380+
F: FnMut(B, Self::Item) -> R,
381+
R: Try<Output = B>,
382+
{
383+
ByRefRFold::try_rfold(self, init, f)
384+
}
385+
#[inline]
386+
fn rfold<B, F>(mut self, init: B, f: F) -> B
387+
where
388+
F: FnMut(B, Self::Item) -> B,
389+
{
390+
#[inline]
391+
fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
392+
move |acc, x| Ok(f(acc, x))
393+
}
394+
ByRefRFold::try_rfold(&mut self, init, ok(f)).unwrap()
395+
}
396+
}
397+
398+
trait ByRefRFold: DoubleEndedIterator {
399+
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
400+
where
401+
F: FnMut(B, Self::Item) -> R,
402+
R: Try<Output = B>;
403+
}
404+
405+
impl<'a, I: DoubleEndedIterator + ?Sized> ByRefRFold for &'a mut I {
406+
#[inline]
407+
default fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
408+
where
409+
F: FnMut(B, Self::Item) -> R,
410+
R: Try<Output = B>,
411+
{
412+
let mut accum = init;
413+
while let Some(x) = self.next() {
414+
accum = f(accum, x)?;
415+
}
416+
try { accum }
417+
}
418+
}
419+
420+
impl<'a, I: DoubleEndedIterator + Sized> ByRefRFold for &'a mut I {
421+
#[inline]
422+
default fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
423+
where
424+
F: FnMut(B, Self::Item) -> R,
425+
R: Try<Output = B>,
426+
{
427+
(**self).try_rfold(init, f)
428+
}
374429
}

library/core/src/iter/traits/iterator.rs

+57-1
Original file line numberDiff line numberDiff line change
@@ -2076,11 +2076,12 @@ pub trait Iterator {
20762076
/// assert!(a[i..].iter().all(|&n| n % 2 == 1)); // odds
20772077
/// ```
20782078
#[unstable(feature = "iter_partition_in_place", reason = "new API", issue = "62543")]
2079-
fn partition_in_place<'a, T: 'a, P>(mut self, ref mut predicate: P) -> usize
2079+
fn partition_in_place<'a, T: 'a, P>(mut self, mut predicate: P) -> usize
20802080
where
20812081
Self: Sized + DoubleEndedIterator<Item = &'a mut T>,
20822082
P: FnMut(&T) -> bool,
20832083
{
2084+
let predicate = &mut predicate;
20842085
// FIXME: should we worry about the count overflowing? The only way to have more than
20852086
// `usize::MAX` mutable references is with ZSTs, which aren't useful to partition...
20862087

@@ -3824,13 +3825,68 @@ impl<I: Iterator + ?Sized> Iterator for &mut I {
38243825
fn next(&mut self) -> Option<I::Item> {
38253826
(**self).next()
38263827
}
3828+
#[inline]
38273829
fn size_hint(&self) -> (usize, Option<usize>) {
38283830
(**self).size_hint()
38293831
}
3832+
#[inline]
38303833
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
38313834
(**self).advance_by(n)
38323835
}
3836+
#[inline]
38333837
fn nth(&mut self, n: usize) -> Option<Self::Item> {
38343838
(**self).nth(n)
38353839
}
3840+
#[inline]
3841+
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
3842+
where
3843+
F: FnMut(B, Self::Item) -> R,
3844+
R: Try<Output = B>,
3845+
{
3846+
ByRefFold::try_fold(self, init, f)
3847+
}
3848+
#[inline]
3849+
fn fold<B, F>(mut self, init: B, f: F) -> B
3850+
where
3851+
F: FnMut(B, Self::Item) -> B,
3852+
{
3853+
#[inline]
3854+
fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
3855+
move |acc, x| Ok(f(acc, x))
3856+
}
3857+
ByRefFold::try_fold(&mut self, init, ok(f)).unwrap()
3858+
}
3859+
}
3860+
3861+
trait ByRefFold: Iterator {
3862+
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
3863+
where
3864+
F: FnMut(B, Self::Item) -> R,
3865+
R: Try<Output = B>;
3866+
}
3867+
3868+
impl<'a, I: Iterator + ?Sized> ByRefFold for &'a mut I {
3869+
#[inline]
3870+
default fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
3871+
where
3872+
F: FnMut(B, Self::Item) -> R,
3873+
R: Try<Output = B>,
3874+
{
3875+
let mut accum = init;
3876+
while let Some(x) = self.next() {
3877+
accum = f(accum, x)?;
3878+
}
3879+
try { accum }
3880+
}
3881+
}
3882+
3883+
impl<'a, I: Iterator + Sized> ByRefFold for &'a mut I {
3884+
#[inline]
3885+
default fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
3886+
where
3887+
F: FnMut(B, Self::Item) -> R,
3888+
R: Try<Output = B>,
3889+
{
3890+
(**self).try_fold(init, f)
3891+
}
38363892
}

library/core/src/ops/function.rs

+5
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ mod impls {
254254
where
255255
F: Fn<A>,
256256
{
257+
#[inline]
257258
extern "rust-call" fn call(&self, args: A) -> F::Output {
258259
(**self).call(args)
259260
}
@@ -264,6 +265,7 @@ mod impls {
264265
where
265266
F: Fn<A>,
266267
{
268+
#[inline]
267269
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
268270
(**self).call(args)
269271
}
@@ -276,6 +278,7 @@ mod impls {
276278
{
277279
type Output = F::Output;
278280

281+
#[inline]
279282
extern "rust-call" fn call_once(self, args: A) -> F::Output {
280283
(*self).call(args)
281284
}
@@ -286,6 +289,7 @@ mod impls {
286289
where
287290
F: FnMut<A>,
288291
{
292+
#[inline]
289293
extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
290294
(*self).call_mut(args)
291295
}
@@ -297,6 +301,7 @@ mod impls {
297301
F: FnMut<A>,
298302
{
299303
type Output = F::Output;
304+
#[inline]
300305
extern "rust-call" fn call_once(self, args: A) -> F::Output {
301306
(*self).call_mut(args)
302307
}

0 commit comments

Comments
 (0)