@@ -4,7 +4,7 @@ use crate::fmt;
44use crate :: ops:: { Add , AddAssign , BitAnd , BitAndAssign , BitOr , BitOrAssign } ;
55use crate :: ops:: { BitXor , BitXorAssign , Div , DivAssign } ;
66use crate :: ops:: { Mul , MulAssign , Neg , Not } ;
7- use crate :: ops:: { Sub , SubAssign } ;
7+ use crate :: ops:: { Shl , ShlAssign , Shr , ShrAssign , Sub , SubAssign } ;
88
99/// Provides intentionally-wrapped arithmetic on `T`.
1010///
@@ -78,6 +78,127 @@ impl<T: fmt::UpperHex> fmt::UpperHex for Saturating<T> {
7878 self . 0 . fmt ( f)
7979 }
8080}
81+ #[ allow( unused_macros) ]
82+ macro_rules! sh_impl_signed {
83+ ( $t: ident, $f: ident) => {
84+ #[ unstable( feature = "saturating_int_impl" , issue = "87920" ) ]
85+ impl Shl <$f> for Saturating <$t> {
86+ type Output = Saturating <$t>;
87+
88+ #[ inline]
89+ fn shl( self , other: $f) -> Saturating <$t> {
90+ if other < 0 {
91+ Saturating ( self . 0 . shr( ( -other & self :: shift_max:: $t as $f) as u32 ) )
92+ } else {
93+ Saturating ( self . 0 . shl( ( other & self :: shift_max:: $t as $f) as u32 ) )
94+ }
95+ }
96+ }
97+ forward_ref_binop! { impl Shl , shl for Saturating <$t>, $f,
98+ #[ unstable( feature = "saturating_int_impl" , issue = "87920" ) ] }
99+
100+ #[ unstable( feature = "saturating_int_impl" , issue = "87920" ) ]
101+ impl ShlAssign <$f> for Saturating <$t> {
102+ #[ inline]
103+ fn shl_assign( & mut self , other: $f) {
104+ * self = * self << other;
105+ }
106+ }
107+ forward_ref_op_assign! { impl ShlAssign , shl_assign for Saturating <$t>, $f }
108+
109+ #[ unstable( feature = "saturating_int_impl" , issue = "87920" ) ]
110+ impl Shr <$f> for Saturating <$t> {
111+ type Output = Saturating <$t>;
112+
113+ #[ inline]
114+ fn shr( self , other: $f) -> Saturating <$t> {
115+ if other < 0 {
116+ Saturating ( self . 0 . shl( ( -other & self :: shift_max:: $t as $f) as u32 ) )
117+ } else {
118+ Saturating ( self . 0 . shr( ( other & self :: shift_max:: $t as $f) as u32 ) )
119+ }
120+ }
121+ }
122+ forward_ref_binop! { impl Shr , shr for Saturating <$t>, $f,
123+ #[ unstable( feature = "saturating_int_impl" , issue = "87920" ) ] }
124+
125+ #[ unstable( feature = "saturating_int_impl" , issue = "87920" ) ]
126+ impl ShrAssign <$f> for Saturating <$t> {
127+ #[ inline]
128+ fn shr_assign( & mut self , other: $f) {
129+ * self = * self >> other;
130+ }
131+ }
132+ forward_ref_op_assign! { impl ShrAssign , shr_assign for Saturating <$t>, $f }
133+ } ;
134+ }
135+
136+ macro_rules! sh_impl_unsigned {
137+ ( $t: ident, $f: ident) => {
138+ #[ unstable( feature = "saturating_int_impl" , issue = "87920" ) ]
139+ impl Shl <$f> for Saturating <$t> {
140+ type Output = Saturating <$t>;
141+
142+ #[ inline]
143+ fn shl( self , other: $f) -> Saturating <$t> {
144+ Saturating ( self . 0 . shl( ( other & self :: shift_max:: $t as $f) as u32 ) )
145+ }
146+ }
147+ forward_ref_binop! { impl Shl , shl for Saturating <$t>, $f,
148+ #[ unstable( feature = "saturating_int_impl" , issue = "87920" ) ] }
149+
150+ #[ unstable( feature = "saturating_int_impl" , issue = "87920" ) ]
151+ impl ShlAssign <$f> for Saturating <$t> {
152+ #[ inline]
153+ fn shl_assign( & mut self , other: $f) {
154+ * self = * self << other;
155+ }
156+ }
157+ forward_ref_op_assign! { impl ShlAssign , shl_assign for Saturating <$t>, $f }
158+
159+ #[ unstable( feature = "saturating_int_impl" , issue = "87920" ) ]
160+ impl Shr <$f> for Saturating <$t> {
161+ type Output = Saturating <$t>;
162+
163+ #[ inline]
164+ fn shr( self , other: $f) -> Saturating <$t> {
165+ Saturating ( self . 0 . shr( ( other & self :: shift_max:: $t as $f) as u32 ) )
166+ }
167+ }
168+ forward_ref_binop! { impl Shr , shr for Saturating <$t>, $f,
169+ #[ unstable( feature = "saturating_int_impl" , issue = "87920" ) ] }
170+
171+ #[ unstable( feature = "saturating_int_impl" , issue = "87920" ) ]
172+ impl ShrAssign <$f> for Saturating <$t> {
173+ #[ inline]
174+ fn shr_assign( & mut self , other: $f) {
175+ * self = * self >> other;
176+ }
177+ }
178+ forward_ref_op_assign! { impl ShrAssign , shr_assign for Saturating <$t>, $f }
179+ } ;
180+ }
181+
182+ // FIXME (#23545): uncomment the remaining impls
183+ macro_rules! sh_impl_all {
184+ ( $( $t: ident) * ) => ( $(
185+ //sh_impl_unsigned! { $t, u8 }
186+ //sh_impl_unsigned! { $t, u16 }
187+ //sh_impl_unsigned! { $t, u32 }
188+ //sh_impl_unsigned! { $t, u64 }
189+ //sh_impl_unsigned! { $t, u128 }
190+ sh_impl_unsigned! { $t, usize }
191+
192+ //sh_impl_signed! { $t, i8 }
193+ //sh_impl_signed! { $t, i16 }
194+ //sh_impl_signed! { $t, i32 }
195+ //sh_impl_signed! { $t, i64 }
196+ //sh_impl_signed! { $t, i128 }
197+ //sh_impl_signed! { $t, isize }
198+ ) * )
199+ }
200+
201+ sh_impl_all ! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
81202
82203// FIXME(30524): impl Op<T> for Saturating<T>, impl OpAssign<T> for Saturating<T>
83204macro_rules! saturating_impl {
@@ -774,3 +895,39 @@ macro_rules! saturating_int_impl_unsigned {
774895}
775896
776897saturating_int_impl_unsigned ! { usize u8 u16 u32 u64 u128 }
898+
899+ mod shift_max {
900+ #![ allow( non_upper_case_globals) ]
901+
902+ #[ cfg( target_pointer_width = "16" ) ]
903+ mod platform {
904+ pub const usize: u32 = super :: u16;
905+ pub const isize: u32 = super :: i16;
906+ }
907+
908+ #[ cfg( target_pointer_width = "32" ) ]
909+ mod platform {
910+ pub const usize: u32 = super :: u32;
911+ pub const isize: u32 = super :: i32;
912+ }
913+
914+ #[ cfg( target_pointer_width = "64" ) ]
915+ mod platform {
916+ pub const usize: u32 = super :: u64;
917+ pub const isize: u32 = super :: i64;
918+ }
919+
920+ pub const i8: u32 = ( 1 << 3 ) - 1 ;
921+ pub const i16: u32 = ( 1 << 4 ) - 1 ;
922+ pub const i32: u32 = ( 1 << 5 ) - 1 ;
923+ pub const i64: u32 = ( 1 << 6 ) - 1 ;
924+ pub const i128: u32 = ( 1 << 7 ) - 1 ;
925+ pub use self :: platform:: isize;
926+
927+ pub const u8: u32 = i8;
928+ pub const u16: u32 = i16;
929+ pub const u32: u32 = i32;
930+ pub const u64: u32 = i64;
931+ pub const u128: u32 = i128;
932+ pub use self :: platform:: usize;
933+ }
0 commit comments