1use super::*;
4use core::mem::MaybeUninit;
5use core::ops::{Add, Div, Mul, Sub};
6use core::ptr;
7use typenum::operator_aliases::*;
8
9pub unsafe trait GenericSequence<T>: Sized + IntoIterator {
18 type Length: ArrayLength;
20
21 type Sequence: GenericSequence<T, Length = Self::Length> + FromIterator<T>;
23
24 fn generate<F>(f: F) -> Self::Sequence
29 where
30 F: FnMut(usize) -> T;
31
32 #[cfg_attr(not(feature = "internals"), doc(hidden))]
36 #[inline(always)]
37 fn inverted_zip<B, U, F>(
38 self,
39 lhs: GenericArray<B, Self::Length>,
40 mut f: F,
41 ) -> MappedSequence<GenericArray<B, Self::Length>, B, U>
42 where
43 GenericArray<B, Self::Length>:
44 GenericSequence<B, Length = Self::Length> + MappedGenericSequence<B, U>,
45 Self: MappedGenericSequence<T, U>,
46 F: FnMut(B, Self::Item) -> U,
47 {
48 unsafe {
49 let mut left = ManuallyDrop::new(lhs);
50 let mut left = IntrusiveArrayConsumer::new(&mut left);
51
52 let (left_array_iter, left_position) = left.iter_position();
53
54 FromIterator::from_iter(left_array_iter.zip(self).map(|(l, right_value)| {
55 let left_value = ptr::read(l);
56
57 *left_position += 1;
58
59 f(left_value, right_value)
60 }))
61 }
62 }
63
64 #[cfg_attr(not(feature = "internals"), doc(hidden))]
66 #[inline(always)]
67 fn inverted_zip2<B, Lhs, U, F>(self, lhs: Lhs, mut f: F) -> MappedSequence<Lhs, B, U>
68 where
69 Lhs: GenericSequence<B, Length = Self::Length> + MappedGenericSequence<B, U>,
70 Self: MappedGenericSequence<T, U>,
71 F: FnMut(Lhs::Item, Self::Item) -> U,
72 {
73 FromIterator::from_iter(lhs.into_iter().zip(self).map(|(l, r)| f(l, r)))
74 }
75}
76
77pub type SequenceItem<T> = <T as IntoIterator>::Item;
82
83unsafe impl<'a, T: 'a, S: GenericSequence<T>> GenericSequence<T> for &'a S
84where
85 &'a S: IntoIterator,
86{
87 type Length = S::Length;
88 type Sequence = S::Sequence;
89
90 #[inline(always)]
91 fn generate<F>(f: F) -> Self::Sequence
92 where
93 F: FnMut(usize) -> T,
94 {
95 S::generate(f)
96 }
97}
98
99unsafe impl<'a, T: 'a, S: GenericSequence<T>> GenericSequence<T> for &'a mut S
100where
101 &'a mut S: IntoIterator,
102{
103 type Length = S::Length;
104 type Sequence = S::Sequence;
105
106 #[inline(always)]
107 fn generate<F>(f: F) -> Self::Sequence
108 where
109 F: FnMut(usize) -> T,
110 {
111 S::generate(f)
112 }
113}
114
115pub unsafe trait Lengthen<T>: Sized + GenericSequence<T> {
124 type Longer: Shorten<T, Shorter = Self>;
126
127 fn append(self, last: T) -> Self::Longer;
141
142 fn prepend(self, first: T) -> Self::Longer;
156}
157
158pub unsafe trait Shorten<T>: Sized + GenericSequence<T> {
167 type Shorter: Lengthen<T, Longer = Self>;
169
170 fn pop_back(self) -> (Self::Shorter, T);
185
186 fn pop_front(self) -> (T, Self::Shorter);
200}
201
202unsafe impl<T, N: ArrayLength> Lengthen<T> for GenericArray<T, N>
203where
204 N: Add<B1>,
205 Add1<N>: ArrayLength,
206 Add1<N>: Sub<B1, Output = N>,
207 Sub1<Add1<N>>: ArrayLength,
208{
209 type Longer = GenericArray<T, Add1<N>>;
210
211 #[inline]
212 fn append(self, last: T) -> Self::Longer {
213 let mut longer: MaybeUninit<Self::Longer> = MaybeUninit::uninit();
214
215 let out_ptr = longer.as_mut_ptr() as *mut Self;
217
218 unsafe {
219 ptr::write(out_ptr, self);
221 ptr::write(out_ptr.add(1) as *mut T, last);
223
224 longer.assume_init()
225 }
226 }
227
228 #[inline]
229 fn prepend(self, first: T) -> Self::Longer {
230 let mut longer: MaybeUninit<Self::Longer> = MaybeUninit::uninit();
231
232 let out_ptr = longer.as_mut_ptr() as *mut T;
234
235 unsafe {
236 ptr::write(out_ptr, first);
238 ptr::write(out_ptr.add(1) as *mut Self, self);
240
241 longer.assume_init()
242 }
243 }
244}
245
246unsafe impl<T, N: ArrayLength> Shorten<T> for GenericArray<T, N>
247where
248 N: Sub<B1>,
249 Sub1<N>: ArrayLength,
250 Sub1<N>: Add<B1, Output = N>,
251 Add1<Sub1<N>>: ArrayLength,
252{
253 type Shorter = GenericArray<T, Sub1<N>>;
254
255 #[inline]
256 fn pop_back(self) -> (Self::Shorter, T) {
257 let whole = ManuallyDrop::new(self);
258
259 unsafe {
260 let init = ptr::read(whole.as_ptr() as _);
261 let last = ptr::read(whole.as_ptr().add(Sub1::<N>::USIZE) as _);
262
263 (init, last)
264 }
265 }
266
267 #[inline]
268 fn pop_front(self) -> (T, Self::Shorter) {
269 let whole = ManuallyDrop::new(self);
271
272 unsafe {
273 let head = ptr::read(whole.as_ptr() as _);
274 let tail = ptr::read(whole.as_ptr().offset(1) as _);
275
276 (head, tail)
277 }
278 }
279}
280
281pub unsafe trait Split<T, K: ArrayLength>: GenericSequence<T> {
287 type First: GenericSequence<T>;
289 type Second: GenericSequence<T>;
291
292 fn split(self) -> (Self::First, Self::Second);
294}
295
296unsafe impl<T, N, K> Split<T, K> for GenericArray<T, N>
297where
298 N: ArrayLength,
299 K: ArrayLength,
300 N: Sub<K>,
301 Diff<N, K>: ArrayLength,
302{
303 type First = GenericArray<T, K>;
304 type Second = GenericArray<T, Diff<N, K>>;
305
306 #[inline]
307 fn split(self) -> (Self::First, Self::Second) {
308 unsafe {
309 let whole = ManuallyDrop::new(self);
311
312 let head = ptr::read(whole.as_ptr() as *const _);
313 let tail = ptr::read(whole.as_ptr().add(K::USIZE) as *const _);
314
315 (head, tail)
316 }
317 }
318}
319
320unsafe impl<'a, T, N, K> Split<T, K> for &'a GenericArray<T, N>
321where
322 N: ArrayLength,
323 K: ArrayLength,
324 N: Sub<K>,
325 Diff<N, K>: ArrayLength,
326{
327 type First = &'a GenericArray<T, K>;
328 type Second = &'a GenericArray<T, Diff<N, K>>;
329
330 #[inline]
331 fn split(self) -> (Self::First, Self::Second) {
332 unsafe {
333 let ptr_to_first: *const T = self.as_ptr();
334 let head = &*(ptr_to_first as *const _);
335 let tail = &*(ptr_to_first.add(K::USIZE) as *const _);
336 (head, tail)
337 }
338 }
339}
340
341unsafe impl<'a, T, N, K> Split<T, K> for &'a mut GenericArray<T, N>
342where
343 N: ArrayLength,
344 K: ArrayLength,
345 N: Sub<K>,
346 Diff<N, K>: ArrayLength,
347{
348 type First = &'a mut GenericArray<T, K>;
349 type Second = &'a mut GenericArray<T, Diff<N, K>>;
350
351 #[inline]
352 fn split(self) -> (Self::First, Self::Second) {
353 unsafe {
354 let ptr_to_first: *mut T = self.as_mut_ptr();
355 let head = &mut *(ptr_to_first as *mut _);
356 let tail = &mut *(ptr_to_first.add(K::USIZE) as *mut _);
357 (head, tail)
358 }
359 }
360}
361
362pub unsafe trait Concat<T, M: ArrayLength>: GenericSequence<T> {
368 type Rest: GenericSequence<T, Length = M>;
370
371 type Output: GenericSequence<T>;
373
374 fn concat(self, rest: Self::Rest) -> Self::Output;
376}
377
378unsafe impl<T, N, M> Concat<T, M> for GenericArray<T, N>
379where
380 N: ArrayLength + Add<M>,
381 M: ArrayLength,
382 Sum<N, M>: ArrayLength,
383{
384 type Rest = GenericArray<T, M>;
385 type Output = GenericArray<T, Sum<N, M>>;
386
387 #[inline]
388 fn concat(self, rest: Self::Rest) -> Self::Output {
389 let mut output: MaybeUninit<Self::Output> = MaybeUninit::uninit();
390
391 let out_ptr = output.as_mut_ptr() as *mut Self;
392
393 unsafe {
394 ptr::write(out_ptr, self);
396 ptr::write(out_ptr.add(1) as *mut _, rest);
398
399 output.assume_init()
400 }
401 }
402}
403
404pub unsafe trait Remove<T, N: ArrayLength>: GenericSequence<T> {
412 type Output: GenericSequence<T>;
414
415 #[inline]
434 fn remove(self, idx: usize) -> (T, Self::Output) {
435 assert!(
436 idx < N::USIZE,
437 "Index out of bounds: the len is {} but the index is {}",
438 N::USIZE,
439 idx
440 );
441
442 unsafe { self.remove_unchecked(idx) }
443 }
444
445 fn swap_remove(self, idx: usize) -> (T, Self::Output) {
462 assert!(
463 idx < N::USIZE,
464 "Index out of bounds: the len is {} but the index is {}",
465 N::USIZE,
466 idx
467 );
468
469 unsafe { self.swap_remove_unchecked(idx) }
470 }
471
472 unsafe fn remove_unchecked(self, idx: usize) -> (T, Self::Output);
482
483 unsafe fn swap_remove_unchecked(self, idx: usize) -> (T, Self::Output);
491}
492
493unsafe impl<T, N> Remove<T, N> for GenericArray<T, N>
494where
495 N: ArrayLength + Sub<B1>,
496 Sub1<N>: ArrayLength,
497{
498 type Output = GenericArray<T, Sub1<N>>;
499
500 #[inline]
501 unsafe fn remove_unchecked(self, idx: usize) -> (T, Self::Output) {
502 if idx >= N::USIZE || N::USIZE == 0 {
503 core::hint::unreachable_unchecked();
504 }
505
506 let mut array = ManuallyDrop::new(self);
507
508 let dst = array.as_mut_ptr().add(idx);
509
510 let removed = ptr::read(dst);
511
512 ptr::copy(dst.add(1), dst, N::USIZE - idx - 1);
514
515 (removed, mem::transmute_copy(&array))
517 }
518
519 #[inline]
520 unsafe fn swap_remove_unchecked(self, idx: usize) -> (T, Self::Output) {
521 if idx >= N::USIZE || N::USIZE == 0 {
522 core::hint::unreachable_unchecked();
523 }
524
525 let mut array = ManuallyDrop::new(self);
526
527 array.swap(idx, N::USIZE - 1);
528
529 let removed = ptr::read(array.as_ptr().add(N::USIZE - 1));
531
532 (removed, mem::transmute_copy(&array))
534 }
535}
536
537pub unsafe trait Flatten<T, N, M>: GenericSequence<GenericArray<T, N>, Length = M>
545where
546 N: ArrayLength + Mul<M>,
547 Prod<N, M>: ArrayLength,
548{
549 type Output: GenericSequence<T, Length = Prod<N, M>>;
551
552 fn flatten(self) -> Self::Output;
564}
565
566pub unsafe trait Unflatten<T, NM, N>: GenericSequence<T, Length = NM>
573where
574 NM: ArrayLength + Div<N>,
575 N: ArrayLength,
576 Quot<NM, N>: ArrayLength,
577{
578 type Output: GenericSequence<GenericArray<T, N>, Length = Quot<NM, N>>;
580
581 fn unflatten(self) -> Self::Output;
593}
594
595unsafe impl<T, N, M> Flatten<T, N, M> for GenericArray<GenericArray<T, N>, M>
596where
597 N: ArrayLength + Mul<M>,
598 M: ArrayLength,
599 Prod<N, M>: ArrayLength,
600{
601 type Output = GenericArray<T, Prod<N, M>>;
602
603 #[inline(always)]
604 fn flatten(self) -> Self::Output {
605 unsafe { crate::const_transmute(self) }
606 }
607}
608
609unsafe impl<'a, T, N, M> Flatten<T, N, M> for &'a GenericArray<GenericArray<T, N>, M>
610where
611 N: ArrayLength + Mul<M>,
612 M: ArrayLength,
613 Prod<N, M>: ArrayLength,
614{
615 type Output = &'a GenericArray<T, Prod<N, M>>;
616
617 #[inline(always)]
618 fn flatten(self) -> Self::Output {
619 unsafe { mem::transmute(self) }
620 }
621}
622
623unsafe impl<'a, T, N, M> Flatten<T, N, M> for &'a mut GenericArray<GenericArray<T, N>, M>
624where
625 N: ArrayLength + Mul<M>,
626 M: ArrayLength,
627 Prod<N, M>: ArrayLength,
628{
629 type Output = &'a mut GenericArray<T, Prod<N, M>>;
630
631 #[inline(always)]
632 fn flatten(self) -> Self::Output {
633 unsafe { mem::transmute(self) }
634 }
635}
636
637unsafe impl<T, NM, N> Unflatten<T, NM, N> for GenericArray<T, NM>
638where
639 NM: ArrayLength + Div<N>,
640 N: ArrayLength,
641 Quot<NM, N>: ArrayLength,
642{
643 type Output = GenericArray<GenericArray<T, N>, Quot<NM, N>>;
644
645 #[inline(always)]
646 fn unflatten(self) -> Self::Output {
647 unsafe { crate::const_transmute(self) }
648 }
649}
650
651unsafe impl<'a, T, NM, N> Unflatten<T, NM, N> for &'a GenericArray<T, NM>
652where
653 NM: ArrayLength + Div<N>,
654 N: ArrayLength,
655 Quot<NM, N>: ArrayLength,
656{
657 type Output = &'a GenericArray<GenericArray<T, N>, Quot<NM, N>>;
658
659 #[inline(always)]
660 fn unflatten(self) -> Self::Output {
661 unsafe { mem::transmute(self) }
662 }
663}
664
665unsafe impl<'a, T, NM, N> Unflatten<T, NM, N> for &'a mut GenericArray<T, NM>
666where
667 NM: ArrayLength + Div<N>,
668 N: ArrayLength,
669 Quot<NM, N>: ArrayLength,
670{
671 type Output = &'a mut GenericArray<GenericArray<T, N>, Quot<NM, N>>;
672
673 #[inline(always)]
674 fn unflatten(self) -> Self::Output {
675 unsafe { mem::transmute(self) }
676 }
677}