Skip to content

Commit 2412fb1

Browse files
committed
Implement #151
1 parent b10321a commit 2412fb1

File tree

1 file changed

+143
-1
lines changed

1 file changed

+143
-1
lines changed

src/sequence.rs

Lines changed: 143 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use super::*;
44
use core::mem::MaybeUninit;
5-
use core::ops::{Add, Sub};
5+
use core::ops::{Add, Div, Mul, Sub};
66
use core::ptr;
77
use typenum::operator_aliases::*;
88

@@ -532,3 +532,145 @@ where
532532
(removed, mem::transmute_copy(&array))
533533
}
534534
}
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

Comments
 (0)