6
6
// option. This file may not be copied, modified, or distributed
7
7
// except according to those terms.
8
8
9
+ use crate :: dimension;
9
10
use crate :: error:: { from_kind, ErrorKind , ShapeError } ;
10
11
use crate :: imp_prelude:: * ;
11
12
68
69
/// ```
69
70
pub fn concatenate < A , D > ( axis : Axis , arrays : & [ ArrayView < A , D > ] ) -> Result < Array < A , D > , ShapeError >
70
71
where
71
- A : Copy ,
72
+ A : Clone ,
72
73
D : RemoveAxis ,
73
74
{
74
75
if arrays. is_empty ( ) {
@@ -88,24 +89,22 @@ where
88
89
89
90
let stacked_dim = arrays. iter ( ) . fold ( 0 , |acc, a| acc + a. len_of ( axis) ) ;
90
91
res_dim. set_axis ( axis, stacked_dim) ;
92
+ let new_len = dimension:: size_of_shape_checked ( & res_dim) ?;
91
93
92
- // we can safely use uninitialized values here because we will
93
- // overwrite every one of them.
94
- let mut res = Array :: uninit ( res_dim) ;
95
-
96
- {
97
- let mut assign_view = res. view_mut ( ) ;
98
- for array in arrays {
99
- let len = array. len_of ( axis) ;
100
- let ( front, rest) = assign_view. split_at ( axis, len) ;
101
- array. assign_to ( front) ;
102
- assign_view = rest;
103
- }
104
- debug_assert_eq ! ( assign_view. len( ) , 0 ) ;
105
- }
94
+ // start with empty array with precomputed capacity
95
+ res_dim. set_axis ( axis, 0 ) ;
96
+ let mut res;
106
97
unsafe {
107
- Ok ( res. assume_init ( ) )
98
+ res_dim. slice_mut ( ) . swap ( axis. index ( ) , 0 ) ;
99
+ res = Array :: from_shape_vec_unchecked ( res_dim, Vec :: with_capacity ( new_len) ) ;
100
+ res. swap_axes ( axis. index ( ) , 0 ) ;
101
+ }
102
+
103
+ for array in arrays {
104
+ res. try_append_array ( axis, array. clone ( ) ) ?;
108
105
}
106
+ debug_assert_eq ! ( res. len_of( axis) , stacked_dim) ;
107
+ Ok ( res)
109
108
}
110
109
111
110
#[ deprecated( note="Use under the name stack instead." , since="0.15.0" ) ]
0 commit comments