1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
//! Arithmetic on `Iterator.size_hint()` values.
//!
use std::usize;
use std::cmp;
use std::u32;
/// `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.saturating_add(b.0);
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)
}
/// Subtract `x` correctly from 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.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),
_ => 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)
}
/// 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 {
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)
}
|