@@ -134,18 +134,24 @@ public func _log(_ message: @autoclosure () -> String) {
134
134
//===--- Arithmetic -------------------------------------------------------===//
135
135
//===----------------------------------------------------------------------===//
136
136
137
- /// Arithmetic protocol declares methods backing binary arithmetic operators,
138
- /// such as `+`, `-` and `*`; and their mutating counterparts. These methods
139
- /// operate on arguments of the same type.
137
+ /// Declares methods backing binary arithmetic operators, such as `+`, `-` and
138
+ /// `*`; and their mutating counterparts.
140
139
///
141
- /// Both mutating and non-mutating operations are declared in the protocol, but
142
- /// only the mutating ones are required. Should conforming type omit
143
- /// non-mutating implementations, they will be provided by a protocol extension.
144
- /// Implementation in that case will copy `self`, perform a mutating operation
145
- /// on it and return the resulting value.
140
+ /// It provides a suitable basis for arithmetic on scalars such as integers and
141
+ /// floating point numbers.
142
+ ///
143
+ /// Both mutating and non-mutating operations are declared in the protocol,
144
+ /// however only the mutating ones are required, as non-mutating are provided
145
+ /// by the protocol extension.
146
146
public protocol Arithmetic : Equatable, IntegerLiteralConvertible {
147
- /// Initialize to zero
148
- init ( )
147
+ // Since `Arithmetic` extends `IntegerLiteralConvertible` it is logical for
148
+ // it to be initializable from instances of `Integer` as well as from integer
149
+ // literals. Failable exact initializers from other `Arithmetic` types should
150
+ // be defined on child protocols.
151
+
152
+ /// Initializes to the value of `source` if it is representable exactly,
153
+ /// returns `nil` otherwise.
154
+ init? < T : Integer> ( exactly source: T)
149
155
150
156
% for x in binaryArithmetic [ 'Arithmetic'] :
151
157
// defaulted using an in-place counterpart, but can be used as an
@@ -157,6 +163,13 @@ public protocol Arithmetic : Equatable, IntegerLiteralConvertible {
157
163
% end
158
164
}
159
165
166
+ extension Arithmetic {
167
+ @_transparent
168
+ public init( ) {
169
+ self = 0
170
+ }
171
+ }
172
+
160
173
% for Protocol in binaryArithmetic:
161
174
extension ${ Protocol} {
162
175
% for x in binaryArithmetic [ Protocol] :
@@ -176,13 +189,17 @@ extension ${Protocol} {
176
189
/// The only method of this protocol has the default implementation in an
177
190
/// extension, that uses a parameterless initializer and subtraction.
178
191
public protocol SignedArithmetic : Arithmetic {
179
- func negate( ) -> Self
192
+ func negated( ) -> Self
193
+ mutating func negate( )
180
194
}
181
195
182
196
extension SignedArithmetic {
183
- public func negate ( ) -> Self {
197
+ public func negated ( ) -> Self {
184
198
return Self ( ) - self
185
199
}
200
+ public mutating func negate( ) {
201
+ self = negated ( )
202
+ }
186
203
}
187
204
188
205
% for Protocol in binaryArithmetic:
@@ -202,7 +219,7 @@ public func ${x.operator}= <T: ${Protocol}>(lhs: inout T, rhs: T) {
202
219
203
220
@_transparent
204
221
public prefix func - < T: SignedArithmetic> ( x: T) - > T {
205
- return x. negate ( )
222
+ return x. negated ( )
206
223
}
207
224
208
225
//===----------------------------------------------------------------------===//
@@ -234,7 +251,7 @@ public typealias UWord = UInt${word_bits}
234
251
/// `Self` respectively
235
252
public protocol Integer : ${ IntegerBase} {
236
253
237
- // FIXME(compiler limitation ): Ideally, this constraint would just be :
254
+ // FIXME(ABI ): Ideally, this constraint would just be :
238
255
// Integer. Until we get recursive protocol requirements, that isn't
239
256
// possible.
240
257
@@ -263,6 +280,10 @@ public protocol Integer : ${IntegerBase} {
263
280
func isEqual( to rhs: Self ) -> Bool
264
281
func isLess( than rhs: Self ) -> Bool
265
282
283
+ /// Creates an instance of `Self` that has the exact value of `source`,
284
+ /// returns `nil` otherwise.
285
+ init?< T : FloatingPoint> ( exactly source: T)
286
+
266
287
/// Creates an instance of `Self` from the value of any other `Integer`,
267
288
/// trapping if value of `source` cannot be represented by `Self`.
268
289
init< T : Integer> ( _ source: T )
@@ -311,6 +332,10 @@ public protocol Integer : ${IntegerBase} {
311
332
}
312
333
313
334
extension Integer {
335
+ public init? < T : FloatingPoint> ( exactly source: T) {
336
+ fatalError ( )
337
+ }
338
+
314
339
public var countRepresentedWords : Word {
315
340
return ( self . bitWidth + ${ word_bits} - 1 ) / ${ word_bits}
316
341
}
@@ -598,11 +623,6 @@ extension FixedWidthInteger {
598
623
}
599
624
% end
600
625
601
- @_transparent
602
- public init( ) {
603
- self = 0
604
- }
605
-
606
626
@_transparent
607
627
public init< T : Integer> ( extendingOrTruncating source: T) {
608
628
if Self . bitWidth <= ${ word_bits} {
@@ -689,6 +709,17 @@ extension UnsignedInteger where Self : FixedWidthInteger {
689
709
self . init ( extendingOrTruncating: source)
690
710
}
691
711
712
+ @_transparent
713
+ public init?< T : Integer> ( exactly source: T) {
714
+ _assertCond (
715
+ source >= 0 , " negative value \( source) not representable by \( Self . self) " )
716
+ let requiredBits = source. signBitIndex + 1
717
+ if requiredBits > Self . bitWidth {
718
+ return nil
719
+ }
720
+ self . init ( extendingOrTruncating: source)
721
+ }
722
+
692
723
@_transparent
693
724
public static var max: Self {
694
725
return ~ 0
@@ -730,6 +761,15 @@ extension SignedInteger where Self : FixedWidthInteger {
730
761
self . init ( extendingOrTruncating: source)
731
762
}
732
763
764
+ @_transparent
765
+ public init ? < T : Integer > ( exactly source: T ) {
766
+ let requiredBits = source. signBitIndex + ( source >= 0 ? 2 : 1 )
767
+ if requiredBits > Self . bitWidth {
768
+ return nil
769
+ }
770
+ self . init ( extendingOrTruncating: source)
771
+ }
772
+
733
773
@_transparent
734
774
public static var max : Self {
735
775
return ~ min
@@ -974,6 +1014,10 @@ public struct DoubleWidth<
974
1014
fatalError ( )
975
1015
}
976
1016
1017
+ public init ? < T : Arithmetic > ( exactly source: T ) {
1018
+ fatalError ( )
1019
+ }
1020
+
977
1021
public init < T : Integer > ( extendingOrTruncating source: T ) {
978
1022
fatalError ( )
979
1023
}
@@ -1129,9 +1173,9 @@ public struct DoubleWidth<
1129
1173
1130
1174
//===--- Int128/UInt128 ---------------------------------------------------===//
1131
1175
1132
- % for Self in [ 'Int 129 ', 'UInt 129 '] :
1176
+ % for Self in [ 'Int 128 _ ', 'UInt 128 _ '] :
1133
1177
% signed = 'U' not in Self
1134
- % Half = Self [ : - 3 ] + '64 '
1178
+ % Half = Self [ : - 4 ] + '64 '
1135
1179
% Unsigned = 'Signed' if signed else 'Unsigned'
1136
1180
% u = 's' if signed else 'u'
1137
1181
% U = 'U' if signed else ''
0 commit comments