| 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 | |