|
2 | 2 |
|
3 | 3 | use super::*;
|
4 | 4 | use core::mem::MaybeUninit;
|
5 |
| -use core::ops::{Add, Sub}; |
| 5 | +use core::ops::{Add, Div, Mul, Sub}; |
6 | 6 | use core::ptr;
|
7 | 7 | use typenum::operator_aliases::*;
|
8 | 8 |
|
@@ -532,3 +532,145 @@ where
|
532 | 532 | (removed, mem::transmute_copy(&array))
|
533 | 533 | }
|
534 | 534 | }
|
| 535 | + |
| 536 | +/// Defines a `GenericSequence` of `GenericArray`s which can be flattened into a single `GenericArray`, |
| 537 | +/// at zero cost. |
| 538 | +/// |
| 539 | +/// # Safety |
| 540 | +/// While the [`flatten`](Flatten::flatten) method is marked safe, |
| 541 | +/// care must be taken when implementing it. However, the given trait bounds |
| 542 | +/// should be sufficient to ensure safety. |
| 543 | +pub unsafe trait Flatten<T, N, M>: GenericSequence<GenericArray<T, N>, Length = M> |
| 544 | +where |
| 545 | + N: ArrayLength + Mul<M>, |
| 546 | + Prod<N, M>: ArrayLength, |
| 547 | +{ |
| 548 | + /// Flattened sequence type |
| 549 | + type Output: GenericSequence<T, Length = Prod<N, M>>; |
| 550 | + |
| 551 | + /// Flattens the sequence into a single `GenericArray`. |
| 552 | + /// |
| 553 | + /// # Example |
| 554 | + /// |
| 555 | + /// ```rust |
| 556 | + /// # use generic_array::{arr, sequence::Flatten}; |
| 557 | + /// assert_eq!( |
| 558 | + /// arr![arr![1, 2], arr![3, 4], arr![5, 6]].flatten(), |
| 559 | + /// arr![1, 2, 3, 4, 5, 6] |
| 560 | + /// ); |
| 561 | + /// ``` |
| 562 | + fn flatten(self) -> Self::Output; |
| 563 | +} |
| 564 | + |
| 565 | +/// Defines a `GenericSequence` of `T` which can be split evenly into a sequence of `GenericArray`s, |
| 566 | +/// |
| 567 | +/// # Safety |
| 568 | +/// While the [`unflatten`](Unflatten::unflatten) method is marked safe, |
| 569 | +/// care must be taken when implementing it. However, the given trait bounds |
| 570 | +/// should be sufficient to ensure safety. |
| 571 | +pub unsafe trait Unflatten<T, NM, N>: GenericSequence<T, Length = NM> |
| 572 | +where |
| 573 | + NM: ArrayLength + Div<N>, |
| 574 | + N: ArrayLength, |
| 575 | + Quot<NM, N>: ArrayLength, |
| 576 | +{ |
| 577 | + /// Unflattened sequence type |
| 578 | + type Output: GenericSequence<GenericArray<T, N>, Length = Quot<NM, N>>; |
| 579 | + |
| 580 | + /// Unflattens the sequence into a sequence of `GenericArray`s. |
| 581 | + /// |
| 582 | + /// # Example |
| 583 | + /// |
| 584 | + /// ```rust |
| 585 | + /// # use generic_array::{arr, sequence::Unflatten}; |
| 586 | + /// assert_eq!( |
| 587 | + /// arr![1, 2, 3, 4, 5, 6].unflatten(), |
| 588 | + /// arr![arr![1, 2], arr![3, 4], arr![5, 6]] |
| 589 | + /// ); |
| 590 | + /// ``` |
| 591 | + fn unflatten(self) -> Self::Output; |
| 592 | +} |
| 593 | + |
| 594 | +unsafe impl<T, N, M> Flatten<T, N, M> for GenericArray<GenericArray<T, N>, M> |
| 595 | +where |
| 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 | + |
| 608 | +unsafe impl<'a, T, N, M> Flatten<T, N, M> for &'a GenericArray<GenericArray<T, N>, M> |
| 609 | +where |
| 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 | + |
| 622 | +unsafe impl<'a, T, N, M> Flatten<T, N, M> for &'a mut GenericArray<GenericArray<T, N>, M> |
| 623 | +where |
| 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 | + |
| 636 | +unsafe impl<T, NM, N> Unflatten<T, NM, N> for GenericArray<T, NM> |
| 637 | +where |
| 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 | + |
| 650 | +unsafe impl<'a, T, NM, N> Unflatten<T, NM, N> for &'a GenericArray<T, NM> |
| 651 | +where |
| 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 | + |
| 664 | +unsafe impl<'a, T, NM, N> Unflatten<T, NM, N> for &'a mut GenericArray<T, NM> |
| 665 | +where |
| 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 | +} |
0 commit comments