array_fusion/
chunks.rs

1//! Array of arrays utilities.
2
3
4use core::ops::Mul;
5
6pub use hybrid_array;
7use hybrid_array::Array;
8use hybrid_array::ArraySize;
9use hybrid_array::AssocArraySize;
10use hybrid_array::typenum::Prod;
11
12#[cfg(doc)]
13use crate::array_from_core;
14#[cfg(doc)]
15use crate::array_to_core;
16
17
18
19/// Flatten an array of arrays into a single contigues array.
20pub fn flatten<T, I, O>(input: Array<Array<T, I>, O>) -> Array<T, Prod<I, O>>
21where
22	I: Mul<O>,
23	I::Output: ArraySize,
24	I: ArraySize,
25	O: ArraySize,
26	// TODO: find a way to lift this constraint
27	T: Default + Copy,
28{
29	let mut output = Array::default();
30
31	// TODO: is there a more efficient way to do this?
32
33	let mut offset = 0;
34	for array in input.iter() {
35		let len = array.len();
36		output[offset..offset + len].copy_from_slice(array);
37		offset += len;
38	}
39
40	output
41}
42
43/// Split a contigues array into an array of arrays.
44pub fn chunks<T, I, O>(input: Array<T, Prod<I, O>>) -> Array<Array<T, I>, O>
45where
46	I: Mul<O>,
47	I::Output: ArraySize,
48	I: ArraySize,
49	O: ArraySize,
50	// TODO: find a way to lift this constraint
51	T: Default + Copy,
52{
53	let mut output: Array<Array<T, I>, O> = Array::default();
54
55	let mut offset = 0;
56	for array in output.iter_mut() {
57		let len = array.len();
58		array.copy_from_slice(&input[offset..offset + len]);
59		offset += len;
60	}
61
62	output
63}
64
65type ArrayOfArrays<T, const I: usize, const O: usize> =
66	Array<Array<T, <[T; I] as AssocArraySize>::Size>, <[[T; I]; O] as AssocArraySize>::Size>;
67
68/// Converts an `Array` of `Array`s into a core array of arrays.
69///
70/// Notice this is similar to the [`array_to_core`] function, but works on
71/// chunks (i.e. arrays of arrays).
72pub fn chunks_to_core<T, const I: usize, const O: usize>(
73	input: ArrayOfArrays<T, I, O>,
74) -> [[T; I]; O]
75where
76	[T; I]: AssocArraySize,
77	[[T; I]; O]: AssocArraySize,
78	<[T; I] as AssocArraySize>::Size: ArraySize<ArrayType<T> = [T; I]>,
79	<[[T; I]; O] as AssocArraySize>::Size: ArraySize<ArrayType<[T; I]> = [[T; I]; O]>,
80{
81	let a = input.map(|array| array.0);
82
83	a.0
84}
85
86/// Converts a core array of arrays into an `Array` of `Array`s.
87///
88/// This is similar to the [`array_from_core`] function, but works on
89/// chunks (i.e. arrays of arrays).
90pub fn chunks_from_core<T, const I: usize, const O: usize>(
91	input: [[T; I]; O],
92) -> ArrayOfArrays<T, I, O>
93where
94	[T; I]: AssocArraySize,
95	[[T; I]; O]: AssocArraySize,
96	<[T; I] as AssocArraySize>::Size: ArraySize<ArrayType<T> = [T; I]>,
97	<[[T; I]; O] as AssocArraySize>::Size: ArraySize<ArrayType<[T; I]> = [[T; I]; O]>,
98{
99	Array(input).map(|array| Array(array))
100}