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