@@ -244,15 +244,32 @@ pub trait TupleCollect: Sized {
244
244
fn left_shift_push ( & mut self , item : Self :: Item ) ;
245
245
}
246
246
247
+ macro_rules! count_ident{
248
+ ( ) => { 0 } ;
249
+ ( $i0: ident, $( $i: ident, ) * ) => { 1 + count_ident!( $( $i, ) * ) } ;
250
+ }
251
+ macro_rules! ignore_ident{
252
+ ( $id: ident, $( $t: tt) * ) => { $( $t) * } ;
253
+ }
254
+ macro_rules! rev_for_each_ident{
255
+ ( $m: ident, ) => { } ;
256
+ ( $m: ident, $i0: ident, $( $i: ident, ) * ) => {
257
+ rev_for_each_ident!( $m, $( $i, ) * ) ;
258
+ $m!( $i0) ;
259
+ } ;
260
+ }
261
+
247
262
macro_rules! impl_tuple_collect {
248
- ( $N: expr; $A: ident ; $( $X: ident) ,* ; $( $Y: ident) ,* ; $( $Y_rev: ident) ,* ) => (
249
- impl <$A> TupleCollect for ( $( $X) ,* , ) {
250
- type Item = $A;
251
- type Buffer = [ Option <$A>; $N - 1 ] ;
263
+ ( $dummy: ident, ) => { } ; // stop
264
+ ( $dummy: ident, $( $Y: ident, ) * ) => (
265
+ impl_tuple_collect!( $( $Y, ) * ) ;
266
+ impl <A > TupleCollect for ( $( ignore_ident!( $Y, A ) , ) * ) {
267
+ type Item = A ;
268
+ type Buffer = [ Option <A >; count_ident!( $( $Y, ) * ) - 1 ] ;
252
269
253
270
#[ allow( unused_assignments, unused_mut) ]
254
271
fn collect_from_iter<I >( iter: I , buf: & mut Self :: Buffer ) -> Option <Self >
255
- where I : IntoIterator <Item = $ A>
272
+ where I : IntoIterator <Item = A >
256
273
{
257
274
let mut iter = iter. into_iter( ) ;
258
275
$(
@@ -281,7 +298,7 @@ macro_rules! impl_tuple_collect {
281
298
}
282
299
283
300
fn collect_from_iter_no_buf<I >( iter: I ) -> Option <Self >
284
- where I : IntoIterator <Item = $ A>
301
+ where I : IntoIterator <Item = A >
285
302
{
286
303
let mut iter = iter. into_iter( ) ;
287
304
@@ -291,44 +308,20 @@ macro_rules! impl_tuple_collect {
291
308
}
292
309
293
310
fn num_items( ) -> usize {
294
- $N
311
+ count_ident! ( $ ( $Y , ) * )
295
312
}
296
313
297
- fn left_shift_push( & mut self , item: $ A) {
314
+ fn left_shift_push( & mut self , mut item: A ) {
298
315
use std:: mem:: replace;
299
316
300
317
let & mut ( $( ref mut $Y) ,* , ) = self ;
301
- $(
302
- let item = replace( $Y_rev, item) ;
303
- ) *
318
+ macro_rules! replace_item{ ( $i: ident) => {
319
+ item = replace( $i, item) ;
320
+ } } ;
321
+ rev_for_each_ident!( replace_item, $( $Y, ) * ) ;
304
322
drop( item) ;
305
323
}
306
324
}
307
325
)
308
326
}
309
-
310
- // This snippet generates the twelve `impl_tuple_collect!` invocations:
311
- // use core::iter;
312
- // use itertools::Itertools;
313
- //
314
- // for i in 1..=12 {
315
- // println!("impl_tuple_collect!({arity}; A; {ty}; {idents}; {rev_idents});",
316
- // arity=i,
317
- // ty=iter::repeat("A").take(i).join(", "),
318
- // idents=('a'..='z').take(i).join(", "),
319
- // rev_idents=('a'..='z').take(i).collect_vec().into_iter().rev().join(", ")
320
- // );
321
- // }
322
- // It could probably be replaced by a bit more macro cleverness.
323
- impl_tuple_collect ! ( 1 ; A ; A ; a; a) ;
324
- impl_tuple_collect ! ( 2 ; A ; A , A ; a, b; b, a) ;
325
- impl_tuple_collect ! ( 3 ; A ; A , A , A ; a, b, c; c, b, a) ;
326
- impl_tuple_collect ! ( 4 ; A ; A , A , A , A ; a, b, c, d; d, c, b, a) ;
327
- impl_tuple_collect ! ( 5 ; A ; A , A , A , A , A ; a, b, c, d, e; e, d, c, b, a) ;
328
- impl_tuple_collect ! ( 6 ; A ; A , A , A , A , A , A ; a, b, c, d, e, f; f, e, d, c, b, a) ;
329
- impl_tuple_collect ! ( 7 ; A ; A , A , A , A , A , A , A ; a, b, c, d, e, f, g; g, f, e, d, c, b, a) ;
330
- impl_tuple_collect ! ( 8 ; A ; A , A , A , A , A , A , A , A ; a, b, c, d, e, f, g, h; h, g, f, e, d, c, b, a) ;
331
- impl_tuple_collect ! ( 9 ; A ; A , A , A , A , A , A , A , A , A ; a, b, c, d, e, f, g, h, i; i, h, g, f, e, d, c, b, a) ;
332
- impl_tuple_collect ! ( 10 ; A ; A , A , A , A , A , A , A , A , A , A ; a, b, c, d, e, f, g, h, i, j; j, i, h, g, f, e, d, c, b, a) ;
333
- impl_tuple_collect ! ( 11 ; A ; A , A , A , A , A , A , A , A , A , A , A ; a, b, c, d, e, f, g, h, i, j, k; k, j, i, h, g, f, e, d, c, b, a) ;
334
- impl_tuple_collect ! ( 12 ; A ; A , A , A , A , A , A , A , A , A , A , A , A ; a, b, c, d, e, f, g, h, i, j, k, l; l, k, j, i, h, g, f, e, d, c, b, a) ;
327
+ impl_tuple_collect ! ( dummy, a, b, c, d, e, f, g, h, i, j, k, l, ) ;
0 commit comments