10
10
//
11
11
//===----------------------------------------------------------------------===//
12
12
13
- // N.B.: This free function has been manually specialized below where
14
- // `UTF8CodeUnits == UnsafeBufferPoint<UInt8>`. Ensure that any changes are
15
- // made in sync.
16
- @_alwaysEmitIntoClient
17
- @inline ( never)
18
- internal func _parseASCIIDigits<
19
- UTF8CodeUnits: Collection , Result: FixedWidthInteger
20
- > (
21
- _ codeUnits: UTF8CodeUnits , radix: Int , isNegative: Bool
22
- ) -> Result ? where UTF8CodeUnits. Element == UInt8 {
23
- _internalInvariant ( radix >= 2 && radix <= 36 )
24
- guard _fastPath ( !codeUnits. isEmpty) else { return nil }
25
- let multiplicand = Result ( radix)
26
- var result = 0 as Result
27
- if radix <= 10 {
28
- let upperBound = 48 /* "0" */ &+ UInt8 ( radix)
29
- for digit in codeUnits {
30
- let digitValue : Result
31
- if _fastPath ( digit >= 48 && digit < upperBound) {
32
- digitValue = Result ( digit &- 48 )
33
- } else {
34
- return nil
35
- }
36
- let ( temporary, overflow1) =
37
- result. multipliedReportingOverflow ( by: multiplicand)
38
- guard _fastPath ( !overflow1) else { return nil }
39
- let ( nextResult, overflow2) = isNegative
40
- ? temporary. subtractingReportingOverflow ( digitValue)
41
- : temporary. addingReportingOverflow ( digitValue)
42
- guard _fastPath ( !overflow2) else { return nil }
43
- result = nextResult
44
- }
45
- } else {
46
- let uppercaseUpperBound = 65 /* "A" */ &+ UInt8 ( radix &- 10 )
47
- let lowercaseUpperBound = 97 /* "a" */ &+ UInt8 ( radix &- 10 )
48
- for digit in codeUnits {
49
- let digitValue : Result
50
- if _fastPath ( digit >= 48 /* "0" */ && digit < 58 ) {
51
- digitValue = Result ( digit &- 48 )
52
- } else if _fastPath ( digit >= 65 && digit < uppercaseUpperBound) {
53
- digitValue = Result ( digit &- 65 &+ 10 )
54
- } else if _fastPath ( digit >= 97 && digit < lowercaseUpperBound) {
55
- digitValue = Result ( digit &- 97 &+ 10 )
56
- } else {
57
- return nil
58
- }
59
- let ( temporary, overflow1) =
60
- result. multipliedReportingOverflow ( by: multiplicand)
61
- guard _fastPath ( !overflow1) else { return nil }
62
- let ( nextResult, overflow2) = isNegative
63
- ? temporary. subtractingReportingOverflow ( digitValue)
64
- : temporary. addingReportingOverflow ( digitValue)
65
- guard _fastPath ( !overflow2) else { return nil }
66
- result = nextResult
67
- }
68
- }
69
- return result
70
- }
71
-
72
- // N.B.: This free function is a manually specialized version of the function
73
- // above. Ensure that any changes are made in sync.
74
13
@_alwaysEmitIntoClient
75
14
internal func _parseASCIIDigits< Result: FixedWidthInteger > (
76
15
_ codeUnits: UnsafeBufferPointer < UInt8 > , radix: Int , isNegative: Bool
@@ -124,24 +63,6 @@ internal func _parseASCIIDigits<Result: FixedWidthInteger>(
124
63
return result
125
64
}
126
65
127
- @_alwaysEmitIntoClient
128
- @inline ( never)
129
- internal func _parseASCII< UTF8CodeUnits: Collection , Result: FixedWidthInteger > (
130
- _ codeUnits: UTF8CodeUnits , radix: Int
131
- ) -> Result ? where UTF8CodeUnits. Element == UInt8 {
132
- _internalInvariant ( !codeUnits. isEmpty)
133
- let first = codeUnits. first!
134
- if first == 45 /* "-" */ {
135
- return _parseASCIIDigits (
136
- codeUnits. dropFirst ( ) , radix: radix, isNegative: true )
137
- }
138
- if first == 43 /* "+" */ {
139
- return _parseASCIIDigits (
140
- codeUnits. dropFirst ( ) , radix: radix, isNegative: false )
141
- }
142
- return _parseASCIIDigits ( codeUnits, radix: radix, isNegative: false )
143
- }
144
-
145
66
@_alwaysEmitIntoClient
146
67
internal func _parseASCII< Result: FixedWidthInteger > (
147
68
_ codeUnits: UnsafeBufferPointer < UInt8 > , radix: Int
@@ -161,6 +82,14 @@ internal func _parseASCII<Result: FixedWidthInteger>(
161
82
return _parseASCIIDigits ( codeUnits, radix: radix, isNegative: false )
162
83
}
163
84
85
+ @_alwaysEmitIntoClient
86
+ internal func _parseASCII< S: StringProtocol , Result: FixedWidthInteger > (
87
+ _ text: S , radix: Int
88
+ ) -> Result ? {
89
+ var str = String ( text)
90
+ return str. withUTF8 { _parseASCII ( $0, radix: radix) }
91
+ }
92
+
164
93
extension FixedWidthInteger {
165
94
/// Creates a new integer value from the given string and radix.
166
95
///
@@ -203,7 +132,7 @@ extension FixedWidthInteger {
203
132
let result : Self ? =
204
133
text. utf8. withContiguousStorageIfAvailable {
205
134
_parseASCII ( $0, radix: radix)
206
- } ?? _parseASCII ( text. utf8 , radix: radix)
135
+ } ?? _parseASCII ( text, radix: radix)
207
136
guard let result_ = result else { return nil }
208
137
self = result_
209
138
}
0 commit comments