@@ -89,20 +89,31 @@ extension _StringGuts {
89
89
let right = _StringGuts (
90
90
object: _StringObject ( rawBits: rightBits. 0 ) ,
91
91
otherBits: rightBits. 1 )
92
- return _compareDeterministicUnicodeCollation ( left, to: right)
92
+ return _compareDeterministicUnicodeCollation (
93
+ left, 0 ..< left. count, to: right, 0 ..< right. count)
93
94
}
94
-
95
- /// Compares two slices of strings with the Unicode Collation Algorithm.
96
- @_inlineable
97
- public // @testable
95
+ @inline ( never)
96
+ @effects ( readonly)
97
+ public
98
98
static func _compareDeterministicUnicodeCollation(
99
- _ left: _StringGuts , to right: _StringGuts ) -> Int {
99
+ _leftUnsafeStringGutsBitPattern leftBits: ( UInt , UInt ) ,
100
+ _ leftRange: Range < Int > ,
101
+ _rightUnsafeStringGutsBitPattern rightBits: ( UInt , UInt ) ,
102
+ _ rightRange: Range < Int >
103
+ ) -> Int {
104
+ let left = _StringGuts (
105
+ object: _StringObject ( rawBits: leftBits. 0 ) ,
106
+ otherBits: leftBits. 1 )
107
+ let right = _StringGuts (
108
+ object: _StringObject ( rawBits: rightBits. 0 ) ,
109
+ otherBits: rightBits. 1 )
100
110
return _compareDeterministicUnicodeCollation (
101
- left, 0 ..< left . count , to: right, 0 ..< right . count )
111
+ left, leftRange , to: right, rightRange )
102
112
}
103
113
104
114
/// Compares two slices of strings with the Unicode Collation Algorithm.
105
115
@inline ( never) // Hide the CF/ICU dependency
116
+ @effects ( readonly)
106
117
public // @testable
107
118
static func _compareDeterministicUnicodeCollation(
108
119
_ left: _StringGuts , _ leftRange: Range < Int > ,
@@ -206,6 +217,8 @@ extension _StringGuts {
206
217
_ left: _StringGuts , _ leftRange: Range < Int > ,
207
218
to right: _StringGuts , _ rightRange: Range < Int >
208
219
) -> Int {
220
+ defer { _fixLifetime ( left) }
221
+ defer { _fixLifetime ( right) }
209
222
#if _runtime(_ObjC)
210
223
// We only want to perform this optimization on objc runtimes. Elsewhere,
211
224
// we will make it follow the unicode collation algorithm even for ASCII.
@@ -216,25 +229,23 @@ extension _StringGuts {
216
229
let leftASCII = left. _unmanagedASCIIView [ leftRange]
217
230
let rightASCII = right. _unmanagedASCIIView [ rightRange]
218
231
let result = leftASCII. compareASCII ( to: rightASCII)
219
- _fixLifetime ( left)
220
- _fixLifetime ( right)
221
232
return result
222
233
}
223
- return _compareDeterministicUnicodeCollation (
224
- left, leftRange,
225
- to: right, rightRange)
226
- #else
227
- return _compareDeterministicUnicodeCollation (
228
- left, leftRange,
229
- to: right, rightRange)
230
234
#endif
231
- }
235
+ let leftBits = ( left. _object. rawBits, left. _otherBits)
236
+ let rightBits = ( right. _object. rawBits, right. _otherBits)
237
+ return _compareDeterministicUnicodeCollation (
238
+ _leftUnsafeStringGutsBitPattern: leftBits, leftRange,
239
+ _rightUnsafeStringGutsBitPattern: rightBits, rightRange)
240
+ }
232
241
233
242
@_inlineable
234
243
@_versioned
235
244
internal static func compare(
236
245
_ left: _StringGuts , to right: _StringGuts
237
246
) -> Int {
247
+ defer { _fixLifetime ( left) }
248
+ defer { _fixLifetime ( right) }
238
249
#if _runtime(_ObjC)
239
250
// We only want to perform this optimization on objc runtimes. Elsewhere,
240
251
// we will make it follow the unicode collation algorithm even for ASCII.
@@ -245,8 +256,6 @@ extension _StringGuts {
245
256
let leftASCII = left. _unmanagedASCIIView
246
257
let rightASCII = right. _unmanagedASCIIView
247
258
let result = leftASCII. compareASCII ( to: rightASCII)
248
- _fixLifetime ( left)
249
- _fixLifetime ( right)
250
259
return result
251
260
}
252
261
#endif
0 commit comments