@@ -50,19 +50,34 @@ internal func _allASCII(_ input: UnsafeBufferPointer<UInt8>) -> Bool {
50
50
}
51
51
52
52
extension String {
53
- @ usableFromInline
54
- internal static func _fromASCII (
53
+
54
+ internal static func _uncheckedFromASCII (
55
55
_ input: UnsafeBufferPointer < UInt8 >
56
56
) -> String {
57
- _internalInvariant ( _allASCII ( input) , " not actually ASCII " )
58
-
59
57
if let smol = _SmallString ( input) {
60
58
return String ( _StringGuts ( smol) )
61
59
}
62
60
63
61
let storage = __StringStorage. create ( initializingFrom: input, isASCII: true )
64
62
return storage. asString
65
63
}
64
+
65
+ @usableFromInline
66
+ internal static func _fromASCII(
67
+ _ input: UnsafeBufferPointer < UInt8 >
68
+ ) -> String {
69
+ _internalInvariant ( _allASCII ( input) , " not actually ASCII " )
70
+ return _uncheckedFromASCII ( input)
71
+ }
72
+
73
+ internal static func _fromASCIIValidating(
74
+ _ input: UnsafeBufferPointer < UInt8 >
75
+ ) -> String ? {
76
+ if _fastPath ( _allASCII ( input) ) {
77
+ return _uncheckedFromASCII ( input)
78
+ }
79
+ return nil
80
+ }
66
81
67
82
public // SPI(Foundation)
68
83
static func _tryFromUTF8( _ input: UnsafeBufferPointer < UInt8 > ) -> String ? {
@@ -166,9 +181,9 @@ extension String {
166
181
167
182
return contents. withUnsafeBufferPointer { String . _uncheckedFromUTF8 ( $0) }
168
183
}
169
-
170
- @usableFromInline @ inline ( never) // slow- path
171
- internal static func _fromCodeUnits <
184
+
185
+ @inline ( never) // slow path
186
+ private static func _slowFromCodeUnits <
172
187
Input: Collection ,
173
188
Encoding: Unicode . Encoding
174
189
> (
@@ -194,6 +209,46 @@ extension String {
194
209
let str = contents. withUnsafeBufferPointer { String . _uncheckedFromUTF8 ( $0) }
195
210
return ( str, repaired)
196
211
}
212
+
213
+ @usableFromInline @inline ( never) // can't be inlined w/out breaking ABI
214
+ @_specialize (
215
+ where Input == UnsafeBufferPointer< UInt8 > , Encoding == Unicode . ASCII)
216
+ @_specialize (
217
+ where Input == Array< UInt8 > , Encoding == Unicode . ASCII)
218
+ internal static func _fromCodeUnits<
219
+ Input: Collection ,
220
+ Encoding: Unicode . Encoding
221
+ > (
222
+ _ input: Input ,
223
+ encoding: Encoding . Type ,
224
+ repair: Bool
225
+ ) -> ( String , repairsMade: Bool ) ?
226
+ where Input. Element == Encoding . CodeUnit {
227
+ guard _fastPath ( encoding == Unicode . ASCII. self) else {
228
+ return _slowFromCodeUnits ( input, encoding: encoding, repair: repair)
229
+ }
230
+
231
+ var result : String ? = nil
232
+
233
+ if let contigBytes = input as? _HasContiguousBytes ,
234
+ contigBytes. _providesContiguousBytesNoCopy {
235
+ result = contigBytes. withUnsafeBytes { rawBufPtr in
236
+ let buffer = UnsafeBufferPointer (
237
+ start: rawBufPtr. baseAddress? . assumingMemoryBound ( to: UInt8 . self) ,
238
+ count: rawBufPtr. count)
239
+ return String . _fromASCIIValidating ( buffer)
240
+ }
241
+ } else {
242
+ result = Array ( input) . withUnsafeBufferPointer {
243
+ let buffer = UnsafeRawBufferPointer ( $0) . bindMemory ( to: UInt8 . self)
244
+ return String . _fromASCIIValidating ( buffer)
245
+ }
246
+ }
247
+
248
+ return result != nil ?
249
+ ( result!, repairsMade: false ) :
250
+ _slowFromCodeUnits ( input, encoding: encoding, repair: repair)
251
+ }
197
252
198
253
public // @testable
199
254
static func _fromInvalidUTF16(
0 commit comments