// This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2016, 2018 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // @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) || arch(s390x) || arch(powerpc64) || arch(powerpc64le) /// 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 #else #error("This architecture isn't known. Add it to the 32-bit or 64-bit line.") #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 } /// Creates a new value, rounded to the closest possible representation. /// /// If two representable values are equally close, the result is the value /// with more trailing zeros in its significand bit pattern. /// /// - Parameter value: The integer to convert to a floating-point value. public init(_ value: UInt8) { self.native = NativeType(value) } /// Creates a new value, rounded to the closest possible representation. /// /// If two representable values are equally close, the result is the value /// with more trailing zeros in its significand bit pattern. /// /// - Parameter value: The integer to convert to a floating-point value. public init(_ value: Int8) { self.native = NativeType(value) } /// Creates a new value, rounded to the closest possible representation. /// /// If two representable values are equally close, the result is the value /// with more trailing zeros in its significand bit pattern. /// /// - Parameter value: The integer to convert to a floating-point value. public init(_ value: UInt16) { self.native = NativeType(value) } /// Creates a new value, rounded to the closest possible representation. /// /// If two representable values are equally close, the result is the value /// with more trailing zeros in its significand bit pattern. /// /// - Parameter value: The integer to convert to a floating-point value. public init(_ value: Int16) { self.native = NativeType(value) } /// Creates a new value, rounded to the closest possible representation. /// /// If two representable values are equally close, the result is the value /// with more trailing zeros in its significand bit pattern. /// /// - Parameter value: The integer to convert to a floating-point value. public init(_ value: UInt32) { self.native = NativeType(value) } /// Creates a new value, rounded to the closest possible representation. /// /// If two representable values are equally close, the result is the value /// with more trailing zeros in its significand bit pattern. /// /// - Parameter value: The integer to convert to a floating-point value. public init(_ value: Int32) { self.native = NativeType(value) } /// Creates a new value, rounded to the closest possible representation. /// /// If two representable values are equally close, the result is the value /// with more trailing zeros in its significand bit pattern. /// /// - Parameter value: The integer to convert to a floating-point value. public init(_ value: UInt64) { self.native = NativeType(value) } /// Creates a new value, rounded to the closest possible representation. /// /// If two representable values are equally close, the result is the value /// with more trailing zeros in its significand bit pattern. /// /// - Parameter value: The integer to convert to a floating-point value. public init(_ value: Int64) { self.native = NativeType(value) } /// Creates a new value, rounded to the closest possible representation. /// /// If two representable values are equally close, the result is the value /// with more trailing zeros in its significand bit pattern. /// /// - Parameter value: The integer to convert to a floating-point value. public init(_ value: UInt) { self.native = NativeType(value) } /// Creates a new value, rounded to the closest possible representation. /// /// If two representable values are equally close, the result is the value /// with more trailing zeros in its significand bit pattern. /// /// - Parameter value: The integer to convert to a floating-point value. public init(_ value: Int) { self.native = NativeType(value) } /// The native value. public var native: NativeType } extension CGFloat : SignedNumeric { // FIXME(integers): implement public init?<T : BinaryInteger>(exactly source: T) { fatalError() } @_transparent public var magnitude: CGFloat { return CGFloat(Swift.abs(native)) } } 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) { #if arch(i386) || arch(arm) native = NativeType(bitPattern: UInt32(bitPattern)) #elseif arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le) native = NativeType(bitPattern: UInt64(bitPattern)) #else #error("This architecture isn't known. Add it to the 32-bit or 64-bit line.") #endif } @_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, message: "Please use the `abs(_:)` free function") public static func abs(_ x: CGFloat) -> 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`. 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 } @_transparent public func hash(into hasher: inout Hasher) { hasher.combine(native) } @_transparent public func _rawHashValue(seed: Int) -> Int { return native._rawHashValue(seed: seed) } } extension UInt8 { @_transparent public init(_ value: CGFloat) { self = UInt8(value.native) } } extension Int8 { @_transparent public init(_ value: CGFloat) { self = Int8(value.native) } } extension UInt16 { @_transparent public init(_ value: CGFloat) { self = UInt16(value.native) } } extension Int16 { @_transparent public init(_ value: CGFloat) { self = Int16(value.native) } } extension UInt32 { @_transparent public init(_ value: CGFloat) { self = UInt32(value.native) } } extension Int32 { @_transparent public init(_ value: CGFloat) { self = Int32(value.native) } } extension UInt64 { @_transparent public init(_ value: CGFloat) { self = UInt64(value.native) } } extension Int64 { @_transparent public init(_ value: CGFloat) { self = Int64(value.native) } } extension UInt { @_transparent public init(_ value: CGFloat) { self = UInt(value.native) } } extension Int { @_transparent public init(_ value: CGFloat) { self = Int(value.native) } } 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 //===----------------------------------------------------------------------===// @available(*, unavailable, message: "Use truncatingRemainder instead") public func %(lhs: CGFloat, rhs: CGFloat) -> CGFloat { fatalError("% is not available.") } @available(*, unavailable, message: "Use formTruncatingRemainder instead") public func %=(lhs: inout CGFloat, rhs: CGFloat) { fatalError("%= is not available.") } //===----------------------------------------------------------------------===// // tgmath //===----------------------------------------------------------------------===// @_transparent public func acos(_ x: CGFloat) -> CGFloat { return CGFloat(acos(x.native)) } @_transparent public func cos(_ x: CGFloat) -> CGFloat { return CGFloat(cos(x.native)) } @_transparent public func sin(_ x: CGFloat) -> CGFloat { return CGFloat(sin(x.native)) } @_transparent public func asin(_ x: CGFloat) -> CGFloat { return CGFloat(asin(x.native)) } @_transparent public func atan(_ x: CGFloat) -> CGFloat { return CGFloat(atan(x.native)) } @_transparent public func tan(_ x: CGFloat) -> CGFloat { return CGFloat(tan(x.native)) } @_transparent public func acosh(_ x: CGFloat) -> CGFloat { return CGFloat(acosh(x.native)) } @_transparent public func asinh(_ x: CGFloat) -> CGFloat { return CGFloat(asinh(x.native)) } @_transparent public func atanh(_ x: CGFloat) -> CGFloat { return CGFloat(atanh(x.native)) } @_transparent public func cosh(_ x: CGFloat) -> CGFloat { return CGFloat(cosh(x.native)) } @_transparent public func sinh(_ x: CGFloat) -> CGFloat { return CGFloat(sinh(x.native)) } @_transparent public func tanh(_ x: CGFloat) -> CGFloat { return CGFloat(tanh(x.native)) } @_transparent public func exp(_ x: CGFloat) -> CGFloat { return CGFloat(exp(x.native)) } @_transparent public func exp2(_ x: CGFloat) -> CGFloat { return CGFloat(exp2(x.native)) } @_transparent public func expm1(_ x: CGFloat) -> CGFloat { return CGFloat(expm1(x.native)) } @_transparent public func log(_ x: CGFloat) -> CGFloat { return CGFloat(log(x.native)) } @_transparent public func log10(_ x: CGFloat) -> CGFloat { return CGFloat(log10(x.native)) } @_transparent public func log2(_ x: CGFloat) -> CGFloat { return CGFloat(log2(x.native)) } @_transparent public func log1p(_ x: CGFloat) -> CGFloat { return CGFloat(log1p(x.native)) } @_transparent public func logb(_ x: CGFloat) -> CGFloat { return CGFloat(logb(x.native)) } @_transparent public func cbrt(_ x: CGFloat) -> CGFloat { return CGFloat(cbrt(x.native)) } @_transparent public func erf(_ x: CGFloat) -> CGFloat { return CGFloat(erf(x.native)) } @_transparent public func erfc(_ x: CGFloat) -> CGFloat { return CGFloat(erfc(x.native)) } @_transparent public func tgamma(_ x: CGFloat) -> CGFloat { return CGFloat(tgamma(x.native)) } @_transparent public func nearbyint(_ x: CGFloat) -> CGFloat { return CGFloat(x.native.rounded(.toNearestOrEven)) } @_transparent public func rint(_ x: CGFloat) -> CGFloat { return CGFloat(x.native.rounded(.toNearestOrEven)) } @_transparent public func atan2(_ lhs: CGFloat, _ rhs: CGFloat) -> CGFloat { return CGFloat(atan2(lhs.native, rhs.native)) } @_transparent public func hypot(_ lhs: CGFloat, _ rhs: CGFloat) -> CGFloat { return CGFloat(hypot(lhs.native, rhs.native)) } @_transparent public func pow(_ lhs: CGFloat, _ rhs: CGFloat) -> CGFloat { return CGFloat(pow(lhs.native, rhs.native)) } @_transparent public func copysign(_ lhs: CGFloat, _ rhs: CGFloat) -> CGFloat { return CGFloat(copysign(lhs.native, rhs.native)) } @_transparent public func nextafter(_ lhs: CGFloat, _ rhs: CGFloat) -> CGFloat { return CGFloat(nextafter(lhs.native, rhs.native)) } @_transparent public func fdim(_ lhs: CGFloat, _ rhs: CGFloat) -> CGFloat { return CGFloat(fdim(lhs.native, rhs.native)) } @_transparent public func fmax(_ lhs: CGFloat, _ rhs: CGFloat) -> CGFloat { return CGFloat(fmax(lhs.native, rhs.native)) } @_transparent public func fmin(_ lhs: CGFloat, _ rhs: CGFloat) -> CGFloat { return CGFloat(fmin(lhs.native, rhs.native)) } @_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 } @_transparent public func modf(_ x: CGFloat) -> (CGFloat, CGFloat) { let (ipart, fpart) = modf(x.native) return (CGFloat(ipart), CGFloat(fpart)) } @_transparent public func ldexp(_ x: CGFloat, _ n: Int) -> CGFloat { return CGFloat(scalbn(x.native, n)) } @_transparent public func frexp(_ x: CGFloat) -> (CGFloat, Int) { let (frac, exp) = frexp(x.native) return (CGFloat(frac), exp) } @_transparent public func ilogb(_ x: CGFloat) -> Int { return x.native.exponent } @_transparent public func scalbn(_ x: CGFloat, _ n: Int) -> CGFloat { return CGFloat(scalbn(x.native, n)) } #if !os(Windows) @_transparent public func lgamma(_ x: CGFloat) -> (CGFloat, Int) { let (value, sign) = lgamma(x.native) return (CGFloat(value), sign) } #endif @_transparent public func remquo(_ x: CGFloat, _ y: CGFloat) -> (CGFloat, Int) { let (rem, quo) = remquo(x.native, y.native) return (CGFloat(rem), quo) } @_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) } }