@@ -125,12 +125,22 @@ public func _log(@autoclosure message: ()->String) {
125
125
//===----------------------------------------------------------------------===//
126
126
//===--- Arithmetic -------------------------------------------------------===//
127
127
//===----------------------------------------------------------------------===//
128
+
129
+ /// Arithmetic protocol declares methods backing binary arithmetic operators,
130
+ /// such as `+`, `-` and `*`; and their mutating counterparts. These methods
131
+ /// operate on arguments of the same type.
132
+ ///
133
+ /// Both mutating and non-mutating operations are declared in the protocol, but
134
+ /// only the mutating ones are required. Should conforming type omit
135
+ /// non-mutating implementations, they will be provided by a protocol extension.
136
+ /// Implementation in that case will copy `self`, perform a mutating operation
137
+ /// on it and return the resulting value.
128
138
public protocol Arithmetic {
129
139
/// Initialize to zero
130
140
init ( )
131
141
132
142
% for x in binaryArithmetic:
133
- // defaulted using an InPlace counterpart, but can be used as an
143
+ // defaulted using an in-place counterpart, but can be used as an
134
144
// optimization hook
135
145
@warn_unused_result
136
146
func ${ x. name } ( ${ x. firstArg} rhs: Self) - > Self
@@ -151,6 +161,11 @@ extension Arithmetic {
151
161
% end
152
162
}
153
163
164
+ /// SignedArithmetic protocol will only be conformed to by signed numbers,
165
+ /// otherwise it would be posible to negate an unsigned value.
166
+ ///
167
+ /// The only method of this protocol has the default implementation in an
168
+ /// extension, that uses a parameterless initializer and subtraction.
154
169
public protocol SignedArithmetic : Arithmetic {
155
170
func negate( ) -> Self
156
171
}
@@ -187,16 +202,46 @@ public prefix func -<T: SignedArithmetic>(x: T) -> T {
187
202
public typealias Word = Int ${ word_bits}
188
203
public typealias UWord = UInt ${ word_bits}
189
204
190
- % IntegerBase = 'Comparable, Arithmetic, ' + \
205
+ % IntegerBase = 'Comparable, Arithmetic, ' + \
191
206
% 'IntegerLiteralConvertible, CustomStringConvertible'
192
207
208
+ /// Integer protocol is a base for all the integer types that are available in
209
+ /// the standard library, and besides should be suffecient to implement
210
+ /// arbitrary precision integer types.
211
+ ///
212
+ /// `isEqual(to:)` and `isLess(than:)` methods are the ones responsible for
213
+ /// `Equatable` and `Comparable` protocol conformances. In a way similar to how
214
+ /// arithmetic operations are dispatched in `Arithmetic`, `==` and `<` operators
215
+ /// for homogenous comparisons have default implementations that call
216
+ /// `isEqual(to:)` and `isLess(than:)` respectively.
217
+ ///
218
+ /// This protocol adds 3 new initializers to the parameterless one, inherited
219
+ /// from `Arithmetic`. These initializers allow to construct values of type
220
+ /// from instances of any other type, conforming to `Integer`, using different
221
+ /// strategies:
222
+ /// - Perform checks whether the value is representable in `Self`
223
+ /// - Try to represent the value without bounds checking
224
+ /// - Substitute values beyond `Self` bounds with maximum/minimum value of
225
+ /// `Self` respectively
193
226
public protocol Integer : ${ IntegerBase} {
194
227
195
228
// FIXME(compiler limitation): Ideally, this constraint would just be :
196
229
// Integer. Until we get recursive protocol requirements, that isn't
197
230
// possible.
231
+
232
+ /// A type that can hold absolute values of all the possible values of `Self`.
233
+ /// Concrete types do not have to provide a typealias for it as it can be
234
+ /// inferred from an `absoluteValue` property. This property (and type) can be
235
+ /// useful in operations that are simpler to implement in terms of
236
+ /// (potentially larger) unsigned values, for example, printing a value of an
237
+ /// integer (it's just adding a '-' character in front of an absolute value).
238
+ /// Please note, that `absoluteValue` property should not in general be used
239
+ /// as a substitute for an `abs` free function, that returns a value of the
240
+ /// same type.
198
241
associatedtype AbsoluteValue : ${ IntegerBase}
199
242
243
+ static var isSigned : Bool { get }
244
+
200
245
/// An absolute value of the represented number.
201
246
///
202
247
/// Please note that `absoluteValue` has a different type than `self`, and so
@@ -207,28 +252,26 @@ public protocol Integer : ${IntegerBase} {
207
252
// the interface and error messages (and on the type checker) than
208
253
// does having many operator overloads.
209
254
@warn_unused_result
210
- func isEqualTo( rhs: Self ) -> Bool
211
-
255
+ func isEqual( to rhs: Self ) -> Bool
212
256
@warn_unused_result
213
- func isLessThan ( rhs: Self ) -> Bool
257
+ func isLess ( than rhs: Self ) -> Bool
214
258
215
259
init< T : Integer> ( _ source: T )
216
-
217
260
init< T : Integer> ( extendingOrTruncating source: T )
218
261
init< T : Integer> ( clamping source: T )
219
262
263
+ /// Return n-th word in the underlying representation of `self`.
220
264
@warn_unused_result
221
265
func nthWord( n: Word ) -> UWord
222
266
223
- static var isSigned: Bool { get }
224
-
225
- // A number of bits in current representation of `self`
226
- // Will be constant for fixed-width integer types.
267
+ /// A number of bits in current representation of `self`
268
+ /// Will be constant for fixed-width integer types.
227
269
var bitWidth : Word { get }
228
270
229
271
/// If `self` is negative, returns the index of the least significant bit of
230
272
/// our representation such that all more-significant bits are 1.
231
273
/// Has the value -1 if `self` is 0.
274
+ /// Has the value equal to `bitWidth - 1` for fixed width integers.
232
275
var signBitIndex : Word { get }
233
276
}
234
277
@@ -242,13 +285,13 @@ extension Integer {
242
285
@_transparent
243
286
@warn_unused_result
244
287
public func == < T : Integer > ( lhs: T , rhs: T ) -> Bool {
245
- return lhs. isEqualTo ( rhs)
288
+ return lhs. isEqual ( to : rhs)
246
289
}
247
290
248
291
@_transparent
249
292
@warn_unused_result
250
293
public func < < T : Integer > ( lhs: T , rhs: T ) -> Bool {
251
- return lhs. isLessThan ( rhs)
294
+ return lhs. isLess ( than : rhs)
252
295
}
253
296
254
297
//===--- Heterogeneous comparison -----------------------------------------===//
@@ -353,15 +396,34 @@ public enum ArithmeticOverflow {
353
396
case none, overflow
354
397
}
355
398
399
+ /// A protocol for all the fixed width integer types. Main addition to the
400
+ /// `Integer` protocol is binary bitwise operations and bit shifts.
401
+ ///
402
+ /// `WithOverflow` family of methods is used in default implementations of
403
+ /// mutating arithmetic methods (from `Arithmetic` protocol), provided by a
404
+ /// protocol extension. Having these methods allows to provide both safe
405
+ /// (trapping) and unsafe implementation of arithmetic operations without
406
+ /// duplicating code.
407
+ ///
408
+ /// Bitwise binary and shift operators are implemented the same way as
409
+ /// arithmetic operations: free function dispatches a call to a corresponding
410
+ /// protocol method.
411
+ ///
412
+ /// `doubleWidthMultiply` method is a necessary building block to implement
413
+ /// support for integer types of a greater width and as a consequence, arbitrary
414
+ /// precision integers.
356
415
public protocol FixedWidthInteger : Integer {
357
416
static var bitWidth : Word { get }
358
417
418
+ static var max : Self { get }
419
+ static var min : Self { get }
420
+
359
421
% for x in binaryArithmetic:
360
422
% {
361
423
comment = '''
362
- /// Return a pair consisting of `self` ${x.operator } `rhs`,
424
+ /// Return a pair consisting of `self` { } `rhs`,
363
425
/// truncated to fit if necessary, and a flag indicating whether an
364
- /// arithmetic overflow occurred.''' + ('''
426
+ /// arithmetic overflow occurred.'''.format(x.operator) + ('''
365
427
///
366
428
/// - Precondition: `rhs != 0`''' if x.kind == '/' else '')
367
429
} %
@@ -372,18 +434,14 @@ ${comment}
372
434
) -> ( partialValue: Self, overflow: ArithmeticOverflow)
373
435
% end
374
436
375
- @warn_unused_result
376
- func do ubleWidthMultiply( other: Self) - > ( high: Self, low: AbsoluteValue)
377
-
378
- static var max: Self { get }
379
-
380
- static var min: Self { get }
381
-
382
437
% for x in binaryBitwise + maskingShifts:
383
438
@warn_unused_result
384
439
func ${ x. name} ( rhs: Self) - > Self
385
440
% end
386
441
442
+ @warn_unused_result
443
+ func doubleWidthMultiply( other: Self ) -> ( high: Self , low: AbsoluteValue )
444
+
387
445
init( _truncatingBits bits: UWord )
388
446
}
389
447
@@ -695,12 +753,12 @@ public struct ${Self}
695
753
}
696
754
697
755
@warn_unused_result
698
- public func isEqualTo ( rhs: ${ Self} ) -> Bool {
756
+ public func isEqual ( to rhs: ${ Self} ) -> Bool {
699
757
return Bool ( Builtin . cmp_eq_Int ${ bits} ( _storage, rhs. _storage) )
700
758
}
701
759
702
760
@warn_unused_result
703
- public func isLessThan ( rhs: ${ Self} ) -> Bool {
761
+ public func isLess ( than rhs: ${ Self} ) -> Bool {
704
762
return Bool ( Builtin . cmp_ ${ u} lt_Int${ bits} ( _storage, rhs. _storage) )
705
763
}
706
764
@@ -889,13 +947,13 @@ public struct DoubleWidth<
889
947
}
890
948
891
949
@warn_unused_result
892
- public func isEqualTo ( rhs: DoubleWidth < T > ) -> Bool {
950
+ public func isEqual ( to rhs: DoubleWidth < T > ) -> Bool {
893
951
return ( _storage. high == rhs. _storage. high) &&
894
952
( _storage. low == rhs. _storage. low)
895
953
}
896
954
897
955
@warn_unused_result
898
- public func isLessThan ( rhs: DoubleWidth < T > ) -> Bool {
956
+ public func isLess ( than rhs: DoubleWidth < T > ) -> Bool {
899
957
if _storage. high < rhs. _storage. high {
900
958
return true
901
959
}
@@ -913,10 +971,6 @@ public struct DoubleWidth<
913
971
fatalError ( )
914
972
}
915
973
916
- public init < T : Integer > ( clamping source: T ) {
917
- fatalError ( )
918
- }
919
-
920
974
@warn_unused_result
921
975
public func nthWord( n: Word ) -> UWord {
922
976
if T . bitWidth < ${ word_bits} || T . bitWidth % ${ word_bits} != 0 {
@@ -1101,13 +1155,13 @@ public struct ${Self}
1101
1155
}
1102
1156
1103
1157
@warn_unused_result
1104
- public func isEqualTo ( rhs: ${ Self} ) -> Bool {
1105
- return _storage. isEqualTo ( rhs. _storage)
1158
+ public func isEqual ( to rhs: ${ Self} ) -> Bool {
1159
+ return _storage. isEqual ( to : rhs. _storage)
1106
1160
}
1107
1161
1108
1162
@warn_unused_result
1109
- public func isLessThan ( rhs: ${ Self} ) -> Bool {
1110
- return _storage. isLessThan ( rhs. _storage)
1163
+ public func isLess ( than rhs: ${ Self} ) -> Bool {
1164
+ return _storage. isLess ( than : rhs. _storage)
1111
1165
}
1112
1166
1113
1167
% for x in binaryArithmetic:
@@ -1705,7 +1759,7 @@ tests.test("DoubleWidth/Int8/not equal") {
1705
1759
expectNotEqual ( a, b)
1706
1760
}
1707
1761
1708
- tests. test ( " DoubleWidth/Int8/isLessThan " ) {
1762
+ tests. test ( " DoubleWidth/Int8/isLess(than:) " ) {
1709
1763
let a = DoubleWidth< Int8> . min
1710
1764
let z = DoubleWidth < Int8 > ( )
1711
1765
let b = DoubleWidth< Int8> . max
0 commit comments