@@ -46,6 +46,27 @@ pub trait Euclid: Sized + Div<Self, Output = Self> + Rem<Self, Output = Self> {
4646 /// assert_eq!(Euclid::rem_euclid(&-a, &-b), 1);
4747 /// ```
4848 fn rem_euclid ( & self , v : & Self ) -> Self ;
49+
50+ /// Returns both the quotient and remainder from Euclidean division.
51+ ///
52+ /// By default, it internally calls both `Euclid::div_euclid` and `Euclid::rem_euclid`,
53+ /// but it can be overridden in order to implement some optimization.
54+ ///
55+ /// # Examples
56+ ///
57+ /// ```
58+ /// # use num_traits::Euclid;
59+ /// let x = 5u8;
60+ /// let y = 3u8;
61+ ///
62+ /// let div = Euclid::div_euclid(&x, &y);
63+ /// let rem = Euclid::rem_euclid(&x, &y);
64+ ///
65+ /// assert_eq!((div, rem), Euclid::div_rem_euclid(&x, &y));
66+ /// ```
67+ fn div_rem_euclid ( & self , v : & Self ) -> ( Self , Self ) {
68+ ( self . div_euclid ( v) , self . rem_euclid ( v) )
69+ }
4970}
5071
5172macro_rules! euclid_forward_impl {
@@ -174,6 +195,26 @@ pub trait CheckedEuclid: Euclid {
174195 /// Finds the euclid remainder of dividing two numbers, checking for underflow, overflow and
175196 /// division by zero. If any of that happens, `None` is returned.
176197 fn checked_rem_euclid ( & self , v : & Self ) -> Option < Self > ;
198+
199+ /// Returns both the quotient and remainder from checked Euclidean division.
200+ ///
201+ /// By default, it internally calls both `CheckedEuclid::checked_div_euclid` and `CheckedEuclid::checked_rem_euclid`,
202+ /// but it can be overridden in order to implement some optimization.
203+ /// # Examples
204+ ///
205+ /// ```
206+ /// # use num_traits::CheckedEuclid;
207+ /// let x = 5u8;
208+ /// let y = 3u8;
209+ ///
210+ /// let div = CheckedEuclid::checked_div_euclid(&x, &y);
211+ /// let rem = CheckedEuclid::checked_rem_euclid(&x, &y);
212+ ///
213+ /// assert_eq!(Some((div.unwrap(), rem.unwrap())), CheckedEuclid::checked_div_rem_euclid(&x, &y));
214+ /// ```
215+ fn checked_div_rem_euclid ( & self , v : & Self ) -> Option < ( Self , Self ) > {
216+ Some ( ( self . checked_div_euclid ( v) ?, self . checked_rem_euclid ( v) ?) )
217+ }
177218}
178219
179220macro_rules! checked_euclid_forward_impl {
@@ -262,8 +303,11 @@ mod tests {
262303 {
263304 let x: $t = 10 ;
264305 let y: $t = 3 ;
265- assert_eq!( Euclid :: div_euclid( & x, & y) , 3 ) ;
266- assert_eq!( Euclid :: rem_euclid( & x, & y) , 1 ) ;
306+ let div = Euclid :: div_euclid( & x, & y) ;
307+ let rem = Euclid :: rem_euclid( & x, & y) ;
308+ assert_eq!( div, 3 ) ;
309+ assert_eq!( rem, 1 ) ;
310+ assert_eq!( ( div, rem) , Euclid :: div_rem_euclid( & x, & y) ) ;
267311 }
268312 ) +
269313 } ;
@@ -284,6 +328,7 @@ mod tests {
284328 assert_eq!( Euclid :: div_euclid( & -x, & y) , 4 ) ;
285329 assert_eq!( Euclid :: rem_euclid( & x, & y) , 1 ) ;
286330 assert_eq!( Euclid :: rem_euclid( & -x, & y) , 2 ) ;
331+ assert_eq!( ( Euclid :: div_euclid( & x, & y) , Euclid :: rem_euclid( & x, & y) ) , Euclid :: div_rem_euclid( & x, & y) ) ;
287332 let x: $t = $t:: min_value( ) + 1 ;
288333 let y: $t = -1 ;
289334 assert_eq!( Euclid :: div_euclid( & x, & y) , $t:: max_value( ) ) ;
@@ -311,6 +356,7 @@ mod tests {
311356 <= 46.4 * <$t as crate :: float:: FloatCore >:: epsilon( ) ) ;
312357 assert!( Euclid :: div_euclid( & -x, & -y) * -y + Euclid :: rem_euclid( & -x, & -y) + x
313358 <= 46.4 * <$t as crate :: float:: FloatCore >:: epsilon( ) ) ;
359+ assert_eq!( ( Euclid :: div_euclid( & x, & y) , Euclid :: rem_euclid( & x, & y) ) , Euclid :: div_rem_euclid( & x, & y) ) ;
314360 }
315361 ) +
316362 } ;
0 commit comments