Skip to content

Commit 4fd9f81

Browse files
author
Max Moiseev
committed
[stdlib] updating integers prototype
* `remainder` has been removed from `Arithmetic` protocol and added to the `Integer`, so that floating point types can use it. * `Arithmetic` protocol now extends `Equatable` and `IntegerLiteralConvertible`
1 parent ba431a9 commit 4fd9f81

File tree

1 file changed

+44
-23
lines changed

1 file changed

+44
-23
lines changed

test/Prototypes/Integers.swift.gyb

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,21 @@ class struct(object):
4545
def __repr__(self):
4646
return 'struct(%r)' % self.__dict__
4747

48-
binaryArithmetic = [
49-
struct(operator='+', name='adding', mutatingName='add', firstArg='_', llvmName='add', kind='+'),
50-
struct(operator='-', name='subtracting', mutatingName='subtract', firstArg='_', llvmName='sub', kind='-'),
51-
struct(operator='*', name='multiplied', mutatingName='multiply', firstArg='by', llvmName='mul', kind='*'),
52-
struct(operator='/', name='divided', mutatingName='divide', firstArg='by', llvmName='div', kind='/'),
48+
binaryArithmetic = {
49+
'Arithmetic' : [
50+
struct(operator='+', name='adding', mutatingName='add', firstArg='_', llvmName='add', kind='+'),
51+
struct(operator='-', name='subtracting', mutatingName='subtract', firstArg='_', llvmName='sub', kind='-'),
52+
struct(operator='*', name='multiplied', mutatingName='multiply', firstArg='by', llvmName='mul', kind='*'),
53+
struct(operator='/', name='divided', mutatingName='divide', firstArg='by', llvmName='div', kind='/'),
54+
],
55+
'Integer' : [
5356
struct(operator='%', name='remainder', mutatingName='formRemainder', firstArg='dividingBy', llvmName='rem', kind='/'),
54-
]
57+
],
58+
}
5559

60+
# We need the same order of operations, so simple itertools.chain(d.values())
61+
# won't work
62+
allBinaryArithmetic = binaryArithmetic['Arithmetic'] + binaryArithmetic['Integer']
5663

5764
binaryBitwise = [
5865
struct(operator='&', name='and'),
@@ -136,11 +143,11 @@ public func _log(@autoclosure _ message: ()->String) {
136143
/// non-mutating implementations, they will be provided by a protocol extension.
137144
/// Implementation in that case will copy `self`, perform a mutating operation
138145
/// on it and return the resulting value.
139-
public protocol Arithmetic {
146+
public protocol Arithmetic : Equatable, IntegerLiteralConvertible {
140147
/// Initialize to zero
141148
init()
142149

143-
% for x in binaryArithmetic:
150+
% for x in binaryArithmetic['Arithmetic']:
144151
// defaulted using an in-place counterpart, but can be used as an
145152
// optimization hook
146153
@warn_unused_result
@@ -151,16 +158,18 @@ public protocol Arithmetic {
151158
% end
152159
}
153160

154-
extension Arithmetic {
155-
% for x in binaryArithmetic:
156-
% callLabel = x.firstArg + ': ' if not x.firstArg == '_' else ''
161+
% for Protocol in binaryArithmetic:
162+
extension ${Protocol} {
163+
% for x in binaryArithmetic[Protocol]:
164+
% callLabel = x.firstArg + ': ' if not x.firstArg == '_' else ''
157165
public func ${x.name}(${x.firstArg} rhs: Self) -> Self {
158166
var lhs = self
159167
lhs.${x.mutatingName}(${callLabel}rhs)
160168
return lhs
161169
}
162-
% end
170+
% end
163171
}
172+
% end
164173

165174
/// SignedArithmetic protocol will only be conformed to by signed numbers,
166175
/// otherwise it would be possible to negate an unsigned value.
@@ -177,18 +186,20 @@ extension SignedArithmetic {
177186
}
178187
}
179188

180-
% for x in binaryArithmetic:
181-
% callLabel = x.firstArg + ': ' if not x.firstArg == '_' else ''
189+
% for Protocol in binaryArithmetic:
190+
% for x in binaryArithmetic[Protocol]:
191+
% callLabel = x.firstArg + ': ' if not x.firstArg == '_' else ''
182192
@_transparent
183193
@warn_unused_result
184-
public func ${x.operator} <T: Arithmetic>(lhs: T, rhs: T) -> T {
194+
public func ${x.operator} <T: ${Protocol}>(lhs: T, rhs: T) -> T {
185195
return lhs.${x.name}(${callLabel}rhs)
186196
}
187197

188198
@_transparent
189-
public func ${x.operator}= <T: Arithmetic>(lhs: inout T, rhs: T) {
199+
public func ${x.operator}= <T: ${Protocol}>(lhs: inout T, rhs: T) {
190200
lhs.${x.mutatingName}(${callLabel}rhs)
191201
}
202+
% end
192203
% end
193204

194205
@_transparent
@@ -274,6 +285,16 @@ public protocol Integer : ${IntegerBase} {
274285
/// Has the value -1 if `self` is 0.
275286
/// Has the value equal to `bitWidth - 1` for fixed width integers.
276287
var signBitIndex: Word { get }
288+
289+
% for x in binaryArithmetic['Integer']:
290+
// defaulted using an in-place counterpart, but can be used as an
291+
// optimization hook
292+
@warn_unused_result
293+
func ${x.name}(${x.firstArg} rhs: Self) -> Self
294+
295+
// implementation hook
296+
mutating func ${x.mutatingName}(${x.firstArg} rhs: Self)
297+
% end
277298
}
278299

279300
extension Integer {
@@ -419,7 +440,7 @@ public protocol FixedWidthInteger : Integer {
419440
static var max: Self { get }
420441
static var min: Self { get }
421442

422-
% for x in binaryArithmetic:
443+
% for x in allBinaryArithmetic:
423444
%{
424445
comment = '''
425446
/// Return a pair consisting of `self` {} `rhs`,
@@ -551,7 +572,7 @@ extension FixedWidthInteger {
551572
else { self = Self(extendingOrTruncating: source) }
552573
}
553574

554-
% for x in binaryArithmetic:
575+
% for x in allBinaryArithmetic:
555576
% callLabel = x.firstArg + ': ' if not x.firstArg == '_' else ''
556577
@_transparent
557578
public mutating func ${x.mutatingName}(${x.firstArg} rhs: Self) {
@@ -616,7 +637,7 @@ extension FixedWidthInteger {
616637
}
617638
}
618639

619-
% for x in binaryArithmetic:
640+
% for x in allBinaryArithmetic:
620641
% callLabel = x.firstArg + ': ' if not x.firstArg == '_' else ''
621642
% if x.kind != '/':
622643
@warn_unused_result
@@ -763,7 +784,7 @@ public struct ${Self}
763784
return Bool(Builtin.cmp_${u}lt_Int${bits}(_storage, rhs._storage))
764785
}
765786

766-
% for x in binaryArithmetic:
787+
% for x in allBinaryArithmetic:
767788
% callLabel = x.firstArg + ': ' if not x.firstArg == '_' else ''
768789
/// Return a pair consisting of `self` ${x.operator} `rhs`,
769790
/// truncated to fit if necessary, and a flag indicating whether an
@@ -1008,7 +1029,7 @@ public struct DoubleWidth<
10081029

10091030
public static var bitWidth : Word { return 2 * T.bitWidth }
10101031

1011-
% for x in binaryArithmetic[:2]:
1032+
% for x in allBinaryArithmetic[:2]:
10121033
% highAffectedByLowOverflow = 'T.max' if x.operator == '+' else 'T.min'
10131034
public func ${x.name}WithOverflow(_ rhs: DoubleWidth<T>)
10141035
-> (partialValue: DoubleWidth<T>, overflow: ArithmeticOverflow) {
@@ -1089,7 +1110,7 @@ public struct DoubleWidth<
10891110
return mkResult(carry > 0)
10901111
}
10911112

1092-
% for x in binaryArithmetic[3:]:
1113+
% for x in allBinaryArithmetic[3:]:
10931114
@warn_unused_result
10941115
public func ${x.name}WithOverflow(
10951116
${x.firstArg} rhs: DoubleWidth<T>
@@ -1165,7 +1186,7 @@ public struct ${Self}
11651186
return _storage.isLess(than: rhs._storage)
11661187
}
11671188

1168-
% for x in binaryArithmetic:
1189+
% for x in allBinaryArithmetic:
11691190
% callLabel = x.firstArg + ': ' if not x.firstArg == '_' else ''
11701191
/// Return a pair consisting of `self` ${x.operator} `rhs`,
11711192
/// truncated to fit if necessary, and a flag indicating whether an

0 commit comments

Comments
 (0)