@@ -723,10 +723,17 @@ macro_rules! peel {
723723 ( $name: ident, $( $other: ident, ) * ) => ( tuple! { $( $other, ) * } )
724724}
725725
726- /// Evaluates to the number of identifiers passed to it, for example: `count_idents!(a, b, c) == 3
727- macro_rules! count_idents {
728- ( ) => { 0 } ;
729- ( $_i: ident, $( $rest: ident, ) * ) => { 1 + count_idents!( $( $rest, ) * ) }
726+ /// Evaluates to the number of tokens passed to it.
727+ ///
728+ /// Logarithmic counting: every one or two recursive expansions, the number of
729+ /// tokens to count is divided by two, instead of being reduced by one.
730+ /// Therefore, the recursion depth is the binary logarithm of the number of
731+ /// tokens to count, and the expanded tree is likewise very small.
732+ macro_rules! count {
733+ ( ) => ( 0usize ) ;
734+ ( $one: tt) => ( 1usize ) ;
735+ ( $( $pairs: tt $_p: tt) * ) => ( count!( $( $pairs) * ) << 1usize ) ;
736+ ( $odd: tt $( $rest: tt) * ) => ( count!( $( $rest) * ) | 1usize ) ;
730737}
731738
732739macro_rules! tuple {
@@ -735,7 +742,7 @@ macro_rules! tuple {
735742 impl <$( $name: Decodable ) ,* > Decodable for ( $( $name, ) * ) {
736743 #[ allow( non_snake_case) ]
737744 fn decode<D : Decoder >( d: & mut D ) -> Result <( $( $name, ) * ) , D :: Error > {
738- let len: usize = count_idents !( $( $name, ) * ) ;
745+ let len: usize = count !( $( $name) * ) ;
739746 d. read_tuple( len, |d| {
740747 let mut i = 0 ;
741748 let ret = ( $( d. read_tuple_arg( { i+=1 ; i-1 } , |d| -> Result <$name, D :: Error > {
0 commit comments