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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy