generic_array/
sequence.rs1//! Useful traits for manipulating sequences of data stored in `GenericArray`s
2
3use super::*;
4use core::mem::MaybeUninit;
5use core::ops::{Add, Div, Mul, Sub};
6use core::ptr;
7use typenum::operator_aliases::*;
8
9/// Defines some sequence with an associated length and iteration capabilities.
10///
11/// This is useful for passing N-length generic arrays as generics.
12///
13/// # Safety
14/// Care must be taken when implementing such that methods are safe.
15///
16/// Lengths must match, and element drop on panic must be handled.
17pub unsafe trait GenericSequence<T>: Sized + IntoIterator {
18 /// `GenericArray` associated length
19 type Length: ArrayLength;
20
21 /// Owned sequence type used in conjunction with reference implementations of `GenericSequence`
22 type Sequence: GenericSequence<T, Length = Self::Length> + FromIterator<T>;
23
24 /// Initializes a new sequence instance using the given function.
25 ///
26 /// If the generator function panics while initializing the sequence,
27 /// any already initialized elements will be dropped.
28 ///
29 /// See also [`FallibleGenericSequence::try_generate`].
30 fn generate<F>(f: F) -> Self::Sequence
31 where
32 F: FnMut(usize) -> T;
33
34 /// Initializes a new sequence instance by repeating the given value.
35 ///
36 /// This will only clone the value `Length - 1` times, taking ownership for the last element.
37 #[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 // for the last element, take the value
47 value.take().unwrap_unchecked()
48 } else if let Some(ref v) = value {
49 // otherwise, clone it
50 v.clone()
51 } else {
52 // SAFETY: this should never be reached
53 core::hint::unreachable_unchecked()
54 }
55 })
56 }
57
58 /// Treats `self` as the right-hand operand in a zip operation
59 ///
60 /// This is optimized for stack-allocated `GenericArray`s
61 #[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 /// Treats `self` as the right-hand operand in a zip operation
91 #[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
103/// Extension to `FromIterator` for fallible initialization.
104pub trait FromFallibleIterator<T>: Sized {
105 /// Initializes a new collection from a fallible iterator.
106 ///
107 /// If the iterator returns an error or panics while initializing the sequence,
108 /// any already initialized elements will be dropped and the error returned.
109 ///
110 /// This is equivalent to `iter.collect::<Result<GenericArray<T, N>, E>>()` _except_
111 /// it won't panic due to `Result::from_iter` truncating the underlying iterator
112 /// if an error occurs, leading to a length mismatch.
113 fn from_fallible_iter<I, E>(iter: I) -> Result<Self, E>
114 where
115 I: IntoIterator<Item = Result<T, E>>;
116}
117
118/// Extension to `GenericSequence` for fallible initialization.
119///
120/// # Safety
121///
122/// Care must be taken when implementing such that methods are safe.
123///
124/// Lengths must match, and element drop on panic or error must be handled.
125pub unsafe trait FallibleGenericSequence<T>: GenericSequence<T>
126where
127 Self::Sequence: FromFallibleIterator<T>,
128{
129 /// Initializes a new sequence instance using the given fallible function.
130 ///
131 /// If the generator function returns an error or panics while initializing the sequence,
132 /// any already initialized elements will be dropped and the error returned.
133 fn try_generate<F, E>(f: F) -> Result<Self::Sequence, E>
134 where
135 F: FnMut(usize) -> Result<T, E>;
136}
137
138/// Accessor for `GenericSequence` item type, which is really `IntoIterator::Item`
139///
140/// For deeply nested generic mapped sequence types, like shown in `tests/generics.rs`,
141/// this can be useful for keeping things organized.
142pub 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
204/// Defines any `GenericSequence` which can be lengthened or extended by appending
205/// or prepending an element to it.
206///
207/// Any lengthened sequence can be shortened back to the original using `pop_front` or `pop_back`
208///
209/// # Safety
210/// While the [`append`](Lengthen::append) and [`prepend`](Lengthen::prepend)
211/// methods are marked safe, care must be taken when implementing them.
212pub unsafe trait Lengthen<T>: Sized + GenericSequence<T> {
213 /// `GenericSequence` that has one more element than `Self`
214 type Longer: Shorten<T, Shorter = Self>;
215
216 /// Returns a new array with the given element appended to the end of it.
217 ///
218 /// Example:
219 ///
220 /// ```rust
221 /// # use generic_array::{arr, sequence::Lengthen};
222 ///
223 /// let a = arr![1, 2, 3];
224 ///
225 /// let b = a.append(4);
226 ///
227 /// assert_eq!(b, arr![1, 2, 3, 4]);
228 /// ```
229 fn append(self, last: T) -> Self::Longer;
230
231 /// Returns a new array with the given element prepended to the front of it.
232 ///
233 /// Example:
234 ///
235 /// ```rust
236 /// # use generic_array::{arr, sequence::Lengthen};
237 ///
238 /// let a = arr![1, 2, 3];
239 ///
240 /// let b = a.prepend(4);
241 ///
242 /// assert_eq!(b, arr![4, 1, 2, 3]);
243 /// ```
244 fn prepend(self, first: T) -> Self::Longer;
245}
246
247/// Defines a `GenericSequence` which can be shortened by removing the first or last element from it.
248///
249/// Additionally, any shortened sequence can be lengthened by
250/// appending or prepending an element to it.
251///
252/// # Safety
253/// While the [`pop_back`](Shorten::pop_back) and [`pop_front`](Shorten::pop_front)
254/// methods are marked safe, care must be taken when implementing them.
255pub unsafe trait Shorten<T>: Sized + GenericSequence<T> {
256 /// `GenericSequence` that has one less element than `Self`
257 type Shorter: Lengthen<T, Longer = Self>;
258
259 /// Returns a new array without the last element, and the last element.
260 ///
261 /// Example:
262 ///
263 /// ```rust
264 /// # use generic_array::{arr, sequence::Shorten};
265 ///
266 /// let a = arr![1, 2, 3, 4];
267 ///
268 /// let (init, last) = a.pop_back();
269 ///
270 /// assert_eq!(init, arr![1, 2, 3]);
271 /// assert_eq!(last, 4);
272 /// ```
273 fn pop_back(self) -> (Self::Shorter, T);
274
275 /// Returns a new array without the first element, and the first element.
276 /// Example:
277 ///
278 /// ```rust
279 /// # use generic_array::{arr, sequence::Shorten};
280 ///
281 /// let a = arr![1, 2, 3, 4];
282 ///
283 /// let (head, tail) = a.pop_front();
284 ///
285 /// assert_eq!(head, 1);
286 /// assert_eq!(tail, arr![2, 3, 4]);
287 /// ```
288 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 // Note this is *mut Self, so add(1) increments by the whole array
305 let out_ptr = longer.as_mut_ptr() as *mut Self;
306
307 unsafe {
308 // write self first
309 ptr::write(out_ptr, self);
310 // increment past self, then write the last
311 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 // Note this is *mut T, so add(1) increments by a single T
322 let out_ptr = longer.as_mut_ptr() as *mut T;
323
324 unsafe {
325 // write the first at the start
326 ptr::write(out_ptr, first);
327 // increment past the first, then write self
328 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 // ensure this doesn't get dropped
359 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
370/// Defines a `GenericSequence` that can be split into two parts at a given pivot index.
371///
372/// # Safety
373/// While the [`split`](Split::split) method is marked safe,
374/// care must be taken when implementing it.
375pub unsafe trait Split<T, K: ArrayLength>: GenericSequence<T> {
376 /// First part of the resulting split array
377 type First: GenericSequence<T>;
378 /// Second part of the resulting split array
379 type Second: GenericSequence<T>;
380
381 /// Splits an array at the given index, returning the separate parts of the array.
382 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 // ensure this doesn't get dropped
399 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
451/// Defines `GenericSequence`s which can be joined together, forming a larger array.
452///
453/// # Safety
454/// While the [`concat`](Concat::concat) method is marked safe,
455/// care must be taken when implementing it.
456pub unsafe trait Concat<T, M: ArrayLength>: GenericSequence<T> {
457 /// Sequence to be concatenated with `self`
458 type Rest: GenericSequence<T, Length = M>;
459
460 /// Resulting sequence formed by the concatenation.
461 type Output: GenericSequence<T>;
462
463 /// Concatenate, or join, two sequences.
464 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 // write all of self to the pointer
484 ptr::write(out_ptr, self);
485 // increment past self, then write the rest
486 ptr::write(out_ptr.add(1) as *mut _, rest);
487
488 output.assume_init()
489 }
490 }
491}
492
493/// Defines a `GenericSequence` which can be shortened by removing an element at a given index.
494///
495/// # Safety
496/// While the [`remove`](Remove::remove) and [`swap_remove`](Remove::swap_remove) methods are marked safe,
497/// care must be taken when implementing it. The [`remove_unchecked`](Remove::remove_unchecked)
498/// and [`swap_remove_unchecked`](Remove::swap_remove_unchecked) methods are unsafe
499/// and must be used with caution.
500pub unsafe trait Remove<T, N: ArrayLength>: GenericSequence<T> {
501 /// Resulting sequence formed by removing an element at the given index.
502 type Output: GenericSequence<T>;
503
504 /// Removes an element at the given index, shifting elements
505 /// after the given index to the left to fill the gap, resulting
506 /// in a time complexity of O(n) where `n=N-idx-1`
507 ///
508 /// # Example
509 ///
510 /// ```rust
511 /// # use generic_array::{arr, sequence::Remove};
512 /// let a = arr![1, 2, 3, 4];
513 ///
514 /// let (removed, b) = a.remove(2);
515 /// assert_eq!(removed, 3);
516 /// assert_eq!(b, arr![1, 2, 4]);
517 /// ```
518 ///
519 /// # Panics
520 ///
521 /// Panics if the index is out of bounds.
522 #[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 /// Removes an element at the given index, swapping it with the last element.
535 ///
536 /// # Example
537 ///
538 /// ```rust
539 /// # use generic_array::{arr, sequence::Remove};
540 /// let a = arr![1, 2, 3, 4];
541 ///
542 /// let (removed, b) = a.swap_remove(1);
543 /// assert_eq!(removed, 2);
544 /// assert_eq!(b, arr![1, 4, 3]); // note 4 is now at index 1
545 /// ```
546 ///
547 /// # Panics
548 ///
549 /// Panics if the index is out of bounds.
550 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 /// Removes an element at the given index without bounds checking,
562 /// shifting elements after the given index to the left to fill the gap,
563 /// resulting in a time complexity of O(n) where `n=N-idx-1`
564 ///
565 /// See [`remove`](Remove::remove) for an example.
566 ///
567 /// # Safety
568 /// The caller must ensure that the index is within bounds, otherwise
569 /// it is undefined behavior.
570 unsafe fn remove_unchecked(self, idx: usize) -> (T, Self::Output);
571
572 /// Removes an element at the given index without bounds checking, swapping it with the last element.
573 ///
574 /// See [`swap_remove`](Remove::swap_remove) for an example.
575 ///
576 /// # Safety
577 /// The caller must ensure that the index is within bounds, otherwise
578 /// it is undefined behavior.
579 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 // shift all elements over by one to fill gap
602 ptr::copy(dst.add(1), dst, N::USIZE - idx - 1);
603
604 // return removed element and truncated array
605 (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 // remove the last element
619 let removed = ptr::read(array.as_ptr().add(N::USIZE - 1));
620
621 // return removed element and truncated array
622 (removed, mem::transmute_copy(&array))
623 }
624}
625
626/// Defines a `GenericSequence` of `GenericArray`s which can be flattened into a single `GenericArray`,
627/// at zero cost.
628///
629/// # Safety
630/// While the [`flatten`](Flatten::flatten) method is marked safe,
631/// care must be taken when implementing it. However, the given trait bounds
632/// should be sufficient to ensure safety.
633pub 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 /// Flattened sequence type
639 type Output: GenericSequence<T, Length = Prod<N, M>>;
640
641 /// Flattens the sequence into a single `GenericArray`.
642 ///
643 /// # Example
644 ///
645 /// ```rust
646 /// # use generic_array::{arr, sequence::Flatten};
647 /// assert_eq!(
648 /// arr![arr![1, 2], arr![3, 4], arr![5, 6]].flatten(),
649 /// arr![1, 2, 3, 4, 5, 6]
650 /// );
651 /// ```
652 fn flatten(self) -> Self::Output;
653}
654
655/// Defines a `GenericSequence` of `T` which can be split evenly into a sequence of `GenericArray`s,
656///
657/// # Safety
658/// While the [`unflatten`](Unflatten::unflatten) method is marked safe,
659/// care must be taken when implementing it. However, the given trait bounds
660/// should be sufficient to ensure safety.
661pub 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 /// Unflattened sequence type
668 type Output: GenericSequence<GenericArray<T, N>, Length = Quot<NM, N>>;
669
670 /// Unflattens the sequence into a sequence of `GenericArray`s.
671 ///
672 /// # Example
673 ///
674 /// ```rust
675 /// # use generic_array::{arr, sequence::Unflatten};
676 /// assert_eq!(
677 /// arr![1, 2, 3, 4, 5, 6].unflatten(),
678 /// arr![arr![1, 2], arr![3, 4], arr![5, 6]]
679 /// );
680 /// ```
681 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}