<commit_before>//! 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 **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)
}

/// 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)
}

/// Multiply **x** correctly with a **SizeHint**.
///
/// # Examples
///
/// ```
/// use std::usize;
/// use itertools::size_hint;
///
/// assert_eq!(size_hint::mul_scalar((3, Some(4)), 3),
///            (9, Some(12)));
/// assert_eq!(size_hint::mul_scalar((3, Some(4)), usize::MAX),
///            (usize::MAX, None));
/// ```
#[inline]
pub fn mul_scalar(sh: SizeHint, x: usize) -> SizeHint
{
    let (mut low, mut hi) = sh;
    low = low.checked_mul(x).unwrap_or(usize::MAX);
    hi = hi.and_then(|elt| elt.checked_mul(x));
    (low, hi)
}

/// Multiply **SizeHint** correctly
///
/// # Examples
///
/// ```
/// 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));
/// ```
#[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),
        _ => None,
    };
    (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;<commit_msg>size_hint: Fix multiplying with 0<commit_after>//! 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 **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)
}

/// 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)
}

/// Multiply **x** correctly with a **SizeHint**.
///
/// # Examples
///
/// ```
/// use std::usize;
/// use itertools::size_hint;
///
/// assert_eq!(size_hint::mul_scalar((3, Some(4)), 3),
///            (9, Some(12)));
/// assert_eq!(size_hint::mul_scalar((3, Some(4)), usize::MAX),
///            (usize::MAX, None));
/// ```
#[inline]
pub fn mul_scalar(sh: SizeHint, x: usize) -> SizeHint
{
    let (mut low, mut hi) = sh;
    low = low.checked_mul(x).unwrap_or(usize::MAX);
    if x == 0 {
        hi = Some(0)
    } else {
        hi = hi.and_then(|elt| elt.checked_mul(x));
    }
    (low, hi)
}

/// Multiply **SizeHint** correctly
///
/// # Examples
///
/// ```
/// 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)
}

/// 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;
{'fraction_non_alphanumeric': 0.23457556935817805, 'fraction_numerical': 0.012629399585921325, 'mean_word_length': 2.6460377358490565, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7344262', 'n_tokens_mistral': 1898, 'n_tokens_neox': 1903, 'n_words': 434}