Skip to content

Commit ccadd1b

Browse files
authored
Merge pull request #65284 from apple/egorzhdan/5.9-cxx-sequence-foreach
🍒[cxx-interop] Make `CxxConvertibleToCollection.forEach` public
2 parents a3f70c3 + 5b96069 commit ccadd1b

File tree

4 files changed

+41
-2
lines changed

4 files changed

+41
-2
lines changed

benchmark/cxx-source/CxxSetToCollection.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ public let benchmarks = [
3636
runFunction: run_CxxSetOfU32_to_Set,
3737
tags: [.validation, .bridging, .cxxInterop],
3838
setUpFunction: makeSetOnce),
39+
BenchmarkInfo(
40+
name: "CxxSetU32.forEach",
41+
runFunction: run_CxxSetOfU32_forEach,
42+
tags: [.validation, .bridging, .cxxInterop],
43+
setUpFunction: makeSetOnce),
3944
]
4045

4146
func makeSetOnce() {
@@ -58,4 +63,13 @@ public func run_CxxSetOfU32_to_Set(_ n: Int) {
5863
}
5964
}
6065

66+
@inline(never)
67+
public func run_CxxSetOfU32_forEach(_ n: Int) {
68+
for _ in 0..<n {
69+
set.forEach {
70+
blackHole($0)
71+
}
72+
}
73+
}
74+
6175
#endif

stdlib/public/Cxx/CxxConvertibleToCollection.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,26 @@ public protocol CxxConvertibleToCollection<Element> {
2525

2626
extension CxxConvertibleToCollection {
2727
@inlinable
28-
internal func forEach(_ body: (RawIterator.Pointee) -> Void) {
28+
public func forEach(_ body: (RawIterator.Pointee) throws -> Void) rethrows {
2929
var rawIterator = __beginUnsafe()
3030
let endIterator = __endUnsafe()
3131
while rawIterator != endIterator {
32-
body(rawIterator.pointee)
32+
try body(rawIterator.pointee)
3333
rawIterator = rawIterator.successor()
3434
}
3535
}
3636
}
3737

38+
// Break the ambiguity between Sequence.forEach and CxxConvertibleToCollection.forEach.
39+
extension CxxConvertibleToCollection where Self: Sequence {
40+
@inlinable
41+
public func forEach(_ body: (Element) throws -> Void) rethrows {
42+
for element in self {
43+
try body(element)
44+
}
45+
}
46+
}
47+
3848
extension RangeReplaceableCollection {
3949
/// Creates a collection containing the elements of a C++ container.
4050
///

test/Interop/Cxx/stdlib/overlay/custom-collection.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ CxxCollectionTestSuite.test("SimpleCollectionNoSubscript as Swift.Collection") {
1818
expectEqual(c[0], 1)
1919
expectEqual(c[1], 2)
2020
expectEqual(c[4], 5)
21+
22+
var array: [Int32] = []
23+
c.forEach {
24+
array.append($0)
25+
}
26+
expectEqual([1, 2, 3, 4, 5] as [Int32], array)
2127
}
2228

2329
CxxCollectionTestSuite.test("SimpleCollectionReadOnly as Swift.Collection") {

test/Interop/Cxx/stdlib/overlay/custom-convertible-to-collection.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,13 @@ CxxSequenceTestSuite.test("SimpleEmptySequence to Swift.Set") {
3939
expectTrue(set.isEmpty)
4040
}
4141

42+
CxxSequenceTestSuite.test("SimpleSequence.forEach") {
43+
let seq = SimpleSequence()
44+
var array: [Int32] = []
45+
seq.forEach {
46+
array.append($0)
47+
}
48+
expectEqual([1, 2, 3, 4] as [Int32], array)
49+
}
50+
4251
runAllTests()

0 commit comments

Comments
 (0)