1use core::fmt::{Debug, Display};
4
5use crate::storage::utils::min_non_zero_cap;
6
7pub trait Index:
9 Copy
10 + Clone
11 + Debug
12 + Display
13 + Into<usize>
14 + PartialEq
15 + Eq
16 + PartialOrd
17 + Ord
18 + Send
19 + Sync
20 + Sized
21 + 'static
22{
23 const ZERO: Self;
25 const MAX_USIZE: usize;
27
28 fn from_usize(val: usize) -> Self;
31
32 fn try_from_usize(val: usize) -> Option<Self>;
34
35 #[inline]
37 fn to_usize(self) -> usize {
38 self.into()
39 }
40
41 fn saturating_add(self, val: usize) -> Self;
43
44 fn saturating_sub(self, val: usize) -> Self;
46
47 fn saturating_mul(self, val: usize) -> Self;
49}
50
51impl Index for u8 {
52 const ZERO: Self = 0u8;
53 const MAX_USIZE: usize = u8::MAX as usize;
54
55 #[inline]
56 fn from_usize(val: usize) -> Self {
57 val as Self
58 }
59
60 #[inline]
61 fn try_from_usize(val: usize) -> Option<Self> {
62 val.try_into().ok()
63 }
64
65 #[inline]
66 fn to_usize(self) -> usize {
67 self as usize
68 }
69
70 #[inline]
71 fn saturating_add(self, val: usize) -> Self {
72 (self as usize + val) as Self
74 }
76
77 fn saturating_sub(self, val: usize) -> Self {
78 self.to_usize().saturating_sub(val) as Self
79 }
80
81 fn saturating_mul(self, val: usize) -> Self {
82 self.to_usize().saturating_mul(val).min(Self::MAX_USIZE) as Self
83 }
84}
85
86impl Index for usize {
87 const ZERO: Self = 0usize;
88 const MAX_USIZE: usize = usize::MAX;
89
90 #[inline]
91 fn from_usize(val: usize) -> Self {
92 val
93 }
94
95 #[inline]
96 fn try_from_usize(val: usize) -> Option<Self> {
97 Some(val)
98 }
99
100 fn saturating_add(self, val: usize) -> Self {
101 self.saturating_add(val)
102 }
103
104 fn saturating_sub(self, val: usize) -> Self {
105 self.saturating_sub(val)
106 }
107
108 fn saturating_mul(self, val: usize) -> Self {
109 self.saturating_mul(val)
110 }
111}
112
113pub trait Grow: Debug {
115 fn next_capacity<T, I: Index>(prev: I, minimum: I) -> I;
117}
118
119#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
121pub struct GrowExact;
122
123impl Grow for GrowExact {
124 #[inline]
125 fn next_capacity<T, I: Index>(_prev: I, minimum: I) -> I {
126 minimum
127 }
128}
129
130#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
132pub struct GrowDoubling;
133
134impl Grow for GrowDoubling {
135 #[inline]
136 fn next_capacity<T, I: Index>(prev: I, minimum: I) -> I {
137 let preferred = if prev == I::ZERO {
138 I::from_usize(min_non_zero_cap::<T>())
139 } else {
140 prev.saturating_mul(2)
141 };
142 preferred.max(minimum)
143 }
144}