1#![cfg_attr(feature = "nightly", feature(generic_const_exprs))]
3
4pub trait Array<T> {
22 fn len(&self) -> usize;
24
25 fn is_empty(&self) -> bool;
27
28 fn first(&self) -> Option<&T>;
30
31 fn first_mut(&mut self) -> Option<&mut T>;
33
34 fn last(&self) -> Option<&T>;
36
37 fn last_mut(&mut self) -> Option<&mut T>;
39
40 fn get(&self, index: usize) -> Option<&T>;
42
43 fn get_mut(&mut self, index: usize) -> Option<&mut T>;
45
46 fn as_slice(&self) -> &[T];
48
49 fn as_mut_slice(&mut self) -> &mut [T];
51
52 fn map_<F>(self, f: F) -> Self
54 where
55 F: FnMut(T) -> T,
56 Self: Sized;
57
58 fn foldl<A, F>(self, acc: A, f: F) -> A
60 where
61 F: FnMut(A, T) -> A,
62 Self: Sized;
63
64 fn foldr<A, F>(self, acc: A, f: F) -> A
66 where
67 F: FnMut(A, T) -> A,
68 Self: Sized;
69
70 fn resize<const S: usize>(self, elem: T) -> [T; S]
72 where
73 T: Clone,
74 Self: Sized;
75
76 fn resize_with<F, const S: usize>(self, f: F) -> [T; S]
78 where
79 F: FnMut(usize) -> T,
80 Self: Sized;
81
82 #[deprecated(since = "0.4.0", note = "use std::array::from_fn instead")]
83 fn from_fn<F>(f: F) -> Self
85 where
86 F: FnMut(usize) -> T,
87 Self: Sized;
88
89 fn from_iter(iter: impl Iterator<Item = T>) -> Option<Self>
91 where
92 Self: Sized;
93}
94
95impl<T, const N: usize> Array<T> for [T; N] {
96 #[inline]
97 fn len(&self) -> usize {
98 N
99 }
100
101 #[inline]
102 fn is_empty(&self) -> bool {
103 N == 0
104 }
105
106 #[inline]
107 fn first(&self) -> Option<&T> {
108 if N > 0 {
109 Some(&self[0])
110 } else {
111 None
112 }
113 }
114
115 #[inline]
116 fn first_mut(&mut self) -> Option<&mut T> {
117 if N > 0 {
118 Some(&mut self[0])
119 } else {
120 None
121 }
122 }
123
124 #[inline]
125 fn last(&self) -> Option<&T> {
126 if N > 0 {
127 Some(&self[N - 1])
128 } else {
129 None
130 }
131 }
132
133 #[inline]
134 fn last_mut(&mut self) -> Option<&mut T> {
135 if N > 0 {
136 Some(&mut self[N - 1])
137 } else {
138 None
139 }
140 }
141
142 #[inline]
143 fn get(&self, index: usize) -> Option<&T> {
144 if index < N {
145 Some(&self[index])
146 } else {
147 None
148 }
149 }
150
151 #[inline]
152 fn get_mut(&mut self, index: usize) -> Option<&mut T> {
153 if index < N {
154 Some(&mut self[index])
155 } else {
156 None
157 }
158 }
159
160 #[inline]
161 fn as_slice(&self) -> &[T] {
162 self
163 }
164
165 #[inline]
166 fn as_mut_slice(&mut self) -> &mut [T] {
167 self
168 }
169
170 #[inline]
171 fn map_<F>(self, f: F) -> Self
172 where
173 F: FnMut(T) -> T,
174 {
175 self.map(f)
176 }
177
178 #[inline]
179 fn foldl<A, F>(self, mut acc: A, mut f: F) -> A
180 where
181 F: FnMut(A, T) -> A,
182 {
183 for val in self {
184 acc = f(acc, val);
185 }
186 acc
187 }
188
189 #[inline]
190 fn foldr<A, F>(self, mut acc: A, mut f: F) -> A
191 where
192 F: FnMut(A, T) -> A,
193 {
194 for val in self.into_iter().rev() {
195 acc = f(acc, val);
196 }
197 acc
198 }
199
200 #[inline]
201 fn resize<const S: usize>(self, elem: T) -> [T; S]
202 where
203 T: Clone,
204 {
205 self.resize_with(|_| elem.clone())
206 }
207
208 #[inline]
209 fn resize_with<F, const S: usize>(self, mut f: F) -> [T; S]
210 where
211 F: FnMut(usize) -> T,
212 {
213 let mut a = self.into_iter();
214 std::array::from_fn(|i| if i < N { a.next().unwrap() } else { f(i) })
215 }
216
217 #[inline]
218 fn from_fn<F>(f: F) -> Self
219 where
220 F: FnMut(usize) -> T,
221 {
222 std::array::from_fn(f)
223 }
224
225 #[inline]
226 fn from_iter(mut iter: impl Iterator<Item = T>) -> Option<Self> {
227 let mut v = Vec::with_capacity(N); for _ in 0..N {
229 v.push(iter.next()?);
230 }
231 v.try_into().ok()
232 }
233}
234
235pub trait ArrayN<T, const N: usize>: Array<T> {
237 fn zip_with<U, V, F>(self, other: [U; N], f: F) -> [V; N]
239 where
240 F: FnMut(T, U) -> V,
241 Self: Sized;
242
243 fn downcast(self) -> [T; N];
245
246 fn downcast_ref(&self) -> &[T; N];
248
249 fn downcast_mut(&mut self) -> &mut [T; N];
251
252 #[cfg(feature = "nightly")]
254 fn concat<const M: usize>(self, other: [T; M]) -> [T; N + M]
255 where
256 Self: Sized;
257
258 #[cfg(feature = "nightly")]
260 fn split<const P: usize>(self) -> ([T; P], [T; N - P])
261 where
262 Self: Sized;
263}
264
265impl<T, const N: usize> ArrayN<T, N> for [T; N] {
266 #[inline]
267 fn zip_with<U, V, F>(self, other: [U; N], mut f: F) -> [V; N]
268 where
269 F: FnMut(T, U) -> V,
270 {
271 let mut b = other.into_iter();
272 self.map(|a| f(a, b.next().unwrap()))
273 }
274
275 #[inline]
276 fn downcast(self) -> [T; N] {
277 self
278 }
279
280 #[inline]
281 fn downcast_ref(&self) -> &[T; N] {
282 self
283 }
284
285 #[inline]
286 fn downcast_mut(&mut self) -> &mut [T; N] {
287 self
288 }
289
290 #[cfg(feature = "nightly")]
291 fn concat<const M: usize>(self, other: [T; M]) -> [T; N + M] {
292 let mut a = self.into_iter();
293 let mut b = other.into_iter();
294 std::array::from_fn(|i| if i < N { a.next() } else { b.next() }.unwrap())
295 }
296
297 #[cfg(feature = "nightly")]
298 fn split<const P: usize>(self) -> ([T; P], [T; N - P]) {
299 let mut a = self.into_iter();
300 let l = [(); P].map(|_| a.next().unwrap());
301 let r = [(); N - P].map(|_| a.next().unwrap());
302 (l, r)
303 }
304}
305
306#[cfg(test)]
307mod tests;