fast_interleave/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2
3#[cfg(feature = "alloc")]
4extern crate alloc;
5
6#[cfg(feature = "alloc")]
7use alloc::vec::Vec;
8
9use core::{num::NonZeroUsize, ops::Range};
10
11/// Interleave the given channels into the output buffer.
12///
13/// * `input` - The de-interleaved input channels.
14/// * `input_range` - The range in each input channel to read from.
15/// * `output` - The interleaved output buffer to write to.
16///
17/// # Example
18///
19/// ```
20/// # use fast_interleave::*;
21/// let input: Vec<Vec<i32>> = vec![vec![1, 3, 5, 7], vec![2, 4, 6, 8]];
22/// let mut output: Vec<i32> = vec![0; 8];
23///
24/// interleave::<_, _, 2>(&input, 0..4, &mut output);
25///
26/// assert_eq!(&output, &[1, 2, 3, 4, 5, 6, 7, 8]);
27///
28/// // Interleave range in input:
29/// interleave::<_, _, 2>(&input, 2..4, &mut output[0..4]);
30///
31/// assert_eq!(&output, &[5, 6, 7, 8, 5, 6, 7, 8]);
32/// ```
33///
34/// # Panics
35/// Panics when any of the following are true:
36/// * `input.len() < CHANNELS`
37/// * `input_range` is out-of-bounds for any input channel
38/// * `output.len() < (input_range.end - input_range.start) * CHANNELS`
39/// * `CHANNELS` == 0
40pub fn interleave<T: Copy, Vin: AsRef<[T]>, const CHANNELS: usize>(
41    input: &[Vin],
42    input_range: Range<usize>,
43    output: &mut [T],
44) {
45    assert!(CHANNELS > 0);
46    assert!(input.len() >= CHANNELS);
47
48    if input_range.is_empty() {
49        return;
50    }
51
52    assert!(output.len() >= (input_range.end - input_range.start) * CHANNELS);
53
54    for ch in input.iter() {
55        let ch = ch.as_ref();
56        assert!(input_range.start <= ch.len());
57        assert!(input_range.end <= ch.len());
58    }
59
60    // SAFETY: All of the required safety conditions were checked above.
61    unsafe {
62        interleave_unchecked::<T, _, CHANNELS>(input, input_range, output);
63    }
64}
65
66/// Interleave the given channels into the output buffer.
67///
68/// No bounds checking will occur.
69///
70/// * `input` - The de-interleaved input channels.
71/// * `input_range` - The range in each input channel to read from.
72/// * `output` - The interleaved output buffer to write to.
73///
74/// # Example
75///
76/// ```
77/// # use fast_interleave::*;
78/// let input: Vec<Vec<i32>> = vec![vec![1, 3, 5, 7], vec![2, 4, 6, 8]];
79/// let mut output: Vec<i32> = vec![0; 8];
80///
81/// unsafe { interleave_unchecked::<_, _, 2>(&input, 0..4, &mut output); }
82///
83/// assert_eq!(&output, &[1, 2, 3, 4, 5, 6, 7, 8]);
84///
85/// // Interleave range in input:
86/// unsafe { interleave_unchecked::<_, _, 2>(&input, 2..4, &mut output[0..4]); }
87///
88/// assert_eq!(&output, &[5, 6, 7, 8, 5, 6, 7, 8]);
89/// ```
90///
91/// # Safety
92/// The caller must uphold that all of the following conditions are true:
93/// * `input.len() >= CHANNELS`
94/// * `input_range` is within bounds for every input channel
95/// * `output.len() >= (input_range.end - input_range.start) * CHANNELS`
96/// * `CHANNELS` > 0
97pub unsafe fn interleave_unchecked<T: Copy, Vin: AsRef<[T]>, const CHANNELS: usize>(
98    input: &[Vin],
99    input_range: Range<usize>,
100    output: &mut [T],
101) {
102    if input_range.is_empty() {
103        return;
104    }
105
106    unsafe {
107        for i in 0..(input_range.end - input_range.start) {
108            for ch_i in 0..CHANNELS {
109                *output.get_unchecked_mut((i * CHANNELS) + ch_i) = *input
110                    .get_unchecked(ch_i)
111                    .as_ref()
112                    .get_unchecked(input_range.start + i);
113            }
114        }
115    }
116}
117
118/// De-interleave the given data into the output buffer channels.
119///
120/// * `input` - The interleaved input channels.
121/// * `output` - The de-interleaved output channels to write to.
122/// * `output_range` - The range in each output channel to write to.
123///
124/// # Example
125///
126/// ```
127/// # use fast_interleave::*;
128/// let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8];
129/// let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4]];
130///
131/// deinterleave::<_, _, 2>(&input, &mut output, 0..4);
132///
133/// assert_eq!(&output[0], &[1, 3, 5, 7]);
134/// assert_eq!(&output[1], &[2, 4, 6, 8]);
135///
136/// // Deinterleave into a range in output:
137/// deinterleave::<_, _, 2>(&input[0..4], &mut output, 2..4);
138///
139/// assert_eq!(&output[0], &[1, 3, 1, 3]);
140/// assert_eq!(&output[1], &[2, 4, 2, 4]);
141/// ```
142///
143/// # Panics
144/// Panics when any of the following are true:
145/// * `output.len() < CHANNELS`
146/// * `output_range` is out-of-bounds for any output channel
147/// * `input.len() < (output_range.end - output_range.start) * CHANNELS`
148/// * `CHANNELS` == 0
149pub fn deinterleave<T: Copy, Vout: AsMut<[T]>, const CHANNELS: usize>(
150    input: &[T],
151    output: &mut [Vout],
152    output_range: Range<usize>,
153) {
154    assert!(CHANNELS > 0);
155    assert!(output.len() >= CHANNELS);
156
157    if output_range.is_empty() {
158        return;
159    }
160
161    assert!(input.len() >= (output_range.end - output_range.start) * CHANNELS);
162
163    for ch in output.iter_mut() {
164        let ch = ch.as_mut();
165        assert!(output_range.start <= ch.len());
166        assert!(output_range.end <= ch.len());
167    }
168
169    // SAFETY: All of the required safety conditions were checked above.
170    unsafe {
171        deinterleave_unchecked::<T, _, CHANNELS>(input, output, output_range);
172    }
173}
174
175/// De-interleave the given channels into the output buffer.
176///
177/// No bounds checking will occur.
178///
179/// * `input` - The interleaved input channels.
180/// * `output` - The de-interleaved output channels to write to.
181/// * `output_range` - The range in each output channel to write to.
182///
183/// # Example
184///
185/// ```
186/// # use fast_interleave::*;
187/// let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8];
188/// let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4]];
189///
190/// unsafe { deinterleave_unchecked::<_, _, 2>(&input, &mut output, 0..4); }
191///
192/// assert_eq!(&output[0], &[1, 3, 5, 7]);
193/// assert_eq!(&output[1], &[2, 4, 6, 8]);
194///
195/// // Deinterleave into a range in output:
196/// unsafe { deinterleave_unchecked::<_, _, 2>(&input[0..4], &mut output, 2..4); }
197///
198/// assert_eq!(&output[0], &[1, 3, 1, 3]);
199/// assert_eq!(&output[1], &[2, 4, 2, 4]);
200/// ```
201///
202/// # Safety
203/// The caller must uphold that all of the following conditions are true:
204/// * `output.len() >= CHANNELS`
205/// * `output_range` is within bounds for every output channel
206/// * `input.len() >= (output_range.end - output_range.start) * CHANNELS`
207/// * `CHANNELS` > 0
208pub unsafe fn deinterleave_unchecked<T: Copy, Vout: AsMut<[T]>, const CHANNELS: usize>(
209    input: &[T],
210    output: &mut [Vout],
211    output_range: Range<usize>,
212) {
213    if output_range.is_empty() {
214        return;
215    }
216
217    unsafe {
218        for i in 0..(output_range.end - output_range.start) {
219            for ch_i in 0..CHANNELS {
220                *output
221                    .get_unchecked_mut(ch_i)
222                    .as_mut()
223                    .get_unchecked_mut(output_range.start + i) =
224                    *input.get_unchecked((i * CHANNELS) + ch_i)
225            }
226        }
227    }
228}
229
230/// Interleave a variable number of input channels into the output buffer
231/// with a variable number of channels.
232///
233/// * `input` - The input channels.
234/// * `input_range` - The range in each channel in `input` to read from.
235/// * `output` - The interleaved output buffer to write to.
236/// * `num_out_channels` - The number of interleaved channels in `output`.
237///
238/// Note, if `num_out_channels.get() > input.len()`, then the extra samples in
239/// each output frame will be left untouched.
240///
241/// # Example
242///
243/// ```
244/// # use fast_interleave::*;
245/// # use std::num::NonZeroUsize;
246/// let input: Vec<Vec<i32>> = vec![vec![1, 3, 5, 7], vec![2, 4, 6, 8]];
247/// let mut output: Vec<i32> = vec![0; 12];
248///
249/// interleave_variable(&input, 0..4, &mut output, NonZeroUsize::new(3).unwrap());
250///
251/// assert_eq!(&output, &[1, 2, 0, 3, 4, 0, 5, 6, 0, 7, 8, 0]);
252/// ```
253///
254/// # Panics
255/// Panics when any of the following are true:
256/// * `input_range` is out-of-bounds for any input channel
257/// * `output.len() < (input_range.end - input_range.start) * num_out_channels.get()`
258pub fn interleave_variable<T: Copy, Vin: AsRef<[T]>>(
259    input: &[Vin],
260    input_range: Range<usize>,
261    output: &mut [T],
262    num_out_channels: NonZeroUsize,
263) {
264    if input_range.is_empty() || input.is_empty() {
265        return;
266    }
267
268    let in_frames = input_range.end - input_range.start;
269
270    assert!(output.len() >= in_frames * num_out_channels.get());
271
272    if num_out_channels.get() == 1 {
273        // Mono, no need to interleave.
274        output[..in_frames].copy_from_slice(&input[0].as_ref()[input_range.clone()]);
275
276        return;
277    }
278
279    if num_out_channels.get() == 2 && input.len() >= 2 {
280        // Provide an optimized loop for stereo since it is a common case.
281        interleave::<T, _, 2>(input, input_range, output);
282        return;
283    }
284
285    for (ch_i, in_ch) in (0..num_out_channels.get()).zip(input.iter()) {
286        let in_ch = in_ch.as_ref();
287
288        assert!(input_range.start < in_ch.len() && input_range.end <= in_ch.len());
289
290        // SAFETY: We have checked that the output slice has sufficient length and that
291        // the `input_range` is within bounds of the input channel slice.
292        unsafe {
293            for i in 0..in_frames {
294                *output.get_unchecked_mut((i * num_out_channels.get()) + ch_i) =
295                    *in_ch.get_unchecked(input_range.start + i);
296            }
297        }
298    }
299}
300
301/// Interleave a variable number of input channels into a new interleaved `Vec`
302/// with a variable number of channels.
303///
304/// The returned `Vec` with have a length of
305/// `(input_range.end - input_range.start) * num_out_channels.get()`.
306///
307/// * `input` - The input channels.
308/// * `input_range` - The range in each channel in `input` to read from.
309/// * `num_out_channels` - The number of interleaved channels in output `Vec`.
310///
311/// Note, if `num_out_channels.get() > input.len()`, then the extra samples in
312/// each output frame will be set to the default value.
313///
314/// # Example
315///
316/// ```
317/// # use fast_interleave::*;
318/// # use std::num::NonZeroUsize;
319/// let input: Vec<Vec<i32>> = vec![vec![1, 3, 5, 7], vec![2, 4, 6, 8]];
320/// let mut output: Vec<i32> = vec![0; 12];
321///
322/// let output = interleave_to_vec_variable(&input, 0..4, NonZeroUsize::new(3).unwrap());
323///
324/// assert_eq!(&output, &[1, 2, 0, 3, 4, 0, 5, 6, 0, 7, 8, 0]);
325/// ```
326///
327/// # Panics
328/// Panics if `input_range` is out-of-bounds for any input channel.
329#[cfg(feature = "alloc")]
330pub fn interleave_to_vec_variable<T: Copy + Default, Vin: AsRef<[T]>>(
331    input: &[Vin],
332    input_range: Range<usize>,
333    num_out_channels: NonZeroUsize,
334) -> Vec<T> {
335    let out_len = (input_range.end - input_range.start) * num_out_channels.get();
336
337    let mut out: Vec<T> = Vec::new();
338    out.reserve_exact(out_len);
339
340    if num_out_channels.get() > input.len() {
341        out.resize(out_len, T::default());
342    } else {
343        // Safety:
344        // * The vec has been initialized with a capacity of `out_len` above.
345        // * `interleave_variable` is gauranteed to completely intialize the output
346        // slice up to `(input_range.end - input_range.start) * num_out_channels.get()`
347        // when `num_out_channels.get() <= input.len()`.
348        unsafe {
349            out.set_len(out_len);
350        }
351    }
352
353    interleave_variable(input, input_range, out.as_mut_slice(), num_out_channels);
354
355    out
356}
357
358/// Deinterleave the given data with a variable number of channels into
359/// the output buffers with a variable number of channels.
360///
361/// * `input` - The interleaved input data.
362/// * `num_in_channels` - The number of interleaved channels in `input`.
363/// * `output` - The de-interleaved output buffer to write to.
364/// * `out_range` - The range in each channel in `output` to write to.
365///
366/// Note, if `output.len() > num_in_channels.get()`, then the extra output channels
367/// will be left untouched.
368///
369/// # Example
370///
371/// ```
372/// # use fast_interleave::*;
373/// # use std::num::NonZeroUsize;
374/// let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8];
375/// let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4], vec![0; 4]];
376///
377/// deinterleave_variable(&input, NonZeroUsize::new(2).unwrap(), &mut output, 0..4);
378///
379/// assert_eq!(&output[0], &[1, 3, 5, 7]);
380/// assert_eq!(&output[1], &[2, 4, 6, 8]);
381/// assert_eq!(&output[2], &[0, 0, 0, 0]);
382/// ```
383///
384/// # Panics
385/// Panics when any of the following are true:
386/// * `output_range` is out-of-bounds for any output channel
387/// * `input.len() < (output_range.end - output_range.start) * num_in_channels.get()`
388pub fn deinterleave_variable<T: Copy, Vout: AsMut<[T]>>(
389    input: &[T],
390    num_in_channels: NonZeroUsize,
391    output: &mut [Vout],
392    output_range: Range<usize>,
393) {
394    if output_range.is_empty() || output.is_empty() {
395        return;
396    }
397
398    let out_frames = output_range.end - output_range.start;
399
400    if num_in_channels.get() == 1 {
401        // Mono, no need to deinterleave.
402        output[0].as_mut()[output_range.clone()].copy_from_slice(&input[..out_frames]);
403
404        return;
405    }
406
407    if num_in_channels.get() == 2 && output.len() >= 2 {
408        // Provide an optimized loop for stereo since it is a common case.
409        deinterleave::<T, _, 2>(input, output, output_range);
410        return;
411    }
412
413    assert!(input.len() >= (output_range.end - output_range.start) * num_in_channels.get());
414
415    for (ch_i, out_ch) in (0..num_in_channels.get()).zip(output.iter_mut()) {
416        let out_ch = out_ch.as_mut();
417
418        assert!(output_range.start < out_ch.len() && output_range.end <= out_ch.len());
419
420        // SAFETY: We have checked that the input slice has sufficient length and that
421        // the `output_range` is within bounds of the output channel slice.
422        unsafe {
423            for i in 0..(output_range.end - output_range.start) {
424                *out_ch.get_unchecked_mut(output_range.start + i) =
425                    *input.get_unchecked((i * num_in_channels.get()) + ch_i);
426            }
427        }
428    }
429}
430
431#[cfg(test)]
432mod tests {
433    #[cfg(feature = "alloc")]
434    use alloc::{vec, vec::Vec};
435
436    use super::*;
437
438    #[test]
439    fn test_interleave() {
440        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4]];
441        let mut output: Vec<i32> = vec![0; 4];
442        interleave::<_, _, 1>(&input, 1..4, &mut output);
443        assert_eq!(&output, &[2, 3, 4, 0]);
444
445        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8]];
446        let mut output: Vec<i32> = vec![0; 8];
447        interleave::<_, _, 2>(&input, 1..4, &mut output);
448        assert_eq!(&output, &[2, 6, 3, 7, 4, 8, 0, 0]);
449
450        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8], vec![9, 10, 11, 12]];
451        let mut output: Vec<i32> = vec![0; 12];
452        interleave::<_, _, 3>(&input, 1..4, &mut output);
453        assert_eq!(&output, &[2, 6, 10, 3, 7, 11, 4, 8, 12, 0, 0, 0]);
454    }
455
456    #[test]
457    fn test_deinterleave() {
458        let input: Vec<i32> = vec![1, 2, 3, 4];
459        let mut output: Vec<Vec<i32>> = vec![vec![0; 4]];
460        deinterleave::<_, _, 1>(&input, &mut output, 1..4);
461        assert_eq!(&output[0], &[0, 1, 2, 3]);
462
463        let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8];
464        let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4]];
465        deinterleave::<_, _, 2>(&input, &mut output, 1..4);
466        assert_eq!(&output[0], &[0, 1, 3, 5]);
467        assert_eq!(&output[1], &[0, 2, 4, 6]);
468
469        let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
470        let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4], vec![0; 4]];
471        deinterleave::<_, _, 3>(&input, &mut output, 1..4);
472        assert_eq!(&output[0], &[0, 1, 4, 7]);
473        assert_eq!(&output[1], &[0, 2, 5, 8]);
474        assert_eq!(&output[2], &[0, 3, 6, 9]);
475    }
476
477    #[test]
478    fn test_interleave_variable() {
479        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4]];
480        let mut output: Vec<i32> = vec![0; 4];
481        interleave_variable(&input, 1..4, &mut output, NonZeroUsize::new(1).unwrap());
482        assert_eq!(&output, &[2, 3, 4, 0]);
483
484        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8]];
485        let mut output: Vec<i32> = vec![0; 8];
486        interleave_variable(&input, 0..4, &mut output, NonZeroUsize::new(1).unwrap());
487        assert_eq!(&output, &[1, 2, 3, 4, 0, 0, 0, 0]);
488
489        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4]];
490        let mut output: Vec<i32> = vec![0; 8];
491        interleave_variable(&input, 0..4, &mut output, NonZeroUsize::new(2).unwrap());
492        assert_eq!(&output, &[1, 0, 2, 0, 3, 0, 4, 0]);
493
494        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8]];
495        let mut output: Vec<i32> = vec![0; 8];
496        interleave_variable(&input, 0..4, &mut output, NonZeroUsize::new(2).unwrap());
497        assert_eq!(&output, &[1, 5, 2, 6, 3, 7, 4, 8]);
498
499        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8], vec![9, 10, 11, 12]];
500        let mut output: Vec<i32> = vec![0; 8];
501        interleave_variable(&input, 0..4, &mut output, NonZeroUsize::new(2).unwrap());
502        assert_eq!(&output, &[1, 5, 2, 6, 3, 7, 4, 8]);
503
504        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8], vec![9, 10, 11, 12]];
505        let mut output: Vec<i32> = vec![0; 12];
506        interleave_variable(&input, 0..4, &mut output, NonZeroUsize::new(3).unwrap());
507        assert_eq!(&output, &[1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12]);
508    }
509
510    #[test]
511    fn test_interleave_to_vec_variable() {
512        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4]];
513        let output = interleave_to_vec_variable(&input, 1..4, NonZeroUsize::new(1).unwrap());
514        assert_eq!(&output, &[2, 3, 4]);
515
516        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8]];
517        let output = interleave_to_vec_variable(&input, 0..4, NonZeroUsize::new(1).unwrap());
518        assert_eq!(&output, &[1, 2, 3, 4]);
519
520        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4]];
521        let output = interleave_to_vec_variable(&input, 0..4, NonZeroUsize::new(2).unwrap());
522        assert_eq!(&output, &[1, 0, 2, 0, 3, 0, 4, 0]);
523
524        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8]];
525        let output = interleave_to_vec_variable(&input, 0..4, NonZeroUsize::new(2).unwrap());
526        assert_eq!(&output, &[1, 5, 2, 6, 3, 7, 4, 8]);
527
528        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8], vec![9, 10, 11, 12]];
529        let output = interleave_to_vec_variable(&input, 0..4, NonZeroUsize::new(2).unwrap());
530        assert_eq!(&output, &[1, 5, 2, 6, 3, 7, 4, 8]);
531
532        let input: Vec<Vec<i32>> = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8], vec![9, 10, 11, 12]];
533        let output = interleave_to_vec_variable(&input, 0..4, NonZeroUsize::new(3).unwrap());
534        assert_eq!(&output, &[1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12]);
535    }
536
537    #[test]
538    fn test_deinterleave_variable() {
539        let input: Vec<i32> = vec![1, 2, 3, 4];
540        let mut output: Vec<Vec<i32>> = vec![vec![0; 4]];
541        deinterleave_variable(&input, NonZeroUsize::new(1).unwrap(), &mut output, 1..4);
542        assert_eq!(&output[0], &[0, 1, 2, 3]);
543
544        let input: Vec<i32> = vec![1, 2, 3, 4];
545        let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4]];
546        deinterleave_variable(&input, NonZeroUsize::new(1).unwrap(), &mut output, 0..4);
547        assert_eq!(&output[0], &[1, 2, 3, 4]);
548        assert_eq!(&output[1], &[0, 0, 0, 0]);
549
550        let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8];
551        let mut output: Vec<Vec<i32>> = vec![vec![0; 4]];
552        deinterleave_variable(&input, NonZeroUsize::new(2).unwrap(), &mut output, 0..4);
553        assert_eq!(&output[0], &[1, 3, 5, 7]);
554
555        let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8];
556        let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4]];
557        deinterleave_variable(&input, NonZeroUsize::new(2).unwrap(), &mut output, 0..4);
558        assert_eq!(&output[0], &[1, 3, 5, 7]);
559        assert_eq!(&output[1], &[2, 4, 6, 8]);
560
561        let input: Vec<i32> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
562        let mut output: Vec<Vec<i32>> = vec![vec![0; 4], vec![0; 4], vec![0; 4]];
563        deinterleave_variable(&input, NonZeroUsize::new(3).unwrap(), &mut output, 0..4);
564        assert_eq!(&output[0], &[1, 4, 7, 10]);
565        assert_eq!(&output[1], &[2, 5, 8, 11]);
566        assert_eq!(&output[2], &[3, 6, 9, 12]);
567    }
568}