Skip to content

Commit 0626a97

Browse files
xwuparkera
authored andcommitted
Update NSScanner to use BinaryFloatingPoint (#631)
* Update NSScanner to use BinaryFloatingPoint * Make another fix and add test [NSScanner] * Fixup typos [TestNSScanner]
1 parent 705aa96 commit 0626a97

File tree

2 files changed

+15
-32
lines changed

2 files changed

+15
-32
lines changed

Foundation/NSScanner.swift

Lines changed: 7 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -224,37 +224,12 @@ internal protocol _IntegerLike : Integer, _BitShiftable {
224224
static var min: Self { get }
225225
}
226226

227-
internal protocol _FloatArithmeticType {
228-
static func +(lhs: Self, rhs: Self) -> Self
229-
static func -(lhs: Self, rhs: Self) -> Self
230-
static func *(lhs: Self, rhs: Self) -> Self
231-
static func /(lhs: Self, rhs: Self) -> Self
232-
}
233-
234-
internal protocol _FloatLike : FloatingPoint, _FloatArithmeticType {
235-
init(_ value: Int)
236-
init(_ value: Double)
237-
static var max: Self { get }
238-
static var min: Self { get }
239-
}
240-
241227
extension Int : _IntegerLike { }
242228
extension Int32 : _IntegerLike { }
243229
extension Int64 : _IntegerLike { }
244230
extension UInt32 : _IntegerLike { }
245231
extension UInt64 : _IntegerLike { }
246232

247-
// these might be good to have in the stdlib
248-
extension Float : _FloatLike {
249-
static var max: Float { return FLT_MAX }
250-
static var min: Float { return FLT_MIN }
251-
}
252-
253-
extension Double : _FloatLike {
254-
static var max: Double { return DBL_MAX }
255-
static var min: Double { return DBL_MIN }
256-
}
257-
258233
private func numericValue(_ ch: unichar) -> Int {
259234
if (ch >= unichar(unicodeScalarLiteral: "0") && ch <= unichar(unicodeScalarLiteral: "9")) {
260235
return Int(ch) - Int(unichar(unicodeScalarLiteral: "0"))
@@ -366,7 +341,7 @@ extension String {
366341
return true
367342
}
368343

369-
internal func scan<T: _FloatLike>(_ skipSet: CharacterSet?, locale: Locale?, locationToScanFrom: inout Int, to: (T) -> Void) -> Bool {
344+
internal func scan<T: BinaryFloatingPoint>(_ skipSet: CharacterSet?, locale: Locale?, locationToScanFrom: inout Int, to: (T) -> Void) -> Bool {
370345
let ds_chars = decimalSep(locale).utf16
371346
let ds = ds_chars[ds_chars.startIndex]
372347
var buf = _NSStringBuffer(string: self, start: locationToScanFrom, end: length)
@@ -388,13 +363,13 @@ extension String {
388363
if numeral == -1 {
389364
break
390365
}
391-
// if (localResult >= T.max / T(10)) && ((localResult > T.max / T(10)) || T(numericValue(buf.currentCharacter) - (neg ? 1 : 0)) >= T.max - localResult * T(10)) is evidently too complex; so break it down to more "edible chunks"
392-
let limit1 = localResult >= T.max / T(10)
393-
let limit2 = localResult > T.max / T(10)
394-
let limit3 = T(numeral - (neg ? 1 : 0)) >= T.max - localResult * T(10)
366+
// if (localResult >= T.greatestFiniteMagnitude / T(10)) && ((localResult > T.greatestFiniteMagnitude / T(10)) || T(numericValue(buf.currentCharacter) - (neg ? 1 : 0)) >= T.greatestFiniteMagnitude - localResult * T(10)) is evidently too complex; so break it down to more "edible chunks"
367+
let limit1 = localResult >= T.greatestFiniteMagnitude / T(10)
368+
let limit2 = localResult > T.greatestFiniteMagnitude / T(10)
369+
let limit3 = T(numeral - (neg ? 1 : 0)) >= T.greatestFiniteMagnitude - localResult * T(10)
395370
if (limit1) && (limit2 || limit3) {
396371
// apply the clamps and advance past the ending of the buffer where there are still digits
397-
localResult = neg ? T.min : T.max
372+
localResult = neg ? -T.infinity : T.infinity
398373
neg = false
399374
repeat {
400375
buf.advance()
@@ -425,7 +400,7 @@ extension String {
425400
return true
426401
}
427402

428-
internal func scanHex<T: _FloatLike>(_ skipSet: CharacterSet?, locale: Locale?, locationToScanFrom: inout Int, to: (T) -> Void) -> Bool {
403+
internal func scanHex<T: BinaryFloatingPoint>(_ skipSet: CharacterSet?, locale: Locale?, locationToScanFrom: inout Int, to: (T) -> Void) -> Bool {
429404
NSUnimplemented()
430405
}
431406
}

TestFoundation/TestNSScanner.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class TestNSScanner : XCTestCase {
2424
static var allTests: [(String, (TestNSScanner) -> () throws -> Void)] {
2525
return [
2626
("test_scanInteger", test_scanInteger),
27+
("test_scanFloat", test_scanFloat),
2728
]
2829
}
2930

@@ -33,4 +34,11 @@ class TestNSScanner : XCTestCase {
3334
XCTAssert(scanner.scanInteger(&value), "An Integer should be found in the string `123`.")
3435
XCTAssertEqual(value, 123, "Scanned Integer value of the string `123` should be `123`.")
3536
}
37+
38+
func test_scanFloat() {
39+
let scanner = Scanner(string: "-350000000000000000000000000000000000000000")
40+
var value: Float = 0
41+
XCTAssert(scanner.scanFloat(&value), "A Float should be found in the string `-350000000000000000000000000000000000000000`.")
42+
XCTAssert(value.isInfinite, "Scanned Float value of the string `-350000000000000000000000000000000000000000` should be infinite`.")
43+
}
3644
}

0 commit comments

Comments
 (0)