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 {
8282 _internalInvariant ( _str. count == 1 )
8383 _internalInvariant ( _str. _guts. isFastUTF8)
8484
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)
8886 }
8987 #endif // INTERNAL_CHECKS_ENABLED
9088}
@@ -178,16 +176,11 @@ extension Character :
178176 _debugPrecondition ( s. index ( after: s. startIndex) == s. endIndex,
179177 " Can't form a Character from a String containing more than one extended grapheme cluster " )
180178
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) {
185180 self . init ( unchecked: s)
186181 return
187182 }
188-
189- // TODO(@eject): Outline this
190- self . init ( unchecked: s. _withUTF8 { String . _uncheckedFromUTF8 ( $0) } )
183+ self . init ( unchecked: String . _copying ( s) )
191184 }
192185}
193186
Original file line number Diff line number Diff line change @@ -88,10 +88,7 @@ extension String: _HasContiguousBytes {
8888 try body ( $0)
8989 }
9090 }
91-
92- return try ContiguousArray ( self . utf8) . withUnsafeBufferPointer {
93- try body ( $0)
94- }
91+ return try String . _copying ( self ) . _guts. withFastUTF8 { try body ( $0) }
9592 }
9693
9794 @inlinable @inline ( __always)
@@ -116,10 +113,7 @@ extension Substring: _HasContiguousBytes {
116113 return try body ( $0)
117114 }
118115 }
119-
120- return try ContiguousArray ( self . utf8) . withUnsafeBufferPointer {
121- try body ( $0)
122- }
116+ return try String . _copying ( self ) . _guts. withFastUTF8 { try body ( $0) }
123117 }
124118
125119 @inlinable @inline ( __always)
Original file line number Diff line number Diff line change @@ -197,7 +197,25 @@ extension String {
197197 return substring. _wholeString
198198 }
199199
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+ }
201219 }
202220}
203221
Original file line number Diff line number Diff line change @@ -485,8 +485,15 @@ extension _StringObject {
485485 _internalInvariant ( isLarge)
486486 return ( discriminatedObjectRawBits & 0x4000_0000_0000_0000 ) != 0
487487 }
488- }
489488
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+ }
490497
491498/*
492499
Original file line number Diff line number Diff line change @@ -491,6 +491,8 @@ extension __StringStorage {
491491 _internalInvariant ( rawSelf + Int( _StringObject. nativeBias) == rawStart)
492492 _internalInvariant ( self . _realCapacity > self . count, " no room for nul-terminator " )
493493 _internalInvariant ( self . terminator. pointee == 0 , " not nul terminated " )
494+ let str = asString
495+ _internalInvariant ( str. _guts. _object. isPreferredRepresentation)
494496
495497 _countAndFlags. _invariantCheck ( )
496498 if isASCII {
@@ -803,6 +805,8 @@ extension __SharedStringStorage {
803805 _countAndFlags. _invariantCheck ( )
804806 _internalInvariant ( !_countAndFlags. isNativelyStored)
805807 _internalInvariant ( !_countAndFlags. isTailAllocated)
808+ let str = asString
809+ _internalInvariant ( !str. _guts. _object. isPreferredRepresentation)
806810 }
807811#endif // INTERNAL_CHECKS_ENABLED
808812}
You can’t perform that action at this time.
0 commit comments