@@ -290,44 +290,42 @@ extension FlattenCollection: Collection {
290
290
@inlinable // lazy-performance
291
291
public func distance( from start: Index , to end: Index ) -> Int {
292
292
let distanceIsNegative = start > end
293
-
293
+
294
294
// The following check ensures that distance(from:to:) is invoked on
295
295
// the _base at least once, to trigger a _precondition in forward only
296
296
// collections.
297
297
if distanceIsNegative {
298
298
_ = _base. distance ( from: _base. endIndex, to: _base. startIndex)
299
299
}
300
-
300
+
301
301
// This path handles indices belonging to the same collection.
302
302
if start. _outer == end. _outer {
303
303
guard let i = start. _inner, let j = end. _inner else { return 0 }
304
304
return _base [ start. _outer] . distance ( from: i, to: j)
305
305
}
306
-
306
+
307
307
// The following path combines the distances of three regions.
308
- var distance : Int = 0
309
- let step : Int
310
308
let lowerBound : Index
311
309
let upperBound : Index
312
-
310
+
311
+ let step : Int
312
+ var distance : Int
313
+
314
+ // Note that lowerBound is a valid index because start != end.
313
315
if distanceIsNegative {
314
316
step = - 1
315
317
lowerBound = end
316
318
upperBound = start
319
+ let lowest = _base [ lowerBound. _outer]
320
+ distance = lowest. distance ( from: lowest. endIndex, to: lowerBound. _inner!)
317
321
} else {
318
322
step = 01
319
323
lowerBound = start
320
324
upperBound = end
325
+ let lowest = _base [ lowerBound. _outer]
326
+ distance = lowest. distance ( from: lowerBound. _inner!, to: lowest. endIndex)
321
327
}
322
-
323
- // This always unwraps because start._outer != end._outer.
324
- if let inner = lowerBound. _inner {
325
- let collection = _base [ lowerBound. _outer]
326
- distance += distanceIsNegative
327
- ? collection. distance ( from: collection. endIndex, to: inner)
328
- : collection. distance ( from: inner, to: collection. endIndex)
329
- }
330
-
328
+
331
329
// We can use each collection's count in the middle region since the
332
330
// fast path ensures that the other regions cover a nonzero distance,
333
331
// which means that an extra Int.min distance should trap regardless.
@@ -337,15 +335,16 @@ extension FlattenCollection: Collection {
337
335
distance += _base [ outer] . count &* step
338
336
_base. formIndex ( after: & outer)
339
337
}
340
-
341
- /// This unwraps if start != endIndex and end != endIndex.
338
+
339
+ // This unwraps if start != endIndex and end != endIndex. We can use the
340
+ // positive distance for the same reason that we can use the collection's
341
+ // count in the middle region.
342
342
if let inner = upperBound. _inner {
343
- let collection = _base [ upperBound. _outer]
344
- distance += distanceIsNegative
345
- ? collection. distance ( from: inner, to: collection. startIndex)
346
- : collection. distance ( from: collection. startIndex, to: inner)
343
+ // 0 ... Int.max can always be negated.
344
+ let highest = _base [ upperBound. _outer]
345
+ distance += highest. distance ( from: highest. startIndex, to: inner) &* step
347
346
}
348
-
347
+
349
348
return distance
350
349
}
351
350
0 commit comments