@@ -82,50 +82,6 @@ impl Arena {
82
82
}
83
83
}
84
84
85
- /// Allocate many items at once, without reallocating
86
- #[ inline]
87
- pub fn alloc_many < ' input , ' output , T : Sized + Copy + ' input , V : Into < Cow < ' input , [ T ] > > > (
88
- & ' output self ,
89
- vals : V ,
90
- ) -> & ' output [ T ] {
91
- use std:: { mem, ptr, slice} ;
92
-
93
- let vals = vals. into ( ) ;
94
-
95
- if vals. as_ref ( ) . is_empty ( ) {
96
- return & [ ] ;
97
- }
98
-
99
- let len = vals. as_ref ( ) . len ( ) ;
100
- let bytes = len * mem:: size_of :: < T > ( ) ;
101
-
102
- match vals {
103
- Cow :: Owned ( mut vec) => {
104
- let p = vec. as_mut_ptr ( ) ;
105
- let cap = vec. capacity ( ) ;
106
-
107
- mem:: forget ( vec) ;
108
-
109
- let out = self . alloc_vec ( unsafe {
110
- Vec :: from_raw_parts (
111
- p as _ ,
112
- len * mem:: size_of :: < T > ( ) ,
113
- cap * mem:: size_of :: < T > ( ) ,
114
- )
115
- } ) ;
116
-
117
- unsafe { slice:: from_raw_parts ( out as _ , len) }
118
- }
119
- Cow :: Borrowed ( slice) => {
120
- let ptr = self . require ( bytes) ;
121
-
122
- unsafe { ptr:: copy_nonoverlapping ( slice. as_ptr ( ) as _ , ptr, bytes) } ;
123
-
124
- unsafe { slice:: from_raw_parts ( ptr as _ , len) }
125
- }
126
- }
127
- }
128
-
129
85
/// Put the value onto the page of the arena and return a reference to it.
130
86
#[ inline]
131
87
pub fn alloc < ' arena , T : Sized + Copy > ( & ' arena self , value : T ) -> & ' arena T {
@@ -157,6 +113,35 @@ impl Arena {
157
113
}
158
114
}
159
115
116
+ /// Put a `Vec<T>` on the arena without reallocating.
117
+ pub fn alloc_vec < ' arena , T : Copy > ( & ' arena self , mut val : Vec < T > ) -> & ' arena [ T ] {
118
+ use std:: { mem, slice} ;
119
+
120
+ let ptr = val. as_mut_ptr ( ) ;
121
+ let cap = val. capacity ( ) ;
122
+ let len = val. len ( ) ;
123
+
124
+ mem:: forget ( val) ;
125
+
126
+ let out = self . alloc_byte_vec ( unsafe {
127
+ Vec :: from_raw_parts ( ptr as _ , 0 , cap * size_of :: < T > ( ) )
128
+ } ) ;
129
+
130
+ unsafe { slice:: from_raw_parts ( out as _ , len) }
131
+ }
132
+
133
+ /// Allocate many items at once, avoid allocation for owned values.
134
+ #[ inline]
135
+ pub fn alloc_cow < ' input , ' arena , T > ( & ' arena self , vals : Cow < ' input , [ T ] > ) -> & ' arena [ T ]
136
+ where
137
+ T : Sized + Copy + ' input ,
138
+ {
139
+ match vals {
140
+ Cow :: Owned ( vec) => self . alloc_vec ( vec) ,
141
+ Cow :: Borrowed ( slice) => self . alloc_slice ( slice) ,
142
+ }
143
+ }
144
+
160
145
/// Allocate an `&str` slice onto the arena and return a reference to it. This is
161
146
/// useful when the original slice has an undefined lifetime.
162
147
///
@@ -191,7 +176,7 @@ impl Arena {
191
176
/// This does not copy or reallocate the original `String`.
192
177
pub fn alloc_string < ' arena > ( & ' arena self , val : String ) -> & ' arena str {
193
178
let len = val. len ( ) ;
194
- let ptr = self . alloc_vec ( val. into_bytes ( ) ) ;
179
+ let ptr = self . alloc_byte_vec ( val. into_bytes ( ) ) ;
195
180
196
181
unsafe {
197
182
use std:: str:: from_utf8_unchecked;
@@ -202,7 +187,7 @@ impl Arena {
202
187
}
203
188
204
189
#[ inline]
205
- fn alloc_vec ( & self , mut val : Vec < u8 > ) -> * mut u8 {
190
+ fn alloc_byte_vec ( & self , mut val : Vec < u8 > ) -> * mut u8 {
206
191
let ptr = val. as_mut_ptr ( ) ;
207
192
208
193
let mut temp = self . store . replace ( Vec :: new ( ) ) ;
@@ -213,7 +198,7 @@ impl Arena {
213
198
}
214
199
215
200
fn alloc_bytes ( & self , size : usize ) -> * mut u8 {
216
- self . alloc_vec ( Vec :: with_capacity ( size) )
201
+ self . alloc_byte_vec ( Vec :: with_capacity ( size) )
217
202
}
218
203
219
204
#[ inline]
@@ -243,7 +228,7 @@ impl Arena {
243
228
}
244
229
245
230
fn grow ( & self ) {
246
- let ptr = self . alloc_vec ( Vec :: with_capacity ( ARENA_BLOCK ) ) ;
231
+ let ptr = self . alloc_byte_vec ( Vec :: with_capacity ( ARENA_BLOCK ) ) ;
247
232
self . ptr . set ( ptr) ;
248
233
}
249
234
@@ -303,7 +288,18 @@ mod test {
303
288
let vecs = vec ! [ vec![ 1u64 , 2 , 3 , 4 ] , vec![ 7 ; ARENA_BLOCK * 2 ] , vec![ ] ] ;
304
289
305
290
for vec in vecs {
306
- assert_eq ! ( arena. alloc_many( vec. clone( ) ) , & vec[ ..] ) ;
291
+ assert_eq ! ( arena. alloc_vec( vec. clone( ) ) , & vec[ ..] ) ;
292
+ }
293
+ }
294
+
295
+ #[ test]
296
+ fn allocate_some_cows ( ) {
297
+ let arena = Arena :: new ( ) ;
298
+
299
+ let vecs = vec ! [ vec![ 1u64 , 2 , 3 , 4 ] , vec![ 7 ; ARENA_BLOCK * 2 ] , vec![ ] ] ;
300
+
301
+ for vec in vecs {
302
+ assert_eq ! ( arena. alloc_cow( vec. clone( ) . into( ) ) , & vec[ ..] ) ;
307
303
}
308
304
}
309
305
0 commit comments