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
#[cfg(test)]
mod tests;
mod helpers;
use helpers::{index_to_position, position_to_index};
use std::borrow::Borrow;
use std::convert::AsRef;
use std::default::Default;
use std::iter::IntoIterator;
use std::ops::{Index, IndexMut};
use std::vec::IntoIter;
#[derive(Debug)]
pub struct NArray<T> {
dimensions: usize,
magnitudes: Vec<usize>,
data: Vec<T>
}
impl<T> NArray<T> {
pub fn from_function<F>(dim: usize, mag: &[usize], func: F) -> Self
where F: Fn(&[usize]) -> T
{
if dim != mag.len() {
panic!("Attempted to initialise NArray of dimension {} but {} magnitudes supplied",
dim,
mag.len());
}
let max_size = mag.clone().into_iter().fold(1, |acc, &item| acc*item);
let mut data = Vec::<T>::with_capacity(max_size);
for n in 0..max_size {
let i = position_to_index(mag, n);
data.push(func(i.borrow()));
}
NArray {
dimensions: dim,
magnitudes: mag.to_vec(),
data: data
}
}
}
impl<T: Default> NArray<T> {
pub fn new(dim: usize, mag: &[usize]) -> Self {
Self::from_function(dim, mag, |_: &[usize]| -> T { T::default() })
}
}
impl<T, S: AsRef<[usize]>> Index<S> for NArray<T> {
type Output = T;
fn index(&self, index: S) -> &Self::Output {
let index = index.as_ref();
return &self.data[index_to_position(self.dimensions, &self.magnitudes, index)]
}
}
impl<T, S: AsRef<[usize]>> IndexMut<S> for NArray<T> {
fn index_mut(&mut self, index: S) -> &mut Self::Output {
let index = index.as_ref();
return &mut self.data[index_to_position(self.dimensions, &self.magnitudes, index)];
}
}
impl<T> IntoIterator for NArray<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.data.into_iter()
}
}