diff options
Diffstat (limited to 'src/size_hint.rs')
-rw-r--r-- | src/size_hint.rs | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/src/size_hint.rs b/src/size_hint.rs index be54443..1168eca 100644 --- a/src/size_hint.rs +++ b/src/size_hint.rs @@ -3,6 +3,7 @@ use std::usize; use std::cmp; +use std::u32; /// **SizeHint** is the return type of **Iterator::size_hint()**. pub type SizeHint = (usize, Option<usize>); @@ -10,7 +11,7 @@ pub type SizeHint = (usize, Option<usize>); /// Add **SizeHint** correctly. #[inline] pub fn add(a: SizeHint, b: SizeHint) -> SizeHint { - let min = a.0.checked_add(b.0).unwrap_or(usize::MAX); + let min = a.0.saturating_add(b.0); let max = match (a.1, b.1) { (Some(x), Some(y)) => x.checked_add(y), _ => None, @@ -56,7 +57,7 @@ pub fn sub_scalar(sh: SizeHint, x: usize) -> SizeHint { /// ``` #[inline] pub fn mul(a: SizeHint, b: SizeHint) -> SizeHint { - let low = a.0.checked_mul(b.0).unwrap_or(usize::MAX); + let low = a.0.saturating_mul(b.0); let hi = match (a.1, b.1) { (Some(x), Some(y)) => x.checked_mul(y), (Some(0), None) | (None, Some(0)) => Some(0), @@ -74,6 +75,20 @@ pub fn mul_scalar(sh: SizeHint, x: usize) -> SizeHint { (low, hi) } +/// Raise `base` correctly by a **`SizeHint`** exponent. +#[inline] +pub fn pow_scalar_base(base: usize, exp: SizeHint) -> SizeHint { + let exp_low = cmp::min(exp.0, u32::MAX as usize) as u32; + let low = base.saturating_pow(exp_low); + + let hi = exp.1.and_then(|exp| { + let exp_hi = cmp::min(exp, u32::MAX as usize) as u32; + base.checked_pow(exp_hi) + }); + + (low, hi) +} + /// Return the maximum #[inline] pub fn max(a: SizeHint, b: SizeHint) -> SizeHint { |