66// option. This file may not be copied, modified, or distributed
77// except according to those terms.
88
9+ use crate :: dimension;
910use crate :: error:: { from_kind, ErrorKind , ShapeError } ;
1011use crate :: imp_prelude:: * ;
1112
6869/// ```
6970pub fn concatenate < A , D > ( axis : Axis , arrays : & [ ArrayView < A , D > ] ) -> Result < Array < A , D > , ShapeError >
7071where
71- A : Copy ,
72+ A : Clone ,
7273 D : RemoveAxis ,
7374{
7475 if arrays. is_empty ( ) {
@@ -88,24 +89,22 @@ where
8889
8990 let stacked_dim = arrays. iter ( ) . fold ( 0 , |acc, a| acc + a. len_of ( axis) ) ;
9091 res_dim. set_axis ( axis, stacked_dim) ;
92+ let new_len = dimension:: size_of_shape_checked ( & res_dim) ?;
9193
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;
10697 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 ( ) ) ?;
108105 }
106+ debug_assert_eq ! ( res. len_of( axis) , stacked_dim) ;
107+ Ok ( res)
109108}
110109
111110#[ deprecated( note="Use under the name stack instead." , since="0.15.0" ) ]
0 commit comments