1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
pub fn full() -> Full {
Full(())
}
pub trait Range {
#[doc(hidden)]
fn map_mut_linear<'a, T>(&self, buf: &'a mut [T]) -> &'a mut [T];
#[doc(hidden)]
fn map_iter_interleaved<'a, T: 'a, B, I, E>(&self, buf: B, iter: I, each: E)
where
B: Iterator<Item = &'a mut T>,
I: IntoIterator<Item = T>,
E: FnMut((&mut T, T));
fn offset(self, offset: usize) -> Offset<Self>
where
Self: Sized + Range,
{
Offset { base: self, offset }
}
fn chunk(self, n: usize, len: usize) -> Chunk<Self>
where
Self: Sized + Range,
{
Chunk { base: self, n, len }
}
}
pub struct Full(());
impl Range for Full {
fn map_mut_linear<'a, T>(&self, buf: &'a mut [T]) -> &'a mut [T] {
buf
}
fn map_iter_interleaved<'a, T: 'a, B, I, E>(&self, buf: B, iter: I, each: E)
where
B: Iterator<Item = &'a mut T>,
I: IntoIterator<Item = T>,
E: FnMut((&mut T, T)),
{
buf.zip(iter).for_each(each);
}
}
pub struct Offset<R> {
#[allow(dead_code)]
base: R,
offset: usize,
}
impl Range for Offset<Full> {
fn map_mut_linear<'a, T>(&self, buf: &'a mut [T]) -> &'a mut [T] {
&mut buf[self.offset..]
}
fn map_iter_interleaved<'a, T: 'a, B, I, E>(&self, buf: B, iter: I, each: E)
where
B: Iterator<Item = &'a mut T>,
I: IntoIterator<Item = T>,
E: FnMut((&mut T, T)),
{
buf.skip(self.offset).zip(iter).for_each(each);
}
}
pub struct Chunk<R> {
base: R,
n: usize,
len: usize,
}
impl Range for Chunk<Offset<Full>> {
fn map_mut_linear<'a, T>(&self, buf: &'a mut [T]) -> &'a mut [T] {
let buf = &mut buf[self.base.offset + self.n * self.len..];
let len = usize::min(buf.len(), self.len);
&mut buf[..len]
}
fn map_iter_interleaved<'a, T: 'a, B, I, E>(&self, buf: B, iter: I, each: E)
where
B: Iterator<Item = &'a mut T>,
I: IntoIterator<Item = T>,
E: FnMut((&mut T, T)),
{
buf.skip(self.base.offset + self.n * self.len)
.take(self.len)
.zip(iter)
.for_each(each);
}
}