Skip to content

Commit 08b6e35

Browse files
committed
Merge pull request #102 from bluss/split-the-file
Split lib.rs into many files
2 parents 603b8d9 + d31c5e1 commit 08b6e35

11 files changed

+2712
-2579
lines changed

src/data_traits.rs

+177
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
2+
//! The data (inner representation) traits for ndarray
3+
4+
use std::mem;
5+
use std::rc::Rc;
6+
7+
use {
8+
ArrayBase,
9+
Dimension,
10+
ViewRepr,
11+
};
12+
13+
/// Array’s inner representation.
14+
///
15+
/// ***Note:*** `Data` is not an extension interface at this point.
16+
/// Traits in Rust can serve many different roles. This trait is public because
17+
/// it is used as a bound on public methods.
18+
pub unsafe trait Data {
19+
type Elem;
20+
fn slice(&self) -> &[Self::Elem];
21+
}
22+
23+
/// Array’s writable inner representation.
24+
pub unsafe trait DataMut : Data {
25+
fn slice_mut(&mut self) -> &mut [Self::Elem];
26+
#[inline]
27+
fn ensure_unique<D>(&mut ArrayBase<Self, D>)
28+
where Self: Sized,
29+
D: Dimension
30+
{ }
31+
32+
#[inline]
33+
fn is_unique(&mut self) -> bool {
34+
true
35+
}
36+
}
37+
38+
/// Clone an Array’s storage.
39+
pub unsafe trait DataClone : Data {
40+
/// Unsafe because, `ptr` must point inside the current storage.
41+
unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem);
42+
}
43+
44+
unsafe impl<A> Data for Rc<Vec<A>> {
45+
type Elem = A;
46+
fn slice(&self) -> &[A] {
47+
self
48+
}
49+
}
50+
51+
// NOTE: Copy on write
52+
unsafe impl<A> DataMut for Rc<Vec<A>>
53+
where A: Clone
54+
{
55+
fn slice_mut(&mut self) -> &mut [A] {
56+
&mut Rc::make_mut(self)[..]
57+
}
58+
59+
fn ensure_unique<D>(self_: &mut ArrayBase<Self, D>)
60+
where Self: Sized,
61+
D: Dimension
62+
{
63+
if Rc::get_mut(&mut self_.data).is_some() {
64+
return;
65+
}
66+
if self_.dim.size() <= self_.data.len() / 2 {
67+
// Create a new vec if the current view is less than half of
68+
// backing data.
69+
unsafe {
70+
*self_ = ArrayBase::from_vec_dim_unchecked(self_.dim.clone(),
71+
self_.iter()
72+
.cloned()
73+
.collect());
74+
}
75+
return;
76+
}
77+
let our_off = (self_.ptr as isize - self_.data.as_ptr() as isize) /
78+
mem::size_of::<A>() as isize;
79+
let rvec = Rc::make_mut(&mut self_.data);
80+
unsafe {
81+
self_.ptr = rvec.as_mut_ptr().offset(our_off);
82+
}
83+
}
84+
85+
fn is_unique(&mut self) -> bool {
86+
Rc::get_mut(self).is_some()
87+
}
88+
}
89+
90+
unsafe impl<A> DataClone for Rc<Vec<A>> {
91+
unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) {
92+
// pointer is preserved
93+
(self.clone(), ptr)
94+
}
95+
}
96+
97+
unsafe impl<A> Data for Vec<A> {
98+
type Elem = A;
99+
fn slice(&self) -> &[A] {
100+
self
101+
}
102+
}
103+
104+
unsafe impl<A> DataMut for Vec<A> {
105+
fn slice_mut(&mut self) -> &mut [A] {
106+
self
107+
}
108+
}
109+
110+
unsafe impl<A> DataClone for Vec<A>
111+
where A: Clone
112+
{
113+
unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) {
114+
let mut u = self.clone();
115+
let our_off = (self.as_ptr() as isize - ptr as isize) /
116+
mem::size_of::<A>() as isize;
117+
let new_ptr = u.as_mut_ptr().offset(our_off);
118+
(u, new_ptr)
119+
}
120+
}
121+
122+
unsafe impl<'a, A> Data for ViewRepr<&'a A> {
123+
type Elem = A;
124+
fn slice(&self) -> &[A] {
125+
&[]
126+
}
127+
}
128+
129+
unsafe impl<'a, A> DataClone for ViewRepr<&'a A> {
130+
unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) {
131+
(*self, ptr)
132+
}
133+
}
134+
135+
unsafe impl<'a, A> Data for ViewRepr<&'a mut A> {
136+
type Elem = A;
137+
fn slice(&self) -> &[A] {
138+
&[]
139+
}
140+
}
141+
142+
unsafe impl<'a, A> DataMut for ViewRepr<&'a mut A> {
143+
fn slice_mut(&mut self) -> &mut [A] {
144+
&mut []
145+
}
146+
}
147+
148+
/// Array representation that is a unique or shared owner of its data.
149+
pub unsafe trait DataOwned : Data {
150+
fn new(elements: Vec<Self::Elem>) -> Self;
151+
fn into_shared(self) -> Rc<Vec<Self::Elem>>;
152+
}
153+
154+
/// Array representation that is a lightweight view.
155+
pub unsafe trait DataShared : Clone + DataClone { }
156+
157+
unsafe impl<A> DataShared for Rc<Vec<A>> {}
158+
unsafe impl<'a, A> DataShared for ViewRepr<&'a A> {}
159+
160+
unsafe impl<A> DataOwned for Vec<A> {
161+
fn new(elements: Vec<A>) -> Self {
162+
elements
163+
}
164+
fn into_shared(self) -> Rc<Vec<A>> {
165+
Rc::new(self)
166+
}
167+
}
168+
169+
unsafe impl<A> DataOwned for Rc<Vec<A>> {
170+
fn new(elements: Vec<A>) -> Self {
171+
Rc::new(elements)
172+
}
173+
fn into_shared(self) -> Rc<Vec<A>> {
174+
self
175+
}
176+
}
177+

src/free_functions.rs

+194
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
2+
use std::slice;
3+
4+
use libnum;
5+
use imp_prelude::*;
6+
7+
/// ***Deprecated: Use `ArrayBase::zeros` instead.***
8+
///
9+
/// Return an array filled with zeros
10+
#[cfg_attr(has_deprecated, deprecated(note="Use `ArrayBase::zeros` instead."))]
11+
pub fn zeros<A, D>(dim: D) -> OwnedArray<A, D>
12+
where A: Clone + libnum::Zero, D: Dimension,
13+
{
14+
ArrayBase::zeros(dim)
15+
}
16+
17+
/// Return a zero-dimensional array with the element `x`.
18+
pub fn arr0<A>(x: A) -> OwnedArray<A, ()>
19+
{
20+
unsafe { ArrayBase::from_vec_dim_unchecked((), vec![x]) }
21+
}
22+
23+
/// Return a one-dimensional array with elements from `xs`.
24+
pub fn arr1<A: Clone>(xs: &[A]) -> OwnedArray<A, Ix> {
25+
ArrayBase::from_vec(xs.to_vec())
26+
}
27+
28+
/// Return a one-dimensional array with elements from `xs`.
29+
pub fn rcarr1<A: Clone>(xs: &[A]) -> RcArray<A, Ix> {
30+
arr1(xs).into_shared()
31+
}
32+
33+
/// Return a zero-dimensional array view borrowing `x`.
34+
pub fn aview0<A>(x: &A) -> ArrayView<A, ()> {
35+
unsafe { ArrayView::new_(x, (), ()) }
36+
}
37+
38+
/// Return a one-dimensional array view with elements borrowing `xs`.
39+
///
40+
/// ```
41+
/// use ndarray::aview1;
42+
///
43+
/// let data = [1.0; 1024];
44+
///
45+
/// // Create a 2D array view from borrowed data
46+
/// let a2d = aview1(&data).into_shape((32, 32)).unwrap();
47+
///
48+
/// assert!(
49+
/// a2d.scalar_sum() == 1024.0
50+
/// );
51+
/// ```
52+
pub fn aview1<A>(xs: &[A]) -> ArrayView<A, Ix> {
53+
ArrayView::from_slice(xs)
54+
}
55+
56+
/// Return a two-dimensional array view with elements borrowing `xs`.
57+
pub fn aview2<A, V: FixedInitializer<Elem=A>>(xs: &[V]) -> ArrayView<A, (Ix, Ix)> {
58+
let cols = V::len();
59+
let rows = xs.len();
60+
let data = unsafe {
61+
slice::from_raw_parts(xs.as_ptr() as *const A, cols * rows)
62+
};
63+
let dim = (rows as Ix, cols as Ix);
64+
unsafe {
65+
let strides = dim.default_strides();
66+
ArrayView::new_(data.as_ptr(), dim, strides)
67+
}
68+
}
69+
70+
/// Return a one-dimensional read-write array view with elements borrowing `xs`.
71+
///
72+
/// ```
73+
/// #[macro_use(s)]
74+
/// extern crate ndarray;
75+
///
76+
/// use ndarray::aview_mut1;
77+
///
78+
/// // Create an array view over some data, then slice it and modify it.
79+
/// fn main() {
80+
/// let mut data = [0; 1024];
81+
/// {
82+
/// let mut a = aview_mut1(&mut data).into_shape((32, 32)).unwrap();
83+
/// a.slice_mut(s![.., ..;3]).assign_scalar(&5);
84+
/// }
85+
/// assert_eq!(&data[..10], [5, 0, 0, 5, 0, 0, 5, 0, 0, 5]);
86+
/// }
87+
/// ```
88+
pub fn aview_mut1<A>(xs: &mut [A]) -> ArrayViewMut<A, Ix> {
89+
ArrayViewMut::from_slice(xs)
90+
}
91+
92+
/// Fixed-size array used for array initialization
93+
pub unsafe trait FixedInitializer {
94+
type Elem;
95+
fn as_init_slice(&self) -> &[Self::Elem];
96+
fn len() -> usize;
97+
}
98+
99+
macro_rules! impl_arr_init {
100+
(__impl $n: expr) => (
101+
unsafe impl<T> FixedInitializer for [T; $n] {
102+
type Elem = T;
103+
fn as_init_slice(&self) -> &[T] { self }
104+
fn len() -> usize { $n }
105+
}
106+
);
107+
() => ();
108+
($n: expr, $($m:expr,)*) => (
109+
impl_arr_init!(__impl $n);
110+
impl_arr_init!($($m,)*);
111+
)
112+
113+
}
114+
115+
impl_arr_init!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,);
116+
117+
/// Return a two-dimensional array with elements from `xs`.
118+
///
119+
/// ```
120+
/// use ndarray::arr2;
121+
///
122+
/// let a = arr2(&[[1, 2, 3],
123+
/// [4, 5, 6]]);
124+
/// assert!(
125+
/// a.shape() == [2, 3]
126+
/// );
127+
/// ```
128+
pub fn arr2<A: Clone, V: FixedInitializer<Elem = A>>(xs: &[V]) -> OwnedArray<A, (Ix, Ix)> {
129+
// FIXME: Simplify this when V is fix size array
130+
let (m, n) = (xs.len() as Ix,
131+
xs.get(0).map_or(0, |snd| snd.as_init_slice().len() as Ix));
132+
let dim = (m, n);
133+
let mut result = Vec::<A>::with_capacity(dim.size());
134+
for snd in xs {
135+
let snd = snd.as_init_slice();
136+
result.extend(snd.iter().cloned());
137+
}
138+
unsafe {
139+
ArrayBase::from_vec_dim_unchecked(dim, result)
140+
}
141+
}
142+
143+
/// Return a two-dimensional array with elements from `xs`.
144+
///
145+
pub fn rcarr2<A: Clone, V: FixedInitializer<Elem = A>>(xs: &[V]) -> RcArray<A, (Ix, Ix)> {
146+
arr2(xs).into_shared()
147+
}
148+
149+
/// Return a three-dimensional array with elements from `xs`.
150+
///
151+
/// **Panics** if the slices are not all of the same length.
152+
///
153+
/// ```
154+
/// use ndarray::arr3;
155+
///
156+
/// let a = arr3(&[[[1, 2],
157+
/// [3, 4]],
158+
/// [[5, 6],
159+
/// [7, 8]],
160+
/// [[9, 0],
161+
/// [1, 2]]]);
162+
/// assert!(
163+
/// a.shape() == [3, 2, 2]
164+
/// );
165+
/// ```
166+
pub fn arr3<A: Clone, V: FixedInitializer<Elem=U>, U: FixedInitializer<Elem=A>>(xs: &[V])
167+
-> OwnedArray<A, (Ix, Ix, Ix)>
168+
{
169+
// FIXME: Simplify this when U/V are fix size arrays
170+
let m = xs.len() as Ix;
171+
let fst = xs.get(0).map(|snd| snd.as_init_slice());
172+
let thr = fst.and_then(|elt| elt.get(0).map(|elt2| elt2.as_init_slice()));
173+
let n = fst.map_or(0, |v| v.len() as Ix);
174+
let o = thr.map_or(0, |v| v.len() as Ix);
175+
let dim = (m, n, o);
176+
let mut result = Vec::<A>::with_capacity(dim.size());
177+
for snd in xs {
178+
let snd = snd.as_init_slice();
179+
for thr in snd.iter() {
180+
let thr = thr.as_init_slice();
181+
result.extend(thr.iter().cloned());
182+
}
183+
}
184+
unsafe {
185+
ArrayBase::from_vec_dim_unchecked(dim, result)
186+
}
187+
}
188+
189+
/// Return a three-dimensional array with elements from `xs`.
190+
pub fn rcarr3<A: Clone, V: FixedInitializer<Elem=U>, U: FixedInitializer<Elem=A>>(xs: &[V])
191+
-> RcArray<A, (Ix, Ix, Ix)>
192+
{
193+
arr3(xs).into_shared()
194+
}

src/impl_clone.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use imp_prelude::*;
2+
use DataClone;
3+
4+
impl<S: DataClone, D: Clone> Clone for ArrayBase<S, D> {
5+
fn clone(&self) -> ArrayBase<S, D> {
6+
unsafe {
7+
let (data, ptr) = self.data.clone_with_ptr(self.ptr);
8+
ArrayBase {
9+
data: data,
10+
ptr: ptr,
11+
dim: self.dim.clone(),
12+
strides: self.strides.clone(),
13+
}
14+
}
15+
}
16+
}
17+
18+
impl<S: DataClone + Copy, D: Copy> Copy for ArrayBase<S, D> {}
19+

0 commit comments

Comments
 (0)