Skip to content

Commit ebeee4d

Browse files
authored
Merge pull request #80163 from swiftlang/gaborh/vector-span-property
[cxx-interop] Add span property to std::vector
2 parents 586c113 + 3d6c714 commit ebeee4d

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

lib/ClangImporter/ClangDerivedConformances.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1079,7 +1079,9 @@ void swift::conformToCxxVectorIfNeeded(ClangImporter::Implementation &impl,
10791079
decl, ctx.getIdentifier("value_type"));
10801080
auto iterType = lookupDirectSingleWithoutExtensions<TypeAliasDecl>(
10811081
decl, ctx.getIdentifier("const_iterator"));
1082-
if (!valueType || !iterType)
1082+
auto sizeType = lookupDirectSingleWithoutExtensions<TypeAliasDecl>(
1083+
decl, ctx.getIdentifier("size_type"));
1084+
if (!valueType || !iterType || !sizeType)
10831085
return;
10841086

10851087
ProtocolDecl *cxxRandomAccessIteratorProto =
@@ -1097,6 +1099,8 @@ void swift::conformToCxxVectorIfNeeded(ClangImporter::Implementation &impl,
10971099
valueType->getUnderlyingType());
10981100
impl.addSynthesizedTypealias(decl, ctx.Id_ArrayLiteralElement,
10991101
valueType->getUnderlyingType());
1102+
impl.addSynthesizedTypealias(decl, ctx.getIdentifier("Size"),
1103+
sizeType->getUnderlyingType());
11001104
impl.addSynthesizedTypealias(decl, ctx.getIdentifier("RawIterator"),
11011105
rawIteratorTy);
11021106
impl.addSynthesizedProtocolAttrs(decl, {KnownProtocolKind::CxxVector});

stdlib/public/Cxx/CxxVector.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@ public protocol CxxVector<Element>: ExpressibleByArrayLiteral {
1717
associatedtype Element
1818
associatedtype RawIterator: UnsafeCxxRandomAccessIterator
1919
where RawIterator.Pointee == Element
20+
associatedtype Size: BinaryInteger
2021

2122
init()
2223

2324
mutating func push_back(_ element: Element)
25+
26+
func size() -> Size
27+
func __dataUnsafe() -> UnsafePointer<Element>?
2428
}
2529

2630
extension CxxVector {
@@ -45,3 +49,16 @@ extension CxxVector {
4549
self.init(elements)
4650
}
4751
}
52+
53+
@available(SwiftStdlib 6.2, *)
54+
extension CxxVector {
55+
public var span: Span<Element> {
56+
@lifetime(borrow self)
57+
@_alwaysEmitIntoClient
58+
borrowing get {
59+
let buffer = unsafe UnsafeBufferPointer(start: self.__dataUnsafe(), count: Int(self.size()))
60+
let span = unsafe Span(_unsafeElements: buffer)
61+
return unsafe _cxxOverrideLifetime(span, borrowing: self)
62+
}
63+
}
64+
}

test/Interop/Cxx/stdlib/use-std-vector.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,19 @@ StdVectorTestSuite.test("VectorOfString subclass for loop") {
190190
expectEqual(count, 1)
191191
}
192192

193+
StdVectorTestSuite.test("VectorOfInt to span").require(.stdlib_6_2).code {
194+
guard #available(SwiftStdlib 6.2, *) else { return }
195+
196+
let v = Vector([1, 2, 3])
197+
// FIXME: remove 'withExtendedLifetime' once lifetime analysis is fixed.
198+
withExtendedLifetime(v) {
199+
let s = $0.span
200+
expectEqual(s.count, 3)
201+
expectFalse(s.isEmpty)
202+
expectEqual(s[0], 1)
203+
expectEqual(s[1], 2)
204+
expectEqual(s[2], 3)
205+
}
206+
}
207+
193208
runAllTests()

0 commit comments

Comments
 (0)