Skip to content

Commit d6e2922

Browse files
committed
Implement Array::from for vectors of nested arrays
1 parent 6552943 commit d6e2922

File tree

1 file changed

+58
-19
lines changed

1 file changed

+58
-19
lines changed

src/free_functions.rs

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// except according to those terms.
88

99
use std::slice;
10+
use std::mem::{size_of, forget};
1011

1112
use imp_prelude::*;
1213

@@ -121,21 +122,65 @@ impl_arr_init!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,);
121122
/// a.shape() == [2, 3]
122123
/// );
123124
/// ```
124-
pub fn arr2<A: Clone, V: FixedInitializer<Elem = A>>(xs: &[V]) -> Array2<A> {
125-
let (m, n) = (xs.len(), V::len());
126-
let dim = Ix2(m, n);
127-
let mut result = Vec::<A>::with_capacity(dim.size());
128-
for snd in xs {
129-
result.extend_from_slice(snd.as_init_slice());
125+
pub fn arr2<A: Clone, V: FixedInitializer<Elem = A>>(xs: &[V]) -> Array2<A>
126+
where V: Clone,
127+
{
128+
Array2::from(xs.to_vec())
129+
}
130+
131+
impl<A> From<Vec<A>> for Array1<A> {
132+
fn from(xs: Vec<A>) -> Self {
133+
Array1::from_vec(xs)
130134
}
131-
unsafe {
132-
ArrayBase::from_shape_vec_unchecked(dim, result)
135+
}
136+
137+
impl<A, V> From<Vec<V>> for Array2<A>
138+
where V: FixedInitializer<Elem = A>
139+
{
140+
fn from(mut xs: Vec<V>) -> Self {
141+
let (m, n) = (xs.len(), V::len());
142+
let dim = Ix2(m, n);
143+
let ptr = xs.as_mut_ptr();
144+
let len = xs.len();
145+
let cap = xs.capacity();
146+
forget(xs);
147+
unsafe {
148+
let v = if size_of::<A>() == 0 {
149+
Vec::from_raw_parts(ptr as *mut A, len * V::len(), cap)
150+
} else {
151+
Vec::from_raw_parts(ptr as *mut A, len * V::len(), cap * V::len())
152+
};
153+
ArrayBase::from_shape_vec_unchecked(dim, v)
154+
}
155+
}
156+
}
157+
158+
impl<A, V, U> From<Vec<V>> for Array3<A>
159+
where V: FixedInitializer<Elem=U>,
160+
U: FixedInitializer<Elem=A>
161+
{
162+
fn from(mut xs: Vec<V>) -> Self {
163+
let dim = Ix3(xs.len(), V::len(), U::len());
164+
let ptr = xs.as_mut_ptr();
165+
let len = xs.len();
166+
let cap = xs.capacity();
167+
forget(xs);
168+
unsafe {
169+
let v = if size_of::<A>() == 0 {
170+
Vec::from_raw_parts(ptr as *mut A, len * V::len(), cap)
171+
} else {
172+
let len = len * V::len() * U::len();
173+
let cap = cap * V::len() * U::len();
174+
Vec::from_raw_parts(ptr as *mut A, len, cap)
175+
};
176+
ArrayBase::from_shape_vec_unchecked(dim, v)
177+
}
133178
}
134179
}
135180

136181
/// Create a two-dimensional array with elements from `xs`.
137182
///
138-
pub fn rcarr2<A: Clone, V: FixedInitializer<Elem = A>>(xs: &[V]) -> RcArray<A, Ix2> {
183+
pub fn rcarr2<A: Clone, V: Clone + FixedInitializer<Elem = A>>(xs: &[V]) -> RcArray<A, Ix2> {
139184
arr2(xs).into_shared()
140185
}
141186

@@ -158,22 +203,16 @@ pub fn rcarr2<A: Clone, V: FixedInitializer<Elem = A>>(xs: &[V]) -> RcArray<A, I
158203
/// ```
159204
pub fn arr3<A: Clone, V: FixedInitializer<Elem=U>, U: FixedInitializer<Elem=A>>(xs: &[V])
160205
-> Array3<A>
206+
where V: Clone,
207+
U: Clone,
161208
{
162-
let dim = Ix3(xs.len(), V::len(), U::len());
163-
let mut result = Vec::<A>::with_capacity(dim.size());
164-
for snd in xs {
165-
for thr in snd.as_init_slice() {
166-
result.extend_from_slice(thr.as_init_slice());
167-
}
168-
}
169-
unsafe {
170-
ArrayBase::from_shape_vec_unchecked(dim, result)
171-
}
209+
Array3::from(xs.to_vec())
172210
}
173211

174212
/// Create a three-dimensional array with elements from `xs`.
175213
pub fn rcarr3<A: Clone, V: FixedInitializer<Elem=U>, U: FixedInitializer<Elem=A>>(xs: &[V])
176214
-> RcArray<A, Ix3>
215+
where V: Clone, U: Clone,
177216
{
178217
arr3(xs).into_shared()
179218
}

0 commit comments

Comments
 (0)