@@ -233,14 +233,90 @@ impl From<TokenTree> for TokenStream {
233
233
}
234
234
}
235
235
236
+ /// Non-generic helper for implementing `FromIterator<TokenTree>` and
237
+ /// `Extend<TokenTree>` with less monomorphization in calling crates.
238
+ struct ExtendStreamWithTreesHelper {
239
+ trees : Vec <
240
+ bridge:: TokenTree <
241
+ bridge:: client:: Group ,
242
+ bridge:: client:: Punct ,
243
+ bridge:: client:: Ident ,
244
+ bridge:: client:: Literal ,
245
+ > ,
246
+ > ,
247
+ }
248
+
249
+ impl ExtendStreamWithTreesHelper {
250
+ fn new ( capacity : usize ) -> Self {
251
+ ExtendStreamWithTreesHelper { trees : Vec :: with_capacity ( capacity) }
252
+ }
253
+
254
+ fn push ( & mut self , tree : TokenTree ) {
255
+ self . trees . push ( tree_to_bridge_tree ( tree) ) ;
256
+ }
257
+
258
+ fn build ( self ) -> TokenStream {
259
+ if self . trees . is_empty ( ) {
260
+ TokenStream ( None )
261
+ } else {
262
+ TokenStream ( Some ( bridge:: client:: TokenStream :: concat_trees ( None , self . trees ) ) )
263
+ }
264
+ }
265
+
266
+ fn extend ( self , stream : & mut TokenStream ) {
267
+ if self . trees . is_empty ( ) {
268
+ return ;
269
+ }
270
+ stream. 0 = Some ( bridge:: client:: TokenStream :: concat_trees ( stream. 0 . take ( ) , self . trees ) )
271
+ }
272
+ }
273
+
274
+ /// Non-generic helper for implementing `FromIterator<TokenStream>` and
275
+ /// `Extend<TokenStream>` with less monomorphization in calling crates.
276
+ struct ExtendStreamWithStreamsHelper {
277
+ streams : Vec < bridge:: client:: TokenStream > ,
278
+ }
279
+
280
+ impl ExtendStreamWithStreamsHelper {
281
+ fn new ( capacity : usize ) -> Self {
282
+ ExtendStreamWithStreamsHelper { streams : Vec :: with_capacity ( capacity) }
283
+ }
284
+
285
+ fn push ( & mut self , stream : TokenStream ) {
286
+ if let Some ( stream) = stream. 0 {
287
+ self . streams . push ( stream) ;
288
+ }
289
+ }
290
+
291
+ fn build ( mut self ) -> TokenStream {
292
+ if self . streams . len ( ) <= 1 {
293
+ TokenStream ( self . streams . pop ( ) )
294
+ } else {
295
+ TokenStream ( Some ( bridge:: client:: TokenStream :: concat_streams ( None , self . streams ) ) )
296
+ }
297
+ }
298
+
299
+ fn extend ( mut self , stream : & mut TokenStream ) {
300
+ if self . streams . is_empty ( ) {
301
+ return ;
302
+ }
303
+ let base = stream. 0 . take ( ) ;
304
+ if base. is_none ( ) && self . streams . len ( ) == 1 {
305
+ stream. 0 = self . streams . pop ( ) ;
306
+ } else {
307
+ stream. 0 = Some ( bridge:: client:: TokenStream :: concat_streams ( base, self . streams ) ) ;
308
+ }
309
+ }
310
+ }
311
+
236
312
/// Collects a number of token trees into a single stream.
237
313
#[ stable( feature = "proc_macro_lib2" , since = "1.29.0" ) ]
238
314
impl iter:: FromIterator < TokenTree > for TokenStream {
239
315
fn from_iter < I : IntoIterator < Item = TokenTree > > ( trees : I ) -> Self {
240
- TokenStream ( Some ( bridge :: client :: TokenStream :: concat_trees (
241
- None ,
242
- trees . into_iter ( ) . map ( tree_to_bridge_tree ) . collect ( ) ,
243
- ) ) )
316
+ let iter = trees . into_iter ( ) ;
317
+ let mut builder = ExtendStreamWithTreesHelper :: new ( iter . size_hint ( ) . 0 ) ;
318
+ iter . for_each ( |tree| builder . push ( tree ) ) ;
319
+ builder . build ( )
244
320
}
245
321
}
246
322
@@ -249,30 +325,30 @@ impl iter::FromIterator<TokenTree> for TokenStream {
249
325
#[ stable( feature = "proc_macro_lib" , since = "1.15.0" ) ]
250
326
impl iter:: FromIterator < TokenStream > for TokenStream {
251
327
fn from_iter < I : IntoIterator < Item = TokenStream > > ( streams : I ) -> Self {
252
- TokenStream ( Some ( bridge :: client :: TokenStream :: concat_streams (
253
- None ,
254
- streams . into_iter ( ) . filter_map ( |stream| stream . 0 ) . collect ( ) ,
255
- ) ) )
328
+ let iter = streams . into_iter ( ) ;
329
+ let mut builder = ExtendStreamWithStreamsHelper :: new ( iter . size_hint ( ) . 0 ) ;
330
+ iter . for_each ( |stream| builder . push ( stream ) ) ;
331
+ builder . build ( )
256
332
}
257
333
}
258
334
259
335
#[ stable( feature = "token_stream_extend" , since = "1.30.0" ) ]
260
336
impl Extend < TokenTree > for TokenStream {
261
337
fn extend < I : IntoIterator < Item = TokenTree > > ( & mut self , trees : I ) {
262
- * self = TokenStream ( Some ( bridge :: client :: TokenStream :: concat_trees (
263
- self . 0 . take ( ) ,
264
- trees . into_iter ( ) . map ( |tree| tree_to_bridge_tree ( tree) ) . collect ( ) ,
265
- ) ) ) ;
338
+ let iter = trees . into_iter ( ) ;
339
+ let mut builder = ExtendStreamWithTreesHelper :: new ( iter . size_hint ( ) . 0 ) ;
340
+ iter . for_each ( |tree| builder . push ( tree) ) ;
341
+ builder . extend ( self ) ;
266
342
}
267
343
}
268
344
269
345
#[ stable( feature = "token_stream_extend" , since = "1.30.0" ) ]
270
346
impl Extend < TokenStream > for TokenStream {
271
347
fn extend < I : IntoIterator < Item = TokenStream > > ( & mut self , streams : I ) {
272
- * self = TokenStream ( Some ( bridge :: client :: TokenStream :: concat_streams (
273
- self . 0 . take ( ) ,
274
- streams . into_iter ( ) . filter_map ( |stream| stream . 0 ) . collect ( ) ,
275
- ) ) ) ;
348
+ let iter = streams . into_iter ( ) ;
349
+ let mut builder = ExtendStreamWithStreamsHelper :: new ( iter . size_hint ( ) . 0 ) ;
350
+ iter . for_each ( |stream| builder . push ( stream ) ) ;
351
+ builder . extend ( self ) ;
276
352
}
277
353
}
278
354
0 commit comments