Skip to content

Commit 1824371

Browse files
committed
range changes
1 parent 84a554c commit 1824371

37 files changed

+3139
-1157
lines changed

library/alloc/src/collections/btree/node.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
546546
impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
547547
/// # Safety
548548
/// Every item returned by `range` is a valid edge index for the node.
549-
unsafe fn correct_childrens_parent_links<R: Iterator<Item = usize>>(&mut self, range: R) {
549+
unsafe fn correct_childrens_parent_links<R: IntoIterator<Item = usize>>(&mut self, range: R) {
550550
for i in range {
551551
debug_assert!(i <= self.len());
552552
unsafe { Handle::new_edge(self.reborrow_mut(), i) }.correct_parent_link();

library/alloc/src/collections/vec_deque/tests.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -899,10 +899,13 @@ fn test_extend_impl(trusted_len: bool) {
899899
Self { test: VecDeque::new(), expected: VecDeque::new(), trusted_len }
900900
}
901901

902-
fn test_extend<I>(&mut self, iter: I)
902+
fn test_extend<I, IntoIter>(&mut self, iter: I)
903903
where
904-
I: Iterator<Item = usize> + TrustedLen + Clone,
904+
I: IntoIterator<IntoIter = IntoIter>,
905+
IntoIter: Iterator<Item = usize> + TrustedLen + Clone,
905906
{
907+
let iter = iter.into_iter();
908+
906909
struct BasicIterator<I>(I);
907910
impl<I> Iterator for BasicIterator<I>
908911
where

library/alloc/tests/str.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -590,15 +590,15 @@ mod slice_index {
590590

591591
good: data[0..=5] == "abcdef";
592592
good: data[{
593-
let mut iter = 0..=5;
593+
let mut iter = core::ops::range::legacy::RangeInclusive::from(0..=5);
594594
iter.by_ref().count(); // exhaust it
595595
iter
596596
}] == "";
597597

598598
// 0..=6 is out of bounds before exhaustion, so it
599599
// stands to reason that it still would be after.
600600
bad: data[{
601-
let mut iter = 0..=6;
601+
let mut iter = core::ops::range::legacy::RangeInclusive::from(0..=6);
602602
iter.by_ref().count(); // exhaust it
603603
iter
604604
}];

library/core/benches/iter.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -493,42 +493,42 @@ fn bench_next_chunk_trusted_random_access(b: &mut Bencher) {
493493

494494
#[bench]
495495
fn bench_next_chunk_filter_even(b: &mut Bencher) {
496-
let a = (0..1024).next_chunk::<1024>().unwrap();
496+
let a = (0..1024).into_iter().next_chunk::<1024>().unwrap();
497497

498498
b.iter(|| black_box(&a).iter().filter(|&&i| i % 2 == 0).next_chunk::<32>())
499499
}
500500

501501
#[bench]
502502
fn bench_next_chunk_filter_predictably_true(b: &mut Bencher) {
503-
let a = (0..1024).next_chunk::<1024>().unwrap();
503+
let a = (0..1024).into_iter().next_chunk::<1024>().unwrap();
504504

505505
b.iter(|| black_box(&a).iter().filter(|&&i| i < 100).next_chunk::<32>())
506506
}
507507

508508
#[bench]
509509
fn bench_next_chunk_filter_mostly_false(b: &mut Bencher) {
510-
let a = (0..1024).next_chunk::<1024>().unwrap();
510+
let a = (0..1024).into_iter().next_chunk::<1024>().unwrap();
511511

512512
b.iter(|| black_box(&a).iter().filter(|&&i| i > 900).next_chunk::<32>())
513513
}
514514

515515
#[bench]
516516
fn bench_next_chunk_filter_map_even(b: &mut Bencher) {
517-
let a = (0..1024).next_chunk::<1024>().unwrap();
517+
let a = (0..1024).into_iter().next_chunk::<1024>().unwrap();
518518

519519
b.iter(|| black_box(&a).iter().filter_map(|&i| (i % 2 == 0).then(|| i)).next_chunk::<32>())
520520
}
521521

522522
#[bench]
523523
fn bench_next_chunk_filter_map_predictably_true(b: &mut Bencher) {
524-
let a = (0..1024).next_chunk::<1024>().unwrap();
524+
let a = (0..1024).into_iter().next_chunk::<1024>().unwrap();
525525

526526
b.iter(|| black_box(&a).iter().filter_map(|&i| (i < 100).then(|| i)).next_chunk::<32>())
527527
}
528528

529529
#[bench]
530530
fn bench_next_chunk_filter_map_mostly_false(b: &mut Bencher) {
531-
let a = (0..1024).next_chunk::<1024>().unwrap();
531+
let a = (0..1024).into_iter().next_chunk::<1024>().unwrap();
532532

533533
b.iter(|| black_box(&a).iter().filter_map(|&i| (i > 900).then(|| i)).next_chunk::<32>())
534534
}

library/core/src/array/iter.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,9 @@ impl<T, const N: usize> IntoIter<T, N> {
132132
/// unsafe { Ok(buffer.transpose().assume_init()) }
133133
/// }
134134
///
135-
/// let r: [_; 4] = next_chunk(&mut (10..16)).unwrap();
135+
/// let r: [_; 4] = next_chunk(&mut (10..16).into_iter()).unwrap();
136136
/// assert_eq!(r, [10, 11, 12, 13]);
137-
/// let r: IntoIter<_, 40> = next_chunk(&mut (10..16)).unwrap_err();
137+
/// let r: IntoIter<_, 40> = next_chunk(&mut (10..16).into_iter()).unwrap_err();
138138
/// assert_eq!(r.collect::<Vec<_>>(), vec![10, 11, 12, 13, 14, 15]);
139139
/// ```
140140
#[unstable(feature = "array_into_iter_constructors", issue = "91583")]

library/core/src/escape.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Helper code for character escaping.
22
33
use crate::ascii;
4+
use crate::iter::range::RangeIter;
45
use crate::num::NonZeroUsize;
56
use crate::ops::Range;
67

@@ -68,14 +69,14 @@ pub(crate) struct EscapeIterInner<const N: usize> {
6869
pub(crate) data: [ascii::Char; N],
6970

7071
// Invariant: alive.start <= alive.end <= N.
71-
pub(crate) alive: Range<u8>,
72+
pub(crate) alive: RangeIter<u8>,
7273
}
7374

7475
impl<const N: usize> EscapeIterInner<N> {
7576
pub fn new(data: [ascii::Char; N], alive: Range<u8>) -> Self {
7677
const { assert!(N < 256) };
7778
debug_assert!(alive.start <= alive.end && usize::from(alive.end) <= N, "{alive:?}");
78-
Self { data, alive }
79+
Self { data, alive: alive.into_iter() }
7980
}
8081

8182
pub fn from_array<const M: usize>(array: [ascii::Char; M]) -> Self {
@@ -87,15 +88,15 @@ impl<const N: usize> EscapeIterInner<N> {
8788
}
8889

8990
pub fn as_ascii(&self) -> &[ascii::Char] {
90-
&self.data[usize::from(self.alive.start)..usize::from(self.alive.end)]
91+
&self.data[usize::from(self.alive.inner.start)..usize::from(self.alive.inner.end)]
9192
}
9293

9394
pub fn as_str(&self) -> &str {
9495
self.as_ascii().as_str()
9596
}
9697

9798
pub fn len(&self) -> usize {
98-
usize::from(self.alive.end - self.alive.start)
99+
usize::from(self.alive.inner.end - self.alive.inner.start)
99100
}
100101

101102
pub fn next(&mut self) -> Option<u8> {

library/core/src/iter/adapters/step_by.rs

+143-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::convert::TryFrom;
22
use crate::{
33
intrinsics,
4-
iter::{from_fn, TrustedLen},
5-
ops::{Range, Try},
4+
iter::{from_fn, range::RangeIter, TrustedLen},
5+
ops::{range::legacy::Range, Try},
66
};
77

88
/// An iterator for stepping iterators by a custom amount.
@@ -486,6 +486,89 @@ macro_rules! spec_int_ranges {
486486
/// the outer length calculation won't encounter clamped values
487487
#[unstable(feature = "trusted_len", issue = "37572")]
488488
unsafe impl TrustedLen for StepBy<Range<$t>> {}
489+
490+
impl SpecRangeSetup<RangeIter<$t>> for RangeIter<$t> {
491+
#[inline]
492+
fn setup(mut r: RangeIter<$t>, step: usize) -> RangeIter<$t> {
493+
r.inner = <Range<$t> as SpecRangeSetup::<Range<$t>>>::setup(r.inner.clone(), step);
494+
r
495+
}
496+
}
497+
498+
unsafe impl StepByImpl<RangeIter<$t>> for StepBy<RangeIter<$t>> {
499+
#[inline]
500+
fn spec_next(&mut self) -> Option<$t> {
501+
// if a step size larger than the type has been specified fall back to
502+
// t::MAX, in which case remaining will be at most 1.
503+
// The `+ 1` can't overflow since the constructor substracted 1 from the original value.
504+
let step = <$t>::try_from(self.step + 1).unwrap_or(<$t>::MAX);
505+
let remaining = self.iter.inner.end;
506+
if remaining > 0 {
507+
let val = self.iter.inner.start;
508+
// this can only overflow during the last step, after which the value
509+
// will not be used
510+
self.iter.inner.start = val.wrapping_add(step);
511+
self.iter.inner.end = remaining - 1;
512+
Some(val)
513+
} else {
514+
None
515+
}
516+
}
517+
518+
#[inline]
519+
fn spec_size_hint(&self) -> (usize, Option<usize>) {
520+
let remaining = self.iter.inner.end as usize;
521+
(remaining, Some(remaining))
522+
}
523+
524+
// The methods below are all copied from the Iterator trait default impls.
525+
// We have to repeat them here so that the specialization overrides the StepByImpl defaults
526+
527+
#[inline]
528+
fn spec_nth(&mut self, n: usize) -> Option<Self::Item> {
529+
self.advance_by(n).ok()?;
530+
self.next()
531+
}
532+
533+
#[inline]
534+
fn spec_try_fold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R
535+
where
536+
F: FnMut(Acc, Self::Item) -> R,
537+
R: Try<Output = Acc>
538+
{
539+
let mut accum = init;
540+
while let Some(x) = self.next() {
541+
accum = f(accum, x)?;
542+
}
543+
try { accum }
544+
}
545+
546+
#[inline]
547+
fn spec_fold<Acc, F>(self, init: Acc, mut f: F) -> Acc
548+
where
549+
F: FnMut(Acc, Self::Item) -> Acc
550+
{
551+
// if a step size larger than the type has been specified fall back to
552+
// t::MAX, in which case remaining will be at most 1.
553+
let step = <$t>::try_from(self.step + 1).unwrap_or(<$t>::MAX);
554+
let remaining = self.iter.inner.end;
555+
let mut acc = init;
556+
let mut val = self.iter.inner.start;
557+
for _ in 0..remaining {
558+
acc = f(acc, val);
559+
// this can only overflow during the last step, after which the value
560+
// will no longer be used
561+
val = val.wrapping_add(step);
562+
}
563+
acc
564+
}
565+
}
566+
567+
/// Safety: This macro is only applied to ranges over types <= usize
568+
/// which means the inner length is guaranteed to fit into a usize and so
569+
/// the outer length calculation won't encounter clamped values
570+
#[unstable(feature = "trusted_len", issue = "37572")]
571+
unsafe impl TrustedLen for StepBy<RangeIter<$t>> {}
489572
)*)
490573
}
491574

@@ -550,6 +633,64 @@ macro_rules! spec_int_ranges_r {
550633
accum
551634
}
552635
}
636+
637+
unsafe impl StepByBackImpl<RangeIter<$t>> for StepBy<RangeIter<$t>> {
638+
639+
#[inline]
640+
fn spec_next_back(&mut self) -> Option<Self::Item>
641+
where RangeIter<$t>: DoubleEndedIterator + ExactSizeIterator,
642+
{
643+
let step = (self.step + 1) as $t;
644+
let remaining = self.iter.inner.end;
645+
if remaining > 0 {
646+
let start = self.iter.inner.start;
647+
self.iter.inner.end = remaining - 1;
648+
Some(start + step * (remaining - 1))
649+
} else {
650+
None
651+
}
652+
}
653+
654+
// The methods below are all copied from the Iterator trait default impls.
655+
// We have to repeat them here so that the specialization overrides the StepByImplBack defaults
656+
657+
#[inline]
658+
fn spec_nth_back(&mut self, n: usize) -> Option<Self::Item>
659+
where Self: DoubleEndedIterator,
660+
{
661+
if self.advance_back_by(n).is_err() {
662+
return None;
663+
}
664+
self.next_back()
665+
}
666+
667+
#[inline]
668+
fn spec_try_rfold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R
669+
where
670+
Self: DoubleEndedIterator,
671+
F: FnMut(Acc, Self::Item) -> R,
672+
R: Try<Output = Acc>
673+
{
674+
let mut accum = init;
675+
while let Some(x) = self.next_back() {
676+
accum = f(accum, x)?;
677+
}
678+
try { accum }
679+
}
680+
681+
#[inline]
682+
fn spec_rfold<Acc, F>(mut self, init: Acc, mut f: F) -> Acc
683+
where
684+
Self: DoubleEndedIterator,
685+
F: FnMut(Acc, Self::Item) -> Acc
686+
{
687+
let mut accum = init;
688+
while let Some(x) = self.next_back() {
689+
accum = f(accum, x);
690+
}
691+
accum
692+
}
693+
}
553694
)*)
554695
}
555696

library/core/src/iter/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,6 @@ pub(crate) use self::adapters::try_process;
464464
pub(crate) use self::traits::UncheckedIterator;
465465

466466
mod adapters;
467-
mod range;
467+
pub(crate) mod range;
468468
mod sources;
469469
mod traits;

0 commit comments

Comments
 (0)