mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Allow 'static' (or, in classes, final 'class') operators to be declared within types and extensions thereof. Within protocols, require operators to be marked 'static'. Use a warning with a Fix-It to stage this in, so we don't break the world's code. Protocol conformance checking already seems to work, so add some tests for that. Update a pile of tests and the standard library to include the required 'static' keywords. There is an amusing name-mangling change here. Global operators were getting marked as 'static' (for silly reasons), so their mangled names had the 'Z' modifier for static methods, even though this doesn't make sense. Now, operators within types and extensions need to be 'static' as written.
164 lines
5.3 KiB
Swift
164 lines
5.3 KiB
Swift
//===--- IntegerArithmetic.swift.gyb --------------------------*- swift -*-===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2016 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
%# Ignore the following admonition; it applies to the resulting .swift file only
|
|
|
|
// Automatically Generated From IntegerArithmetic.swift.gyb. Do Not Edit
|
|
// Directly!
|
|
|
|
%{
|
|
integerBinaryOps = [
|
|
('add', '+', 'Adds', 'the result'),
|
|
('subtract', '-', 'Subtracts', 'the result'),
|
|
('multiply', '*', 'Multiplies', 'the result'),
|
|
('divide', '/', 'Divides', 'the result'),
|
|
('remainder', '%', 'Divides', 'the remainder')
|
|
]
|
|
}%
|
|
|
|
/// This protocol is an implementation detail of `IntegerArithmetic`; do
|
|
/// not use it directly.
|
|
///
|
|
/// Its requirements are inherited by `IntegerArithmetic` and thus must
|
|
/// be satisfied by types conforming to that protocol.
|
|
@_show_in_interface
|
|
public protocol _IntegerArithmetic {
|
|
% for name, _, Action, result in integerBinaryOps:
|
|
/// ${Action} `lhs` and `rhs`, returning ${result} and a `Bool` that is
|
|
/// `true` iff the operation caused an arithmetic overflow.
|
|
static func ${name}WithOverflow(_ lhs: Self, _ rhs: Self) -> (Self, overflow: Bool)
|
|
% end
|
|
}
|
|
|
|
/// The common requirements for types that support integer arithmetic.
|
|
public protocol IntegerArithmetic : _IntegerArithmetic, Comparable {
|
|
// Checked arithmetic functions. Specific implementations in
|
|
// FixedPoint.swift.gyb support static checking for integer types.
|
|
% for name, op, Action, result in integerBinaryOps:
|
|
/// ${Action} `lhs` and `rhs`, returning ${result} and trapping in case of
|
|
/// arithmetic overflow (except in -Ounchecked builds).
|
|
static func ${op} (lhs: Self, rhs: Self) -> Self
|
|
% end
|
|
|
|
/// Explicitly convert to `IntMax`, trapping on overflow (except in
|
|
/// -Ounchecked builds).
|
|
func toIntMax() -> IntMax
|
|
}
|
|
|
|
% for name, op, Action, result in integerBinaryOps:
|
|
/// ${Action} `lhs` and `rhs`, returning ${result} and trapping in case of
|
|
/// arithmetic overflow (except in -Ounchecked builds).
|
|
@_transparent
|
|
public func ${op} <T : _IntegerArithmetic>(lhs: T, rhs: T) -> T {
|
|
return _overflowChecked(T.${name}WithOverflow(lhs, rhs))
|
|
}
|
|
|
|
% if (op != '/') and (op != '%'):
|
|
/// ${Action} `lhs` and `rhs`, silently discarding any overflow.
|
|
@_transparent
|
|
public func &${op} <T : _IntegerArithmetic>(lhs: T, rhs: T) -> T {
|
|
return T.${name}WithOverflow(lhs, rhs).0
|
|
}
|
|
% end
|
|
|
|
/// ${Action} `lhs` and `rhs` and stores ${result} in `lhs`, trapping in
|
|
/// case of arithmetic overflow (except in -Ounchecked builds).
|
|
@_transparent
|
|
public func ${op}= <T : _IntegerArithmetic>(lhs: inout T, rhs: T) {
|
|
lhs = lhs ${op} rhs
|
|
}
|
|
% end
|
|
|
|
//===--- SignedNumber -----------------------------------------------------===//
|
|
// A numeric type that supports abs(x), +x and -x
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// SignedNumber itself contains only operator requirements having
|
|
// default implementations on the base protocol.
|
|
/// Instances of conforming types can be subtracted, arithmetically
|
|
/// negated, and initialized from `0`.
|
|
///
|
|
/// Axioms:
|
|
///
|
|
/// - `x - 0 == x`
|
|
/// - `-x == 0 - x`
|
|
/// - `-(-x) == x`
|
|
public protocol SignedNumber : Comparable, ExpressibleByIntegerLiteral {
|
|
/// Returns the result of negating `x`.
|
|
static prefix func - (x: Self) -> Self
|
|
|
|
/// Returns the difference between `lhs` and `rhs`.
|
|
static func - (lhs: Self, rhs: Self) -> Self
|
|
|
|
// Do not use this operator directly; call abs(x) instead
|
|
static func ~> (_:Self,_:(_Abs, ())) -> Self
|
|
}
|
|
|
|
// Unary negation in terms of subtraction. This is a default
|
|
// implementation; models of SignedNumber can provide their own
|
|
// implementations.
|
|
@_transparent
|
|
public prefix func - <T : SignedNumber>(x: T) -> T {
|
|
return 0 - x
|
|
}
|
|
|
|
// Unary +
|
|
@_transparent
|
|
public prefix func + <T : SignedNumber>(x: T) -> T {
|
|
return x
|
|
}
|
|
|
|
//===--- abs(x) -----------------------------------------------------------===//
|
|
public struct _Abs {}
|
|
|
|
@_versioned
|
|
internal func _abs<Args>(_ args: Args) -> (_Abs, Args) {
|
|
return (_Abs(), args)
|
|
}
|
|
|
|
// Do not use this operator directly; call abs(x) instead
|
|
@_transparent
|
|
public func ~> <T : SignedNumber>(x:T,_:(_Abs, ())) -> T {
|
|
return x < 0 ? -x : x
|
|
}
|
|
|
|
// FIXME: should this be folded into SignedNumber?
|
|
/// A type that supports an "absolute value" function.
|
|
public protocol AbsoluteValuable : SignedNumber {
|
|
/// Returns the absolute value of `x`.
|
|
static func abs(_ x: Self) -> Self
|
|
}
|
|
|
|
// Do not use this operator directly; call abs(x) instead
|
|
@_transparent
|
|
public func ~> <T : AbsoluteValuable>(x:T,_:(_Abs, ())) -> T {
|
|
return T.abs(x)
|
|
}
|
|
|
|
/// Returns the absolute value of `x`.
|
|
///
|
|
/// Concrete instances of `SignedNumber` can specialize this
|
|
/// function by conforming to `AbsoluteValuable`.
|
|
@_transparent
|
|
public func abs<T : SignedNumber>(_ x: T) -> T {
|
|
return x~>_abs()
|
|
}
|
|
|
|
@available(*, unavailable, renamed: "IntegerArithmetic")
|
|
public typealias IntegerArithmeticType = IntegerArithmetic
|
|
|
|
@available(*, unavailable, renamed: "SignedNumber")
|
|
public typealias SignedNumberType = SignedNumber
|
|
|
|
// ${'Local Variables'}:
|
|
// eval: (read-only-mode 1)
|
|
// End:
|