1use std::cmp;
5use std::usize;
6
7pub type SizeHint = (usize, Option<usize>);
9
10#[inline]
12pub fn add(a: SizeHint, b: SizeHint) -> SizeHint {
13 let min = a.0.saturating_add(b.0);
14 let max = match (a.1, b.1) {
15 (Some(x), Some(y)) => x.checked_add(y),
16 _ => None,
17 };
18
19 (min, max)
20}
21
22#[inline]
24pub fn add_scalar(sh: SizeHint, x: usize) -> SizeHint {
25 let (mut low, mut hi) = sh;
26 low = low.saturating_add(x);
27 hi = hi.and_then(|elt| elt.checked_add(x));
28 (low, hi)
29}
30
31#[inline]
33pub fn sub_scalar(sh: SizeHint, x: usize) -> SizeHint {
34 let (mut low, mut hi) = sh;
35 low = low.saturating_sub(x);
36 hi = hi.map(|elt| elt.saturating_sub(x));
37 (low, hi)
38}
39
40#[inline]
42pub fn mul(a: SizeHint, b: SizeHint) -> SizeHint {
43 let low = a.0.saturating_mul(b.0);
44 let hi = match (a.1, b.1) {
45 (Some(x), Some(y)) => x.checked_mul(y),
46 (Some(0), None) | (None, Some(0)) => Some(0),
47 _ => None,
48 };
49 (low, hi)
50}
51
52#[inline]
54pub fn mul_scalar(sh: SizeHint, x: usize) -> SizeHint {
55 let (mut low, mut hi) = sh;
56 low = low.saturating_mul(x);
57 hi = hi.and_then(|elt| elt.checked_mul(x));
58 (low, hi)
59}
60
61#[inline]
63pub fn max(a: SizeHint, b: SizeHint) -> SizeHint {
64 let (a_lower, a_upper) = a;
65 let (b_lower, b_upper) = b;
66
67 let lower = cmp::max(a_lower, b_lower);
68
69 let upper = match (a_upper, b_upper) {
70 (Some(x), Some(y)) => Some(cmp::max(x, y)),
71 _ => None,
72 };
73
74 (lower, upper)
75}
76
77#[inline]
79pub fn min(a: SizeHint, b: SizeHint) -> SizeHint {
80 let (a_lower, a_upper) = a;
81 let (b_lower, b_upper) = b;
82 let lower = cmp::min(a_lower, b_lower);
83 let upper = match (a_upper, b_upper) {
84 (Some(u1), Some(u2)) => Some(cmp::min(u1, u2)),
85 _ => a_upper.or(b_upper),
86 };
87 (lower, upper)
88}
89
90#[test]
91fn mul_size_hints() {
92 assert_eq!(mul((3, Some(4)), (3, Some(4))), (9, Some(16)));
93 assert_eq!(mul((3, Some(4)), (usize::MAX, None)), (usize::MAX, None));
94 assert_eq!(mul((3, None), (0, Some(0))), (0, Some(0)));
95}