Skip to content

Commit b869aa5

Browse files
committedSep 7, 2020
Add saturating methods for Duration
1 parent 9fe551a commit b869aa5

File tree

5 files changed

+156
-16
lines changed

5 files changed

+156
-16
lines changed
 

‎library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
#![feature(doc_cfg)]
101101
#![feature(doc_spotlight)]
102102
#![feature(duration_consts_2)]
103+
#![feature(duration_saturating_ops)]
103104
#![feature(extern_types)]
104105
#![feature(fundamental)]
105106
#![feature(intrinsics)]

‎library/core/src/time.rs

+97
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,34 @@ impl Duration {
108108
#[unstable(feature = "duration_constants", issue = "57391")]
109109
pub const NANOSECOND: Duration = Duration::from_nanos(1);
110110

111+
/// The minimum duration.
112+
///
113+
/// # Examples
114+
///
115+
/// ```
116+
/// #![feature(duration_constants)]
117+
/// use std::time::Duration;
118+
///
119+
/// assert_eq!(Duration::MIN, Duration::new(0, 0));
120+
/// ```
121+
#[unstable(feature = "duration_constants", issue = "57391")]
122+
pub const MIN: Duration = Duration::from_nanos(0);
123+
124+
/// The maximum duration.
125+
///
126+
/// It is roughly equal to a duration of 584,942,417,355 years.
127+
///
128+
/// # Examples
129+
///
130+
/// ```
131+
/// #![feature(duration_constants)]
132+
/// use std::time::Duration;
133+
///
134+
/// assert_eq!(Duration::MAX, Duration::new(u64::MAX, 1_000_000_000 - 1));
135+
/// ```
136+
#[unstable(feature = "duration_constants", issue = "57391")]
137+
pub const MAX: Duration = Duration::new(u64::MAX, NANOS_PER_SEC - 1);
138+
111139
/// Creates a new `Duration` from the specified number of whole seconds and
112140
/// additional nanoseconds.
113141
///
@@ -450,6 +478,29 @@ impl Duration {
450478
}
451479
}
452480

481+
/// Saturating `Duration` addition. Computes `self + other`, returning [`Duration::MAX`]
482+
/// if overflow occurred.
483+
///
484+
/// # Examples
485+
///
486+
/// ```
487+
/// #![feature(duration_saturating_ops)]
488+
/// #![feature(duration_constants)]
489+
/// use std::time::Duration;
490+
///
491+
/// assert_eq!(Duration::new(0, 0).saturating_add(Duration::new(0, 1)), Duration::new(0, 1));
492+
/// assert_eq!(Duration::new(1, 0).saturating_add(Duration::new(u64::MAX, 0)), Duration::MAX);
493+
/// ```
494+
#[unstable(feature = "duration_saturating_ops", issue = "76416")]
495+
#[inline]
496+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
497+
pub const fn saturating_add(self, rhs: Duration) -> Duration {
498+
match self.checked_add(rhs) {
499+
Some(res) => res,
500+
None => Duration::MAX,
501+
}
502+
}
503+
453504
/// Checked `Duration` subtraction. Computes `self - other`, returning [`None`]
454505
/// if the result would be negative or if overflow occurred.
455506
///
@@ -485,6 +536,29 @@ impl Duration {
485536
}
486537
}
487538

539+
/// Saturating `Duration` subtraction. Computes `self - other`, returning [`Duration::MIN`]
540+
/// if the result would be negative or if overflow occurred.
541+
///
542+
/// # Examples
543+
///
544+
/// ```
545+
/// #![feature(duration_saturating_ops)]
546+
/// #![feature(duration_constants)]
547+
/// use std::time::Duration;
548+
///
549+
/// assert_eq!(Duration::new(0, 1).saturating_sub(Duration::new(0, 0)), Duration::new(0, 1));
550+
/// assert_eq!(Duration::new(0, 0).saturating_sub(Duration::new(0, 1)), Duration::MIN);
551+
/// ```
552+
#[unstable(feature = "duration_saturating_ops", issue = "76416")]
553+
#[inline]
554+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
555+
pub const fn saturating_sub(self, rhs: Duration) -> Duration {
556+
match self.checked_sub(rhs) {
557+
Some(res) => res,
558+
None => Duration::MIN,
559+
}
560+
}
561+
488562
/// Checked `Duration` multiplication. Computes `self * other`, returning
489563
/// [`None`] if overflow occurred.
490564
///
@@ -515,6 +589,29 @@ impl Duration {
515589
None
516590
}
517591

592+
/// Saturating `Duration` multiplication. Computes `self * other`, returning
593+
/// [`Duration::MAX`] if overflow occurred.
594+
///
595+
/// # Examples
596+
///
597+
/// ```
598+
/// #![feature(duration_saturating_ops)]
599+
/// #![feature(duration_constants)]
600+
/// use std::time::Duration;
601+
///
602+
/// assert_eq!(Duration::new(0, 500_000_001).saturating_mul(2), Duration::new(1, 2));
603+
/// assert_eq!(Duration::new(u64::MAX - 1, 0).saturating_mul(2), Duration::MAX);
604+
/// ```
605+
#[unstable(feature = "duration_saturating_ops", issue = "76416")]
606+
#[inline]
607+
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
608+
pub const fn saturating_mul(self, rhs: u32) -> Duration {
609+
match self.checked_mul(rhs) {
610+
Some(res) => res,
611+
None => Duration::MAX,
612+
}
613+
}
614+
518615
/// Checked `Duration` division. Computes `self / other`, returning [`None`]
519616
/// if `other == 0`.
520617
///

‎library/core/tests/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#![feature(core_private_diy_float)]
1111
#![feature(debug_non_exhaustive)]
1212
#![feature(dec2flt)]
13+
#![feature(duration_constants)]
14+
#![feature(duration_saturating_ops)]
1315
#![feature(exact_size_is_empty)]
1416
#![feature(fixed_size_array)]
1517
#![feature(flt2dec)]

‎library/core/tests/time.rs

+30
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,16 @@ fn checked_add() {
8989
assert_eq!(Duration::new(1, 0).checked_add(Duration::new(u64::MAX, 0)), None);
9090
}
9191

92+
#[test]
93+
fn saturating_add() {
94+
assert_eq!(Duration::new(0, 0).saturating_add(Duration::new(0, 1)), Duration::new(0, 1));
95+
assert_eq!(
96+
Duration::new(0, 500_000_000).saturating_add(Duration::new(0, 500_000_001)),
97+
Duration::new(1, 1)
98+
);
99+
assert_eq!(Duration::new(1, 0).saturating_add(Duration::new(u64::MAX, 0)), Duration::MAX);
100+
}
101+
92102
#[test]
93103
fn sub() {
94104
assert_eq!(Duration::new(0, 1) - Duration::new(0, 0), Duration::new(0, 1));
@@ -107,6 +117,17 @@ fn checked_sub() {
107117
assert_eq!(zero.checked_sub(one_sec), None);
108118
}
109119

120+
#[test]
121+
fn saturating_sub() {
122+
let zero = Duration::new(0, 0);
123+
let one_nano = Duration::new(0, 1);
124+
let one_sec = Duration::new(1, 0);
125+
assert_eq!(one_nano.saturating_sub(zero), Duration::new(0, 1));
126+
assert_eq!(one_sec.saturating_sub(one_nano), Duration::new(0, 999_999_999));
127+
assert_eq!(zero.saturating_sub(one_nano), Duration::MIN);
128+
assert_eq!(zero.saturating_sub(one_sec), Duration::MIN);
129+
}
130+
110131
#[test]
111132
#[should_panic]
112133
fn sub_bad1() {
@@ -136,6 +157,15 @@ fn checked_mul() {
136157
assert_eq!(Duration::new(u64::MAX - 1, 0).checked_mul(2), None);
137158
}
138159

160+
#[test]
161+
fn saturating_mul() {
162+
assert_eq!(Duration::new(0, 1).saturating_mul(2), Duration::new(0, 2));
163+
assert_eq!(Duration::new(1, 1).saturating_mul(3), Duration::new(3, 3));
164+
assert_eq!(Duration::new(0, 500_000_001).saturating_mul(4), Duration::new(2, 4));
165+
assert_eq!(Duration::new(0, 500_000_001).saturating_mul(4000), Duration::new(2000, 4000));
166+
assert_eq!(Duration::new(u64::MAX - 1, 0).saturating_mul(2), Duration::MAX);
167+
}
168+
139169
#[test]
140170
fn div() {
141171
assert_eq!(Duration::new(0, 1) / 2, Duration::new(0, 0));

‎src/test/ui/consts/duration-consts-2.rs

+26-16
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#![feature(const_panic)]
44
#![feature(duration_consts_2)]
55
#![feature(div_duration)]
6+
#![feature(duration_saturating_ops)]
67

78
use std::time::Duration;
89

@@ -15,29 +16,29 @@ fn duration() {
1516

1617
const MAX : Duration = Duration::new(u64::MAX, 1_000_000_000 - 1);
1718

18-
const MAX_ADD_ZERO : Option<Duration> = MAX.checked_add(ZERO);
19-
assert_eq!(MAX_ADD_ZERO, Some(MAX));
19+
const MAX_CHECKED_ADD_ZERO : Option<Duration> = MAX.checked_add(ZERO);
20+
assert_eq!(MAX_CHECKED_ADD_ZERO, Some(MAX));
2021

21-
const MAX_ADD_ONE : Option<Duration> = MAX.checked_add(ONE);
22-
assert_eq!(MAX_ADD_ONE, None);
22+
const MAX_CHECKED_ADD_ONE : Option<Duration> = MAX.checked_add(ONE);
23+
assert_eq!(MAX_CHECKED_ADD_ONE, None);
2324

24-
const ONE_SUB_ONE : Option<Duration> = ONE.checked_sub(ONE);
25-
assert_eq!(ONE_SUB_ONE, Some(ZERO));
25+
const ONE_CHECKED_SUB_ONE : Option<Duration> = ONE.checked_sub(ONE);
26+
assert_eq!(ONE_CHECKED_SUB_ONE, Some(ZERO));
2627

27-
const ZERO_SUB_ONE : Option<Duration> = ZERO.checked_sub(ONE);
28-
assert_eq!(ZERO_SUB_ONE, None);
28+
const ZERO_CHECKED_SUB_ONE : Option<Duration> = ZERO.checked_sub(ONE);
29+
assert_eq!(ZERO_CHECKED_SUB_ONE, None);
2930

30-
const ONE_MUL_ONE : Option<Duration> = ONE.checked_mul(1);
31-
assert_eq!(ONE_MUL_ONE, Some(ONE));
31+
const ONE_CHECKED_MUL_ONE : Option<Duration> = ONE.checked_mul(1);
32+
assert_eq!(ONE_CHECKED_MUL_ONE, Some(ONE));
3233

33-
const MAX_MUL_TWO : Option<Duration> = MAX.checked_mul(2);
34-
assert_eq!(MAX_MUL_TWO, None);
34+
const MAX_CHECKED_MUL_TWO : Option<Duration> = MAX.checked_mul(2);
35+
assert_eq!(MAX_CHECKED_MUL_TWO, None);
3536

36-
const ONE_DIV_ONE : Option<Duration> = ONE.checked_div(1);
37-
assert_eq!(ONE_DIV_ONE, Some(ONE));
37+
const ONE_CHECKED_DIV_ONE : Option<Duration> = ONE.checked_div(1);
38+
assert_eq!(ONE_CHECKED_DIV_ONE, Some(ONE));
3839

39-
const ONE_DIV_ZERO : Option<Duration> = ONE.checked_div(0);
40-
assert_eq!(ONE_DIV_ZERO, None);
40+
const ONE_CHECKED_DIV_ZERO : Option<Duration> = ONE.checked_div(0);
41+
assert_eq!(ONE_CHECKED_DIV_ZERO, None);
4142

4243
const MAX_AS_F32 : f32 = MAX.as_secs_f32();
4344
assert_eq!(MAX_AS_F32, 18446744000000000000.0_f32);
@@ -50,6 +51,15 @@ fn duration() {
5051

5152
const ONE_AS_F64 : f64 = ONE.div_duration_f64(ONE);
5253
assert_eq!(ONE_AS_F64, 1.0_f64);
54+
55+
const MAX_SATURATING_ADD_ONE : Duration = MAX.saturating_add(ONE);
56+
assert_eq!(MAX_SATURATING_ADD_ONE, MAX);
57+
58+
const ZERO_SATURATING_SUB_ONE : Duration = ZERO.saturating_sub(ONE);
59+
assert_eq!(ZERO_SATURATING_SUB_ONE, ZERO);
60+
61+
const MAX_SATURATING_MUL_TWO : Duration = MAX.saturating_mul(2);
62+
assert_eq!(MAX_SATURATING_MUL_TWO, MAX);
5363
}
5464

5565
fn main() {

0 commit comments

Comments
 (0)
Please sign in to comment.