@@ -4048,5 +4048,123 @@ macro_rules! int_impl {
40484048 {
40494049 traits:: WidenTarget :: internal_widen( self )
40504050 }
4051+
4052+
4053+ /// Converts `self` to the target integer type, saturating at the numeric
4054+ /// bounds instead of overflowing.
4055+ ///
4056+ /// # Examples
4057+ ///
4058+ /// ```
4059+ /// #![feature(integer_casts)]
4060+ #[ doc = concat!( "assert_eq!(i8::MAX, " , stringify!( $SelfT) , "::MAX.saturating_cast());" ) ]
4061+ #[ doc = concat!( "assert_eq!(i8::MIN, " , stringify!( $SelfT) , "::MIN.saturating_cast());" ) ]
4062+ #[ doc = concat!( "assert_eq!(42u8, 42" , stringify!( $SelfT) , ".saturating_cast());" ) ]
4063+ #[ doc = concat!( "assert_eq!(0u8, (-42" , stringify!( $SelfT) , ").saturating_cast());" ) ]
4064+ /// ```
4065+ #[ must_use = "this returns the cast result and does not modify the original" ]
4066+ #[ unstable( feature = "integer_casts" , issue = "157388" ) ]
4067+ #[ rustc_const_unstable( feature = "integer_casts" , issue = "157388" ) ]
4068+ #[ inline( always) ]
4069+ pub const fn saturating_cast<T : [ const ] BoundedCastFromInt <Self >>( self ) -> T {
4070+ T :: saturating_cast_from( self )
4071+ }
4072+
4073+ /// Converts `self` to the target integer type, wrapping around at the
4074+ /// boundary of the target type.
4075+ ///
4076+ /// # Examples
4077+ ///
4078+ /// ```
4079+ /// #![feature(integer_casts)]
4080+ #[ doc = concat!( "assert_eq!(" , stringify!( $SelfT) , "::MAX as i8, " , stringify!( $SelfT) , "::MAX.wrapping_cast());" ) ]
4081+ #[ doc = concat!( "assert_eq!(" , stringify!( $SelfT) , "::MIN as i8, " , stringify!( $SelfT) , "::MIN.wrapping_cast());" ) ]
4082+ #[ doc = concat!( "assert_eq!(42u8, 42" , stringify!( $SelfT) , ".wrapping_cast());" ) ]
4083+ #[ doc = concat!( "assert_eq!(u8::MAX - 41, (-42" , stringify!( $SelfT) , ").wrapping_cast());" ) ]
4084+ /// ```
4085+ #[ must_use = "this returns the cast result and does not modify the original" ]
4086+ #[ unstable( feature = "integer_casts" , issue = "157388" ) ]
4087+ #[ rustc_const_unstable( feature = "integer_casts" , issue = "157388" ) ]
4088+ #[ inline( always) ]
4089+ pub const fn wrapping_cast<T : [ const ] BoundedCastFromInt <Self >>( self ) -> T {
4090+ T :: wrapping_cast_from( self )
4091+ }
4092+
4093+ /// Converts `self` to the target integer type, returning `None` if the value
4094+ /// is not representable by the target type.
4095+ ///
4096+ /// # Examples
4097+ ///
4098+ /// ```
4099+ /// #![feature(integer_casts)]
4100+ #[ doc = concat!( "assert_eq!(Some(42u8), 42" , stringify!( $SelfT) , ".checked_cast());" ) ]
4101+ #[ doc = concat!( "assert_eq!((-42" , stringify!( $SelfT) , ").checked_cast::<u8>(), None);" ) ]
4102+ /// ```
4103+ #[ must_use = "this returns the cast result and does not modify the original" ]
4104+ #[ unstable( feature = "integer_casts" , issue = "157388" ) ]
4105+ #[ rustc_const_unstable( feature = "integer_casts" , issue = "157388" ) ]
4106+ #[ inline( always) ]
4107+ pub const fn checked_cast<T : [ const ] CheckedCastFromInt <Self >>( self ) -> Option <T > {
4108+ T :: checked_cast_from( self )
4109+ }
4110+
4111+ /// Converts `self` to the target integer type, panicking if the value
4112+ /// is not representable by the target type.
4113+ ///
4114+ /// # Panics
4115+ ///
4116+ /// This function will panic if the value is not representable by the target type.
4117+ ///
4118+ /// # Examples
4119+ ///
4120+ /// ```
4121+ /// #![feature(integer_casts)]
4122+ #[ doc = concat!( "assert_eq!(42u8, 42" , stringify!( $SelfT) , ".strict_cast());" ) ]
4123+ /// ```
4124+ ///
4125+ /// The following will panic:
4126+ ///
4127+ /// ```should_panic
4128+ /// #![feature(integer_casts)]
4129+ #[ doc = concat!( "let _ = (-42" , stringify!( $SelfT) , ").strict_cast::<u8>();" ) ]
4130+ /// ```
4131+ #[ must_use = "this returns the cast result and does not modify the original" ]
4132+ #[ unstable( feature = "integer_casts" , issue = "157388" ) ]
4133+ #[ rustc_const_unstable( feature = "integer_casts" , issue = "157388" ) ]
4134+ #[ inline( always) ]
4135+ #[ track_caller]
4136+ pub const fn strict_cast<T : [ const ] CheckedCastFromInt <Self >>( self ) -> T {
4137+ T :: strict_cast_from( self )
4138+ }
4139+
4140+ /// Converts `self` to the target integer type, assuming the value is
4141+ /// representable by the target type.
4142+ ///
4143+ /// # Safety
4144+ ///
4145+ /// This results in undefined behavior if the integer value of `self` is bigger than `T::MAX`,
4146+ /// or smaller than `T::MIN`, where `T` is the target type.
4147+ #[ must_use = "this returns the cast result and does not modify the original" ]
4148+ #[ unstable( feature = "integer_casts" , issue = "157388" ) ]
4149+ #[ rustc_const_unstable( feature = "integer_casts" , issue = "157388" ) ]
4150+ #[ inline( always) ]
4151+ pub const unsafe fn unchecked_cast<T : [ const ] CheckedCastFromInt <Self >>( self ) -> T {
4152+ assert_unsafe_precondition!(
4153+ check_language_ub,
4154+ concat!( stringify!( $SelfT) , "::unchecked_cast must fit in the target type" ) ,
4155+ (
4156+ // Check has to be performed up-front because it depends on generic T.
4157+ in_bounds: bool = {
4158+ let cast_val = self . checked_cast:: <T >( ) ;
4159+ let ret = cast_val. is_some( ) ;
4160+ core:: mem:: forget( cast_val) ; // We don't have const Drop, but we know it's an int.
4161+ ret
4162+ } ,
4163+ ) => in_bounds,
4164+ ) ;
4165+
4166+ // SAFETY: this is guaranteed to be safe by the caller.
4167+ unsafe { T :: unchecked_cast_from( self ) }
4168+ }
40514169 }
40524170}
0 commit comments