Skip to content

Commit f70a4b9

Browse files
committed
doccomments for StepBy specializations
1 parent 1bc095c commit f70a4b9

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

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

+41
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ use crate::{
1616
#[stable(feature = "iterator_step_by", since = "1.28.0")]
1717
#[derive(Clone, Debug)]
1818
pub struct StepBy<I> {
19+
/// This field is guaranteed to be preprocessed by the specialized `SpecRangeSetup::setup`
20+
/// in the constructor.
21+
/// For most iterators that processing is a no-op, but for Range<{integer}> types it is lossy
22+
/// which means the inner iterator cannot be returned to user code.
23+
/// Additionally this type-dependent preprocessing means specialized implementations
24+
/// cannot be used interchangeably.
1925
iter: I,
2026
step: usize,
2127
first_take: bool,
@@ -133,6 +139,16 @@ impl<T> SpecRangeSetup<T> for T {
133139
}
134140
}
135141

142+
/// Specialization trait to optimize `StepBy<Range<{integer}>>` iteration.
143+
///
144+
/// # Correctness
145+
///
146+
/// Technically this is safe to implement (look ma, no unsafe!), but in reality
147+
/// a lot of unsafe code relies on ranges over integers being correct.
148+
///
149+
/// For correctness *all* public StepBy methods must be specialized
150+
/// because `setup` drastically alters the meaning of the struct fields so that mixing
151+
/// different implementations would lead to incorrect results.
136152
trait StepByImpl<I> {
137153
type Item;
138154

@@ -152,6 +168,16 @@ trait StepByImpl<I> {
152168
F: FnMut(Acc, Self::Item) -> Acc;
153169
}
154170

171+
/// Specialization trait for double-ended iteration.
172+
///
173+
/// See also: `StepByImpl`
174+
///
175+
/// # Correctness
176+
///
177+
/// The specializations must be implemented together with `StepByImpl`
178+
/// where applicable. I.e. if `StepBy` does support backwards iteration
179+
/// for a given iterator and that is specialized for forward iteration then
180+
/// it must also be specialized for backwards iteration.
155181
trait StepByBackImpl<I> {
156182
type Item;
157183

@@ -357,6 +383,21 @@ impl<I: DoubleEndedIterator + ExactSizeIterator> StepByBackImpl<I> for StepBy<I>
357383
}
358384
}
359385

386+
/// For these implementations, `SpecRangeSetup` calculates the number
387+
/// of iterations that will be needed and stores that in `iter.end`.
388+
///
389+
/// The various iterator implementations then rely on that to not need
390+
/// overflow checking, letting loops just be counted instead.
391+
///
392+
/// These only work for unsigned types, and will need to be reworked
393+
/// if you want to use it to specialize on signed types.
394+
///
395+
/// Currently these are only implemented for integers up to usize due to
396+
/// correctness issues around ExactSizeIterator impls on 16bit platforms.
397+
/// And since ExactSizeIterator is a prerequisite for backwards iteration
398+
/// and we must consistently specialize backwards and forwards iteration
399+
/// that makes the situation complicated enough that it's not covered
400+
/// for now.
360401
macro_rules! spec_int_ranges {
361402
($($t:ty)*) => ($(
362403

0 commit comments

Comments
 (0)