Skip to content

Commit 8b46dab

Browse files
committed
Move ArrayBase stuff to its own module
1 parent 8688f4b commit 8b46dab

File tree

2 files changed

+247
-231
lines changed

2 files changed

+247
-231
lines changed

src/base.rs

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
use std::slice;
2+
use std::vec;
3+
4+
use {DimensionInfo,
5+
Array,
6+
MutableArray,
7+
InternalArray,
8+
InternalMutableArray,
9+
ArraySlice,
10+
MutArraySlice,
11+
ArrayParent,
12+
MutArrayParent};
13+
14+
/// A multi-dimensional array.
15+
#[derive(PartialEq, Eq, Clone, Debug)]
16+
pub struct ArrayBase<T> {
17+
info: Vec<DimensionInfo>,
18+
data: Vec<T>,
19+
}
20+
21+
impl<T> ArrayBase<T> {
22+
/// Creates a new multi-dimensional array from its underlying components.
23+
///
24+
/// The data array should be provided in the higher-dimensional equivalent
25+
/// of row-major order.
26+
///
27+
/// ## Failure
28+
///
29+
/// Fails if there are 0 dimensions or the number of elements provided does
30+
/// not match the number of elements specified.
31+
pub fn from_raw(data: Vec<T>, info: Vec<DimensionInfo>)
32+
-> ArrayBase<T> {
33+
assert!((data.is_empty() && info.is_empty()) ||
34+
data.len() == info.iter().fold(1, |acc, i| acc * i.len),
35+
"Size mismatch");
36+
ArrayBase {
37+
info: info,
38+
data: data,
39+
}
40+
}
41+
42+
/// Creates a new one-dimensional array from a vector.
43+
pub fn from_vec(data: Vec<T>, lower_bound: isize) -> ArrayBase<T> {
44+
ArrayBase {
45+
info: vec!(DimensionInfo {
46+
len: data.len(),
47+
lower_bound: lower_bound
48+
}),
49+
data: data
50+
}
51+
}
52+
53+
/// Wraps this array in a new dimension of size 1.
54+
///
55+
/// For example the one-dimensional array `[1,2]` would turn into
56+
/// the two-dimensional array `[[1,2]]`.
57+
pub fn wrap(&mut self, lower_bound: isize) {
58+
self.info.insert(0, DimensionInfo {
59+
len: 1,
60+
lower_bound: lower_bound
61+
})
62+
}
63+
64+
/// Takes ownership of another array, appending it to the top-level
65+
/// dimension of this array.
66+
///
67+
/// The dimensions of the other array must have an identical shape to the
68+
/// dimensions of a slice of this array. This includes both the sizes of
69+
/// the dimensions as well as their lower bounds.
70+
///
71+
/// For example, if `[3,4]` is pushed onto `[[1,2]]`, the result is
72+
/// `[[1,2],[3,4]]`.
73+
///
74+
/// ## Failure
75+
///
76+
/// Fails if the other array does not have dimensions identical to the
77+
/// dimensions of a slice of this array.
78+
pub fn push_move(&mut self, other: ArrayBase<T>) {
79+
assert!(self.info.len() - 1 == other.info.len(),
80+
"Cannot append differently shaped arrays");
81+
for (info1, info2) in self.info.iter().skip(1).zip(other.info.iter()) {
82+
assert!(info1 == info2, "Cannot join differently shaped arrays");
83+
}
84+
self.info[0].len += 1;
85+
self.data.extend(other.data.into_iter());
86+
}
87+
88+
/// Returns an iterator over references to the values in this array, in the
89+
/// higher-dimensional equivalent of row-major order.
90+
pub fn iter<'a>(&'a self) -> Iter<'a, T> {
91+
Iter {
92+
inner: self.data.iter(),
93+
}
94+
}
95+
96+
/// Returns an iterator over references to the values in this array, in the
97+
/// higher-dimensional equivalent of row-major order.
98+
pub fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> {
99+
IterMut {
100+
inner: self.data.iter_mut(),
101+
}
102+
}
103+
}
104+
105+
impl<'a, T: 'a> IntoIterator for &'a ArrayBase<T> {
106+
type Item = &'a T;
107+
type IntoIter = Iter<'a, T>;
108+
109+
fn into_iter(self) -> Iter<'a, T> {
110+
self.iter()
111+
}
112+
}
113+
114+
impl<'a, T: 'a> IntoIterator for &'a mut ArrayBase<T> {
115+
type Item = &'a mut T;
116+
type IntoIter = IterMut<'a, T>;
117+
118+
fn into_iter(self) -> IterMut<'a, T> {
119+
self.iter_mut()
120+
}
121+
}
122+
123+
impl<T> IntoIterator for ArrayBase<T> {
124+
type Item = T;
125+
type IntoIter = IntoIter<T>;
126+
127+
fn into_iter(self) -> IntoIter<T> {
128+
IntoIter {
129+
inner: self.data.into_iter()
130+
}
131+
}
132+
}
133+
134+
impl<T> Array<T> for ArrayBase<T> {
135+
fn dimension_info<'a>(&'a self) -> &'a [DimensionInfo] {
136+
&*self.info
137+
}
138+
139+
fn slice<'a>(&'a self, idx: isize) -> ArraySlice<'a, T> {
140+
assert!(self.info.len() != 1,
141+
"Attempted to slice a one-dimensional array");
142+
ArraySlice {
143+
parent: ArrayParent::Base(self),
144+
idx: self.shift_idx(idx),
145+
}
146+
}
147+
148+
fn get<'a>(&'a self, idx: isize) -> &'a T {
149+
assert!(self.info.len() == 1,
150+
"Attempted to get from a multi-dimensional array");
151+
self.raw_get(self.shift_idx(idx), 1)
152+
}
153+
}
154+
155+
impl<T> MutableArray<T> for ArrayBase<T> {
156+
fn slice_mut<'a>(&'a mut self, idx: isize) -> MutArraySlice<'a, T> {
157+
assert!(self.info.len() != 1,
158+
"Attempted to slice_mut into a one-dimensional array");
159+
MutArraySlice {
160+
idx: self.shift_idx(idx),
161+
parent: MutArrayParent::Base(self),
162+
}
163+
}
164+
165+
fn get_mut<'a>(&'a mut self, idx: isize) -> &'a mut T {
166+
assert!(self.info.len() == 1,
167+
"Attempted to get_mut from a multi-dimensional array");
168+
let idx = self.shift_idx(idx);
169+
self.raw_get_mut(idx, 1)
170+
}
171+
}
172+
173+
impl<T> InternalArray<T> for ArrayBase<T> {
174+
fn raw_get<'a>(&'a self, idx: usize, _size: usize) -> &'a T {
175+
&self.data[idx]
176+
}
177+
}
178+
179+
impl<T> InternalMutableArray<T> for ArrayBase<T> {
180+
fn raw_get_mut<'a>(&'a mut self, idx: usize, _size: usize) -> &'a mut T {
181+
&mut self.data[idx]
182+
}
183+
}
184+
185+
/// An iterator over references to values of an `ArrayBase` in the
186+
/// higher-dimensional equivalent of row-major order.
187+
pub struct Iter<'a, T: 'a> {
188+
inner: slice::Iter<'a, T>,
189+
}
190+
191+
impl<'a, T: 'a> Iterator for Iter<'a, T> {
192+
type Item = &'a T;
193+
194+
fn next(&mut self) -> Option<&'a T> {
195+
self.inner.next()
196+
}
197+
}
198+
199+
impl<'a, T: 'a> DoubleEndedIterator for Iter<'a, T> {
200+
fn next_back(&mut self) -> Option<&'a T> {
201+
self.inner.next_back()
202+
}
203+
}
204+
205+
/// An iterator over mutable references to values of an `ArrayBase` in the
206+
/// higher-dimensional equivalent of row-major order.
207+
pub struct IterMut<'a, T: 'a> {
208+
inner: slice::IterMut<'a, T>,
209+
}
210+
211+
impl<'a, T: 'a> Iterator for IterMut<'a, T> {
212+
type Item = &'a mut T;
213+
214+
fn next(&mut self) -> Option<&'a mut T> {
215+
self.inner.next()
216+
}
217+
}
218+
219+
impl<'a, T: 'a> DoubleEndedIterator for IterMut<'a, T> {
220+
fn next_back(&mut self) -> Option<&'a mut T> {
221+
self.inner.next_back()
222+
}
223+
}
224+
225+
/// An iterator over values of an `ArrayBase` in the higher-dimensional
226+
/// equivalent of row-major order.
227+
pub struct IntoIter<T> {
228+
inner: vec::IntoIter<T>,
229+
}
230+
231+
impl<T> Iterator for IntoIter<T> {
232+
type Item = T;
233+
234+
fn next(&mut self) -> Option<T> {
235+
self.inner.next()
236+
}
237+
}
238+
239+
impl<T> DoubleEndedIterator for IntoIter<T> {
240+
fn next_back(&mut self) -> Option<T> {
241+
self.inner.next_back()
242+
}
243+
}

0 commit comments

Comments
 (0)