@@ -78,6 +78,41 @@ macro_rules! impl_int_arith {
78
78
pub fn saturating_sub( self , second: Self ) -> Self {
79
79
unsafe { crate :: intrinsics:: simd_saturating_sub( self , second) }
80
80
}
81
+
82
+ /// Lanewise saturating absolute value, implemented in Rust.
83
+ ///
84
+ /// # Examples
85
+ /// # use core_simd::*;
86
+ #[ doc = concat!( "# use core::" , stringify!( $n) , "::{MIN, MAX};" ) ]
87
+ #[ doc = concat!( "let x = " , stringify!( $name) , "::splat([MIN, -2, 0, 3]);" ) ]
88
+ /// let unsat = x.abs();
89
+ /// let sat = x.saturating_abs();
90
+ #[ doc = concat!( "assert_eq!(unsat, " , stringify!( $name) , "::from_array([MIN, 2, 0, 3]);" ) ]
91
+ #[ doc = concat!( "assert_eq!(sat, " , stringify!( $name) , "::from_array([MAX, 2, 0, 3]));" ) ]
92
+ /// ```
93
+ #[ inline]
94
+ pub fn saturating_abs( self ) -> Self {
95
+ // arith shift for -1 or 0 mask based on sign bit, giving 2s complement
96
+ const SHR : $n = <$n>:: BITS as $n - 1 ;
97
+ let m = self >> SHR ;
98
+ ( self ^m) . saturating_sub( m)
99
+ }
100
+
101
+ /// Lanewise saturating negation, implemented in Rust.
102
+ ///
103
+ /// # Examples
104
+ /// # use core_simd::*;
105
+ #[ doc = concat!( "# use core::" , stringify!( $n) , "::{MIN, MAX};" ) ]
106
+ #[ doc = concat!( "let x = " , stringify!( $name) , "::splat([MIN, -2, 3, MAX]);" ) ]
107
+ /// let unsat = -x;
108
+ /// let sat = x.saturating_neg();
109
+ #[ doc = concat!( "assert_eq!(unsat, " , stringify!( $name) , "::from_array([MIN, 2, -3, MIN + 1]);" ) ]
110
+ #[ doc = concat!( "assert_eq!(sat, " , stringify!( $name) , "::from_array([MAX, 2, -3, MIN + 1]));" ) ]
111
+ /// ```
112
+ #[ inline]
113
+ pub fn saturating_neg( self ) -> Self {
114
+ Self :: splat( 0 ) . saturating_sub( self )
115
+ }
81
116
} ) +
82
117
}
83
118
}
0 commit comments