Skip to content

Commit 1115909

Browse files
authored
Merge 711378d into f0082a8
2 parents f0082a8 + 711378d commit 1115909

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

stdlib/public/Cxx/std/String.swift

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -229,13 +229,9 @@ extension String {
229229
///
230230
/// - Complexity: O(*n*), where *n* is the number of bytes in the C++ string.
231231
public init(_ cxxString: std.string) {
232-
let buffer = UnsafeBufferPointer<CChar>(
233-
start: cxxString.__c_strUnsafe(),
234-
count: cxxString.size())
235-
self = buffer.withMemoryRebound(to: UInt8.self) {
232+
self = cxxString.withUTF8 {
236233
String(decoding: $0, as: UTF8.self)
237234
}
238-
withExtendedLifetime(cxxString) {}
239235
}
240236

241237
/// Creates a String having the same content as the given C++ UTF-16 string.
@@ -272,3 +268,17 @@ extension String {
272268
withExtendedLifetime(cxxU32String) {}
273269
}
274270
}
271+
272+
// MARK: Converting a C++ string to a C string
273+
274+
extension std.string {
275+
@inlinable
276+
public borrowing func withUTF8<Result>(
277+
_ body: (UnsafeBufferPointer<UInt8>) throws -> Result
278+
) rethrows -> Result {
279+
let buffer = UnsafeBufferPointer<CChar>(
280+
start: self.__c_strUnsafe(),
281+
count: self.size())
282+
return try buffer.withMemoryRebound(to: UInt8.self, body)
283+
}
284+
}

test/Interop/Cxx/stdlib/overlay/std-string-overlay.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,4 +377,28 @@ StdStringOverlayTestSuite.test("std::string from C string") {
377377
expectEqual(str, std.string("abc"))
378378
}
379379

380+
StdStringOverlayTestSuite.test("std::string to UTF-8") {
381+
std.string().withUTF8 { ptr in
382+
expectEqual(ptr.count, 0)
383+
}
384+
std.string("abc").withUTF8 { ptr in
385+
expectEqual(ptr.count, 3)
386+
expectEqual(ptr.baseAddress?.pointee, 97)
387+
expectEqual(ptr.baseAddress?.successor().pointee, 98)
388+
expectEqual(ptr.baseAddress?.successor().successor().pointee, 99)
389+
}
390+
391+
let bytes: [UInt8] = [0xE1, 0xC1, 0xAC]
392+
var str = std.string()
393+
for byte in bytes {
394+
str.push_back(CChar(bitPattern: byte))
395+
}
396+
str.withUTF8 { ptr in
397+
expectEqual(ptr.count, 3)
398+
expectEqual(ptr.baseAddress?.pointee, 0xE1)
399+
expectEqual(ptr.baseAddress?.successor().pointee, 0xC1)
400+
expectEqual(ptr.baseAddress?.successor().successor().pointee, 0xAC)
401+
}
402+
}
403+
380404
runAllTests()

0 commit comments

Comments
 (0)