@@ -44,6 +44,12 @@ public protocol ${Self} : ${Conformance} {
44
44
/// - Complexity: O(1).
45
45
func advanced(by n: Stride) -> Self
46
46
47
+ /// `_step` is an implementation detail of Strideable; do not use it directly.
48
+ static func _step(
49
+ after current: (index: Int?, value: Self),
50
+ from start: Self, by distance: Self.Stride
51
+ ) -> (index: Int?, value: Self)
52
+
47
53
associatedtype _DisabledRangeIndex = _DisabledRangeIndex_
48
54
}
49
55
@@ -125,22 +131,54 @@ public func -= <T : UnsignedInteger>(
125
131
126
132
//===----------------------------------------------------------------------===//
127
133
128
- /// An iterator for the result of `stride(from:to:)`.
134
+ extension Strideable {
135
+ public static func _step(
136
+ after current: (index: Int?, value: Self),
137
+ from start: Self, by distance: Self.Stride
138
+ ) -> (index: Int?, value: Self) {
139
+ return (nil, current.value + distance)
140
+ }
141
+ }
142
+
143
+ extension Strideable where Stride : FloatingPoint {
144
+ public static func _step(
145
+ after current: (index: Int?, value: Self),
146
+ from start: Self, by distance: Self.Stride
147
+ ) -> (index: Int?, value: Self) {
148
+ if let i = current.index {
149
+ return (i + 1, start + Stride(i + 1) * distance)
150
+ }
151
+ // If current.index == nil, either we're just starting out (in which case
152
+ // the next index is 1), or we should proceed without an index just as
153
+ // though this floating point specialization doesn't exist.
154
+ return (current.value == start ? 1 : nil, current.value + distance)
155
+ }
156
+ }
157
+
158
+ /// An iterator for `StrideTo<Element>`.
129
159
public struct StrideToIterator<Element : Strideable> : IteratorProtocol {
130
- internal var _current : Element
160
+ internal let _start : Element
131
161
internal let _end: Element
132
162
internal let _stride: Element.Stride
163
+ internal var _current: (index: Int?, value: Element)
164
+
165
+ internal init(_start: Element, end: Element, stride: Element.Stride) {
166
+ self._start = _start
167
+ _end = end
168
+ _stride = stride
169
+ _current = (nil, _start)
170
+ }
133
171
134
172
/// Advances to the next element and returns it, or `nil` if no next element
135
173
/// exists.
136
174
///
137
175
/// Once `nil` has been returned, all subsequent calls return `nil`.
138
176
public mutating func next() -> Element? {
139
- if _stride > 0 ? _current >= _end : _current <= _end {
177
+ let result = _current.value
178
+ if _stride > 0 ? result >= _end : result <= _end {
140
179
return nil
141
180
}
142
- let result = _current
143
- _current += _stride
181
+ _current = Element._step(after: _current, from: _start, by: _stride)
144
182
return result
145
183
}
146
184
}
@@ -153,12 +191,12 @@ public struct StrideTo<Element : Strideable> : Sequence, CustomReflectable {
153
191
///
154
192
/// - Complexity: O(1).
155
193
public func makeIterator() -> StrideToIterator<Element> {
156
- return StrideToIterator(_current : _start, _end : _end, _stride : _stride)
194
+ return StrideToIterator(_start : _start, end : _end, stride : _stride)
157
195
}
158
196
159
197
internal init(_start: Element, end: Element, stride: Element.Stride) {
160
198
_precondition(stride != 0, "stride size must not be zero")
161
- // Unreachable endpoints are allowed; they just make for an
199
+ // At start, striding away from end is allowed; it just makes for an
162
200
// already-empty Sequence.
163
201
self._start = _start
164
202
self._end = end
@@ -175,21 +213,29 @@ public struct StrideTo<Element : Strideable> : Sequence, CustomReflectable {
175
213
}
176
214
177
215
/// Returns the sequence of values (`self`, `self + stride`, `self +
178
- /// stride + stride`, ... *last*) where *last* is the last value in
179
- /// the progression that is less than `end`.
216
+ /// 2 * stride`, ... *last*) where *last* is the last value in the
217
+ /// progression that is less than `end`.
180
218
public func stride<T : Strideable>(
181
219
from start: T, to end: T, by stride: T.Stride
182
220
) -> StrideTo<T> {
183
221
return StrideTo(_start: start, end: end, stride: stride)
184
222
}
185
223
186
- /// An `IteratorProtocol` for `StrideThrough<Element>`.
224
+ /// An iterator for `StrideThrough<Element>`.
187
225
public struct StrideThroughIterator<Element : Strideable> : IteratorProtocol {
188
- internal var _current : Element
226
+ internal let _start : Element
189
227
internal let _end: Element
190
228
internal let _stride: Element.Stride
229
+ internal var _current: (index: Int?, value: Element)
191
230
internal var _done: Bool = false
192
231
232
+ internal init(_start: Element, end: Element, stride: Element.Stride) {
233
+ self._start = _start
234
+ _end = end
235
+ _stride = stride
236
+ _current = (nil, _start)
237
+ }
238
+
193
239
/// Advances to the next element and returns it, or `nil` if no next element
194
240
/// exists.
195
241
///
@@ -198,15 +244,15 @@ public struct StrideThroughIterator<Element : Strideable> : IteratorProtocol {
198
244
if _done {
199
245
return nil
200
246
}
201
- if _stride > 0 ? _current >= _end : _current <= _end {
202
- if _current == _end {
247
+ let result = _current.value
248
+ if _stride > 0 ? result >= _end : result <= _end {
249
+ if result == _end {
203
250
_done = true
204
- return _current
251
+ return result
205
252
}
206
253
return nil
207
254
}
208
- let result = _current
209
- _current += _stride
255
+ _current = Element._step(after: _current, from: _start, by: _stride)
210
256
return result
211
257
}
212
258
}
@@ -221,8 +267,7 @@ public struct StrideThrough<
221
267
///
222
268
/// - Complexity: O(1).
223
269
public func makeIterator() -> StrideThroughIterator<Element> {
224
- return StrideThroughIterator(
225
- _current: _start, _end: _end, _stride: _stride, _done: false)
270
+ return StrideThroughIterator(_start: _start, end: _end, stride: _stride)
226
271
}
227
272
228
273
internal init(_start: Element, end: Element, stride: Element.Stride) {
@@ -243,8 +288,8 @@ public struct StrideThrough<
243
288
}
244
289
245
290
/// Returns the sequence of values (`self`, `self + stride`, `self +
246
- /// stride + stride`, ... *last*) where *last* is the last value in
247
- /// the progression less than or equal to `end`.
291
+ /// 2 * stride`, ... *last*) where *last* is the last value in the
292
+ /// progression less than or equal to `end`.
248
293
///
249
294
/// - Note: There is no guarantee that `end` is an element of the sequence.
250
295
public func stride<T : Strideable>(
0 commit comments