11
11
//===----------------------------------------------------------------------===//
12
12
13
13
@_alwaysEmitIntoClient
14
- internal func _parseASCIIDigits < Result: FixedWidthInteger > (
14
+ internal func _parseDigitsInASCII < Result: FixedWidthInteger > (
15
15
_ codeUnits: UnsafeBufferPointer < UInt8 > , radix: Int , isNegative: Bool
16
16
) -> Result ? {
17
17
_internalInvariant ( radix >= 2 && radix <= 36 )
18
18
guard _fastPath ( !codeUnits. isEmpty) else { return nil }
19
- let numericalUpperBound , uppercaseUpperBound , lowercaseUpperBound : UInt8
19
+
20
+ // ASCII constants, named for clarity:
21
+ let _0 = 48 as UInt8 , _A = 65 as UInt8 , _a = 97 as UInt8
22
+
23
+ let numericalUpperBound : UInt8
24
+ let uppercaseUpperBound : UInt8
25
+ let lowercaseUpperBound : UInt8
20
26
if radix <= 10 {
21
- numericalUpperBound = 48 /* "0" */ &+ UInt8 ( radix)
22
- uppercaseUpperBound = 65
23
- lowercaseUpperBound = 97
27
+ numericalUpperBound = _0 &+ UInt8 ( truncatingIfNeeded : radix)
28
+ uppercaseUpperBound = _A
29
+ lowercaseUpperBound = _a
24
30
} else {
25
- numericalUpperBound = 58
26
- uppercaseUpperBound = 65 /* "A" */ &+ UInt8 ( radix &- 10 )
27
- lowercaseUpperBound = 97 /* "a" */ &+ UInt8 ( radix &- 10 )
31
+ numericalUpperBound = _0 &+ 10
32
+ uppercaseUpperBound = _A &+ UInt8 ( truncatingIfNeeded : radix &- 10 )
33
+ lowercaseUpperBound = _a &+ UInt8 ( truncatingIfNeeded : radix &- 10 )
28
34
}
29
- let multiplicand = Result ( radix)
35
+ let multiplicand = Result ( truncatingIfNeeded : radix)
30
36
var result = 0 as Result
31
37
for digit in codeUnits {
32
38
let digitValue : Result
33
- if _fastPath ( digit >= 48 && digit < numericalUpperBound) {
34
- digitValue = Result ( digit &- 48 )
35
- } else if _fastPath ( digit >= 65 && digit < uppercaseUpperBound) {
36
- digitValue = Result ( digit &- 65 &+ 10 )
37
- } else if _fastPath ( digit >= 97 && digit < lowercaseUpperBound) {
38
- digitValue = Result ( digit &- 97 &+ 10 )
39
+ if _fastPath ( digit >= _0 && digit < numericalUpperBound) {
40
+ digitValue = Result ( truncatingIfNeeded : digit &- _0 )
41
+ } else if _fastPath ( digit >= _A && digit < uppercaseUpperBound) {
42
+ digitValue = Result ( truncatingIfNeeded : digit &- _A &+ 10 )
43
+ } else if _fastPath ( digit >= _a && digit < lowercaseUpperBound) {
44
+ digitValue = Result ( truncatingIfNeeded : digit &- _a &+ 10 )
39
45
} else {
40
46
return nil
41
47
}
42
- let ( temporary, overflow1) =
43
- result. multipliedReportingOverflow ( by: multiplicand)
44
- guard _fastPath ( !overflow1) else { return nil }
45
- let ( nextResult, overflow2) = isNegative
46
- ? temporary. subtractingReportingOverflow ( digitValue)
47
- : temporary. addingReportingOverflow ( digitValue)
48
- guard _fastPath ( !overflow2) else { return nil }
49
- result = nextResult
48
+ let overflow1 : Bool
49
+ ( result, overflow1) = result. multipliedReportingOverflow ( by: multiplicand)
50
+ let overflow2 : Bool
51
+ ( result, overflow2) = isNegative
52
+ ? result. subtractingReportingOverflow ( digitValue)
53
+ : result. addingReportingOverflow ( digitValue)
54
+ guard _fastPath ( !overflow1 && !overflow2) else { return nil }
50
55
}
51
56
return result
52
57
}
@@ -56,18 +61,22 @@ internal func _parseASCII<Result: FixedWidthInteger>(
56
61
_ codeUnits: UnsafeBufferPointer < UInt8 > , radix: Int
57
62
) -> Result ? {
58
63
_internalInvariant ( !codeUnits. isEmpty)
64
+
65
+ // ASCII constants, named for clarity:
66
+ let _plus = 43 as UInt8 , _minus = 45 as UInt8
67
+
59
68
let first = codeUnits [ 0 ]
60
- if first == 45 /* "-" */ {
61
- return _parseASCIIDigits (
69
+ if first == _minus {
70
+ return _parseDigitsInASCII (
62
71
UnsafeBufferPointer ( rebasing: codeUnits [ 1 ... ] ) ,
63
72
radix: radix, isNegative: true )
64
73
}
65
- if first == 43 /* "+" */ {
66
- return _parseASCIIDigits (
74
+ if first == _plus {
75
+ return _parseDigitsInASCII (
67
76
UnsafeBufferPointer ( rebasing: codeUnits [ 1 ... ] ) ,
68
77
radix: radix, isNegative: false )
69
78
}
70
- return _parseASCIIDigits ( codeUnits, radix: radix, isNegative: false )
79
+ return _parseDigitsInASCII ( codeUnits, radix: radix, isNegative: false )
71
80
}
72
81
73
82
@_alwaysEmitIntoClient
@@ -150,18 +159,18 @@ extension FixedWidthInteger {
150
159
}
151
160
}
152
161
153
- // -----------------------------------------------------------------------------
162
+ //=== ----------------------------------------------------------------------===//
154
163
// Old entry points preserved for ABI compatibility.
155
- // -----------------------------------------------------------------------------
164
+ //=== ----------------------------------------------------------------------===//
156
165
157
166
/// Returns c as a UTF16.CodeUnit. Meant to be used as _ascii16("x").
158
- @usableFromInline
167
+ @usableFromInline // Previously '@inlinable'.
159
168
internal func _ascii16( _ c: Unicode . Scalar ) -> UTF16 . CodeUnit {
160
169
_internalInvariant ( c. value >= 0 && c. value <= 0x7F , " not ASCII " )
161
170
return UTF16 . CodeUnit ( c. value)
162
171
}
163
172
164
- @usableFromInline
173
+ @usableFromInline // Previously '@inlinable @inline(__always)'.
165
174
internal func _asciiDigit< CodeUnit: UnsignedInteger , Result: BinaryInteger > (
166
175
codeUnit u_: CodeUnit , radix: Result
167
176
) -> Result ? {
@@ -179,7 +188,7 @@ internal func _asciiDigit<CodeUnit: UnsignedInteger, Result: BinaryInteger>(
179
188
return Result ( truncatingIfNeeded: d)
180
189
}
181
190
182
- @usableFromInline
191
+ @usableFromInline // Previously '@inlinable @inline(__always)'.
183
192
internal func _parseUnsignedASCII<
184
193
Rest: IteratorProtocol , Result: FixedWidthInteger
185
194
> (
@@ -209,12 +218,10 @@ where Rest.Element: UnsignedInteger {
209
218
return result
210
219
}
211
220
212
- //
213
- // Before it was superseded, this function was about 20KB of always-inline code,
214
- // most of which were MOV instructions.
215
- //
221
+ // This function has been superseded because it is about 20KB of previously
222
+ // always-inline code, most of which are MOV instructions.
216
223
217
- @usableFromInline
224
+ @usableFromInline // Previously '@inlinable @inline(__always)'.
218
225
internal func _parseASCII<
219
226
CodeUnits: IteratorProtocol , Result: FixedWidthInteger
220
227
> (
0 commit comments