Skip to content

Commit fdc89ab

Browse files
authored
Merge pull request #66389 from apple/egorzhdan/5.9-borrow-cxx-convertible
🍒[cxx-interop] Initializing a Swift.Array from CxxConvertibleToCollection should not copy the collection
2 parents d836766 + 07b049f commit fdc89ab

File tree

4 files changed

+30
-2
lines changed

4 files changed

+30
-2
lines changed

stdlib/public/Cxx/CxxConvertibleToCollection.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ extension RangeReplaceableCollection {
5555
/// container when each element is copied in O(1). Note that this might not
5656
/// be true for certain C++ types, e.g. those with a custom copy
5757
/// constructor that performs additional logic.
58-
public init<C: CxxConvertibleToCollection>(_ elements: C)
58+
@inlinable
59+
public init<C: CxxConvertibleToCollection>(_ elements: __shared C)
5960
where C.RawIterator.Pointee == Element {
6061

6162
self.init()
@@ -72,7 +73,8 @@ extension SetAlgebra {
7273
/// container when each element is copied in O(1). Note that this might not
7374
/// be true for certain C++ types, e.g. those with a custom copy
7475
/// constructor that performs additional logic.
75-
public init<C: CxxConvertibleToCollection>(_ elements: C)
76+
@inlinable
77+
public init<C: CxxConvertibleToCollection>(_ elements: __shared C)
7678
where C.RawIterator.Pointee == Element {
7779

7880
self.init()

stdlib/public/Cxx/CxxSet.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public protocol CxxSet<Element> {
1818
}
1919

2020
extension CxxSet {
21+
@inlinable
2122
public func contains(_ element: Element) -> Bool {
2223
return count(element) > 0
2324
}

test/Interop/Cxx/stdlib/overlay/Inputs/custom-sequence.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ struct SimpleSequenceWithOutOfLineEqualEqual {
1414
ConstIteratorOutOfLineEq end() const { return ConstIteratorOutOfLineEq(5); }
1515
};
1616

17+
static int copiesCount = 0;
18+
19+
struct SimpleCopyAwareSequence {
20+
ConstIterator begin() const { return ConstIterator(1); }
21+
ConstIterator end() const { return ConstIterator(5); }
22+
23+
SimpleCopyAwareSequence() {}
24+
SimpleCopyAwareSequence(const SimpleCopyAwareSequence &other) { copiesCount++; }
25+
};
26+
1727
struct SimpleArrayWrapper {
1828
private:
1929
int a[5] = {10, 20, 30, 40, 50};

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,21 @@ CxxSequenceTestSuite.test("SimpleSequence to Swift.Array") {
1515
expectEqual([1, 2, 3, 4] as [Int32], array)
1616
}
1717

18+
#if !os(Linux) // this test crashes on Linux (https://github.com/apple/swift/issues/66363)
19+
CxxSequenceTestSuite.test("SimpleCopyAwareSequence to Swift.Array") {
20+
copiesCount = 0
21+
22+
let seq = SimpleCopyAwareSequence()
23+
24+
let seqCopy = seq
25+
expectEqual(1, copiesCount) // make sure our copy tracking mechanism works
26+
27+
let array = Array(seq)
28+
29+
expectEqual(1, copiesCount) // make sure we don't copy the C++ sequence value unnecessarily
30+
}
31+
#endif
32+
1833
CxxSequenceTestSuite.test("SimpleSequenceWithOutOfLineEqualEqual to Swift.Array") {
1934
let seq = SimpleSequenceWithOutOfLineEqualEqual()
2035
let array = Array(seq)

0 commit comments

Comments
 (0)