| //===--- CGFloat.swift.gyb ------------------------------------*- swift -*-===// |
| // |
| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2014 - 2017 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 |
| // |
| //===----------------------------------------------------------------------===// |
| |
| %{ |
| |
| from SwiftIntTypes import all_integer_types |
| |
| # Number of bits in the Builtin.Word type |
| word_bits = int(CMAKE_SIZEOF_VOID_P) * 8 |
| |
| }% |
| |
| @_exported import CoreGraphics |
| import Darwin |
| |
| @frozen |
| public struct CGFloat { |
| #if arch(i386) || arch(arm) |
| /// The native type used to store the CGFloat, which is Float on |
| /// 32-bit architectures and Double on 64-bit architectures. |
| public typealias NativeType = Float |
| #elseif arch(x86_64) || arch(arm64) |
| /// The native type used to store the CGFloat, which is Float on |
| /// 32-bit architectures and Double on 64-bit architectures. |
| public typealias NativeType = Double |
| #endif |
| |
| @_transparent public init() { |
| self.native = 0.0 |
| } |
| |
| @_transparent public init(_ value: Float) { |
| self.native = NativeType(value) |
| } |
| |
| @_transparent public init(_ value: Double) { |
| self.native = NativeType(value) |
| } |
| |
| #if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64)) |
| @_transparent public init(_ value: Float80) { |
| self.native = NativeType(value) |
| } |
| #endif |
| |
| @_transparent public init(_ value: CGFloat) { |
| self.native = value.native |
| } |
| |
| /// The native value. |
| public var native: NativeType |
| } |
| |
| extension CGFloat : SignedNumeric { |
| @_alwaysEmitIntoClient // availability |
| public init<T: BinaryInteger>(_ source: T) { |
| self.native = NativeType(source) |
| } |
| |
| @_transparent |
| public init?<T: BinaryInteger>(exactly source: T) { |
| guard let native = NativeType(exactly: source) else { return nil } |
| self.native = native |
| } |
| |
| @_transparent |
| public var magnitude: CGFloat { |
| return CGFloat(native.magnitude) |
| } |
| } |
| |
| extension CGFloat : BinaryFloatingPoint { |
| |
| public typealias RawSignificand = UInt |
| public typealias Exponent = Int |
| |
| @_transparent |
| public static var exponentBitCount: Int { |
| return NativeType.exponentBitCount |
| } |
| |
| @_transparent |
| public static var significandBitCount: Int { |
| return NativeType.significandBitCount |
| } |
| |
| // Conversions to/from integer encoding. These are not part of the |
| // BinaryFloatingPoint prototype because there's no guarantee that an |
| // integer type of the same size actually exists (e.g. Float80). |
| @_transparent |
| public var bitPattern: UInt { |
| return UInt(native.bitPattern) |
| } |
| |
| @_transparent |
| public init(bitPattern: UInt) { |
| native = NativeType(bitPattern: UInt${word_bits}(bitPattern)) |
| } |
| |
| @_transparent |
| public var sign: FloatingPointSign { |
| return native.sign |
| } |
| |
| @_transparent |
| public var exponentBitPattern: UInt { |
| return native.exponentBitPattern |
| } |
| |
| @_transparent |
| public var significandBitPattern: UInt { |
| return UInt(native.significandBitPattern) |
| } |
| |
| @_transparent |
| public init(sign: FloatingPointSign, |
| exponentBitPattern: UInt, |
| significandBitPattern: UInt) { |
| native = NativeType(sign: sign, |
| exponentBitPattern: exponentBitPattern, |
| significandBitPattern: NativeType.RawSignificand(significandBitPattern)) |
| } |
| |
| @_transparent |
| public init(nan payload: RawSignificand, signaling: Bool) { |
| native = NativeType(nan: NativeType.RawSignificand(payload), |
| signaling: signaling) |
| } |
| |
| @_transparent |
| public static var infinity: CGFloat { |
| return CGFloat(NativeType.infinity) |
| } |
| |
| @_transparent |
| public static var nan: CGFloat { |
| return CGFloat(NativeType.nan) |
| } |
| |
| @_transparent |
| public static var signalingNaN: CGFloat { |
| return CGFloat(NativeType.signalingNaN) |
| } |
| |
| @available(*, unavailable, renamed: "nan") |
| public static var quietNaN: CGFloat { |
| fatalError("unavailable") |
| } |
| |
| @_transparent |
| public static var greatestFiniteMagnitude: CGFloat { |
| return CGFloat(NativeType.greatestFiniteMagnitude) |
| } |
| |
| @_transparent |
| public static var pi: CGFloat { |
| return CGFloat(NativeType.pi) |
| } |
| |
| @_transparent |
| public var ulp: CGFloat { |
| return CGFloat(native.ulp) |
| } |
| |
| @_transparent |
| public static var leastNormalMagnitude: CGFloat { |
| return CGFloat(NativeType.leastNormalMagnitude) |
| } |
| |
| @_transparent |
| public static var leastNonzeroMagnitude: CGFloat { |
| return CGFloat(NativeType.leastNonzeroMagnitude) |
| } |
| |
| @_transparent |
| public var exponent: Int { |
| return native.exponent |
| } |
| |
| @_transparent |
| public var significand: CGFloat { |
| return CGFloat(native.significand) |
| } |
| |
| @_transparent |
| public init(sign: FloatingPointSign, exponent: Int, significand: CGFloat) { |
| native = NativeType(sign: sign, |
| exponent: exponent, significand: significand.native) |
| } |
| |
| @_transparent |
| public mutating func round(_ rule: FloatingPointRoundingRule) { |
| native.round(rule) |
| } |
| |
| @_transparent |
| public var nextUp: CGFloat { |
| return CGFloat(native.nextUp) |
| } |
| |
| @_transparent |
| public mutating func negate() { |
| native.negate() |
| } |
| |
| @_transparent |
| public static func +=(lhs: inout CGFloat, rhs: CGFloat) { |
| lhs.native += rhs.native |
| } |
| |
| @_transparent |
| public static func -=(lhs: inout CGFloat, rhs: CGFloat) { |
| lhs.native -= rhs.native |
| } |
| |
| @_transparent |
| public static func *=(lhs: inout CGFloat, rhs: CGFloat) { |
| lhs.native *= rhs.native |
| } |
| |
| @_transparent |
| public static func /=(lhs: inout CGFloat, rhs: CGFloat) { |
| lhs.native /= rhs.native |
| } |
| |
| @_transparent |
| public mutating func formTruncatingRemainder(dividingBy other: CGFloat) { |
| native.formTruncatingRemainder(dividingBy: other.native) |
| } |
| |
| @_transparent |
| public mutating func formRemainder(dividingBy other: CGFloat) { |
| native.formRemainder(dividingBy: other.native) |
| } |
| |
| @_transparent |
| public mutating func formSquareRoot( ) { |
| native.formSquareRoot( ) |
| } |
| |
| @_transparent |
| public mutating func addProduct(_ lhs: CGFloat, _ rhs: CGFloat) { |
| native.addProduct(lhs.native, rhs.native) |
| } |
| |
| @_transparent |
| public func isEqual(to other: CGFloat) -> Bool { |
| return self.native.isEqual(to: other.native) |
| } |
| |
| @_transparent |
| public func isLess(than other: CGFloat) -> Bool { |
| return self.native.isLess(than: other.native) |
| } |
| |
| @_transparent |
| public func isLessThanOrEqualTo(_ other: CGFloat) -> Bool { |
| return self.native.isLessThanOrEqualTo(other.native) |
| } |
| |
| @_transparent |
| public var isNormal: Bool { |
| return native.isNormal |
| } |
| |
| @_transparent |
| public var isFinite: Bool { |
| return native.isFinite |
| } |
| |
| @_transparent |
| public var isZero: Bool { |
| return native.isZero |
| } |
| |
| @_transparent |
| public var isSubnormal: Bool { |
| return native.isSubnormal |
| } |
| |
| @_transparent |
| public var isInfinite: Bool { |
| return native.isInfinite |
| } |
| |
| @_transparent |
| public var isNaN: Bool { |
| return native.isNaN |
| } |
| |
| @_transparent |
| public var isSignalingNaN: Bool { |
| return native.isSignalingNaN |
| } |
| |
| @available(*, unavailable, renamed: "isSignalingNaN") |
| public var isSignaling: Bool { |
| fatalError("unavailable") |
| } |
| |
| @_transparent |
| public var isCanonical: Bool { |
| return true |
| } |
| |
| @_transparent |
| public var floatingPointClass: FloatingPointClassification { |
| return native.floatingPointClass |
| } |
| |
| @_transparent |
| public var binade: CGFloat { |
| return CGFloat(native.binade) |
| } |
| |
| @_transparent |
| public var significandWidth: Int { |
| return native.significandWidth |
| } |
| |
| /// Create an instance initialized to `value`. |
| @_transparent |
| public init(floatLiteral value: NativeType) { |
| native = value |
| } |
| |
| /// Create an instance initialized to `value`. |
| @_transparent |
| public init(integerLiteral value: Int) { |
| native = NativeType(value) |
| } |
| } |
| |
| extension CGFloat { |
| @available(*, unavailable, renamed: "leastNormalMagnitude") |
| public static var min: CGFloat { |
| fatalError("unavailable") |
| } |
| |
| @available(*, unavailable, renamed: "greatestFiniteMagnitude") |
| public static var max: CGFloat { |
| fatalError("unavailable") |
| } |
| } |
| |
| @available(*, unavailable, renamed: "CGFloat.leastNormalMagnitude") |
| public var CGFLOAT_MIN: CGFloat { |
| fatalError("unavailable") |
| } |
| |
| @available(*, unavailable, renamed: "CGFloat.greatestFiniteMagnitude") |
| public var CGFLOAT_MAX: CGFloat { |
| fatalError("unavailable") |
| } |
| |
| extension CGFloat : CustomReflectable { |
| /// Returns a mirror that reflects `self`. |
| public var customMirror: Mirror { |
| return Mirror(reflecting: native) |
| } |
| } |
| |
| extension CGFloat : CustomStringConvertible { |
| /// A textual representation of `self`. |
| @_transparent |
| public var description: String { |
| return native.description |
| } |
| } |
| |
| extension CGFloat : Hashable { |
| /// The hash value. |
| /// |
| /// **Axiom:** `x == y` implies `x.hashValue == y.hashValue` |
| /// |
| /// - Note: the hash value is not guaranteed to be stable across |
| /// different invocations of the same program. Do not persist the |
| /// hash value across program runs. |
| @_transparent |
| public var hashValue: Int { |
| return native.hashValue |
| } |
| |
| /// Hashes the essential components of this value by feeding them into the |
| /// given hasher. |
| /// |
| /// - Parameter hasher: The hasher to use when combining the components |
| /// of this instance. |
| @inlinable @_transparent |
| public func hash(into hasher: inout Hasher) { |
| hasher.combine(native) |
| } |
| |
| @_alwaysEmitIntoClient @inlinable // Introduced in 5.1 |
| public func _rawHashValue(seed: Int) -> Int { |
| return native._rawHashValue(seed: seed) |
| } |
| } |
| |
| % for dst_ty in all_integer_types(word_bits): |
| |
| extension ${dst_ty.stdlib_name} { |
| @_transparent |
| public init(_ value: CGFloat) { |
| self = ${dst_ty.stdlib_name}(value.native) |
| } |
| } |
| |
| % end |
| |
| |
| extension Double { |
| @_transparent |
| public init(_ value: CGFloat) { |
| self = Double(value.native) |
| } |
| } |
| |
| extension Float { |
| @_transparent |
| public init(_ value: CGFloat) { |
| self = Float(value.native) |
| } |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Standard Operator Table |
| //===----------------------------------------------------------------------===// |
| |
| // TODO: These should not be necessary, since they're already provided by |
| // <T: FloatingPoint>, but in practice they are currently needed to |
| // disambiguate overloads. We should find a way to remove them, either by |
| // tweaking the overload resolution rules, or by removing the other |
| // definitions in the standard lib, or both. |
| |
| extension CGFloat { |
| @_transparent |
| public static func +(lhs: CGFloat, rhs: CGFloat) -> CGFloat { |
| var lhs = lhs |
| lhs += rhs |
| return lhs |
| } |
| |
| @_transparent |
| public static func -(lhs: CGFloat, rhs: CGFloat) -> CGFloat { |
| var lhs = lhs |
| lhs -= rhs |
| return lhs |
| } |
| |
| @_transparent |
| public static func *(lhs: CGFloat, rhs: CGFloat) -> CGFloat { |
| var lhs = lhs |
| lhs *= rhs |
| return lhs |
| } |
| |
| @_transparent |
| public static func /(lhs: CGFloat, rhs: CGFloat) -> CGFloat { |
| var lhs = lhs |
| lhs /= rhs |
| return lhs |
| } |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Strideable Conformance |
| //===----------------------------------------------------------------------===// |
| |
| extension CGFloat : Strideable { |
| /// Returns a stride `x` such that `self.advanced(by: x)` approximates |
| /// `other`. |
| /// |
| /// - Complexity: O(1). |
| @_transparent |
| public func distance(to other: CGFloat) -> CGFloat { |
| return CGFloat(other.native - self.native) |
| } |
| |
| /// Returns a `Self` `x` such that `self.distance(to: x)` approximates |
| /// `n`. |
| /// |
| /// - Complexity: O(1). |
| @_transparent |
| public func advanced(by amount: CGFloat) -> CGFloat { |
| return CGFloat(self.native + amount.native) |
| } |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Deprecated operators |
| //===----------------------------------------------------------------------===// |
| |
| @_transparent |
| @available(*, unavailable, message: "Use truncatingRemainder instead") |
| public func %(lhs: CGFloat, rhs: CGFloat) -> CGFloat { |
| fatalError("% is not available.") |
| } |
| |
| @_transparent |
| @available(*, unavailable, message: "Use formTruncatingRemainder instead") |
| public func %=(lhs: inout CGFloat, rhs: CGFloat) { |
| fatalError("%= is not available.") |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Real conformance |
| //===----------------------------------------------------------------------===// |
| |
| %from SwiftMathFunctions import * |
| |
| extension CGFloat: ElementaryFunctions { |
| % for func in ElementaryFunctions + RealFunctions: |
| |
| @_alwaysEmitIntoClient |
| public static func ${func.decl('CGFloat')} { |
| return CGFloat(NativeType.${func.swiftName}(${func.params("", ".native")})) |
| } |
| % end |
| |
| @_alwaysEmitIntoClient |
| public static func pow(_ x: CGFloat, _ y: CGFloat) -> CGFloat { |
| guard x >= 0 else { return .nan } |
| return CGFloat(NativeType.pow(x.native, y.native)) |
| } |
| |
| @_alwaysEmitIntoClient |
| public static func pow(_ x: CGFloat, _ n: Int) -> CGFloat { |
| // TODO: this implementation isn't quite right for n so large that |
| // the conversion to `CGFloat` rounds. We could also consider using |
| // a multiply-chain implementation for small `n`; this would be faster |
| // for static `n`, but less accurate on platforms with a good `pow` |
| // implementation. |
| return CGFloat(NativeType.pow(x.native, n)) |
| } |
| |
| @_alwaysEmitIntoClient |
| public static func root(_ x: CGFloat, _ n: Int) -> CGFloat { |
| guard x >= 0 || n % 2 != 0 else { return .nan } |
| // TODO: this implementation isn't quite right for n so large that |
| // the conversion to `CGFloat` rounds. |
| return CGFloat(NativeType.root(x.native, n)) |
| } |
| |
| @_alwaysEmitIntoClient |
| public static func atan2(_ y: CGFloat, _ x: CGFloat) -> CGFloat { |
| return CGFloat(NativeType.atan2(y.native, x.native)) |
| } |
| |
| @_alwaysEmitIntoClient |
| public static func logGamma(_ x: CGFloat) -> CGFloat { |
| return CGFloat(NativeType.logGamma(x.native)) |
| } |
| |
| @_alwaysEmitIntoClient |
| public static func signGamma(_ x: CGFloat) -> FloatingPointSign { |
| if x >= 0 { return .plus } |
| let trunc = x.rounded(.towardZero) |
| if x == trunc { return .plus } |
| let halfTrunc = trunc/2 |
| if halfTrunc == halfTrunc.rounded(.towardZero) { return .minus } |
| return .plus |
| } |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // tgmath |
| //===----------------------------------------------------------------------===// |
| |
| %{ |
| UnaryFunctions = [ |
| 'acos', 'asin', 'atan', 'cos', 'sin', 'tan', |
| 'acosh', 'asinh', 'atanh', 'cosh', 'sinh', 'tanh', |
| 'exp', 'exp2', 'expm1', |
| 'log', 'log10', 'log1p', 'log2', 'logb', |
| 'cbrt', 'erf', 'erfc', 'tgamma', |
| 'nearbyint', 'rint' |
| ] |
| |
| BinaryFunctions = [ |
| 'atan2', 'hypot', 'pow', 'copysign', 'nextafter', 'fdim', 'fmax', 'fmin' |
| ] |
| }% |
| |
| %for ufunc in UnaryFunctions: |
| % if ufunc in ['rint','nearbyint']: |
| @available(swift, deprecated: 5.1, message: "Swift does not model dynamic rounding modes, use x.rounded(.toNearestOrEven) instead.") |
| @_transparent |
| public func ${ufunc}(_ x: CGFloat) -> CGFloat { |
| return x.rounded(.toNearestOrEven) |
| } |
| % else: |
| @_transparent |
| public func ${ufunc}(_ x: CGFloat) -> CGFloat { |
| return CGFloat(${ufunc}(x.native)) |
| } |
| % end |
| |
| %end |
| |
| %for bfunc in BinaryFunctions: |
| @_transparent |
| public func ${bfunc}(_ lhs: CGFloat, _ rhs: CGFloat) -> CGFloat { |
| return CGFloat(${bfunc}(lhs.native, rhs.native)) |
| } |
| |
| %end |
| |
| @_transparent |
| @available(*, unavailable, message: "use the floatingPointClass property.") |
| public func fpclassify(_ x: CGFloat) -> Int { |
| fatalError("unavailable") |
| } |
| |
| @available(*, unavailable, message: "use the isNormal property.") |
| public func isnormal(_ value: CGFloat) -> Bool { return value.isNormal } |
| |
| @available(*, unavailable, message: "use the isFinite property.") |
| public func isfinite(_ value: CGFloat) -> Bool { return value.isFinite } |
| |
| @available(*, unavailable, message: "use the isInfinite property.") |
| public func isinf(_ value: CGFloat) -> Bool { return value.isInfinite } |
| |
| @available(*, unavailable, message: "use the isNaN property.") |
| public func isnan(_ value: CGFloat) -> Bool { return value.isNaN } |
| |
| @available(*, unavailable, message: "use the sign property.") |
| public func signbit(_ value: CGFloat) -> Int { return value.sign.rawValue } |
| |
| @available(swift, deprecated: 4.2, renamed: "scalbn") |
| @_transparent |
| public func ldexp(_ x: CGFloat, _ n: Int) -> CGFloat { |
| return CGFloat(ldexp(x.native, n)) |
| } |
| |
| @available(swift, deprecated: 4.2, message: "use the exponent property.") |
| @_transparent |
| public func ilogb(_ x: CGFloat) -> Int { |
| return Int(x.exponent) |
| } |
| |
| @_transparent |
| public func lgamma(_ x: CGFloat) -> (CGFloat, Int) { |
| let (value, sign) = lgamma(x.native) |
| return (CGFloat(value), sign) |
| } |
| |
| @_transparent |
| public func remquo(_ x: CGFloat, _ y: CGFloat) -> (CGFloat, Int) { |
| let (rem, quo) = remquo(x.native, y.native) |
| return (CGFloat(rem), quo) |
| } |
| |
| @available(swift, deprecated: 4.2, message: |
| "use CGFloat(nan: CGFloat.RawSignificand) instead.") |
| @_transparent |
| public func nan(_ tag: String) -> CGFloat { |
| return CGFloat(nan(tag) as CGFloat.NativeType) |
| } |
| |
| @_transparent |
| public func j0(_ x: CGFloat) -> CGFloat { |
| return CGFloat(j0(Double(x.native))) |
| } |
| |
| @_transparent |
| public func j1(_ x: CGFloat) -> CGFloat { |
| return CGFloat(j1(Double(x.native))) |
| } |
| |
| @_transparent |
| public func jn(_ n: Int, _ x: CGFloat) -> CGFloat { |
| return CGFloat(jn(n, Double(x.native))) |
| } |
| |
| @_transparent |
| public func y0(_ x: CGFloat) -> CGFloat { |
| return CGFloat(y0(Double(x.native))) |
| } |
| |
| @_transparent |
| public func y1(_ x: CGFloat) -> CGFloat { |
| return CGFloat(y1(Double(x.native))) |
| } |
| |
| @_transparent |
| public func yn(_ n: Int, _ x: CGFloat) -> CGFloat { |
| return CGFloat(yn(n, Double(x.native))) |
| } |
| |
| extension CGFloat : _CVarArgPassedAsDouble, _CVarArgAligned { |
| /// Transform `self` into a series of machine words that can be |
| /// appropriately interpreted by C varargs |
| @_transparent |
| public var _cVarArgEncoding: [Int] { |
| return native._cVarArgEncoding |
| } |
| |
| /// Return the required alignment in bytes of |
| /// the value returned by `_cVarArgEncoding`. |
| @_transparent |
| public var _cVarArgAlignment: Int { |
| return native._cVarArgAlignment |
| } |
| } |
| |
| extension CGFloat : Codable { |
| @_transparent |
| public init(from decoder: Decoder) throws { |
| let container = try decoder.singleValueContainer() |
| do { |
| self.native = try container.decode(NativeType.self) |
| } catch DecodingError.typeMismatch(let type, let context) { |
| // We may have encoded as a different type on a different platform. A |
| // strict fixed-format decoder may disallow a conversion, so let's try the |
| // other type. |
| do { |
| if NativeType.self == Float.self { |
| self.native = NativeType(try container.decode(Double.self)) |
| } else { |
| self.native = NativeType(try container.decode(Float.self)) |
| } |
| } catch { |
| // Failed to decode as the other type, too. This is neither a Float nor |
| // a Double. Throw the old error; we don't want to clobber the original |
| // info. |
| throw DecodingError.typeMismatch(type, context) |
| } |
| } |
| } |
| |
| @_transparent |
| public func encode(to encoder: Encoder) throws { |
| var container = encoder.singleValueContainer() |
| try container.encode(self.native) |
| } |
| } |