1use std::any::Any;
2
3use 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`.
9pub 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
18pub trait CountUInt: Copy + Any {
19 fn into_max_uint(self) -> MaxCountUInt;
20}
21
22/// A type like `CountUInt` but with more options.
23pub trait AsCountUInt {
24 fn as_max_uint(&self) -> MaxCountUInt;
25}
26
27impl<T: AsCountUInt> AsCountUInt for &T {
28 #[inline]
29 fn as_max_uint(&self) -> MaxCountUInt {
30 T::as_max_uint(self)
31 }
32}
33
34macro_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`.
62impl_uint!(u8, u16, u32, u64, usize);
63