@@ -95,6 +95,30 @@ extension std.u32string {
95
95
}
96
96
}
97
97
98
+ extension std . wstring {
99
+ /// Creates a C++ wide character string having the same content as the given
100
+ /// Swift string.
101
+ ///
102
+ /// Note that the definition of a wide character differs across platforms:
103
+ /// it is UTF-16 on Windows but UTF-32 on other platforms.
104
+ ///
105
+ /// - Complexity: O(*n*), where *n* is the number of wide characters in the
106
+ /// Swift string.
107
+ @_alwaysEmitIntoClient
108
+ public init ( _ string: String ) {
109
+ self . init ( )
110
+ #if os(Windows)
111
+ for char in string. utf16 {
112
+ self . push_back ( char)
113
+ }
114
+ #else
115
+ for char in string. unicodeScalars {
116
+ self . push_back ( char)
117
+ }
118
+ #endif
119
+ }
120
+ }
121
+
98
122
// MARK: Initializing C++ string from a Swift String literal
99
123
100
124
extension std . string : ExpressibleByStringLiteral ,
@@ -124,6 +148,15 @@ extension std.u32string: ExpressibleByStringLiteral,
124
148
}
125
149
}
126
150
151
+ extension std . wstring : ExpressibleByStringLiteral ,
152
+ ExpressibleByStringInterpolation {
153
+
154
+ @_alwaysEmitIntoClient
155
+ public init ( stringLiteral value: String ) {
156
+ self . init ( value)
157
+ }
158
+ }
159
+
127
160
// MARK: Concatenating and comparing C++ strings
128
161
129
162
extension std . string : Equatable , Comparable {
@@ -213,6 +246,35 @@ extension std.u32string: Equatable, Comparable {
213
246
}
214
247
}
215
248
249
+ extension std . wstring : Equatable , Comparable {
250
+ @_alwaysEmitIntoClient
251
+ public static func == ( lhs: std . wstring , rhs: std . wstring ) -> Bool {
252
+ return lhs. compare ( rhs) == 0
253
+ }
254
+
255
+ @_alwaysEmitIntoClient
256
+ public static func < ( lhs: std . wstring , rhs: std . wstring ) -> Bool {
257
+ return lhs. compare ( rhs) < 0
258
+ }
259
+
260
+ @_alwaysEmitIntoClient
261
+ public static func += ( lhs: inout std . wstring , rhs: std . wstring ) {
262
+ lhs. append ( rhs)
263
+ }
264
+
265
+ @_alwaysEmitIntoClient
266
+ public mutating func append( _ other: std . wstring ) {
267
+ unsafe __appendUnsafe( other) // ignore the returned pointer
268
+ }
269
+
270
+ @_alwaysEmitIntoClient
271
+ public static func + ( lhs: std . wstring , rhs: std . wstring ) -> std . wstring {
272
+ var copy = lhs
273
+ copy += rhs
274
+ return copy
275
+ }
276
+ }
277
+
216
278
// MARK: Hashing C++ strings
217
279
218
280
extension std . string : Hashable {
@@ -242,6 +304,15 @@ extension std.u32string: Hashable {
242
304
}
243
305
}
244
306
307
+ extension std . wstring : Hashable {
308
+ @_alwaysEmitIntoClient
309
+ public func hash( into hasher: inout Hasher ) {
310
+ // Call std::hash<std::wstring>::operator()
311
+ let cxxHash = __swift_interopComputeHashOfWString ( self )
312
+ hasher. combine ( cxxHash)
313
+ }
314
+ }
315
+
245
316
// MARK: Getting a Swift description of a C++ string
246
317
247
318
extension std . string : CustomDebugStringConvertible {
@@ -265,6 +336,13 @@ extension std.u32string: CustomDebugStringConvertible {
265
336
}
266
337
}
267
338
339
+ extension std . wstring : CustomDebugStringConvertible {
340
+ @_alwaysEmitIntoClient
341
+ public var debugDescription : String {
342
+ return " std.wstring( \( String ( self ) ) ) "
343
+ }
344
+ }
345
+
268
346
extension std . string : CustomStringConvertible {
269
347
@_alwaysEmitIntoClient
270
348
public var description : String {
@@ -286,6 +364,13 @@ extension std.u32string: CustomStringConvertible {
286
364
}
287
365
}
288
366
367
+ extension std . wstring : CustomStringConvertible {
368
+ @_alwaysEmitIntoClient
369
+ public var description : String {
370
+ return String ( self )
371
+ }
372
+ }
373
+
289
374
// MARK: Initializing Swift String from a C++ string
290
375
291
376
extension String {
@@ -342,6 +427,36 @@ extension String {
342
427
}
343
428
withExtendedLifetime ( cxxU32String) { }
344
429
}
430
+
431
+ /// Creates a String having the same content as the given C++ wide character
432
+ /// string.
433
+ ///
434
+ /// Note that the definition of a wide character differs across platforms:
435
+ /// it is UTF-16 on Windows but UTF-32 on other platforms.
436
+ ///
437
+ /// If `cxxString` contains ill-formed UTF code unit sequences, this
438
+ /// initializer replaces them with the Unicode replacement character
439
+ /// (`"\u{FFFD}"`).
440
+ ///
441
+ /// - Complexity: O(*n*), where *n* is the number of wide characters in the
442
+ /// C++ string.
443
+ @_alwaysEmitIntoClient
444
+ public init ( _ cxxWString: std . wstring ) {
445
+ #if os(Windows)
446
+ let buffer = unsafe UnsafeBufferPointer< UInt16 > (
447
+ start: cxxWString. __dataUnsafe ( ) ,
448
+ count: cxxWString. size ( ) )
449
+ self = unsafe String( decoding: buffer, as: UTF16 . self)
450
+ #else
451
+ let buffer = unsafe UnsafeBufferPointer< Unicode . Scalar > (
452
+ start: cxxWString. __dataUnsafe ( ) ,
453
+ count: cxxWString. size ( ) )
454
+ self = unsafe buffer. withMemoryRebound ( to: UInt32 . self) {
455
+ unsafe String( decoding: $0, as: UTF32 . self)
456
+ }
457
+ #endif
458
+ withExtendedLifetime ( cxxWString) { }
459
+ }
345
460
}
346
461
347
462
// MARK: Initializing Swift String from a C++ string_view
@@ -403,6 +518,24 @@ extension String {
403
518
}
404
519
unsafe withExtendedLifetime ( cxxU32StringView) { }
405
520
}
521
+
522
+ @_alwaysEmitIntoClient
523
+ public init ( _ cxxWStringView: std . wstring_view ) {
524
+ #if os(Windows)
525
+ let buffer = unsafe UnsafeBufferPointer< UInt16 > (
526
+ start: cxxWStringView. __dataUnsafe ( ) ,
527
+ count: cxxWStringView. size ( ) )
528
+ self = unsafe String( decoding: buffer, as: UTF16 . self)
529
+ #else
530
+ let buffer = unsafe UnsafeBufferPointer< Unicode . Scalar > (
531
+ start: cxxWStringView. __dataUnsafe ( ) ,
532
+ count: cxxWStringView. size ( ) )
533
+ self = unsafe buffer. withMemoryRebound ( to: UInt32 . self) {
534
+ unsafe String( decoding: $0, as: UTF32 . self)
535
+ }
536
+ #endif
537
+ withExtendedLifetime ( cxxWStringView) { }
538
+ }
406
539
}
407
540
408
541
@available ( SwiftCompatibilitySpan 5 . 0 , * )
@@ -463,3 +596,18 @@ extension std.u32string {
463
596
}
464
597
}
465
598
}
599
+
600
+ @available ( SwiftCompatibilitySpan 5 . 0 , * )
601
+ extension std . wstring {
602
+ public var span : Span < CWideChar > {
603
+ @_lifetime ( borrow self)
604
+ @_alwaysEmitIntoClient
605
+ borrowing get {
606
+ let buffer = unsafe UnsafeBufferPointer( start: self . __dataUnsafe ( ) , count: Int ( self . size ( ) ) )
607
+ let rawBuffer = UnsafeRawBufferPointer ( buffer)
608
+ let bufferWithFixedType = unsafe rawBuffer. assumingMemoryBound ( to: CWideChar . self)
609
+ let span = unsafe Span( _unsafeElements: bufferWithFixedType)
610
+ return unsafe _cxxOverrideLifetime ( span, borrowing: self )
611
+ }
612
+ }
613
+ }
0 commit comments