($name:ident, $($other:ident,)*) => (tuple! { $($other,)* })
}
-/// Evaluates to the number of identifiers passed to it, for example: `count_idents!(a, b, c) == 3
-macro_rules! count_idents {
- () => { 0 };
- ($_i:ident, $($rest:ident,)*) => { 1 + count_idents!($($rest,)*) }
+/// Evaluates to the number of tokens passed to it.
+///
+/// Logarithmic counting: every one or two recursive expansions, the number of
+/// tokens to count is divided by two, instead of being reduced by one.
+/// Therefore, the recursion depth is the binary logarithm of the number of
+/// tokens to count, and the expanded tree is likewise very small.
+macro_rules! count {
+ () => (0usize);
+ ($one:tt) => (1usize);
+ ($($pairs:tt $_p:tt)*) => (count!($($pairs)*) << 1usize);
+ ($odd:tt $($rest:tt)*) => (count!($($rest)*) | 1usize);
}
macro_rules! tuple {
() => ();
( $($name:ident,)+ ) => (
- impl<$($name:Decodable),*> Decodable for ($($name,)*) {
+ impl<$($name:Decodable),+> Decodable for ($($name,)+) {
#[allow(non_snake_case)]
- fn decode<D: Decoder>(d: &mut D) -> Result<($($name,)*), D::Error> {
- let len: usize = count_idents!($($name,)*);
+ fn decode<D: Decoder>(d: &mut D) -> Result<($($name,)+), D::Error> {
+ let len: usize = count!($($name)+);
d.read_tuple(len, |d| {
let mut i = 0;
let ret = ($(d.read_tuple_arg({ i+=1; i-1 }, |d| -> Result<$name, D::Error> {
Decodable::decode(d)
- })?,)*);
+ })?,)+);
Ok(ret)
})
}
}
- impl<$($name:Encodable),*> Encodable for ($($name,)*) {
+ impl<$($name:Encodable),+> Encodable for ($($name,)+) {
#[allow(non_snake_case)]
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
- let ($(ref $name,)*) = *self;
+ let ($(ref $name,)+) = *self;
let mut n = 0;
- $(let $name = $name; n += 1;)*
+ $(let $name = $name; n += 1;)+
s.emit_tuple(n, |s| {
let mut i = 0;
- $(s.emit_tuple_arg({ i+=1; i-1 }, |s| $name.encode(s))?;)*
+ $(s.emit_tuple_arg({ i+=1; i-1 }, |s| $name.encode(s))?;)+
Ok(())
})
}
}
- peel! { $($name,)* }
+ peel! { $($name,)+ }
)
}