Skip to content

Commit 5d943f4

Browse files
committed
[stdlib] Further simplify string-to-integer parsing and change some inlining choices.
1 parent 0319bdc commit 5d943f4

File tree

1 file changed

+30
-42
lines changed

1 file changed

+30
-42
lines changed

stdlib/public/core/IntegerParsing.swift

Lines changed: 30 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -16,49 +16,37 @@ internal func _parseASCIIDigits<Result: FixedWidthInteger>(
1616
) -> Result? {
1717
_internalInvariant(radix >= 2 && radix <= 36)
1818
guard _fastPath(!codeUnits.isEmpty) else { return nil }
19-
let multiplicand = Result(radix)
20-
var result = 0 as Result
19+
let numericalUpperBound, uppercaseUpperBound, lowercaseUpperBound: UInt8
2120
if radix <= 10 {
22-
let upperBound = 48 /* "0" */ &+ UInt8(radix)
23-
for digit in codeUnits {
24-
let digitValue: Result
25-
if _fastPath(digit >= 48 && digit < upperBound) {
26-
digitValue = Result(digit &- 48)
27-
} else {
28-
return nil
29-
}
30-
let (temporary, overflow1) =
31-
result.multipliedReportingOverflow(by: multiplicand)
32-
guard _fastPath(!overflow1) else { return nil }
33-
let (nextResult, overflow2) = isNegative
34-
? temporary.subtractingReportingOverflow(digitValue)
35-
: temporary.addingReportingOverflow(digitValue)
36-
guard _fastPath(!overflow2) else { return nil }
37-
result = nextResult
38-
}
21+
numericalUpperBound = 48 /* "0" */ &+ UInt8(radix)
22+
uppercaseUpperBound = 65
23+
lowercaseUpperBound = 97
3924
} else {
40-
let uppercaseUpperBound = 65 /* "A" */ &+ UInt8(radix &- 10)
41-
let lowercaseUpperBound = 97 /* "a" */ &+ UInt8(radix &- 10)
42-
for digit in codeUnits {
43-
let digitValue: Result
44-
if _fastPath(digit >= 48 /* "0" */ && digit < 58) {
45-
digitValue = Result(digit &- 48)
46-
} else if _fastPath(digit >= 65 && digit < uppercaseUpperBound) {
47-
digitValue = Result(digit &- 65 &+ 10)
48-
} else if _fastPath(digit >= 97 && digit < lowercaseUpperBound) {
49-
digitValue = Result(digit &- 97 &+ 10)
50-
} else {
51-
return nil
52-
}
53-
let (temporary, overflow1) =
54-
result.multipliedReportingOverflow(by: multiplicand)
55-
guard _fastPath(!overflow1) else { return nil }
56-
let (nextResult, overflow2) = isNegative
57-
? temporary.subtractingReportingOverflow(digitValue)
58-
: temporary.addingReportingOverflow(digitValue)
59-
guard _fastPath(!overflow2) else { return nil }
60-
result = nextResult
25+
numericalUpperBound = 58
26+
uppercaseUpperBound = 65 /* "A" */ &+ UInt8(radix &- 10)
27+
lowercaseUpperBound = 97 /* "a" */ &+ UInt8(radix &- 10)
28+
}
29+
let multiplicand = Result(radix)
30+
var result = 0 as Result
31+
for digit in codeUnits {
32+
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+
} else {
40+
return nil
6141
}
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
6250
}
6351
return result
6452
}
@@ -83,6 +71,7 @@ internal func _parseASCII<Result: FixedWidthInteger>(
8371
}
8472

8573
@_alwaysEmitIntoClient
74+
@inline(never)
8675
internal func _parseASCII<S: StringProtocol, Result: FixedWidthInteger>(
8776
_ text: S, radix: Int
8877
) -> Result? {
@@ -124,8 +113,7 @@ extension FixedWidthInteger {
124113
/// - radix: The radix, or base, to use for converting `text` to an integer
125114
/// value. `radix` must be in the range `2...36`. The default is 10.
126115
@inlinable
127-
@_specialize(kind: partial, where S == String)
128-
@_specialize(kind: partial, where S == Substring)
116+
@inline(__always)
129117
public init?<S: StringProtocol>(_ text: S, radix: Int = 10) {
130118
_precondition(2...36 ~= radix, "Radix not in range 2...36")
131119
guard _fastPath(!text.isEmpty) else { return nil }

0 commit comments

Comments
 (0)