提交 b869aa5f 编写于 作者: M marmeladema

Add saturating methods for `Duration`

上级 9fe551ae
...@@ -100,6 +100,7 @@ ...@@ -100,6 +100,7 @@
#![feature(doc_cfg)] #![feature(doc_cfg)]
#![feature(doc_spotlight)] #![feature(doc_spotlight)]
#![feature(duration_consts_2)] #![feature(duration_consts_2)]
#![feature(duration_saturating_ops)]
#![feature(extern_types)] #![feature(extern_types)]
#![feature(fundamental)] #![feature(fundamental)]
#![feature(intrinsics)] #![feature(intrinsics)]
......
...@@ -108,6 +108,34 @@ impl Duration { ...@@ -108,6 +108,34 @@ impl Duration {
#[unstable(feature = "duration_constants", issue = "57391")] #[unstable(feature = "duration_constants", issue = "57391")]
pub const NANOSECOND: Duration = Duration::from_nanos(1); pub const NANOSECOND: Duration = Duration::from_nanos(1);
/// The minimum duration.
///
/// # Examples
///
/// ```
/// #![feature(duration_constants)]
/// use std::time::Duration;
///
/// assert_eq!(Duration::MIN, Duration::new(0, 0));
/// ```
#[unstable(feature = "duration_constants", issue = "57391")]
pub const MIN: Duration = Duration::from_nanos(0);
/// The maximum duration.
///
/// It is roughly equal to a duration of 584,942,417,355 years.
///
/// # Examples
///
/// ```
/// #![feature(duration_constants)]
/// use std::time::Duration;
///
/// assert_eq!(Duration::MAX, Duration::new(u64::MAX, 1_000_000_000 - 1));
/// ```
#[unstable(feature = "duration_constants", issue = "57391")]
pub const MAX: Duration = Duration::new(u64::MAX, NANOS_PER_SEC - 1);
/// Creates a new `Duration` from the specified number of whole seconds and /// Creates a new `Duration` from the specified number of whole seconds and
/// additional nanoseconds. /// additional nanoseconds.
/// ///
...@@ -450,6 +478,29 @@ pub const fn checked_add(self, rhs: Duration) -> Option<Duration> { ...@@ -450,6 +478,29 @@ pub const fn checked_add(self, rhs: Duration) -> Option<Duration> {
} }
} }
/// Saturating `Duration` addition. Computes `self + other`, returning [`Duration::MAX`]
/// if overflow occurred.
///
/// # Examples
///
/// ```
/// #![feature(duration_saturating_ops)]
/// #![feature(duration_constants)]
/// use std::time::Duration;
///
/// assert_eq!(Duration::new(0, 0).saturating_add(Duration::new(0, 1)), Duration::new(0, 1));
/// assert_eq!(Duration::new(1, 0).saturating_add(Duration::new(u64::MAX, 0)), Duration::MAX);
/// ```
#[unstable(feature = "duration_saturating_ops", issue = "76416")]
#[inline]
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
pub const fn saturating_add(self, rhs: Duration) -> Duration {
match self.checked_add(rhs) {
Some(res) => res,
None => Duration::MAX,
}
}
/// Checked `Duration` subtraction. Computes `self - other`, returning [`None`] /// Checked `Duration` subtraction. Computes `self - other`, returning [`None`]
/// if the result would be negative or if overflow occurred. /// if the result would be negative or if overflow occurred.
/// ///
...@@ -485,6 +536,29 @@ pub const fn checked_sub(self, rhs: Duration) -> Option<Duration> { ...@@ -485,6 +536,29 @@ pub const fn checked_sub(self, rhs: Duration) -> Option<Duration> {
} }
} }
/// Saturating `Duration` subtraction. Computes `self - other`, returning [`Duration::MIN`]
/// if the result would be negative or if overflow occurred.
///
/// # Examples
///
/// ```
/// #![feature(duration_saturating_ops)]
/// #![feature(duration_constants)]
/// use std::time::Duration;
///
/// assert_eq!(Duration::new(0, 1).saturating_sub(Duration::new(0, 0)), Duration::new(0, 1));
/// assert_eq!(Duration::new(0, 0).saturating_sub(Duration::new(0, 1)), Duration::MIN);
/// ```
#[unstable(feature = "duration_saturating_ops", issue = "76416")]
#[inline]
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
pub const fn saturating_sub(self, rhs: Duration) -> Duration {
match self.checked_sub(rhs) {
Some(res) => res,
None => Duration::MIN,
}
}
/// Checked `Duration` multiplication. Computes `self * other`, returning /// Checked `Duration` multiplication. Computes `self * other`, returning
/// [`None`] if overflow occurred. /// [`None`] if overflow occurred.
/// ///
...@@ -515,6 +589,29 @@ pub const fn checked_mul(self, rhs: u32) -> Option<Duration> { ...@@ -515,6 +589,29 @@ pub const fn checked_mul(self, rhs: u32) -> Option<Duration> {
None None
} }
/// Saturating `Duration` multiplication. Computes `self * other`, returning
/// [`Duration::MAX`] if overflow occurred.
///
/// # Examples
///
/// ```
/// #![feature(duration_saturating_ops)]
/// #![feature(duration_constants)]
/// use std::time::Duration;
///
/// assert_eq!(Duration::new(0, 500_000_001).saturating_mul(2), Duration::new(1, 2));
/// assert_eq!(Duration::new(u64::MAX - 1, 0).saturating_mul(2), Duration::MAX);
/// ```
#[unstable(feature = "duration_saturating_ops", issue = "76416")]
#[inline]
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
pub const fn saturating_mul(self, rhs: u32) -> Duration {
match self.checked_mul(rhs) {
Some(res) => res,
None => Duration::MAX,
}
}
/// Checked `Duration` division. Computes `self / other`, returning [`None`] /// Checked `Duration` division. Computes `self / other`, returning [`None`]
/// if `other == 0`. /// if `other == 0`.
/// ///
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#![feature(core_private_diy_float)] #![feature(core_private_diy_float)]
#![feature(debug_non_exhaustive)] #![feature(debug_non_exhaustive)]
#![feature(dec2flt)] #![feature(dec2flt)]
#![feature(duration_constants)]
#![feature(duration_saturating_ops)]
#![feature(exact_size_is_empty)] #![feature(exact_size_is_empty)]
#![feature(fixed_size_array)] #![feature(fixed_size_array)]
#![feature(flt2dec)] #![feature(flt2dec)]
......
...@@ -89,6 +89,16 @@ fn checked_add() { ...@@ -89,6 +89,16 @@ fn checked_add() {
assert_eq!(Duration::new(1, 0).checked_add(Duration::new(u64::MAX, 0)), None); assert_eq!(Duration::new(1, 0).checked_add(Duration::new(u64::MAX, 0)), None);
} }
#[test]
fn saturating_add() {
assert_eq!(Duration::new(0, 0).saturating_add(Duration::new(0, 1)), Duration::new(0, 1));
assert_eq!(
Duration::new(0, 500_000_000).saturating_add(Duration::new(0, 500_000_001)),
Duration::new(1, 1)
);
assert_eq!(Duration::new(1, 0).saturating_add(Duration::new(u64::MAX, 0)), Duration::MAX);
}
#[test] #[test]
fn sub() { fn sub() {
assert_eq!(Duration::new(0, 1) - Duration::new(0, 0), Duration::new(0, 1)); assert_eq!(Duration::new(0, 1) - Duration::new(0, 0), Duration::new(0, 1));
...@@ -107,6 +117,17 @@ fn checked_sub() { ...@@ -107,6 +117,17 @@ fn checked_sub() {
assert_eq!(zero.checked_sub(one_sec), None); assert_eq!(zero.checked_sub(one_sec), None);
} }
#[test]
fn saturating_sub() {
let zero = Duration::new(0, 0);
let one_nano = Duration::new(0, 1);
let one_sec = Duration::new(1, 0);
assert_eq!(one_nano.saturating_sub(zero), Duration::new(0, 1));
assert_eq!(one_sec.saturating_sub(one_nano), Duration::new(0, 999_999_999));
assert_eq!(zero.saturating_sub(one_nano), Duration::MIN);
assert_eq!(zero.saturating_sub(one_sec), Duration::MIN);
}
#[test] #[test]
#[should_panic] #[should_panic]
fn sub_bad1() { fn sub_bad1() {
...@@ -136,6 +157,15 @@ fn checked_mul() { ...@@ -136,6 +157,15 @@ fn checked_mul() {
assert_eq!(Duration::new(u64::MAX - 1, 0).checked_mul(2), None); assert_eq!(Duration::new(u64::MAX - 1, 0).checked_mul(2), None);
} }
#[test]
fn saturating_mul() {
assert_eq!(Duration::new(0, 1).saturating_mul(2), Duration::new(0, 2));
assert_eq!(Duration::new(1, 1).saturating_mul(3), Duration::new(3, 3));
assert_eq!(Duration::new(0, 500_000_001).saturating_mul(4), Duration::new(2, 4));
assert_eq!(Duration::new(0, 500_000_001).saturating_mul(4000), Duration::new(2000, 4000));
assert_eq!(Duration::new(u64::MAX - 1, 0).saturating_mul(2), Duration::MAX);
}
#[test] #[test]
fn div() { fn div() {
assert_eq!(Duration::new(0, 1) / 2, Duration::new(0, 0)); assert_eq!(Duration::new(0, 1) / 2, Duration::new(0, 0));
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#![feature(const_panic)] #![feature(const_panic)]
#![feature(duration_consts_2)] #![feature(duration_consts_2)]
#![feature(div_duration)] #![feature(div_duration)]
#![feature(duration_saturating_ops)]
use std::time::Duration; use std::time::Duration;
...@@ -15,29 +16,29 @@ fn duration() { ...@@ -15,29 +16,29 @@ fn duration() {
const MAX : Duration = Duration::new(u64::MAX, 1_000_000_000 - 1); const MAX : Duration = Duration::new(u64::MAX, 1_000_000_000 - 1);
const MAX_ADD_ZERO : Option<Duration> = MAX.checked_add(ZERO); const MAX_CHECKED_ADD_ZERO : Option<Duration> = MAX.checked_add(ZERO);
assert_eq!(MAX_ADD_ZERO, Some(MAX)); assert_eq!(MAX_CHECKED_ADD_ZERO, Some(MAX));
const MAX_ADD_ONE : Option<Duration> = MAX.checked_add(ONE); const MAX_CHECKED_ADD_ONE : Option<Duration> = MAX.checked_add(ONE);
assert_eq!(MAX_ADD_ONE, None); assert_eq!(MAX_CHECKED_ADD_ONE, None);
const ONE_SUB_ONE : Option<Duration> = ONE.checked_sub(ONE); const ONE_CHECKED_SUB_ONE : Option<Duration> = ONE.checked_sub(ONE);
assert_eq!(ONE_SUB_ONE, Some(ZERO)); assert_eq!(ONE_CHECKED_SUB_ONE, Some(ZERO));
const ZERO_SUB_ONE : Option<Duration> = ZERO.checked_sub(ONE); const ZERO_CHECKED_SUB_ONE : Option<Duration> = ZERO.checked_sub(ONE);
assert_eq!(ZERO_SUB_ONE, None); assert_eq!(ZERO_CHECKED_SUB_ONE, None);
const ONE_MUL_ONE : Option<Duration> = ONE.checked_mul(1); const ONE_CHECKED_MUL_ONE : Option<Duration> = ONE.checked_mul(1);
assert_eq!(ONE_MUL_ONE, Some(ONE)); assert_eq!(ONE_CHECKED_MUL_ONE, Some(ONE));
const MAX_MUL_TWO : Option<Duration> = MAX.checked_mul(2); const MAX_CHECKED_MUL_TWO : Option<Duration> = MAX.checked_mul(2);
assert_eq!(MAX_MUL_TWO, None); assert_eq!(MAX_CHECKED_MUL_TWO, None);
const ONE_DIV_ONE : Option<Duration> = ONE.checked_div(1); const ONE_CHECKED_DIV_ONE : Option<Duration> = ONE.checked_div(1);
assert_eq!(ONE_DIV_ONE, Some(ONE)); assert_eq!(ONE_CHECKED_DIV_ONE, Some(ONE));
const ONE_DIV_ZERO : Option<Duration> = ONE.checked_div(0); const ONE_CHECKED_DIV_ZERO : Option<Duration> = ONE.checked_div(0);
assert_eq!(ONE_DIV_ZERO, None); assert_eq!(ONE_CHECKED_DIV_ZERO, None);
const MAX_AS_F32 : f32 = MAX.as_secs_f32(); const MAX_AS_F32 : f32 = MAX.as_secs_f32();
assert_eq!(MAX_AS_F32, 18446744000000000000.0_f32); assert_eq!(MAX_AS_F32, 18446744000000000000.0_f32);
...@@ -50,6 +51,15 @@ fn duration() { ...@@ -50,6 +51,15 @@ fn duration() {
const ONE_AS_F64 : f64 = ONE.div_duration_f64(ONE); const ONE_AS_F64 : f64 = ONE.div_duration_f64(ONE);
assert_eq!(ONE_AS_F64, 1.0_f64); assert_eq!(ONE_AS_F64, 1.0_f64);
const MAX_SATURATING_ADD_ONE : Duration = MAX.saturating_add(ONE);
assert_eq!(MAX_SATURATING_ADD_ONE, MAX);
const ZERO_SATURATING_SUB_ONE : Duration = ZERO.saturating_sub(ONE);
assert_eq!(ZERO_SATURATING_SUB_ONE, ZERO);
const MAX_SATURATING_MUL_TWO : Duration = MAX.saturating_mul(2);
assert_eq!(MAX_SATURATING_MUL_TWO, MAX);
} }
fn main() { fn main() {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册