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