aboutsummaryrefslogtreecommitdiff
path: root/src/size_hint.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/size_hint.rs')
-rw-r--r--src/size_hint.rs19
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 {