Skip to content

Commit e06f80a

Browse files
committed
FlattenSequence/distance(from:to:) untrapping Int.min (v3).
1. I added a file with some tests [test/stdlib/FlattenDistanceFromTo.swift]. 2. I used [test/stdlib/StaticBigInt.swift] as the template for the new file.
1 parent e8db705 commit e06f80a

File tree

1 file changed

+144
-0
lines changed

1 file changed

+144
-0
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// RUN: %target-run-simple-swift(-parse-as-library)
14+
// REQUIRES: executable_test
15+
// REQUIRES: reflection
16+
// UNSUPPORTED: use_os_stdlib
17+
// END.
18+
//
19+
//===----------------------------------------------------------------------===//
20+
21+
import StdlibUnittest
22+
23+
@main
24+
final class FlattenDistanceFromToTests {
25+
26+
static func main() {
27+
let tests = FlattenDistanceFromToTests()
28+
let suite = TestSuite("FlattenDistanceFromToTests")
29+
suite.test("EachIndexPair", tests.testEachIndexPair)
30+
runAllTests()
31+
}
32+
}
33+
34+
//===----------------------------------------------------------------------===//
35+
// MARK: - Each Index Pair
36+
//===----------------------------------------------------------------------===//
37+
38+
extension FlattenDistanceFromToTests {
39+
40+
/// Performs one `action` per lane size case through `limits`.
41+
///
42+
/// limits: [0,1,2,3]
43+
/// ─────────────────
44+
/// [][ ][ ][ ]
45+
/// [][1][ ][ ]
46+
/// [][ ][2 ][ ]
47+
/// [][1][ ][ ]
48+
/// [][ ][2,2][ ]
49+
/// [][1][2,2][ ]
50+
/// [][ ][ ][3 ]
51+
/// ─────────────────
52+
/// [][1][2,2][3,3,3]
53+
///
54+
func forEachLaneSizeCase(
55+
through limits: [Int],
56+
perform action: ([[Int]]) -> Void
57+
) {
58+
var array = Array(repeating: [Int](), count: limits.count)
59+
var index = array.startIndex
60+
while index < limits.endIndex {
61+
action(array)
62+
63+
if array[index].count < limits[index] {
64+
array[index].append(index)
65+
continue
66+
}
67+
68+
while index < limits.endIndex, array[index].count == limits[index] {
69+
array.formIndex(after: &index)
70+
}
71+
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+
}
79+
}
80+
}
81+
}
82+
83+
/// Performs one `action` per offset-index pair in `collection`.
84+
///
85+
/// collection: [[0],[1,2]].joined()
86+
/// ────────────────────────────────
87+
/// offset: 0, index: 0,0
88+
/// offset: 1, index: 1,0
89+
/// offset: 2, index: 1,1
90+
/// offset: 3, index: 2
91+
///
92+
func forEachEnumeratedIndexIncludingEndIndex<T: Collection>(
93+
in collection: T,
94+
perform action: ((offset: Int, index: T.Index)) -> Void
95+
) {
96+
var state = (offset: 0, index: collection.startIndex)
97+
while true {
98+
action(state)
99+
100+
if state.index == collection.endIndex {
101+
return
102+
}
103+
104+
state.offset += 1
105+
collection.formIndex(after: &state.index)
106+
}
107+
}
108+
109+
/// Checks the distance between each index pair in various cases.
110+
///
111+
/// You need three lanes to exercise the first, the middle, the last region.
112+
/// The past-the-end index is a separate lane, so the middle region contains
113+
/// one additional lane when the past-the-end index is selected.
114+
///
115+
func testEachIndexPair() {
116+
var invocations = 0 as Int
117+
118+
for lanes in 0 ... 3 {
119+
let limits = Array(repeating: 3, count: lanes)
120+
121+
forEachLaneSizeCase(through: limits) { base in
122+
let collection: FlattenSequence = base.joined()
123+
124+
forEachEnumeratedIndexIncludingEndIndex(in: collection) { start in
125+
forEachEnumeratedIndexIncludingEndIndex(in: collection) { end in
126+
let pair = (from: start.offset, to: end.offset)
127+
128+
invocations += 1
129+
130+
expectEqual(
131+
collection.distance(from: start.index, to: end.index),
132+
end.offset - start.offset,
133+
"""
134+
index distance != offset distance for \(pair) in \(base).joined()
135+
"""
136+
)
137+
}
138+
}
139+
}
140+
}
141+
142+
expectEqual(invocations, 2502, "unexpected workload")
143+
}
144+
}

0 commit comments

Comments
 (0)