@@ -256,9 +256,6 @@ public struct ${Self}
256
256
}
257
257
% end
258
258
259
- /// Create an instance initialized to `value`.
260
- @_transparent public
261
- init ( _ value: ${ Self} ) { self = value }
262
259
263
260
% if bits > 8 :
264
261
/// Creates an integer from its big-endian representation, changing the
@@ -429,44 +426,72 @@ extension ${Self} {
429
426
extension ${ Self} : SignedNumber { }
430
427
% end
431
428
432
- // Construction from other integer types
433
- @_transparent
434
- extension ${ Self} {
435
- % for src_ty in all_integer_types ( word_bits) :
436
- % srcBits = src_ty. bits
437
- % srcSigned = src_ty. is_signed
438
- % Src = src_ty. stdlib_name
439
- % ( srcSign, srcExt) = ( 's', 'sext') if srcSigned else ( 'u', 'zext')
440
- % if Self != Src:
441
- public init( _ v: ${ Src} ) {
429
+
430
+ % {
431
+ import gyb
432
+
433
+ fixed_fixed_conversion_function = gyb. parse_template ( " fixed_fixed_conversion_function " ,
434
+ """
442
435
%
443
- let srcNotWord = v. _value
436
+ let srcNotWord = value._value
437
+ let result: (value: Builtin.${BuiltinName}, error: Builtin.Int1)
444
438
%
445
- % if srcBits == bits and srcSign == sign:
446
- let dstNotWord = srcNotWord
439
+ % if srcBits == bits and srcSign == sign: # Exact same size/signedness.
440
+ result = ( srcNotWord, false._value)
447
441
%
448
- % elif srcBits == bits:
449
- let tmp = Builtin. ${ srcSign} _to_${ sign} _checked_conversion_Int${ srcBits} ( srcNotWord)
450
- Builtin . condfail ( tmp. 1 )
451
- let dstNotWord = tmp. 0
442
+ % elif srcBits == bits: # Same size, switching signs.
443
+ result = Builtin.${srcSign}_to_${sign}_checked_conversion_Int${srcBits}(srcNotWord)
452
444
%
453
- % elif srcBits > bits:
454
- let tmp = Builtin. ${ srcSign} _to_${ sign} _checked_trunc_Int${ srcBits} _Int${ bits} ( srcNotWord)
455
- Builtin . condfail ( tmp. 1 )
456
- let dstNotWord = tmp. 0
445
+ % elif srcBits > bits: # Larger input, check for truncation.
446
+ result = Builtin.${srcSign}_to_${sign}_checked_trunc_Int${srcBits}_Int${bits}(srcNotWord)
457
447
%
458
- % elif srcSigned and not signed:
459
- let tmp = Builtin . s_to_u_checked_conversion_Int ${ srcBits} ( srcNotWord)
460
- Builtin . condfail ( tmp. 1 )
461
- let dstNotWord = Builtin . ${ srcExt} _Int${ srcBits} _Int${ bits} ( tmp. 0 )
448
+ % elif srcSigned and not signed: # Smaller size input, signed going to unsigned.
449
+ let (tmp, signError) = Builtin.s_to_u_checked_conversion_Int${srcBits}(srcNotWord)
450
+ result = (Builtin.${srcExt}_Int${srcBits}_Int${bits}(tmp), signError)
462
451
%
463
- % else :
464
- let dstNotWord = Builtin . ${ srcExt} _Int${ srcBits} _Int${ bits} ( srcNotWord)
452
+ % else: # Smaller size input, unsigned to signed or unsigned to unsigned.
453
+ result = ( Builtin.${srcExt}_Int${srcBits}_Int${bits}(srcNotWord), false._value )
465
454
% end
466
- %
467
- self . _value = dstNotWord
455
+ %
456
+ % if not safelyConvertable:
457
+ ${error_check}
458
+ % end
459
+ self._value = result.value
460
+ """ )
461
+ } %
462
+
463
+ % for src_ty in all_integer_types( word_bits) :
464
+ % srcBits = src_ty. bits
465
+ % srcSigned = src_ty. is_signed
466
+ % Src = src_ty. stdlib_name
467
+ % ( srcSign, srcExt) = ( 's', 'sext') if srcSigned else ( 'u', 'zext')
468
+ % safelyConvertable = ( srcBits < bits and ( srcSign == sign or signed) ) or ( srcBits == bits and srcSign == sign)
469
+
470
+ @_transparent
471
+ extension ${ Self} {
472
+
473
+ @_transparent
474
+ public init( _ value: ${ Src} ) {
475
+ ${ gyb. execute_template (
476
+ fixed_fixed_conversion_function,
477
+ error_check= " Builtin.condfail(result.error) " ,
478
+ ** locals( )
479
+ )
480
+ }
481
+ }
482
+
483
+ % if safelyConvertable :
484
+ @available( * , message: " Converting ${Src} to ${Self} will always succeed. " )
485
+ % end
486
+ @_transparent
487
+ public init? ( exactly value: ${ Src} ) {
488
+ ${ gyb. execute_template (
489
+ fixed_fixed_conversion_function,
490
+ error_check= " if Bool(result.error) == true { return nil } " ,
491
+ ** locals( )
492
+ )
493
+ }
468
494
}
469
- % end
470
495
471
496
% if should_define_truncating_bit_pattern_init ( src_ty= src_ty, dst_ty= self_ty) :
472
497
/// Construct a `${Self}` having the same bitwise representation as
@@ -488,8 +513,10 @@ extension ${Self} {
488
513
}
489
514
490
515
% end
516
+ }
491
517
% end
492
518
519
+ extension ${ Self} {
493
520
/// Construct a `${Self}` having the same memory representation as
494
521
/// the `${OtherSelf}` `bitPattern`. No range or overflow checking
495
522
/// occurs, and the resulting `${Self}` may not have the same numeric
0 commit comments