2424use fmt;
2525use iter:: Sum ;
2626use ops:: { Add , Sub , Mul , Div , AddAssign , SubAssign , MulAssign , DivAssign } ;
27+ use { u64, u128} ;
2728
2829const NANOS_PER_SEC : u32 = 1_000_000_000 ;
2930const NANOS_PER_MILLI : u32 = 1_000_000 ;
@@ -501,13 +502,81 @@ impl Mul<u32> for Duration {
501502 }
502503}
503504
505+ #[ stable( feature = "duration_mul_div_extras" , since = "1.29.0" ) ]
506+ impl Mul < Duration > for u32 {
507+ type Output = Duration ;
508+
509+ fn mul ( self , rhs : Duration ) -> Duration {
510+ rhs. checked_mul ( self ) . expect ( "overflow when multiplying scalar by duration" )
511+ }
512+ }
513+
514+ #[ stable( feature = "duration_mul_div_extras" , since = "1.29.0" ) ]
515+ impl Mul < f64 > for Duration {
516+ type Output = Duration ;
517+
518+ fn mul ( self , rhs : f64 ) -> Duration {
519+ const NPS : f64 = NANOS_PER_SEC as f64 ;
520+ let nanos_f64 = rhs * ( NPS * ( self . secs as f64 ) + ( self . nanos as f64 ) ) ;
521+ if !nanos_f64. is_finite ( ) {
522+ panic ! ( "got non-finite value when multiplying duration by float" ) ;
523+ }
524+ if nanos_f64 > ( u128:: MAX as f64 ) {
525+ panic ! ( "overflow when multiplying duration by float" ) ;
526+ } ;
527+ let nanos_u128 = nanos_f64 as u128 ;
528+ let secs = nanos_u128 / ( NANOS_PER_SEC as u128 ) ;
529+ let nanos = nanos_u128 % ( NANOS_PER_SEC as u128 ) ;
530+ if secs > ( u64:: MAX as u128 ) {
531+ panic ! ( "overflow when multiplying duration by float" ) ;
532+ }
533+ Duration {
534+ secs : secs as u64 ,
535+ nanos : nanos as u32 ,
536+ }
537+ }
538+ }
539+
540+ #[ stable( feature = "duration_mul_div_extras" , since = "1.29.0" ) ]
541+ impl Mul < Duration > for f64 {
542+ type Output = Duration ;
543+
544+ fn mul ( self , rhs : Duration ) -> Duration {
545+ const NPS : f64 = NANOS_PER_SEC as f64 ;
546+ let nanos_f64 = self * ( NPS * ( rhs. secs as f64 ) + ( rhs. nanos as f64 ) ) ;
547+ if !nanos_f64. is_finite ( ) {
548+ panic ! ( "got non-finite value when multiplying float by duration" ) ;
549+ }
550+ if nanos_f64 > ( u128:: MAX as f64 ) {
551+ panic ! ( "overflow when multiplying float by duration" ) ;
552+ } ;
553+ let nanos_u128 = nanos_f64 as u128 ;
554+ let secs = nanos_u128 / ( NANOS_PER_SEC as u128 ) ;
555+ let nanos = nanos_u128 % ( NANOS_PER_SEC as u128 ) ;
556+ if secs > ( u64:: MAX as u128 ) {
557+ panic ! ( "overflow when multiplying float by duration" ) ;
558+ }
559+ Duration {
560+ secs : secs as u64 ,
561+ nanos : nanos as u32 ,
562+ }
563+ }
564+ }
565+
504566#[ stable( feature = "time_augmented_assignment" , since = "1.9.0" ) ]
505567impl MulAssign < u32 > for Duration {
506568 fn mul_assign ( & mut self , rhs : u32 ) {
507569 * self = * self * rhs;
508570 }
509571}
510572
573+ #[ stable( feature = "duration_mul_div_extras" , since = "1.29.0" ) ]
574+ impl MulAssign < f64 > for Duration {
575+ fn mul_assign ( & mut self , rhs : f64 ) {
576+ * self = * self * rhs;
577+ }
578+ }
579+
511580#[ stable( feature = "duration" , since = "1.3.0" ) ]
512581impl Div < u32 > for Duration {
513582 type Output = Duration ;
@@ -517,13 +586,59 @@ impl Div<u32> for Duration {
517586 }
518587}
519588
589+ #[ stable( feature = "duration_mul_div_extras" , since = "1.29.0" ) ]
590+ impl Div < f64 > for Duration {
591+ type Output = Duration ;
592+
593+ fn div ( self , rhs : f64 ) -> Duration {
594+ const NPS : f64 = NANOS_PER_SEC as f64 ;
595+ let nanos_f64 = ( NPS * ( self . secs as f64 ) + ( self . nanos as f64 ) ) / rhs;
596+ if !nanos_f64. is_finite ( ) {
597+ panic ! ( "got non-finite value when dividing duration by float" ) ;
598+ }
599+ if nanos_f64 > ( u128:: MAX as f64 ) {
600+ panic ! ( "overflow when dividing duration by float" ) ;
601+ } ;
602+ let nanos_u128 = nanos_f64 as u128 ;
603+ let secs = nanos_u128 / ( NANOS_PER_SEC as u128 ) ;
604+ let nanos = nanos_u128 % ( NANOS_PER_SEC as u128 ) ;
605+ if secs > ( u64:: MAX as u128 ) {
606+ panic ! ( "overflow when dividing duration by float" ) ;
607+ }
608+ Duration {
609+ secs : secs as u64 ,
610+ nanos : nanos as u32 ,
611+ }
612+ }
613+ }
614+
615+ #[ stable( feature = "duration_mul_div_extras" , since = "1.29.0" ) ]
616+ impl Div < Duration > for Duration {
617+ type Output = f64 ;
618+
619+ fn div ( self , rhs : Duration ) -> f64 {
620+ const NPS : f64 = NANOS_PER_SEC as f64 ;
621+ let nanos1 = NPS * ( self . secs as f64 ) + ( self . nanos as f64 ) ;
622+ let nanos2 = NPS * ( rhs. secs as f64 ) + ( rhs. nanos as f64 ) ;
623+ nanos1/nanos2
624+ }
625+ }
626+
520627#[ stable( feature = "time_augmented_assignment" , since = "1.9.0" ) ]
521628impl DivAssign < u32 > for Duration {
522629 fn div_assign ( & mut self , rhs : u32 ) {
523630 * self = * self / rhs;
524631 }
525632}
526633
634+ #[ stable( feature = "duration_mul_div_extras" , since = "1.29.0" ) ]
635+ impl DivAssign < f64 > for Duration {
636+ fn div_assign ( & mut self , rhs : f64 ) {
637+ * self = * self / rhs;
638+ }
639+ }
640+
641+
527642macro_rules! sum_durations {
528643 ( $iter: expr) => { {
529644 let mut total_secs: u64 = 0 ;
0 commit comments