Skip to content

Commit 5c2f51e

Browse files
authored
Merge pull request #86018 from tbkka/tbkka-float-parsing-substring
New FP Parsing: Use relevant part of a substring
2 parents 0134baf + 889dd29 commit 5c2f51e

File tree

3 files changed

+83
-4
lines changed

3 files changed

+83
-4
lines changed

stdlib/public/core/FloatingPointParsing.swift.gyb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,14 +256,13 @@ extension ${Self}: LosslessStringConvertible {
256256
// Use the all-Swift `parse_float${bits}()` implementation for Float16/32/64
257257
@available(SwiftStdlib 5.3, *)
258258
public init?(_ text: Substring) {
259-
// TODO: Someday, this whole function should simplify down to just:
260-
// ${Self}(text.utf8.span)
261259
#if _pointerBitWidth(_16)
262260
// Always fail on 16-bit targets
263261
return nil
264262
#else
265-
// Work around span availability limits
266-
let parsed = unsafe text.base._guts.withFastUTF8 { chars -> ${Self}? in
263+
var mutableText = text
264+
let parsed: ${Self}?
265+
parsed = mutableText.withUTF8 { chars -> ${Self}? in
267266
unsafe parse_float${bits}(chars.span)
268267
}
269268

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift -g %s -o %t/a.out -enable-experimental-feature Extern
3+
// RUN: %target-codesign %t/a.out
4+
// RUN: %target-run %t/a.out
5+
6+
// REQUIRES: executable_test
7+
// REQUIRES: objc_interop
8+
9+
// Needed to declare the ABI entry point
10+
// REQUIRES: swift_feature_Extern
11+
12+
import StdlibUnittest
13+
import Foundation
14+
15+
let tests = TestSuite("FloatingPointParsing")
16+
17+
tests.test("Bridged - short") {
18+
let s1 = "1.02.03.0"
19+
let nss1 = NSString(utf8String: s1)!
20+
let bridged = String(nss1)
21+
let range = bridged.firstIndex(of: "2")!..<bridged.firstIndex(of: "3")!
22+
let sub = bridged[range]
23+
let parsed = Float64(sub)
24+
expectNotNil(parsed)
25+
expectEqual(parsed!.bitPattern, (2.0).bitPattern)
26+
}
27+
28+
tests.test("Bridged - long") {
29+
let s1 = "1.02.0000000000000000000000000000000000000000000000000000000000003.04.05.06.07.08.09.010.011.012.013.014.015.0"
30+
let nss1 = NSString(utf8String: s1)!
31+
let bridged = String(nss1)
32+
let range = bridged.firstIndex(of: "2")!..<bridged.firstIndex(of: "3")!
33+
let sub = bridged[range]
34+
let parsed = Float64(sub)
35+
expectNotNil(parsed)
36+
expectEqual(parsed!.bitPattern, (2.0).bitPattern)
37+
}
38+
39+
runAllTests()

test/stdlib/ParseFloat64.swift

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,47 @@ tests.test("Decimal Floats") {
325325
expectParse("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999.999999999999999999999999999", Float64.infinity)
326326
}
327327

328+
tests.test("Substring - short") {
329+
let s1 = "1.02.03.0"
330+
let s1sub = s1[s1.firstIndex(of: "2")!..<s1.firstIndex(of: "3")!]
331+
let parsed = Float64(s1sub)
332+
expectNotNil(parsed)
333+
expectEqual(parsed!.bitPattern, (2.0).bitPattern)
334+
}
335+
336+
tests.test("Substring - long") {
337+
let s1 = "1.00000000000000000000000000000000002.0000000000000000000000000000000000000000000000000000000003.00000000000000004.0000000000000000"
338+
let s1sub = s1[s1.firstIndex(of: "2")!..<s1.firstIndex(of: "3")!]
339+
let parsed = Float64(s1sub)
340+
expectNotNil(parsed)
341+
expectEqual(parsed!.bitPattern, (2.0).bitPattern)
342+
}
343+
344+
/*
345+
// These need Foundation to run, so can't run on Linux?
346+
tests.test("Bridged - short") {
347+
let s1 = "1.02.03.0"
348+
let nss1 = NSString(utf8String: s1)!
349+
let bridged = String(nss1)
350+
let range = bridged.firstIndex(of: "2")!..<bridged.firstIndex(of: "3")!
351+
let sub = bridged[range]
352+
let parsed = Float64(sub)
353+
expectNotNil(parsed)
354+
expectEqual(parsed!.bitPattern, (2.0).bitPattern)
355+
}
356+
357+
tests.test("Bridged - long") {
358+
let s1 = "1.02.0000000000000000000000000000000000000000000000000000000000003.04.05.06.07.08.09.010.011.012.013.014.015.0"
359+
let nss1 = NSString(utf8String: s1)!
360+
let bridged = String(nss1)
361+
let range = bridged.firstIndex(of: "2")!..<bridged.firstIndex(of: "3")!
362+
let sub = bridged[range]
363+
let parsed = Float64(sub)
364+
expectNotNil(parsed)
365+
expectEqual(parsed!.bitPattern, (2.0).bitPattern)
366+
}
367+
*/
368+
328369
@_extern(c, "_swift_stdlib_strtod_clocale")
329370
func _swift_stdlib_strtod_clocale(
330371
_: Optional<UnsafePointer<CChar>>,

0 commit comments

Comments
 (0)