File tree Expand file tree Collapse file tree 5 files changed +36
-20
lines changed Expand file tree Collapse file tree 5 files changed +36
-20
lines changed Original file line number Diff line number Diff line change @@ -82,9 +82,7 @@ extension Character {
82
82
_internalInvariant ( _str. count == 1 )
83
83
_internalInvariant ( _str. _guts. isFastUTF8)
84
84
85
- // TODO(@eject): Switch to a helper property on StringObject/StringGuts.
86
- _internalInvariant (
87
- _str. _guts. isSmall || _str. _guts. _object. _countAndFlags. isTailAllocated)
85
+ _internalInvariant ( _str. _guts. _object. isPreferredRepresentation)
88
86
}
89
87
#endif // INTERNAL_CHECKS_ENABLED
90
88
}
@@ -178,16 +176,11 @@ extension Character :
178
176
_debugPrecondition ( s. index ( after: s. startIndex) == s. endIndex,
179
177
" Can't form a Character from a String containing more than one extended grapheme cluster " )
180
178
181
- // TODO(@eject): Switch to a helper property on StringObject/StringGuts.
182
- if _fastPath (
183
- s. _guts. isSmall || s. _guts. _object. _countAndFlags. isTailAllocated
184
- ) {
179
+ if _fastPath ( s. _guts. _object. isPreferredRepresentation) {
185
180
self . init ( unchecked: s)
186
181
return
187
182
}
188
-
189
- // TODO(@eject): Outline this
190
- self . init ( unchecked: s. _withUTF8 { String . _uncheckedFromUTF8 ( $0) } )
183
+ self . init ( unchecked: String . _copying ( s) )
191
184
}
192
185
}
193
186
Original file line number Diff line number Diff line change @@ -88,10 +88,7 @@ extension String: _HasContiguousBytes {
88
88
try body ( $0)
89
89
}
90
90
}
91
-
92
- return try ContiguousArray ( self . utf8) . withUnsafeBufferPointer {
93
- try body ( $0)
94
- }
91
+ return try String . _copying ( self ) . _guts. withFastUTF8 { try body ( $0) }
95
92
}
96
93
97
94
@inlinable @inline ( __always)
@@ -116,10 +113,7 @@ extension Substring: _HasContiguousBytes {
116
113
return try body ( $0)
117
114
}
118
115
}
119
-
120
- return try ContiguousArray ( self . utf8) . withUnsafeBufferPointer {
121
- try body ( $0)
122
- }
116
+ return try String . _copying ( self ) . _guts. withFastUTF8 { try body ( $0) }
123
117
}
124
118
125
119
@inlinable @inline ( __always)
Original file line number Diff line number Diff line change @@ -197,7 +197,25 @@ extension String {
197
197
return substring. _wholeString
198
198
}
199
199
200
- return substring. _withUTF8 { return String . _uncheckedFromUTF8 ( $0) }
200
+ return String . _copying ( substring)
201
+ }
202
+
203
+ @_alwaysEmitIntoClient
204
+ @inline ( never) // slow-path
205
+ internal static func _copying( _ str: String ) -> String {
206
+ return String . _copying ( str [ ... ] )
207
+ }
208
+ @_alwaysEmitIntoClient
209
+ @inline ( never) // slow-path
210
+ internal static func _copying( _ str: Substring ) -> String {
211
+ if _fastPath ( str. _wholeGuts. isFastUTF8) {
212
+ return str. _wholeGuts. withFastUTF8 ( range: str. _offsetRange) {
213
+ String . _uncheckedFromUTF8 ( $0)
214
+ }
215
+ }
216
+ return Array ( str. utf8) . withUnsafeBufferPointer {
217
+ String . _uncheckedFromUTF8 ( $0)
218
+ }
201
219
}
202
220
}
203
221
Original file line number Diff line number Diff line change @@ -485,8 +485,15 @@ extension _StringObject {
485
485
_internalInvariant ( isLarge)
486
486
return ( discriminatedObjectRawBits & 0x4000_0000_0000_0000 ) != 0
487
487
}
488
- }
489
488
489
+ // Whether this string is in one of our fastest representations:
490
+ // small or tail-allocated (i.e. mortal/immortal native)
491
+ @_alwaysEmitIntoClient
492
+ @inline ( __always)
493
+ internal var isPreferredRepresentation : Bool {
494
+ return _fastPath ( isSmall || _countAndFlags. isTailAllocated)
495
+ }
496
+ }
490
497
491
498
/*
492
499
Original file line number Diff line number Diff line change @@ -491,6 +491,8 @@ extension __StringStorage {
491
491
_internalInvariant ( rawSelf + Int( _StringObject. nativeBias) == rawStart)
492
492
_internalInvariant ( self . _realCapacity > self . count, " no room for nul-terminator " )
493
493
_internalInvariant ( self . terminator. pointee == 0 , " not nul terminated " )
494
+ let str = asString
495
+ _internalInvariant ( str. _guts. _object. isPreferredRepresentation)
494
496
495
497
_countAndFlags. _invariantCheck ( )
496
498
if isASCII {
@@ -803,6 +805,8 @@ extension __SharedStringStorage {
803
805
_countAndFlags. _invariantCheck ( )
804
806
_internalInvariant ( !_countAndFlags. isNativelyStored)
805
807
_internalInvariant ( !_countAndFlags. isTailAllocated)
808
+ let str = asString
809
+ _internalInvariant ( !str. _guts. _object. isPreferredRepresentation)
806
810
}
807
811
#endif // INTERNAL_CHECKS_ENABLED
808
812
}
You can’t perform that action at this time.
0 commit comments