1#[inline(always)]
9pub(super) const unsafe fn zst_init<T>() -> T {
10 debug_assert!(::core::mem::size_of::<T>() == 0);
11
12 #[expect(clippy::uninit_assumed_init)]
13 unsafe {
14 core::mem::MaybeUninit::uninit().assume_init()
15 }
16}
17
18#[cold]
19#[inline(never)]
20pub(super) const fn cold_path() {}
21
22pub(super) trait IsZST {
24 const IS_ZST: bool;
25}
26
27impl<T> IsZST for T {
28 const IS_ZST: bool = ::core::mem::size_of::<T>() == 0;
34}
35
36#[inline(always)]
38pub(super) const fn min_cap<T>() -> usize {
39 let size = ::core::mem::size_of::<T>();
40 if size < 1 {
41 8
42 } else if size <= 1024 {
43 4
44 } else {
45 1
46 }
47}
48
49#[inline(never)]
55pub(super) fn split_range_bound(
56 src: &impl core::ops::RangeBounds<usize>,
57 len: usize,
58) -> (usize, usize) {
59 let start = match src.start_bound() {
60 core::ops::Bound::Included(&i) => i,
61 core::ops::Bound::Excluded(&i) => i + 1,
62 core::ops::Bound::Unbounded => 0,
63 };
64
65 let end = match src.end_bound() {
66 core::ops::Bound::Included(&i) => i + 1,
67 core::ops::Bound::Excluded(&i) => i,
68 core::ops::Bound::Unbounded => len,
69 };
70
71 assert!(start <= end, "drain start greater than end");
72 assert!(end <= len, "drain end out of bounds");
73 (start, end)
74}
75
76macro_rules! impl_common_traits {
77 ($name:ty) => {
78 impl<T, const N: usize> core::ops::Deref for $name {
79 type Target = [T];
80 #[inline]
81 fn deref(&self) -> &Self::Target {
82 self.as_slice()
83 }
84 }
85
86 impl<T, const N: usize> core::ops::DerefMut for $name {
87 #[inline]
88 fn deref_mut(&mut self) -> &mut Self::Target {
89 self.as_mut_slice()
90 }
91 }
92
93 impl<T: core::fmt::Debug, const N: usize> core::fmt::Debug for $name {
94 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
95 core::fmt::Debug::fmt(self.as_slice(), f)
96 }
97 }
98
99 impl<T, const N: usize> core::convert::AsRef<[T]> for $name {
100 #[inline]
101 fn as_ref(&self) -> &[T] {
102 self.as_slice()
103 }
104 }
105
106 impl<T, const N: usize> core::convert::AsRef<$name> for $name {
107 #[inline]
108 fn as_ref(&self) -> &$name {
109 self
110 }
111 }
112
113 impl<T, const N: usize> core::convert::AsMut<[T]> for $name {
114 #[inline]
115 fn as_mut(&mut self) -> &mut [T] {
116 self.as_mut_slice()
117 }
118 }
119
120 impl<T, const N: usize> core::convert::AsMut<$name> for $name {
121 #[inline]
122 fn as_mut(&mut self) -> &mut $name {
123 self
124 }
125 }
126
127 impl<T, const N: usize> core::borrow::Borrow<[T]> for $name {
128 #[inline]
129 fn borrow(&self) -> &[T] {
130 self.as_slice()
131 }
132 }
133
134 impl<T, const N: usize> core::borrow::BorrowMut<[T]> for $name {
135 #[inline]
136 fn borrow_mut(&mut self) -> &mut [T] {
137 self.as_mut_slice()
138 }
139 }
140
141 impl<T: core::hash::Hash, const N: usize> core::hash::Hash for $name {
142 #[inline]
143 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
144 core::hash::Hash::hash(self.as_slice(), state);
145 }
146 }
147
148 impl<T, I: core::slice::SliceIndex<[T]>, const N: usize> core::ops::Index<I> for $name {
149 type Output = <I as core::slice::SliceIndex<[T]>>::Output;
150 #[inline]
151 fn index(&self, index: I) -> &Self::Output {
152 core::ops::Index::index(self.as_slice(), index)
153 }
154 }
155
156 impl<T, I: core::slice::SliceIndex<[T]>, const N: usize> core::ops::IndexMut<I> for $name {
157 #[inline]
158 fn index_mut(&mut self, index: I) -> &mut Self::Output {
159 core::ops::IndexMut::index_mut(self.as_mut_slice(), index)
160 }
161 }
162
163 impl<'a, T, const N: usize> IntoIterator for &'a $name {
164 type Item = &'a T;
165 type IntoIter = core::slice::Iter<'a, T>;
166 #[inline]
167 fn into_iter(self) -> Self::IntoIter {
168 self.as_slice().iter()
169 }
170 }
171
172 impl<'a, T, const N: usize> IntoIterator for &'a mut $name {
173 type Item = &'a mut T;
174 type IntoIter = core::slice::IterMut<'a, T>;
175 #[inline]
176 fn into_iter(self) -> Self::IntoIter {
177 self.as_mut_slice().iter_mut()
178 }
179 }
180
181 impl<T: core::cmp::Ord, const N: usize> core::cmp::Ord for $name {
182 #[inline]
183 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
184 core::cmp::Ord::cmp(self.as_slice(), other.as_slice())
185 }
186 }
187
188 impl<T: core::cmp::PartialOrd, const N: usize> core::cmp::PartialOrd for $name {
189 #[inline]
190 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
191 core::cmp::PartialOrd::partial_cmp(self.as_slice(), other.as_slice())
192 }
193 }
194
195 impl<T: Eq, const N: usize> Eq for $name {}
196
197 impl<T, U, const N: usize> core::cmp::PartialEq<[U]> for $name
198 where
199 T: core::cmp::PartialEq<U>,
200 {
201 #[inline]
202 fn eq(&self, other: &[U]) -> bool {
203 core::cmp::PartialEq::eq(self.as_slice(), other)
204 }
205 }
206
207 impl<T, U, const N: usize> core::cmp::PartialEq<&[U]> for $name
208 where
209 T: core::cmp::PartialEq<U>,
210 {
211 #[inline]
212 fn eq(&self, other: &&[U]) -> bool {
213 core::cmp::PartialEq::eq(self.as_slice(), *other)
214 }
215 }
216
217 impl<T, U, const N: usize> core::cmp::PartialEq<&mut [U]> for $name
218 where
219 T: core::cmp::PartialEq<U>,
220 {
221 #[inline]
222 fn eq(&self, other: &&mut [U]) -> bool {
223 core::cmp::PartialEq::eq(self.as_slice(), *other)
224 }
225 }
226
227 impl<T, U, const N: usize, const P: usize> core::cmp::PartialEq<[U; P]> for $name
228 where
229 T: core::cmp::PartialEq<U>,
230 {
231 #[inline]
232 fn eq(&self, other: &[U; P]) -> bool {
233 core::cmp::PartialEq::eq(self.as_slice(), other.as_slice())
234 }
235 }
236
237 impl<T, U, const N: usize, const P: usize> core::cmp::PartialEq<&[U; P]> for $name
238 where
239 T: core::cmp::PartialEq<U>,
240 {
241 #[inline]
242 fn eq(&self, other: &&[U; P]) -> bool {
243 core::cmp::PartialEq::eq(self.as_slice(), other.as_slice())
244 }
245 }
246 };
247}
248
249pub(super) use impl_common_traits;