//===----------------------------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// import SwiftShims %{ allFloatBits = [16, 32, 64, 80] def floatName(bits): if bits == 16: return 'Float16' if bits == 32: return 'Float' if bits == 64: return 'Double' if bits == 80: return 'Float80' cFuncSuffix2 = {16: 'f16', 32: 'f', 64: 'd', 80: 'ld'} }% /// Returns `true` iff isspace(u) would return nonzero when the current /// locale is the C locale. @inlinable // FIXME(sil-serialize-all) internal func _isspace_clocale(_ u: UTF16.CodeUnit) -> Bool { return "\t\n\u{b}\u{c}\r ".utf16.contains(u) } % for bits in allFloatBits: % Self = floatName(bits) % if bits == 80: #if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64)) % end //===--- Parsing ----------------------------------------------------------===// %if bits == 16: @available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, *) %end extension ${Self}: LosslessStringConvertible { /// Creates a new instance from the given string. /// /// The string passed as `text` can represent a real number in decimal or /// hexadecimal format or special floating-point values for infinity and NaN /// ("not a number"). /// /// The given string may begin with a plus or minus sign character (`+` or /// `-`). The allowed formats for each of these representations is then as /// follows: /// /// - A *decimal value* contains the significand, a sequence of decimal /// digits that may include a decimal point. /// /// let c = ${Self}("-1.0") /// // c == -1.0 /// /// let d = ${Self}("28.375") /// // d == 28.375 /// /// A decimal value may also include an exponent following the significand, /// indicating the power of 10 by which the significand should be /// multiplied. If included, the exponent is separated by a single /// character, `e` or `E`, and consists of an optional plus or minus sign /// character and a sequence of decimal digits. /// /// let e = ${Self}("2837.5e-2") /// // e == 28.375 /// /// - A *hexadecimal value* contains the significand, either `0X` or `0x`, /// followed by a sequence of hexadecimal digits. The significand may /// include a decimal point. /// /// let f = ${Self}("0x1c.6") /// // f == 28.375 /// /// A hexadecimal value may also include an exponent following the /// significand, indicating the power of 2 by which the significand should /// be multiplied. If included, the exponent is separated by a single /// character, `p` or `P`, and consists of an optional plus or minus sign /// character and a sequence of decimal digits. /// /// let g = ${Self}("0x1.c6p4") /// // g == 28.375 /// /// - A value of *infinity* contains one of the strings `"inf"` or /// `"infinity"`, case insensitive. /// /// let i = ${Self}("inf") /// // i == ${Self}.infinity /// /// let j = ${Self}("-Infinity") /// // j == -${Self}.infinity /// /// - A value of *NaN* contains the string `"nan"`, case insensitive. /// /// let n = ${Self}("-nan") /// // n?.isNaN == true /// // n?.sign == .minus /// /// A NaN value may also include a payload in parentheses following the /// `"nan"` keyword. The payload consists of a sequence of decimal digits, /// or the characters `0X` or `0x` followed by a sequence of hexadecimal /// digits. If the payload contains any other characters, it is ignored. /// If the value of the payload is larger than can be stored as the /// payload of a `${Self}.nan`, the least significant bits are used. /// /// let p = ${Self}("nan(0x10)") /// // p?.isNaN == true /// // String(p!) == "nan(0x10)" /// /// Passing any other format or any additional characters as `text` results /// in `nil`. For example, the following conversions result in `nil`: /// /// ${Self}(" 5.0") // Includes whitespace /// ${Self}("±2.0") // Invalid character /// ${Self}("0x1.25e4") // Incorrect exponent format /// /// - Parameter text: The input string to convert to a `${Self}` instance. If /// `text` has invalid characters or is in an invalid format, the result /// is `nil`. @inlinable public init?(_ text: S) { %if bits == 16: self.init(Substring(text)) %else: if #available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, *) { self.init(Substring(text)) } else { self = 0.0 let success = withUnsafeMutablePointer(to: &self) { p -> Bool in text.withCString { chars -> Bool in switch chars[0] { case 9, 10, 11, 12, 13, 32: return false // Reject leading whitespace case 0: return false // Reject empty string default: break } let endPtr = _swift_stdlib_strto${cFuncSuffix2[bits]}_clocale(chars, p) // Succeed only if endPtr points to end of C string return endPtr != nil && endPtr![0] == 0 } } if !success { return nil } } %end } // Caveat: This implementation used to be inlineable. // In particular, we still have to export // _swift_stdlib_strtoXYZ_clocale() // as ABI to support old compiled code that still requires it. @available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, *) public init?(_ text: Substring) { self = 0.0 let success = withUnsafeMutablePointer(to: &self) { p -> Bool in text.withCString { chars -> Bool in switch chars[0] { case 9, 10, 11, 12, 13, 32: return false // Reject leading whitespace case 0: return false // Reject empty string default: break } let endPtr = _swift_stdlib_strto${cFuncSuffix2[bits]}_clocale(chars, p) // Succeed only if endPtr points to end of C string return endPtr != nil && endPtr![0] == 0 } } if !success { return nil } } } % if bits == 80: #endif % end % end // ${'Local Variables'}: // eval: (read-only-mode 1) // End: