Skip to content

Commit c358afe

Browse files
committedJun 16, 2017
[Foundation] Adjust Double and Float bridges to be more lenient
1 parent 689fc28 commit c358afe

File tree

3 files changed

+128
-8
lines changed

3 files changed

+128
-8
lines changed
 

‎stdlib/public/SDK/Foundation/NSNumber.swift

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,24 @@ extension Float : _ObjectiveCBridgeable {
451451
}
452452

453453
public static func _conditionallyBridgeFromObjectiveC(_ x: NSNumber, result: inout Float?) -> Bool {
454-
guard let value = Float(exactly: x) else { return false }
455-
result = value
454+
guard let value = Double(exactly: x) else { return false }
455+
guard !value.isNaN else {
456+
result = Float.nan
457+
return true
458+
}
459+
guard !value.isInfinite else {
460+
if value.sign == .minus {
461+
result = -Float.infinity
462+
} else {
463+
result = Float.infinity
464+
}
465+
return true
466+
}
467+
guard Swift.abs(value) <= Double(Float.greatestFiniteMagnitude) else {
468+
return false
469+
}
470+
471+
result = Float(value)
456472
return true
457473
}
458474

‎test/stdlib/TestNSNumberBridging.swift

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,58 @@ import StdlibUnittest
1818
import Foundation
1919
import CoreGraphics
2020

21+
extension Float {
22+
init?(reasonably value: Float) {
23+
self = value
24+
}
25+
26+
init?(reasonably value: Double) {
27+
guard !value.isNaN else {
28+
self = Float.nan
29+
return
30+
}
31+
32+
guard !value.isInfinite else {
33+
if value.sign == .minus {
34+
self = -Float.infinity
35+
} else {
36+
self = Float.infinity
37+
}
38+
return
39+
}
40+
41+
guard abs(value) <= Double(Float.greatestFiniteMagnitude) else {
42+
return nil
43+
}
44+
45+
self = Float(value)
46+
}
47+
}
48+
49+
extension Double {
50+
init?(reasonably value: Float) {
51+
guard !value.isNaN else {
52+
self = Double.nan
53+
return
54+
}
55+
56+
guard !value.isInfinite else {
57+
if value.sign == .minus {
58+
self = -Double.infinity
59+
} else {
60+
self = Double.infinity
61+
}
62+
return
63+
}
64+
65+
self = Double(value)
66+
}
67+
68+
init?(reasonably value: Double) {
69+
self = value
70+
}
71+
}
72+
2173
var nsNumberBridging = TestSuite("NSNumberBridging")
2274

2375
func testFloat(_ lhs: Float?, _ rhs: Float?, file: String = #file, line: UInt = #line) {
@@ -645,7 +697,7 @@ func testNSNumberBridgeFromFloat() {
645697
expectEqual(UInt(exactly: interestingValue), uint)
646698

647699
let float = (number!) as? Float
648-
let expectedFloat = Float(exactly: interestingValue)
700+
let expectedFloat = Float(reasonably: interestingValue)
649701
testFloat(expectedFloat, float)
650702

651703
let double = (number!) as? Double
@@ -685,7 +737,7 @@ func testNSNumberBridgeFromDouble() {
685737
expectEqual(UInt(exactly: interestingValue), uint)
686738

687739
let float = (number!) as? Float
688-
let expectedFloat = Float(exactly: interestingValue)
740+
let expectedFloat = Float(reasonably: interestingValue)
689741
testFloat(expectedFloat, float)
690742

691743
let double = (number!) as? Double
@@ -725,7 +777,7 @@ func testNSNumberBridgeFromCGFloat() {
725777
expectEqual(UInt(exactly: interestingValue.native), uint)
726778

727779
let float = (number!) as? Float
728-
let expectedFloat = Float(exactly: interestingValue.native)
780+
let expectedFloat = Float(reasonably: interestingValue.native)
729781
testFloat(expectedFloat, float)
730782

731783
let double = (number!) as? Double

‎validation-test/stdlib/ValidationNSNumberBridging.swift

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,58 @@ import StdlibUnittest
1818
import Foundation
1919
import CoreGraphics
2020

21+
extension Float {
22+
init?(reasonably value: Float) {
23+
self = value
24+
}
25+
26+
init?(reasonably value: Double) {
27+
guard !value.isNaN else {
28+
self = Float.nan
29+
return
30+
}
31+
32+
guard !value.isInfinite else {
33+
if value.sign == .minus {
34+
self = -Float.infinity
35+
} else {
36+
self = Float.infinity
37+
}
38+
return
39+
}
40+
41+
guard abs(value) <= Double(Float.greatestFiniteMagnitude) else {
42+
return nil
43+
}
44+
45+
self = Float(value)
46+
}
47+
}
48+
49+
extension Double {
50+
init?(reasonably value: Float) {
51+
guard !value.isNaN else {
52+
self = Double.nan
53+
return
54+
}
55+
56+
guard !value.isInfinite else {
57+
if value.sign == .minus {
58+
self = -Double.infinity
59+
} else {
60+
self = Double.infinity
61+
}
62+
return
63+
}
64+
65+
self = Double(value)
66+
}
67+
68+
init?(reasonably value: Double) {
69+
self = value
70+
}
71+
}
72+
2173
var nsNumberBridging = TestSuite("NSNumberBridgingValidation")
2274

2375
func testFloat(_ lhs: Float?, _ rhs: Float?, file: String = #file, line: UInt = #line) {
@@ -645,7 +697,7 @@ func testNSNumberBridgeFromFloat() {
645697
expectEqual(UInt(exactly: interestingValue), uint)
646698

647699
let float = (number!) as? Float
648-
let expectedFloat = Float(exactly: interestingValue)
700+
let expectedFloat = Float(reasonably: interestingValue)
649701
testFloat(expectedFloat, float)
650702

651703
let double = (number!) as? Double
@@ -685,7 +737,7 @@ func testNSNumberBridgeFromDouble() {
685737
expectEqual(UInt(exactly: interestingValue), uint)
686738

687739
let float = (number!) as? Float
688-
let expectedFloat = Float(exactly: interestingValue)
740+
let expectedFloat = Float(reasonably: interestingValue)
689741
testFloat(expectedFloat, float)
690742

691743
let double = (number!) as? Double
@@ -725,7 +777,7 @@ func testNSNumberBridgeFromCGFloat() {
725777
expectEqual(UInt(exactly: interestingValue.native), uint)
726778

727779
let float = (number!) as? Float
728-
let expectedFloat = Float(exactly: interestingValue.native)
780+
let expectedFloat = Float(reasonably: interestingValue.native)
729781
testFloat(expectedFloat, float)
730782

731783
let double = (number!) as? Double

0 commit comments

Comments
 (0)