Skip to content

Commit 6a38df6

Browse files
committed
Revert "Revert "[cxx-interop] Add conversions between std::u16string and Swift.String""
This re-lands #61695 since the linker error on CentOS has been fixed. This reverts commit e97b1c8
1 parent e405b50 commit 6a38df6

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

stdlib/public/Cxx/std/String.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
// MARK: Initializing C++ string from a Swift String
14+
1315
extension std.string {
1416
/// Creates a C++ string having the same content as the given Swift string.
1517
///
@@ -23,12 +25,31 @@ extension std.string {
2325
}
2426
}
2527

28+
extension std.u16string {
29+
public init(_ string: String) {
30+
self.init()
31+
for char in string.utf16 {
32+
self.push_back(char)
33+
}
34+
}
35+
}
36+
37+
// MARK: Initializing C++ string from a Swift String literal
38+
2639
extension std.string: ExpressibleByStringLiteral {
2740
public init(stringLiteral value: String) {
2841
self.init(value)
2942
}
3043
}
3144

45+
extension std.u16string: ExpressibleByStringLiteral {
46+
public init(stringLiteral value: String) {
47+
self.init(value)
48+
}
49+
}
50+
51+
// MARK: Initializing Swift String from a C++ string
52+
3253
extension String {
3354
/// Creates a String having the same content as the given C++ string.
3455
///
@@ -46,4 +67,13 @@ extension String {
4667
}
4768
withExtendedLifetime(cxxString) {}
4869
}
70+
71+
// TODO: add doc comment
72+
public init(_ cxxU16String: std.u16string) {
73+
let buffer = UnsafeBufferPointer<UInt16>(
74+
start: cxxU16String.__dataUnsafe(),
75+
count: cxxU16String.size())
76+
self = String(decoding: buffer, as: UTF16.self)
77+
withExtendedLifetime(cxxU16String) {}
78+
}
4979
}

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,36 @@ StdStringOverlayTestSuite.test("std::string <=> Swift.String") {
3737
expectEqual(swift6, "xyz\0abc")
3838
}
3939

40+
StdStringOverlayTestSuite.test("std::u16string <=> Swift.String") {
41+
let cxx1 = std.u16string()
42+
let swift1 = String(cxx1)
43+
expectEqual(swift1, "")
44+
45+
let cxx2 = std.u16string("something123")
46+
expectEqual(cxx2.size(), 12)
47+
let swift2 = String(cxx2)
48+
expectEqual(swift2, "something123")
49+
50+
let cxx3: std.u16string = "literal"
51+
expectEqual(cxx3.size(), 7)
52+
53+
let cxx4: std.u16string = "тест"
54+
expectEqual(cxx4.size(), 4)
55+
let swift4 = String(cxx4)
56+
expectEqual(swift4, "тест")
57+
58+
// Emojis are represented by more than one CWideChar.
59+
let cxx5: std.u16string = "emoji_🤖"
60+
expectEqual(cxx5.size(), 8)
61+
let swift5 = String(cxx5)
62+
expectEqual(swift5, "emoji_🤖")
63+
64+
let cxx6 = std.u16string("xyz\0abc")
65+
expectEqual(cxx6.size(), 7)
66+
let swift6 = String(cxx6)
67+
expectEqual(swift6, "xyz\0abc")
68+
}
69+
4070
StdStringOverlayTestSuite.test("std::string as Swift.Sequence") {
4171
let cxx1 = std.string()
4272
var iterated = false

0 commit comments

Comments
 (0)