1use core::{marker::Destruct, mem::MaybeUninit, ops::Try};
2
3use crate::{Bulk, DoubleEndedBulk, Guard, IntoBulk, SplitBulk, StaticBulk, util::{self, LengthSpec, Same}};
4
5pub mod array
6{
7 #[derive(Clone, Debug)]
8 pub struct IntoBulk<T, const N: usize>
9 {
10 pub(super) array: [T; N]
11 }
12
13 #[derive(Clone, Debug)]
14 pub struct Bulk<'a, T, const N: usize>
15 {
16 pub(super) array: &'a [T; N]
17 }
18
19 #[derive(Debug)]
20 pub struct BulkMut<'a, T, const N: usize>
21 {
22 pub(super) array: &'a mut [T; N]
23 }
24}
25
26macro_rules! impl_bulk {
27 (
28 impl $bulk:ident<$($a:lifetime,)? $t:ident, const $n:ident: usize>; for $item:ty; in $array:ty;
29 {
30 fn for_each($self_for_each:ident, $f_for_each:ident) -> _
31 $for_each:block
32
33 fn try_for_each($self_try_for_each:ident, $f_try_for_each:ident) -> _
34 $try_for_each:block
35
36 fn rev_for_each($self_rev_for_each:ident, $f_rev_for_each:ident) -> _
37 $rev_for_each:block
38
39 fn try_rev_for_each($self_try_rev_for_each:ident, $f_try_rev_for_each:ident) -> _
40 $try_rev_for_each:block
41
42 fn collect_array($self_collect_array:ident) -> _
43 $collect_array:block
44
45 fn split_at($self_split_at_dyn:ident, $n_split_at_dyn:ident) -> _
46 $split_at_dyn:block
47
48 $(fn nth($self_nth:ident, $n_nth:ident) -> _
49 $nth:block)?
50 }
51 {
52 $split:ident
53 }
54 ) => {
55 impl<$($a,)? $t, const $n: usize> array::$bulk<$($a,)? $t, $n>
56 {
57 #[allow(unused)]
58 #[inline]
59 pub(crate) const fn into_inner(self) -> $array
60 {
61 let Self {array} = self;
62 array
63 }
64 }
65 impl<$($a,)? $t, const $n: usize> IntoIterator for array::$bulk<$($a,)? $t, $n>
66 {
67 type Item = $item;
68 type IntoIter = <$array as IntoIterator>::IntoIter;
69
70 #[inline]
71 fn into_iter(self) -> Self::IntoIter
72 {
73 let Self {array} = self;
74 array.into_iter()
75 }
76 }
77 impl<$($a,)? $t, const $n: usize> const IntoBulk for $array
78 {
79 type IntoBulk = array::$bulk<$($a,)? $t, $n>;
80
81 #[inline]
82 fn into_bulk(self) -> Self::IntoBulk
83 {
84 array::$bulk {
85 array: self
86 }
87 }
88 }
89 impl<$($a,)? $t, const $n: usize> const Bulk for array::$bulk<$($a,)? $t, $n>
90 {
91 #[inline]
92 fn len(&self) -> usize
93 {
94 $n
95 }
96
97 fn first(self) -> Option<Self::Item>
98 where
99 Self::Item: ~const Destruct,
100 Self: Sized
101 {
102 self.nth([(); 0])
103 }
104
105 $(fn nth<L>($self_nth, $n_nth: L) -> Option<Self::Item>
106 where
107 Self::Item: ~const Destruct,
108 Self: Sized,
109 L: ~const LengthSpec
110 $nth)?
111
112 #[inline]
113 fn collect_array($self_collect_array) -> <Self as StaticBulk>::Array<Self::Item>
114 $collect_array
115
116 #[inline]
117 fn for_each<F>($self_for_each, mut $f_for_each: F)
118 where
119 F: ~const FnMut($item) + ~const Destruct
120 $for_each
121
122 #[inline]
123 fn try_for_each<F, R>($self_try_for_each, mut $f_try_for_each: F) -> R
124 where
125 $item: ~const Destruct,
126 F: ~const FnMut($item) -> R + ~const Destruct,
127 R: ~const Try<Output = (), Residual: ~const Destruct>
128 $try_for_each
129 }
130 impl<$($a,)? $t, const $n: usize> const DoubleEndedBulk for array::$bulk<$($a,)? $t, $n>
131 {
132 #[inline]
133 fn rev_for_each<F>($self_rev_for_each, mut $f_rev_for_each: F)
134 where
135 F: ~const FnMut($item) + ~const Destruct
136 $rev_for_each
137
138 #[inline]
139 fn try_rev_for_each<F, R>($self_try_rev_for_each, mut $f_try_rev_for_each: F) -> R
140 where
141 $item: ~const Destruct,
142 F: ~const FnMut($item) -> R + ~const Destruct,
143 R: ~const Try<Output = (), Residual: ~const Destruct>
144 $try_rev_for_each
145 }
146 impl<$($a,)? T, const N: usize, L> SplitBulk<L> for array::$bulk<$($a,)? T, N>
147 where
148 L: LengthSpec
149 {
150 default type Left = <<$array as IntoIterator>::IntoIter as IntoBulk>::IntoBulk;
151 default type Right = <<$array as IntoIterator>::IntoIter as IntoBulk>::IntoBulk;
152
153 #[track_caller]
154 default fn split_at($self_split_at_dyn, $n_split_at_dyn: L) -> (Self::Left, Self::Right)
155 where
156 Self: Sized
157 $split_at_dyn
158 }
159 impl<$($a,)? T, const N: usize, const M: usize> const SplitBulk<[(); M]> for array::$bulk<$($a,)? T, N>
160 where
161 [(); N.saturating_sub(M)]:,
162 [(); N.min(M)]:
163 {
164 type Left = array::$bulk<$($a,)? T, {N.min(M)}>;
165 type Right = array::$bulk<$($a,)? T, {N.saturating_sub(M)}>;
166
167 #[track_caller]
168 fn split_at(self, _n: [(); M]) -> (Self::Left, Self::Right)
169 where
170 Self: Sized
171 {
172 let (left, right) = util::$split(self.array);
173 (
174 array::$bulk {
175 array: left
176 },
177 array::$bulk {
178 array: right
179 }
180 )
181 }
182 }
183 unsafe impl<$($a,)? $t, const $n: usize> StaticBulk for array::$bulk<$($a,)? $t, $n>
184 {
185 type Array<U> = [U; $n];
186 }
187 };
188}
189impl_bulk!(
190 impl IntoBulk<T, const N: usize>; for T; in [T; N];
191 {
192 fn for_each(self, f) -> _
193 {
194 let Self { array } = self;
195 let mut src_array = util::new_init_array(array);
196 let mut src_guard = Guard { array_mut: &mut src_array, initialized: 0..N };
197
198 while src_guard.initialized.start < src_guard.initialized.end
199 {
200 unsafe {
201 f(src_guard.pop_front_unchecked())
202 }
203 }
204
205 core::mem::forget(src_guard);
206 }
207
208 fn try_for_each(self, f) -> _
209 {
210 let Self { array } = self;
211 let mut src_array = util::new_init_array(array);
212 let mut src_guard = Guard { array_mut: &mut src_array, initialized: 0..N };
213
214 while src_guard.initialized.start < src_guard.initialized.end
215 {
216 unsafe {
217 f(src_guard.pop_front_unchecked())?
218 }
219 }
220
221 core::mem::forget(src_guard);
222 R::from_output(())
223 }
224
225 fn rev_for_each(self, f) -> _
226 {
227 let Self { array } = self;
228 let mut src_array = util::new_init_array(array);
229 let mut src_guard = Guard { array_mut: &mut src_array, initialized: 0..N };
230
231 while src_guard.initialized.start < src_guard.initialized.end
232 {
233 unsafe {
234 f(src_guard.pop_back_unchecked())
235 }
236 }
237
238 core::mem::forget(src_guard);
239 }
240
241 fn try_rev_for_each(self, f) -> _
242 {
243 let Self { array } = self;
244 let mut src_array = util::new_init_array(array);
245 let mut src_guard = Guard { array_mut: &mut src_array, initialized: 0..N };
246
247 while src_guard.initialized.start < src_guard.initialized.end
248 {
249 unsafe {
250 f(src_guard.pop_back_unchecked())?
251 }
252 }
253
254 core::mem::forget(src_guard);
255 R::from_output(())
256 }
257
258 fn collect_array(self) -> _
259 {
260 let Self {array} = self;
261 array
262 }
263
264 fn split_at(self, n) -> _
265 {
266 let n = n.len_metadata();
267 let Self {array} = self;
268 let array = MaybeUninit::new(array).transpose();
269 let mut left = array.into_iter();
270 let mut right = unsafe {
271 core::ptr::read(&left)
272 };
273 let _ = left.advance_back_by(N.saturating_sub(n));
274 let _ = right.advance_by(N.min(n));
275 let (left, right): (Self::IntoIter, Self::IntoIter) = unsafe {
276 core::intrinsics::transmute_unchecked((left, right))
277 };
278 (left.into_bulk(), right.into_bulk()).same().ok().unwrap()
279 }
280 }
281 {
282 split_array
283 }
284);
285impl_bulk!(
286 impl Bulk<'a, T, const N: usize>; for &'a T; in &'a [T; N];
287 {
288 fn for_each(self, f) -> _
289 {
290 let Self {array} = self;
291 let mut n = 0;
292 while n < N
293 {
294 f(&array[n]);
295 n += 1;
296 }
297 }
298
299 fn try_for_each(self, f) -> _
300 {
301 let Self {array} = self;
302 let mut n = 0;
303 while n < N
304 {
305 f(&array[n])?;
306 n += 1;
307 }
308 R::from_output(())
309 }
310
311 fn rev_for_each(self, f) -> _
312 {
313 let Self {array} = self;
314 let mut n = N;
315 while n > 0
316 {
317 n -= 1;
318 f(&array[n]);
319 }
320 }
321
322 fn try_rev_for_each(self, f) -> _
323 {
324 let Self {array} = self;
325 let mut n = N;
326 while n > 0
327 {
328 n -= 1;
329 f(&array[n])?;
330 }
331 R::from_output(())
332 }
333
334 fn collect_array(self) -> _
335 {
336 let Self {array} = self;
337 array.each_ref()
338 }
339
340 fn split_at(self, n) -> _
341 {
342 let n = n.len_metadata();
343 let Self {array} = self;
344 let (left, right) = array.split_at(n);
345 (left.into_bulk(), right.into_bulk()).same().ok().unwrap()
346 }
347
348 fn nth(self, n) -> _
349 {
350 let Self {array} = self;
351 array.get(n.len_metadata())
352 }
353 }
354 {
355 split_array_ref
356 }
357);
358impl_bulk!(
359 impl BulkMut<'a, T, const N: usize>; for &'a mut T; in &'a mut [T; N];
360 {
361 fn for_each(self, f) -> _
362 {
363 let Self {array} = self;
364 let mut n = 0;
365 while n < N
366 {
367 f(unsafe {&mut *(&mut array[n] as *mut _)});
368 n += 1;
369 }
370 }
371
372 fn try_for_each(self, f) -> _
373 {
374 let Self {array} = self;
375 let mut n = 0;
376 while n < N
377 {
378 f(unsafe {&mut *(&mut array[n] as *mut _)})?;
379 n += 1;
380 }
381 R::from_output(())
382 }
383
384 fn rev_for_each(self, f) -> _
385 {
386 let Self {array} = self;
387 let mut n = N;
388 while n > 0
389 {
390 n -= 1;
391 f(unsafe {&mut *(&mut array[n] as *mut _)});
392 }
393 }
394
395 fn try_rev_for_each(self, f) -> _
396 {
397 let Self {array} = self;
398 let mut n = N;
399 while n > 0
400 {
401 n -= 1;
402 f(unsafe {&mut *(&mut array[n] as *mut _)})?;
403 }
404 R::from_output(())
405 }
406
407 fn collect_array(self) -> _
408 {
409 let Self {array} = self;
410 array.each_mut()
411 }
412
413 fn split_at(self, n) -> _
414 {
415 let n = n.len_metadata();
416 let Self {array} = self;
417 let (left, right) = array.split_at_mut(n);
418 (left.into_bulk(), right.into_bulk()).same().ok().unwrap()
419 }
420
421 fn nth(self, n) -> _
422 {
423 let Self {array} = self;
424 array.get_mut(n.len_metadata())
425 }
426 }
427 {
428 split_array_mut
429 }
430);
431
432#[cfg(test)]
489mod test
490{
491 use crate::{AsBulk, Bulk};
492
493 #[test]
494 fn it_works()
495 {
496 let a = [1, 2, 3];
497
498 let b = a.bulk().copied().rev().map(|x| 4 - x).collect::<[_; _], _>();
499
500 println!("{:?}", b)
501 }
502}