@@ -289,31 +289,41 @@ extension FlattenCollection: Collection {
289
289
290
290
@inlinable // lazy-performance
291
291
public func distance( from start: Index , to end: Index ) -> Int {
292
- // The following check makes sure that distance(from:to:) is invoked on the
293
- // _base at least once, to trigger a _precondition in forward only
292
+ // The following check ensures that distance(from:to:) is invoked on
293
+ // the _base at least once, to trigger a _precondition in forward only
294
294
// collections.
295
- if end < start {
295
+ if start > end {
296
296
_ = _base. distance ( from: _base. endIndex, to: _base. startIndex)
297
297
}
298
- var _start : Index
299
- let _end : Index
300
- let step : Int
301
- if start > end {
302
- _start = end
303
- _end = start
304
- step = - 1
298
+
299
+ // This handles indices belonging to the same collection.
300
+ if start. _outer == end. _outer {
301
+ guard let i = start. _inner, let j = end. _inner else { return 0 }
302
+ return _base [ start. _outer] . distance ( from: i, to: j)
305
303
}
306
- else {
307
- _start = start
308
- _end = end
309
- step = 1
304
+
305
+ // The following combines the distance of three sections.
306
+ let range = start <= end ? start ..< end : end ..< start
307
+ var outer = range. lowerBound. _outer
308
+ var count = 0 as Int // 0...Int.max
309
+
310
+ if let inner = range. lowerBound. _inner {
311
+ let collection = _base [ outer]
312
+ count += collection. distance ( from: inner, to: collection. endIndex)
313
+ _base. formIndex ( after: & outer)
314
+ }
315
+
316
+ while outer < range. upperBound. _outer {
317
+ count += _base [ outer] . count
318
+ _base. formIndex ( after: & outer)
310
319
}
311
- var count = 0
312
- while _start != _end {
313
- count += step
314
- formIndex ( after : & _start )
320
+
321
+ if let inner = range . upperBound . _inner {
322
+ let collection = _base [ outer ]
323
+ count += collection . distance ( from : collection . startIndex , to : inner )
315
324
}
316
- return count
325
+
326
+ return start <= end ? count : - count
317
327
}
318
328
319
329
@inline ( __always)
0 commit comments