24
24
use fmt;
25
25
use iter:: Sum ;
26
26
use ops:: { Add , Sub , Mul , Div , AddAssign , SubAssign , MulAssign , DivAssign } ;
27
+ use { u64, u128} ;
27
28
28
29
const NANOS_PER_SEC : u32 = 1_000_000_000 ;
29
30
const NANOS_PER_MILLI : u32 = 1_000_000 ;
@@ -501,13 +502,81 @@ impl Mul<u32> for Duration {
501
502
}
502
503
}
503
504
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
+
504
566
#[ stable( feature = "time_augmented_assignment" , since = "1.9.0" ) ]
505
567
impl MulAssign < u32 > for Duration {
506
568
fn mul_assign ( & mut self , rhs : u32 ) {
507
569
* self = * self * rhs;
508
570
}
509
571
}
510
572
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
+
511
580
#[ stable( feature = "duration" , since = "1.3.0" ) ]
512
581
impl Div < u32 > for Duration {
513
582
type Output = Duration ;
@@ -517,13 +586,59 @@ impl Div<u32> for Duration {
517
586
}
518
587
}
519
588
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
+
520
627
#[ stable( feature = "time_augmented_assignment" , since = "1.9.0" ) ]
521
628
impl DivAssign < u32 > for Duration {
522
629
fn div_assign ( & mut self , rhs : u32 ) {
523
630
* self = * self / rhs;
524
631
}
525
632
}
526
633
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
+
527
642
macro_rules! sum_durations {
528
643
( $iter: expr) => { {
529
644
let mut total_secs: u64 = 0 ;
0 commit comments