Skip to content

Commit 7703ae4

Browse files
committed
FlattenSequence/distance(from:to:) untrapping Int.min (v5).
1. FlattenSequence/distance(from:to:) cleanup. 2. FlattenDistanceFromToTests cleanup. 3. FlattenDistanceFromToTests availability checks.
1 parent d5e8bdf commit 7703ae4

File tree

2 files changed

+32
-26
lines changed

2 files changed

+32
-26
lines changed

stdlib/public/core/Flatten.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -289,12 +289,12 @@ extension FlattenCollection: Collection {
289289

290290
@inlinable // lazy-performance
291291
public func distance(from start: Index, to end: Index) -> Int {
292-
let minus = start > end
292+
let distanceIsNegative = start > end
293293

294294
// The following check ensures that distance(from:to:) is invoked on
295295
// the _base at least once, to trigger a _precondition in forward only
296296
// collections.
297-
if minus {
297+
if distanceIsNegative {
298298
_ = _base.distance(from: _base.endIndex, to: _base.startIndex)
299299
}
300300

@@ -310,20 +310,20 @@ extension FlattenCollection: Collection {
310310
let lowerBound: Index
311311
let upperBound: Index
312312

313-
if minus {
313+
if distanceIsNegative {
314+
step = -1
314315
lowerBound = end
315316
upperBound = start
316-
step = -1
317317
} else {
318+
step = 01
318319
lowerBound = start
319320
upperBound = end
320-
step = 01
321321
}
322-
322+
323323
// This always unwraps because start._outer != end._outer.
324324
if let inner = lowerBound._inner {
325325
let collection = _base[lowerBound._outer]
326-
distance += minus
326+
distance += distanceIsNegative
327327
? collection.distance(from: collection.endIndex, to: inner)
328328
: collection.distance(from: inner, to: collection.endIndex)
329329
}
@@ -341,7 +341,7 @@ extension FlattenCollection: Collection {
341341
/// This unwraps if start != endIndex and end != endIndex.
342342
if let inner = upperBound._inner {
343343
let collection = _base[upperBound._outer]
344-
distance += minus
344+
distance += distanceIsNegative
345345
? collection.distance(from: inner, to: collection.startIndex)
346346
: collection.distance(from: collection.startIndex, to: inner)
347347
}

test/stdlib/FlattenDistanceFromTo.swift

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ final class FlattenDistanceFromToTests {
2525
let tests = FlattenDistanceFromToTests()
2626
let suite = TestSuite("FlattenDistanceFromToTests")
2727
suite.test("EachIndexPair", tests.testEachIndexPair)
28-
suite.test("MinMaxOutputs", tests.testMinMaxOutputs)
28+
if #available(SwiftStdlib 6.0, *) {
29+
// The random access time complexity was fixed in Swift 6.0.
30+
suite.test("MinMaxRandomAccess", tests.testMinMaxRandomAccess)
31+
}
2932
runAllTests()
3033
}
3134
}
@@ -50,7 +53,7 @@ extension FlattenDistanceFromToTests {
5053
/// ─────────────────
5154
/// [][1][2,2][3,3,3]
5255
///
53-
func forEachLaneSizeCase(
56+
private func forEachLaneSizeCase(
5457
through limits: [Int],
5558
perform action: ([[Int]]) -> Void
5659
) {
@@ -61,19 +64,18 @@ extension FlattenDistanceFromToTests {
6164

6265
if array[index].count < limits[index] {
6366
array[index].append(index)
64-
continue
65-
}
66-
67-
while index < limits.endIndex, array[index].count == limits[index] {
68-
array.formIndex(after: &index)
69-
}
70-
71-
if index < limits.endIndex {
72-
array[index].append(index)
67+
} else {
68+
while index < limits.endIndex, array[index].count == limits[index] {
69+
array.formIndex(after: &index)
70+
}
7371

74-
while index > array.startIndex {
75-
array.formIndex(before: &index)
76-
array[index].removeAll(keepingCapacity: true)
72+
if index < limits.endIndex {
73+
array[index].append(index)
74+
75+
while index > array.startIndex {
76+
array.formIndex(before: &index)
77+
array[index].removeAll(keepingCapacity: true)
78+
}
7779
}
7880
}
7981
}
@@ -88,10 +90,10 @@ extension FlattenDistanceFromToTests {
8890
/// offset: 2, index: 1,1
8991
/// offset: 3, index: 2
9092
///
91-
func forEachEnumeratedIndexIncludingEndIndex<T: Collection>(
93+
private func forEachEnumeratedIndexIncludingEndIndex<T>(
9294
in collection: T,
9395
perform action: ((offset: Int, index: T.Index)) -> Void
94-
) {
96+
) where T: Collection {
9597
var state = (offset: 0, index: collection.startIndex)
9698
while true {
9799
action(state)
@@ -148,11 +150,15 @@ extension FlattenDistanceFromToTests {
148150

149151
extension FlattenDistanceFromToTests {
150152

151-
/// Checks some `Int.min` and `Int.max` distances.
153+
/// Checks some `Int.min` and `Int.max` distances with random access.
154+
///
155+
/// It needs Swift 6.0+ because prior versions find the distance by
156+
/// iterating from one index to the other, which takes way too long.
152157
///
153158
/// - Note: A distance of `Int.min` requires more than `Int.max` elements.
154159
///
155-
func testMinMaxOutputs() {
160+
@available(SwiftStdlib 6.0, *)
161+
func testMinMaxRandomAccess() {
156162
for s: FlattenSequence in [
157163

158164
[-1..<Int.max/1],

0 commit comments

Comments
 (0)