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