Files
swift-mirror/stdlib/public/Darwin/CoreGraphics/CGFloat.swift.gyb
Stephen Canon fa778ec368 Deprecate nearbyint and rint on CGFloat (#24784)
These functions have never actually been supported in Swift, because Swift does not model the dynamic floating point environment. They may have worked occasionally in the past, but that was only accidental. Deprecate them with an explanatory message.
2019-05-15 11:04:03 -04:00

744 lines
19 KiB
Swift

//===--- 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
@_fixed_layout
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) && (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 {
@_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)
}
@inlinable @_transparent
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: y.native, x: 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)
}
}