Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SE-0246: Protocols and static functions #23824

Merged
merged 1 commit into from Apr 17, 2019
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -509,6 +509,58 @@ public func %=(lhs: inout CGFloat, rhs: CGFloat) {
fatalError("%= is not available.")
}

//===----------------------------------------------------------------------===//
// Real conformance
//===----------------------------------------------------------------------===//
%from SwiftMathFunctions import *

extension CGFloat: Real {
% 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))
}

#if !os(Windows)
@_alwaysEmitIntoClient
public static func logGamma(_ x: CGFloat) -> CGFloat {
return CGFloat(NativeType.logGamma(x.native))
}
#endif
}

//===----------------------------------------------------------------------===//
// tgmath
//===----------------------------------------------------------------------===//
@@ -2,7 +2,7 @@
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// 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
@@ -14,7 +14,7 @@ import SwiftShims

// Generic functions implementable directly on FloatingPoint.
@_transparent
@available(swift, deprecated: 4.2, renamed: "abs")
@available(swift, deprecated: 4.2, obsoleted: 5.1, renamed: "abs")
public func fabs<T: FloatingPoint>(_ x: T) -> T {
return x.magnitude
}
@@ -112,7 +112,7 @@ public func isnan<T: FloatingPoint>(_ value: T) -> Bool { fatalError() }
@available(*, unavailable, message: "use the sign property.")
public func signbit<T: FloatingPoint>(_ value: T) -> Int { fatalError() }

@available(swift, deprecated: 4.2, message: "use the exponent property.")
@available(swift, deprecated: 4.2, obsoleted: 5.1, message: "use the exponent property.")
public func ilogb<T: BinaryFloatingPoint>(_ x: T) -> Int {
return Int(x.exponent)
}
@@ -155,44 +155,15 @@ UnaryFunctions = [
'acos', 'asin', 'atan', 'tan',
'acosh', 'asinh', 'atanh', 'cosh', 'sinh', 'tanh',
'expm1',
'log1p', 'logb',
'cbrt', 'erf', 'erfc', 'tgamma',
'log1p',
'erf', 'erfc',
]

# These functions have a corresponding LLVM intrinsic
# We call this intrinsic via the Builtin method so keep this list in
# sync with core/BuiltinMath.swift.gyb
UnaryIntrinsicFunctions = [
'cos', 'sin',
'exp', 'exp2',
'log', 'log10', 'log2',
'nearbyint', 'rint',
'cos', 'sin', 'exp', 'exp2', 'log', 'log10', 'log2', 'nearbyint', 'rint'
]

# (T, T) -> T
BinaryFunctions = [
'atan2', 'hypot', 'pow',
'copysign', 'nextafter', 'fdim', 'fmax', 'fmin'
]

# These functions have special implementations.
OtherFunctions = [
'scalbn', 'lgamma', 'remquo', 'nan', 'jn', 'yn'
]

# These functions are imported correctly as-is.
OkayFunctions = ['j0', 'j1', 'y0', 'y1']

# These functions are not supported for various reasons.
UnhandledFunctions = [
'math_errhandling', 'scalbln',
'lrint', 'lround', 'llrint', 'llround', 'nexttoward',
'isgreater', 'isgreaterequal', 'isless', 'islessequal',
'islessgreater', 'isunordered', '__exp10',
'__sincos', '__cospi', '__sinpi', '__tanpi', '__sincospi'
]


def AllFloatTypes():
for bits in allFloatBits:
yield floatName(bits), cFloatName(bits), cFuncSuffix(bits)
@@ -226,60 +197,117 @@ def TypedBinaryFunctions():
% end
@_transparent
public func ${ufunc}(_ x: ${T}) -> ${T} {
return ${T}(${ufunc}${f}(${CT}(x)))
return ${T}.${ufunc}(x)
}
% if T == 'Float80':
#endif
% end

% end
@_transparent
public func cbrt(_ x: Float) -> Float {
return Float.root(x, 3)
}

@available(swift, deprecated: 5.1, message: "Use `x.exponent` or `floor(log2(x))`.")
@_transparent
public func logb(_ x: Float) -> Float {
return Float.log2(x).rounded(.down)
}

@_transparent
public func tgamma(_ x: Float) -> Float {
return Float.gamma(x)
}

#if (arch(i386) || arch(x86_64)) && !os(Windows)
@_transparent
public func cbrt(_ x: Float80) -> Float80 {
return Float80.root(x, 3)
}

@available(swift, deprecated: 5.1, message: "Use `x.exponent` or `floor(log2(x))`.")
@_transparent
public func logb(_ x: Float80) -> Float80 {
return Float80.log2(x).rounded(.down)
}

@_transparent
public func tgamma(_ x: Float80) -> Float80 {
return Float80.gamma(x)
}
#endif

#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
// Unary intrinsic functions
// Note these have a corresponding LLVM intrinsic
% for T, ufunc in TypedUnaryIntrinsicFunctions():
% if T == 'Float80':
#if (arch(i386) || arch(x86_64)) && !os(Windows)
% end
% if ufunc[-3:] != 'int':
@_transparent
public func ${ufunc}(_ x: ${T}) -> ${T} {
return _${ufunc}(x)
return ${T}.${ufunc}(x)
}
% if T == 'Float80':
#endif
% end

% end
#else
// FIXME: As of now, we cannot declare 64-bit (Double/CDouble) overlays here.
// Since CoreFoundation also exports libc functions, they will conflict with
// Swift overlays when building Foundation. For now, just like normal
// UnaryFunctions, we define overlays only for OverlayFloatTypes.
% for ufunc in UnaryIntrinsicFunctions:
% for T, CT, f in OverlayFloatTypes():
% if T == 'Float80':
#if (arch(i386) || arch(x86_64)) && !os(Windows)
% end
% else:
@available(swift, deprecated: 5.1, message: "Swift does not model dynamic rounding modes, use x.rounded(.toNearestOrEven) instead.")
@_transparent
public func ${ufunc}(_ x: ${T}) -> ${T} {
return ${T}(${ufunc}${f}(${CT}(x)))
return x.rounded(.toNearestOrEven)
}
% if T == 'Float80':
% end
% if T == 'Float80':
#endif
% end
% end

% end
#endif

// Binary functions
% for T, CT, f, bfunc in TypedBinaryFunctions():
% for T, CT, f in OverlayFloatTypes():
% if T == 'Float80':
#if (arch(i386) || arch(x86_64)) && !os(Windows)
% end
@_transparent
public func ${bfunc}(_ lhs: ${T}, _ rhs: ${T}) -> ${T} {
return ${T}(${bfunc}${f}(${CT}(lhs), ${CT}(rhs)))
public func atan2(_ y: ${T}, _ x: ${T}) -> ${T} {
return ${T}.atan2(y: y, x: x)
}

@_transparent
public func hypot(_ x: ${T}, _ y: ${T}) -> ${T} {
return ${T}.hypot(x, y)
}

@_transparent
public func pow(_ x: ${T}, _ y: ${T}) -> ${T} {
return ${T}.pow(x, y)
}

@_transparent
public func copysign(_ x: ${T}, _ y: ${T}) -> ${T} {
return ${T}(signOf: y, magnitudeOf: x)
}

@_transparent
public func fdim(_ x: ${T}, _ y: ${T}) -> ${T} {
return ${T}(fdim${f}(${CT}(x), ${CT}(y)))
}

@available(swift, deprecated: 5.1, message: "Use the .nextUp and .nextDown properties.")
@_transparent
public func nextafter(_ x: ${T}, _ y: ${T}) -> ${T} {
return y > x ? x.nextUp : (y < x ? x.nextDown : y)
}

@available(swift, deprecated: 5.1, message: "Use ${T}.minimum( ) or Swift.min( )")
@_transparent
public func fmin(_ x: ${T}, _ y: ${T}) -> ${T} {
return .minimum(x, y)
}

@available(swift, deprecated: 5.1, message: "Use ${T}.maximum( ) or Swift.max( )")
@_transparent
public func fmax(_ x: ${T}, _ y: ${T}) -> ${T} {
return .maximum(x, y)
}
% if T == 'Float80':
#endif
@@ -297,9 +325,7 @@ public func ${bfunc}(_ lhs: ${T}, _ rhs: ${T}) -> ${T} {
% end
@_transparent
public func lgamma(_ x: ${T}) -> (${T}, Int) {
var sign = Int32(0)
let value = lgamma${f}_r(${CT}(x), &sign)
return (${T}(value), Int(sign))
return (${T}.logGamma(x), ${T}.signGamma(x) == .plus ? 1 : -1)
}
#endif

@@ -326,8 +352,8 @@ public func remquo(_ x: ${T}, _ y: ${T}) -> (${T}, Int) {
% if T == 'Float80':
#if (arch(i386) || arch(x86_64)) && !os(Windows)
% end
@available(swift, deprecated: 4.2, message:
"use ${T}(nan: ${T}.RawSignificand) instead.")
@available(swift, deprecated: 4.2, obsoleted: 5.1, message:
"use ${T}(nan: ${T}.RawSignificand).")
@_transparent
public func nan(_ tag: String) -> ${T} {
return ${T}(nan${f}(tag))
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.