Files
swift-mirror/stdlib/core/FixedPoint.swift.gyb
Dmitri Hrybenko de9a0c8ff0 stdlib/printing: remove ReplPrintable protocol
It is replaced by debugPrint() family of functions, that are called by REPL.

There is a regression in printing types that don't conform to Printable, this
is tracked by rdar://16898708


Swift SVN r18006
2014-05-13 16:22:56 +00:00

414 lines
11 KiB
Swift

%# -*- mode: swift -*-
%# Ignore the following admonition; it applies to the resulting .swift file only
//// Automatically Generated From FixedPoint.gyb. Do Not Edit Directly!
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 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
//
//===----------------------------------------------------------------------===//
%{
#
# Utility code for later in this template
#
def hexify(n):
"""Return a legible hex representation of n, using '_' separators """
z = '%X' % n
l = len(z)
r = []
while z:
r.insert(0, z[-4:])
z = z[:-4]
return '0x' + '_'.join(r)
# Bit counts for all int types
allNames = [8, 16, 32, 64, 'Int']
# Number of bits in the biggest int type
maxBits = 64
# Number of bits in the Builtin.Word type
wordBits = int(CMAKE_SIZEOF_VOID_P) * 8
# Number of bits in integer literals.
builtinIntLiteralBits = 2048
# FIXME: checked and unchecked conversions of Word types
CastFromWord = 'zextOrBitCast_Word_Int64' if wordBits==64 else 'truncOrBitCast_Word_Int32'
CastToWord = 'truncOrBitCast_Int64_Word' if wordBits==64 else 'zextOrBitCast_Int32_Word'
def maskBits(n):
"""Return an n-bit mask in hex"""
return hexify((1 << n) - 1)
def allInts():
for name in allNames:
for signed in False, True:
yield str(name), int(wordBits if name=='Int' else name), signed
def baseIntName(name):
return 'Int' if name == 'Int' else 'Int' + str(name)
def builtinIntName(name):
return 'Word' if name == 'Int' else 'Int' + str(name)
def intName(name, signed):
return ('' if signed else 'U') + baseIntName(name)
def otherIntName(name, signed):
return ('U' if signed else '') + baseIntName(name)
}%
typealias IntMax = Int${maxBits}
typealias UIntMax = UInt${maxBits}
protocol _Integer
: _BuiltinIntegerLiteralConvertible,
IntegerLiteralConvertible,
Printable,
ArrayBound,
Hashable,
IntegerArithmetic,
BitwiseOperations,
_Incrementable
{
}
protocol Integer : _Integer, RandomAccessIndex {
}
protocol _SignedInteger : _Integer, SignedNumber {
func toIntMax() -> IntMax
class func from(IntMax) -> Self
}
protocol SignedInteger : _SignedInteger, Integer {
}
protocol _UnsignedInteger : _Integer {
func toUIntMax() -> UIntMax
class func from(UIntMax) -> Self
}
protocol UnsignedInteger : _UnsignedInteger, Integer {
}
func numericCast<T : _SignedInteger, U : _SignedInteger>(x: T) -> U {
return .from(x.toIntMax())
}
func numericCast<T : _UnsignedInteger, U : _UnsignedInteger>(x: T) -> U {
return .from(x.toUIntMax())
}
func numericCast<T : _SignedInteger, U : _UnsignedInteger>(x: T) -> U {
return .from(UIntMax(x.toIntMax()))
}
func numericCast<T : _UnsignedInteger, U : _SignedInteger>(x: T) -> U {
return .from(IntMax(x.toUIntMax()))
}
% for (name, bits, signed) in allInts():
% (sign, ext) = ('s', 'sext') if signed else ('u', 'zext')
% BuiltinName = builtinIntName(name)
% Self = intName(name, signed)
% OtherSelf = otherIntName(name, signed)
% ConstructIntType = 'Int' if Self != 'Int' else ''
struct ${Self} : ${'SignedInteger' if sign == 's' else 'UnsignedInteger'} {
var value: Builtin.${BuiltinName}
@transparent
init() {
var maxWidthZero: IntMax = 0
value = Builtin.truncOrBitCast_Int${maxBits}_${BuiltinName}(maxWidthZero.value)
}
@transparent
init(_ v: Builtin.${BuiltinName}) {
value = v
}
@transparent
init(_ value: ${Self}) { self = value }
@transparent
static func _convertFromBuiltinIntegerLiteral(value: Builtin.Int${builtinIntLiteralBits}) -> ${Self} {
return ${Self}(Builtin.s_to_${sign}_checked_trunc_Int${builtinIntLiteralBits}_${BuiltinName}(value).0)
}
@transparent
static func convertFromIntegerLiteral(value: ${Self}) -> ${Self} {
return value
}
@transparent
func _getBuiltinArrayBoundValue() -> Builtin.Word {
% if bits < wordBits:
return Builtin.${ext}OrBitCast_${BuiltinName}_Word(self.value)
% elif bits > wordBits:
return Builtin.truncOrBitCast_${BuiltinName}_Word(self.value)
% elif BuiltinName == 'Word':
return self.value
% else:
return Builtin.${CastToWord}(self.value)
% end
}
typealias ArrayBoundType = ${Self}
func getArrayBoundValue() -> ${Self} {
return self
}
% max = maskBits((bits - 1) if signed else bits)
@transparent
static var max: ${Self} { return ${max} }
@transparent
static var min: ${Self} { return ${'-%s-1' % max if signed else '0'} }
}
extension ${Self} : Hashable {
var hashValue: Int {
% if bits < wordBits:
return Int(Builtin.sextOrBitCast_${BuiltinName}_Word(self.value))
% elif bits > wordBits:
var result: Int = 0
for var i = 0; i < (sizeofValue(self) * 8); i += sizeof(Int.self) * 8 {
result ^= Int(self >> ${Self}(i)) & ~0
}
return result
% elif BuiltinName == 'Word':
return Int(self.value)
% else:
return Int(Builtin.${CastToWord}(self.value))
% end
}
}
extension ${Self} : Printable {
var description: String {
% if signed:
return _int64ToString(self.toIntMax())
% else:
return _uint64ToString(self.toUIntMax())
% end
}
}
@transparent
extension ${Self} : RandomAccessIndex {
@transparent
func succ() -> ${Self} {
return self + 1
}
@transparent
func pred() -> ${Self} {
return self - 1
}
@transparent
func distanceTo(other: ${Self}) -> ${Self}.DistanceType {
return numericCast((numericCast(other) as IntMax) - numericCast(self))
}
@transparent
func advancedBy(amount: ${Self}.DistanceType) -> ${Self} {
return numericCast((numericCast(self) as IntMax) + numericCast(amount))
}
% for Method,op in [('Add', 'add'), ('Subtract', 'sub'), ('Multiply', 'mul')]:
@transparent
static func unchecked${Method}(lhs: ${Self}, _ rhs: ${Self}) -> (${Self}, Bool) {
var tmp = Builtin.${sign}${op}_with_overflow_${BuiltinName}(lhs.value, rhs.value, false.value)
return (${Self}(tmp.0), Bool(tmp.1))
}
% end
% for Method,op in [('Divide', 'div'), ('Modulus', 'rem')]:
@transparent
static func unchecked${Method}(lhs: ${Self}, _ rhs: ${Self}) -> (${Self}, Bool) {
if rhs == 0 {
return (0, true)
}
% if signed:
if lhs == ${Self}.min && rhs == -1 {
return (0, true)
}
% end
// FIXME: currently doesn't detect overflow -- blocked by:
// <rdar://15735295> Need [su]{div,rem}_with_overflow IR
var tmp = Builtin.${sign}${op}_${BuiltinName}(lhs.value, rhs.value)
return (${Self}(tmp), false)
}
%end
% U = '' if signed else 'U'
@transparent
func to${U}IntMax() -> ${U}IntMax {
return ${'self' if Self == U+'Int%s'%maxBits else U+'IntMax(self)'}
}
% if not signed:
func toIntMax() -> IntMax {
return IntMax(toUIntMax())
}
% end
@transparent
static func from(x: ${U}IntMax) -> ${Self} {
return ${'x' if Self == U+'Int%s'%maxBits else Self+'(x)'}
}
}
% if signed:
@transparent
extension ${Self} : SignedNumber {}
% end
%# FIXME: checked conversions of Word types
// construction from other integer types
@transparent
extension ${Self} {
% for (srcName, srcBits, srcSigned) in allInts():
% Src = intName(srcName, srcSigned)
% srcBuiltinName = builtinIntName(srcName)
% (srcSign, srcExt) = ('s', 'sext') if srcSigned else ('u', 'zext')
% if Self != Src:
init(_ v: ${Src}) {
%
% if srcBuiltinName == 'Word':
var srcNotWord = Builtin.${CastFromWord}(v.value)
% else:
var srcNotWord = v.value
% end
%
% if srcBits == bits and srcSign == sign:
var dstNotWord = srcNotWord
%
% elif srcBits == bits:
var tmp = Builtin.${srcSign}_to_${sign}_checked_conversion_Int${srcBits}(srcNotWord)
Builtin.condfail(tmp.1)
var dstNotWord = tmp.0
%
% elif srcBits > bits:
var tmp = Builtin.${srcSign}_to_${sign}_checked_trunc_Int${srcBits}_Int${bits}(srcNotWord)
Builtin.condfail(tmp.1)
var dstNotWord = tmp.0
%
% elif srcSigned and not signed:
var tmp = Builtin.s_to_u_checked_conversion_Int${srcBits}(srcNotWord)
Builtin.condfail(tmp.1)
var dstNotWord = Builtin.${srcExt}_Int${srcBits}_Int${bits}(tmp.0)
%
% else:
var dstNotWord = Builtin.${srcExt}_Int${srcBits}_Int${bits}(srcNotWord)
% end
%
% if BuiltinName == 'Word':
value = Builtin.${CastToWord}(dstNotWord)
% else:
value = dstNotWord
% end
}
% end
% end
func as${'Unsigned' if signed else 'Signed'}() -> ${OtherSelf} {
return ${OtherSelf}(value)
}
}
// Operations with potentially-static overflow checking
//
// FIXME: must use condfail in these operators, rather than
// overflowChecked, pending <rdar://problem/16271923> so that we don't
// foil static checking for numeric overflows.
% for op,method in ('+','add'), ('*','mul'), ('-','sub'):
@transparent
func ${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} {
let (result, error) = Builtin.${sign}${method}_with_overflow_${BuiltinName}(
lhs.value, rhs.value, true.value)
// return overflowChecked((${Self}(result), Bool(error)))
Builtin.condfail(error)
return ${Self}(result)
}
% end
% for op,inst in [('/', 'div'), ('%', 'rem')]:
@transparent
func ${op}(lhs: ${Self}, rhs: ${Self}) -> ${Self} {
Builtin.condfail((rhs == 0).value)
% if signed:
Builtin.condfail(((lhs == ${Self}.min) & (rhs == -1)).value)
% end
// FIXME: currently doesn't detect overflow -- blocked by:
// <rdar://15735295> Need [su]{div,rem}_with_overflow IR
var tmp = Builtin.${sign}${inst}_${BuiltinName}(lhs.value, rhs.value)
return ${Self}(tmp)
}
%end
// Bitwise negate
@transparent @prefix
func ~(rhs: ${Self}) -> ${Self} {
let mask = ${Self}.uncheckedSubtract(0, 1).0
return ${Self}(Builtin.xor_${BuiltinName}(rhs.value, mask.value))
}
% for op, name in (
% ('==','eq'), ('!=','ne'),
% ('<',sign+'lt'), ('<=',sign+'le'),
% ('>',sign+'gt'), ('>=',sign+'ge')):
@transparent
func ${op} (lhs: ${Self}, rhs: ${Self}) -> Bool {
return Bool(Builtin.cmp_${name}_${BuiltinName}(lhs.value, rhs.value))
}
% end
% for op, name in (('<<','shl'), ('>>','ashr' if signed else 'lshr')):
@transparent
func ${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} {
% if signed:
assert(U${Self}(rhs) < U${Self}(sizeofValue(rhs) * 8))
% else:
assert(rhs < ${Self}(sizeofValue(rhs) * 8))
% end
return ${Self}(Builtin.${name}_${BuiltinName}(lhs.value, rhs.value))
}
% end
% for op, name in (('&','and'), ('^','xor'), ('|','or')):
@transparent
func ${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} {
return ${Self}(Builtin.${name}_${BuiltinName}(lhs.value, rhs.value))
}
% end
// bitwise operations
@transparent
extension ${Self} : BitwiseOperations {
static func allZeros() -> ${Self} { return 0 }
}
// Compound assignments
% for op in '+', '-', '*', '<<', '>>', '&', '|', '^':
@transparent @assignment
func ${op}=(inout lhs: ${Self}, rhs: ${Self}) {
lhs = lhs ${op} rhs
}
% end
% end # for bits in allInts
typealias Word = Int
typealias UWord = UInt
// ${'Local Variables'}:
// eval: (read-only-mode 1)
// End: