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
31 where
32 F: FnMut(usize) -> T;
33
34 #[inline(always)]
38 fn repeat(value: T) -> Self::Sequence
39 where
40 T: Clone,
41 {
42 let mut value = Some(value);
43
44 Self::generate(move |i| unsafe {
45 if i + 1 == Self::Length::USIZE {
46 value.take().unwrap_unchecked()
48 } else if let Some(ref v) = value {
49 v.clone()
51 } else {
52 core::hint::unreachable_unchecked()
54 }
55 })
56 }
57
58 #[cfg_attr(not(feature = "internals"), doc(hidden))]
62 #[inline(always)]
63 fn inverted_zip<B, U, F>(
64 self,
65 lhs: GenericArray<B, Self::Length>,
66 mut f: F,
67 ) -> MappedSequence<GenericArray<B, Self::Length>, B, U>
68 where
69 GenericArray<B, Self::Length>:
70 GenericSequence<B, Length = Self::Length> + MappedGenericSequence<B, U>,
71 Self: MappedGenericSequence<T, U>,
72 F: FnMut(B, Self::Item) -> U,
73 {
74 unsafe {
75 let mut left = ManuallyDrop::new(lhs);
76 let mut left = IntrusiveArrayConsumer::new(&mut left);
77
78 let (left_array_iter, left_position) = left.iter_position();
79
80 FromIterator::from_iter(left_array_iter.zip(self).map(|(l, right_value)| {
81 let left_value = ptr::read(l);
82
83 *left_position += 1;
84
85 f(left_value, right_value)
86 }))
87 }
88 }
89
90 #[cfg_attr(not(feature = "internals"), doc(hidden))]
92 #[inline(always)]
93 fn inverted_zip2<B, Lhs, U, F>(self, lhs: Lhs, mut f: F) -> MappedSequence<Lhs, B, U>
94 where
95 Lhs: GenericSequence<B, Length = Self::Length> + MappedGenericSequence<B, U>,
96 Self: MappedGenericSequence<T, U>,
97 F: FnMut(Lhs::Item, Self::Item) -> U,
98 {
99 FromIterator::from_iter(lhs.into_iter().zip(self).map(|(l, r)| f(l, r)))
100 }
101}
102
103pub trait FromFallibleIterator<T>: Sized {
105 fn from_fallible_iter<I, E>(iter: I) -> Result<Self, E>
114 where
115 I: IntoIterator<Item = Result<T, E>>;
116}
117
118pub unsafe trait FallibleGenericSequence<T>: GenericSequence<T>
126where
127 Self::Sequence: FromFallibleIterator<T>,
128{
129 fn try_generate<F, E>(f: F) -> Result<Self::Sequence, E>
134 where
135 F: FnMut(usize) -> Result<T, E>;
136}
137
138pub type SequenceItem<T> = <T as IntoIterator>::Item;
143
144unsafe impl<'a, T: 'a, S: GenericSequence<T>> GenericSequence<T> for &'a S
145where
146 &'a S: IntoIterator,
147{
148 type Length = S::Length;
149 type Sequence = S::Sequence;
150
151 #[inline(always)]
152 fn generate<F>(f: F) -> Self::Sequence
153 where
154 F: FnMut(usize) -> T,
155 {
156 S::generate(f)
157 }
158}
159
160unsafe impl<'a, T: 'a, S: FallibleGenericSequence<T>> FallibleGenericSequence<T> for &'a S
161where
162 &'a S: IntoIterator,
163 Self::Sequence: FromFallibleIterator<T>,
164{
165 #[inline(always)]
166 fn try_generate<F, E>(f: F) -> Result<Self::Sequence, E>
167 where
168 F: FnMut(usize) -> Result<T, E>,
169 {
170 S::try_generate(f)
171 }
172}
173
174unsafe impl<'a, T: 'a, S: GenericSequence<T>> GenericSequence<T> for &'a mut S
175where
176 &'a mut S: IntoIterator,
177{
178 type Length = S::Length;
179 type Sequence = S::Sequence;
180
181 #[inline(always)]
182 fn generate<F>(f: F) -> Self::Sequence
183 where
184 F: FnMut(usize) -> T,
185 {
186 S::generate(f)
187 }
188}
189
190unsafe impl<'a, T: 'a, S: FallibleGenericSequence<T>> FallibleGenericSequence<T> for &'a mut S
191where
192 &'a mut S: IntoIterator,
193 Self::Sequence: FromFallibleIterator<T>,
194{
195 #[inline(always)]
196 fn try_generate<F, E>(f: F) -> Result<Self::Sequence, E>
197 where
198 F: FnMut(usize) -> Result<T, E>,
199 {
200 S::try_generate(f)
201 }
202}
203
204pub unsafe trait Lengthen<T>: Sized + GenericSequence<T> {
213 type Longer: Shorten<T, Shorter = Self>;
215
216 fn append(self, last: T) -> Self::Longer;
230
231 fn prepend(self, first: T) -> Self::Longer;
245}
246
247pub unsafe trait Shorten<T>: Sized + GenericSequence<T> {
256 type Shorter: Lengthen<T, Longer = Self>;
258
259 fn pop_back(self) -> (Self::Shorter, T);
274
275 fn pop_front(self) -> (T, Self::Shorter);
289}
290
291unsafe impl<T, N: ArrayLength> Lengthen<T> for GenericArray<T, N>
292where
293 N: Add<B1>,
294 Add1<N>: ArrayLength,
295 Add1<N>: Sub<B1, Output = N>,
296 Sub1<Add1<N>>: ArrayLength,
297{
298 type Longer = GenericArray<T, Add1<N>>;
299
300 #[inline]
301 fn append(self, last: T) -> Self::Longer {
302 let mut longer: MaybeUninit<Self::Longer> = MaybeUninit::uninit();
303
304 let out_ptr = longer.as_mut_ptr() as *mut Self;
306
307 unsafe {
308 ptr::write(out_ptr, self);
310 ptr::write(out_ptr.add(1) as *mut T, last);
312
313 longer.assume_init()
314 }
315 }
316
317 #[inline]
318 fn prepend(self, first: T) -> Self::Longer {
319 let mut longer: MaybeUninit<Self::Longer> = MaybeUninit::uninit();
320
321 let out_ptr = longer.as_mut_ptr() as *mut T;
323
324 unsafe {
325 ptr::write(out_ptr, first);
327 ptr::write(out_ptr.add(1) as *mut Self, self);
329
330 longer.assume_init()
331 }
332 }
333}
334
335unsafe impl<T, N: ArrayLength> Shorten<T> for GenericArray<T, N>
336where
337 N: Sub<B1>,
338 Sub1<N>: ArrayLength,
339 Sub1<N>: Add<B1, Output = N>,
340 Add1<Sub1<N>>: ArrayLength,
341{
342 type Shorter = GenericArray<T, Sub1<N>>;
343
344 #[inline]
345 fn pop_back(self) -> (Self::Shorter, T) {
346 let whole = ManuallyDrop::new(self);
347
348 unsafe {
349 let init = ptr::read(whole.as_ptr() as _);
350 let last = ptr::read(whole.as_ptr().add(Sub1::<N>::USIZE) as _);
351
352 (init, last)
353 }
354 }
355
356 #[inline]
357 fn pop_front(self) -> (T, Self::Shorter) {
358 let whole = ManuallyDrop::new(self);
360
361 unsafe {
362 let head = ptr::read(whole.as_ptr() as _);
363 let tail = ptr::read(whole.as_ptr().offset(1) as _);
364
365 (head, tail)
366 }
367 }
368}
369
370pub unsafe trait Split<T, K: ArrayLength>: GenericSequence<T> {
376 type First: GenericSequence<T>;
378 type Second: GenericSequence<T>;
380
381 fn split(self) -> (Self::First, Self::Second);
383}
384
385unsafe impl<T, N, K> Split<T, K> for GenericArray<T, N>
386where
387 N: ArrayLength,
388 K: ArrayLength,
389 N: Sub<K>,
390 Diff<N, K>: ArrayLength,
391{
392 type First = GenericArray<T, K>;
393 type Second = GenericArray<T, Diff<N, K>>;
394
395 #[inline]
396 fn split(self) -> (Self::First, Self::Second) {
397 unsafe {
398 let whole = ManuallyDrop::new(self);
400
401 let head = ptr::read(whole.as_ptr() as *const _);
402 let tail = ptr::read(whole.as_ptr().add(K::USIZE) as *const _);
403
404 (head, tail)
405 }
406 }
407}
408
409unsafe impl<'a, T, N, K> Split<T, K> for &'a GenericArray<T, N>
410where
411 N: ArrayLength,
412 K: ArrayLength,
413 N: Sub<K>,
414 Diff<N, K>: ArrayLength,
415{
416 type First = &'a GenericArray<T, K>;
417 type Second = &'a GenericArray<T, Diff<N, K>>;
418
419 #[inline]
420 fn split(self) -> (Self::First, Self::Second) {
421 unsafe {
422 let ptr_to_first: *const T = self.as_ptr();
423 let head = &*(ptr_to_first as *const _);
424 let tail = &*(ptr_to_first.add(K::USIZE) as *const _);
425 (head, tail)
426 }
427 }
428}
429
430unsafe impl<'a, T, N, K> Split<T, K> for &'a mut GenericArray<T, N>
431where
432 N: ArrayLength,
433 K: ArrayLength,
434 N: Sub<K>,
435 Diff<N, K>: ArrayLength,
436{
437 type First = &'a mut GenericArray<T, K>;
438 type Second = &'a mut GenericArray<T, Diff<N, K>>;
439
440 #[inline]
441 fn split(self) -> (Self::First, Self::Second) {
442 unsafe {
443 let ptr_to_first: *mut T = self.as_mut_ptr();
444 let head = &mut *(ptr_to_first as *mut _);
445 let tail = &mut *(ptr_to_first.add(K::USIZE) as *mut _);
446 (head, tail)
447 }
448 }
449}
450
451pub unsafe trait Concat<T, M: ArrayLength>: GenericSequence<T> {
457 type Rest: GenericSequence<T, Length = M>;
459
460 type Output: GenericSequence<T>;
462
463 fn concat(self, rest: Self::Rest) -> Self::Output;
465}
466
467unsafe impl<T, N, M> Concat<T, M> for GenericArray<T, N>
468where
469 N: ArrayLength + Add<M>,
470 M: ArrayLength,
471 Sum<N, M>: ArrayLength,
472{
473 type Rest = GenericArray<T, M>;
474 type Output = GenericArray<T, Sum<N, M>>;
475
476 #[inline]
477 fn concat(self, rest: Self::Rest) -> Self::Output {
478 let mut output: MaybeUninit<Self::Output> = MaybeUninit::uninit();
479
480 let out_ptr = output.as_mut_ptr() as *mut Self;
481
482 unsafe {
483 ptr::write(out_ptr, self);
485 ptr::write(out_ptr.add(1) as *mut _, rest);
487
488 output.assume_init()
489 }
490 }
491}
492
493pub unsafe trait Remove<T, N: ArrayLength>: GenericSequence<T> {
501 type Output: GenericSequence<T>;
503
504 #[inline]
523 fn remove(self, idx: usize) -> (T, Self::Output) {
524 assert!(
525 idx < N::USIZE,
526 "Index out of bounds: the len is {} but the index is {}",
527 N::USIZE,
528 idx
529 );
530
531 unsafe { self.remove_unchecked(idx) }
532 }
533
534 fn swap_remove(self, idx: usize) -> (T, Self::Output) {
551 assert!(
552 idx < N::USIZE,
553 "Index out of bounds: the len is {} but the index is {}",
554 N::USIZE,
555 idx
556 );
557
558 unsafe { self.swap_remove_unchecked(idx) }
559 }
560
561 unsafe fn remove_unchecked(self, idx: usize) -> (T, Self::Output);
571
572 unsafe fn swap_remove_unchecked(self, idx: usize) -> (T, Self::Output);
580}
581
582unsafe impl<T, N> Remove<T, N> for GenericArray<T, N>
583where
584 N: ArrayLength + Sub<B1>,
585 Sub1<N>: ArrayLength,
586{
587 type Output = GenericArray<T, Sub1<N>>;
588
589 #[inline]
590 unsafe fn remove_unchecked(self, idx: usize) -> (T, Self::Output) {
591 if idx >= N::USIZE || N::USIZE == 0 {
592 core::hint::unreachable_unchecked();
593 }
594
595 let mut array = ManuallyDrop::new(self);
596
597 let dst = array.as_mut_ptr().add(idx);
598
599 let removed = ptr::read(dst);
600
601 ptr::copy(dst.add(1), dst, N::USIZE - idx - 1);
603
604 (removed, mem::transmute_copy(&array))
606 }
607
608 #[inline]
609 unsafe fn swap_remove_unchecked(self, idx: usize) -> (T, Self::Output) {
610 if idx >= N::USIZE || N::USIZE == 0 {
611 core::hint::unreachable_unchecked();
612 }
613
614 let mut array = ManuallyDrop::new(self);
615
616 array.swap(idx, N::USIZE - 1);
617
618 let removed = ptr::read(array.as_ptr().add(N::USIZE - 1));
620
621 (removed, mem::transmute_copy(&array))
623 }
624}
625
626pub unsafe trait Flatten<T, N, M>: GenericSequence<GenericArray<T, N>, Length = M>
634where
635 N: ArrayLength + Mul<M>,
636 Prod<N, M>: ArrayLength,
637{
638 type Output: GenericSequence<T, Length = Prod<N, M>>;
640
641 fn flatten(self) -> Self::Output;
653}
654
655pub unsafe trait Unflatten<T, NM, N>: GenericSequence<T, Length = NM>
662where
663 NM: ArrayLength + Div<N>,
664 N: ArrayLength,
665 Quot<NM, N>: ArrayLength,
666{
667 type Output: GenericSequence<GenericArray<T, N>, Length = Quot<NM, N>>;
669
670 fn unflatten(self) -> Self::Output;
682}
683
684unsafe impl<T, N, M> Flatten<T, N, M> for GenericArray<GenericArray<T, N>, M>
685where
686 N: ArrayLength + Mul<M>,
687 M: ArrayLength,
688 Prod<N, M>: ArrayLength,
689{
690 type Output = GenericArray<T, Prod<N, M>>;
691
692 #[inline(always)]
693 fn flatten(self) -> Self::Output {
694 unsafe { crate::const_transmute(self) }
695 }
696}
697
698unsafe impl<'a, T, N, M> Flatten<T, N, M> for &'a GenericArray<GenericArray<T, N>, M>
699where
700 N: ArrayLength + Mul<M>,
701 M: ArrayLength,
702 Prod<N, M>: ArrayLength,
703{
704 type Output = &'a GenericArray<T, Prod<N, M>>;
705
706 #[inline(always)]
707 fn flatten(self) -> Self::Output {
708 unsafe { mem::transmute(self) }
709 }
710}
711
712unsafe impl<'a, T, N, M> Flatten<T, N, M> for &'a mut GenericArray<GenericArray<T, N>, M>
713where
714 N: ArrayLength + Mul<M>,
715 M: ArrayLength,
716 Prod<N, M>: ArrayLength,
717{
718 type Output = &'a mut GenericArray<T, Prod<N, M>>;
719
720 #[inline(always)]
721 fn flatten(self) -> Self::Output {
722 unsafe { mem::transmute(self) }
723 }
724}
725
726unsafe impl<T, NM, N> Unflatten<T, NM, N> for GenericArray<T, NM>
727where
728 NM: ArrayLength + Div<N>,
729 N: ArrayLength,
730 Quot<NM, N>: ArrayLength,
731{
732 type Output = GenericArray<GenericArray<T, N>, Quot<NM, N>>;
733
734 #[inline(always)]
735 fn unflatten(self) -> Self::Output {
736 unsafe { crate::const_transmute(self) }
737 }
738}
739
740unsafe impl<'a, T, NM, N> Unflatten<T, NM, N> for &'a GenericArray<T, NM>
741where
742 NM: ArrayLength + Div<N>,
743 N: ArrayLength,
744 Quot<NM, N>: ArrayLength,
745{
746 type Output = &'a GenericArray<GenericArray<T, N>, Quot<NM, N>>;
747
748 #[inline(always)]
749 fn unflatten(self) -> Self::Output {
750 unsafe { mem::transmute(self) }
751 }
752}
753
754unsafe impl<'a, T, NM, N> Unflatten<T, NM, N> for &'a mut GenericArray<T, NM>
755where
756 NM: ArrayLength + Div<N>,
757 N: ArrayLength,
758 Quot<NM, N>: ArrayLength,
759{
760 type Output = &'a mut GenericArray<GenericArray<T, N>, Quot<NM, N>>;
761
762 #[inline(always)]
763 fn unflatten(self) -> Self::Output {
764 unsafe { mem::transmute(self) }
765 }
766}