blob: f76665a567b7d9fba07d986fbebfa4ba6a12f4cd [file] [log] [blame]
//===--- 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)
}
}