1use std::fmt;
2use std::ops::{Index, IndexMut};
3use std::slice;
4use std::vec;
5
6use crate::Dimension;
7
8#[derive(Debug, PartialEq, Eq, Clone)]
10pub struct Array<T> {
11 dims: Vec<Dimension>,
12 data: Vec<T>,
13}
14
15impl<T: fmt::Display> fmt::Display for Array<T> {
16 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
17 if self.dims.iter().any(|dim| dim.lower_bound != 1) {
18 for dim in &self.dims {
19 write!(
20 fmt,
21 "[{}:{}]",
22 dim.lower_bound,
23 dim.lower_bound + dim.len - 1
24 )?;
25 }
26 write!(fmt, "=")?;
27 }
28 fmt_helper(0, &self.dims, &mut self.data.iter(), fmt)
29 }
30}
31
32fn fmt_helper<'a, T, I>(
33 depth: usize,
34 dims: &[Dimension],
35 data: &mut I,
36 fmt: &mut fmt::Formatter<'_>,
37) -> fmt::Result
38where
39 I: Iterator<Item = &'a T>,
40 T: 'a + fmt::Display,
41{
42 if dims.len() == 0 {
43 return write!(fmt, "{{}}");
44 }
45
46 if depth == dims.len() {
47 return write!(fmt, "{}", data.next().unwrap());
48 }
49
50 write!(fmt, "{{")?;
51 for i in 0..dims[depth].len {
52 if i != 0 {
53 write!(fmt, ",")?;
54 }
55 fmt_helper(depth + 1, dims, data, fmt)?;
56 }
57 write!(fmt, "}}")
58}
59
60impl<T> Array<T> {
61 pub fn from_parts(data: Vec<T>, dimensions: Vec<Dimension>) -> Array<T> {
71 assert!(
72 (data.is_empty() && dimensions.is_empty())
73 || data.len() as i32 == dimensions.iter().fold(1, |acc, i| acc * i.len),
74 "size mismatch"
75 );
76 Array {
77 dims: dimensions,
78 data,
79 }
80 }
81
82 pub fn from_vec(data: Vec<T>, lower_bound: i32) -> Array<T> {
84 Array {
85 dims: vec![Dimension {
86 len: data.len() as i32,
87 lower_bound,
88 }],
89 data,
90 }
91 }
92
93 pub fn wrap(&mut self, lower_bound: i32) {
98 self.dims.insert(
99 0,
100 Dimension {
101 len: 1,
102 lower_bound,
103 },
104 );
105 }
106
107 pub fn push(&mut self, other: Array<T>) {
121 assert!(
122 self.dims.len() - 1 == other.dims.len(),
123 "cannot append differently shaped arrays"
124 );
125 for (dim1, dim2) in self.dims.iter().skip(1).zip(other.dims.iter()) {
126 assert!(dim1 == dim2, "cannot append differently shaped arrays");
127 }
128 self.dims[0].len += 1;
129 self.data.extend(other.data);
130 }
131
132 pub fn dimensions(&self) -> &[Dimension] {
134 &self.dims
135 }
136
137 fn shift_idx(&self, indices: &[i32]) -> i32 {
138 assert_eq!(self.dims.len(), indices.len());
139 self.dims
140 .iter()
141 .zip(indices.iter().cloned())
142 .rev()
143 .fold((0, 1), |(acc, stride), (dim, idx)| {
144 let shifted = dim.shift(idx);
145 (acc + shifted * stride, dim.len * stride)
146 })
147 .0
148 }
149
150 pub fn iter(&self) -> Iter<'_, T> {
153 Iter {
154 inner: self.data.iter(),
155 }
156 }
157
158 pub fn iter_mut(&mut self) -> IterMut<'_, T> {
161 IterMut {
162 inner: self.data.iter_mut(),
163 }
164 }
165
166 pub fn into_inner(self) -> Vec<T> {
169 self.data
170 }
171}
172
173pub trait ArrayIndex {
175 fn index<T>(&self, array: &Array<T>) -> i32;
183}
184
185impl<'a> ArrayIndex for &'a [i32] {
186 fn index<T>(&self, array: &Array<T>) -> i32 {
187 array.shift_idx(*self)
188 }
189}
190
191impl ArrayIndex for i32 {
192 fn index<T>(&self, array: &Array<T>) -> i32 {
193 let slice: &[i32] = &[*self];
194 ArrayIndex::index(&slice, array)
195 }
196}
197
198macro_rules! tuple_impl {
199 ($($name:ident : $t:ty),+) => {
200 impl ArrayIndex for ($($t,)+) {
201 fn index<T>(&self, array: &Array<T>) -> i32 {
202 let ($($name,)+) = *self;
203 let slice: &[i32] = &[$($name),+];
204 ArrayIndex::index(&slice, array)
205 }
206 }
207 }
208}
209
210tuple_impl!(a: i32);
211tuple_impl!(a: i32, b: i32);
212tuple_impl!(a: i32, b: i32, c: i32);
213tuple_impl!(a: i32, b: i32, c: i32, d: i32);
214tuple_impl!(a: i32, b: i32, c: i32, d: i32, e: i32);
215tuple_impl!(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32);
216tuple_impl!(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32);
217tuple_impl!(
218 a: i32,
219 b: i32,
220 c: i32,
221 d: i32,
222 e: i32,
223 f: i32,
224 g: i32,
225 h: i32
226);
227tuple_impl!(
228 a: i32,
229 b: i32,
230 c: i32,
231 d: i32,
232 e: i32,
233 f: i32,
234 g: i32,
235 h: i32,
236 i: i32
237);
238
239impl<T, I: ArrayIndex> Index<I> for Array<T> {
265 type Output = T;
266 fn index(&self, idx: I) -> &T {
267 let idx = idx.index(self);
268 &self.data[idx as usize]
269 }
270}
271
272impl<T, I: ArrayIndex> IndexMut<I> for Array<T> {
273 fn index_mut(&mut self, idx: I) -> &mut T {
274 let idx = idx.index(self);
275 &mut self.data[idx as usize]
276 }
277}
278
279impl<'a, T: 'a> IntoIterator for &'a Array<T> {
280 type Item = &'a T;
281 type IntoIter = Iter<'a, T>;
282
283 fn into_iter(self) -> Iter<'a, T> {
284 self.iter()
285 }
286}
287
288impl<'a, T: 'a> IntoIterator for &'a mut Array<T> {
289 type Item = &'a mut T;
290 type IntoIter = IterMut<'a, T>;
291
292 fn into_iter(self) -> IterMut<'a, T> {
293 self.iter_mut()
294 }
295}
296
297impl<T> IntoIterator for Array<T> {
298 type Item = T;
299 type IntoIter = IntoIter<T>;
300
301 fn into_iter(self) -> IntoIter<T> {
302 IntoIter {
303 inner: self.data.into_iter(),
304 }
305 }
306}
307
308pub struct Iter<'a, T> {
311 inner: slice::Iter<'a, T>,
312}
313
314impl<'a, T: 'a> Iterator for Iter<'a, T> {
315 type Item = &'a T;
316
317 fn next(&mut self) -> Option<&'a T> {
318 self.inner.next()
319 }
320
321 fn size_hint(&self) -> (usize, Option<usize>) {
322 self.inner.size_hint()
323 }
324}
325
326impl<'a, T: 'a> DoubleEndedIterator for Iter<'a, T> {
327 fn next_back(&mut self) -> Option<&'a T> {
328 self.inner.next_back()
329 }
330}
331
332impl<'a, T: 'a> ExactSizeIterator for Iter<'a, T> {
333 fn len(&self) -> usize {
334 self.inner.len()
335 }
336}
337
338pub struct IterMut<'a, T> {
341 inner: slice::IterMut<'a, T>,
342}
343
344impl<'a, T: 'a> Iterator for IterMut<'a, T> {
345 type Item = &'a mut T;
346
347 fn next(&mut self) -> Option<&'a mut T> {
348 self.inner.next()
349 }
350
351 fn size_hint(&self) -> (usize, Option<usize>) {
352 self.inner.size_hint()
353 }
354}
355
356impl<'a, T: 'a> DoubleEndedIterator for IterMut<'a, T> {
357 fn next_back(&mut self) -> Option<&'a mut T> {
358 self.inner.next_back()
359 }
360}
361
362impl<'a, T: 'a> ExactSizeIterator for IterMut<'a, T> {
363 fn len(&self) -> usize {
364 self.inner.len()
365 }
366}
367
368pub struct IntoIter<T> {
371 inner: vec::IntoIter<T>,
372}
373
374impl<T> Iterator for IntoIter<T> {
375 type Item = T;
376
377 fn next(&mut self) -> Option<T> {
378 self.inner.next()
379 }
380
381 fn size_hint(&self) -> (usize, Option<usize>) {
382 self.inner.size_hint()
383 }
384}
385
386impl<T> DoubleEndedIterator for IntoIter<T> {
387 fn next_back(&mut self) -> Option<T> {
388 self.inner.next_back()
389 }
390}
391
392impl<T> ExactSizeIterator for IntoIter<T> {
393 fn len(&self) -> usize {
394 self.inner.len()
395 }
396}