]> git.proxmox.com Git - rustc.git/blobdiff - vendor/itertools-0.8.2/src/size_hint.rs
New upstream version 1.47.0~beta.2+dfsg1
[rustc.git] / vendor / itertools-0.8.2 / src / size_hint.rs
diff --git a/vendor/itertools-0.8.2/src/size_hint.rs b/vendor/itertools-0.8.2/src/size_hint.rs
new file mode 100644 (file)
index 0000000..be54443
--- /dev/null
@@ -0,0 +1,104 @@
+//! Arithmetic on **Iterator** *.size_hint()* values.
+//!
+
+use std::usize;
+use std::cmp;
+
+/// **SizeHint** is the return type of **Iterator::size_hint()**.
+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 max = match (a.1, b.1) {
+        (Some(x), Some(y)) => x.checked_add(y),
+        _ => None,
+    };
+
+    (min, max)
+}
+
+/// Add **x** correctly to a **SizeHint**.
+#[inline]
+pub fn add_scalar(sh: SizeHint, x: usize) -> SizeHint {
+    let (mut low, mut hi) = sh;
+    low = low.saturating_add(x);
+    hi = hi.and_then(|elt| elt.checked_add(x));
+    (low, hi)
+}
+
+/// Sbb **x** correctly to a **SizeHint**.
+#[inline]
+#[allow(dead_code)]
+pub fn sub_scalar(sh: SizeHint, x: usize) -> SizeHint {
+    let (mut low, mut hi) = sh;
+    low = low.saturating_sub(x);
+    hi = hi.map(|elt| elt.saturating_sub(x));
+    (low, hi)
+}
+
+
+/// Multiply **SizeHint** correctly
+///
+/// ```ignore
+/// use std::usize;
+/// use itertools::size_hint;
+///
+/// assert_eq!(size_hint::mul((3, Some(4)), (3, Some(4))),
+///            (9, Some(16)));
+///
+/// assert_eq!(size_hint::mul((3, Some(4)), (usize::MAX, None)),
+///            (usize::MAX, None));
+///
+/// assert_eq!(size_hint::mul((3, None), (0, Some(0))),
+///            (0, Some(0)));
+/// ```
+#[inline]
+pub fn mul(a: SizeHint, b: SizeHint) -> SizeHint {
+    let low = a.0.checked_mul(b.0).unwrap_or(usize::MAX);
+    let hi = match (a.1, b.1) {
+        (Some(x), Some(y)) => x.checked_mul(y),
+        (Some(0), None) | (None, Some(0)) => Some(0),
+        _ => None,
+    };
+    (low, hi)
+}
+
+/// Multiply **x** correctly with a **SizeHint**.
+#[inline]
+pub fn mul_scalar(sh: SizeHint, x: usize) -> SizeHint {
+    let (mut low, mut hi) = sh;
+    low = low.saturating_mul(x);
+    hi = hi.and_then(|elt| elt.checked_mul(x));
+    (low, hi)
+}
+
+/// Return the maximum
+#[inline]
+pub fn max(a: SizeHint, b: SizeHint) -> SizeHint {
+    let (a_lower, a_upper) = a;
+    let (b_lower, b_upper) = b;
+
+    let lower = cmp::max(a_lower, b_lower);
+
+    let upper = match (a_upper, b_upper) {
+        (Some(x), Some(y)) => Some(cmp::max(x, y)),
+        _ => None,
+    };
+
+    (lower, upper)
+}
+
+/// Return the minimum
+#[inline]
+pub fn min(a: SizeHint, b: SizeHint) -> SizeHint {
+    let (a_lower, a_upper) = a;
+    let (b_lower, b_upper) = b;
+    let lower = cmp::min(a_lower, b_lower);
+    let upper = match (a_upper, b_upper) {
+        (Some(u1), Some(u2)) => Some(cmp::min(u1, u2)),
+        _ => a_upper.or(b_upper),
+    };
+    (lower, upper)
+}