1 | use std::any::Any; |
2 | |
3 | use crate::counter::{IntoCounter, ItemsCount}; |
4 | |
5 | /// The largest unsigned integer usable by counters provided by this crate. |
6 | /// |
7 | /// If `usize > u64`, this is a type alias to `usize`. Otherwise, it is a type |
8 | /// alias to `u64`. |
9 | pub type MaxCountUInt = condtype::num::Usize64; |
10 | |
11 | /// `u8`-`u64` and `usize`. |
12 | /// |
13 | /// We deliberately do not implement this trait for `u128` to make it |
14 | /// impossible† to overflow `u128` when summing counts for averaging. |
15 | /// |
16 | /// †When `usize` is larger than `u64`, it becomes possible to overflow `u128`. |
17 | /// In this case, Divan assumes |
18 | pub trait CountUInt: Copy + Any { |
19 | fn into_max_uint(self) -> MaxCountUInt; |
20 | } |
21 | |
22 | /// A type like `CountUInt` but with more options. |
23 | pub trait AsCountUInt { |
24 | fn as_max_uint(&self) -> MaxCountUInt; |
25 | } |
26 | |
27 | impl<T: AsCountUInt> AsCountUInt for &T { |
28 | #[inline ] |
29 | fn as_max_uint(&self) -> MaxCountUInt { |
30 | T::as_max_uint(self) |
31 | } |
32 | } |
33 | |
34 | macro_rules! impl_uint { |
35 | ($($i:ty),+) => { |
36 | $(impl CountUInt for $i { |
37 | #[inline] |
38 | fn into_max_uint(self) -> MaxCountUInt { |
39 | self as _ |
40 | } |
41 | })+ |
42 | |
43 | $(impl AsCountUInt for $i { |
44 | #[inline] |
45 | fn as_max_uint(&self) -> MaxCountUInt { |
46 | *self as _ |
47 | } |
48 | })+ |
49 | |
50 | $(impl IntoCounter for $i { |
51 | type Counter = ItemsCount; |
52 | |
53 | #[inline] |
54 | fn into_counter(self) -> ItemsCount { |
55 | ItemsCount::new(self) |
56 | } |
57 | })+ |
58 | }; |
59 | } |
60 | |
61 | // These types must be losslessly convertible to `MaxCountUInt`. |
62 | impl_uint!(u8, u16, u32, u64, usize); |
63 | |