Rollup merge of #59600 - tobia:master, r=pnkfelix
Replaced linear token counting macros with optimized implementation There are currently two distinct token-counting macros in the source. Both implement the trivial algorithm, with linear complexity. They may or may not be adequate for their use case, but considering that other people are probably going to copy and paste them whenever they need a token-counting macro, I replaced them with an optimized implementation with logarithmic complexity.
This commit is contained in:
commit
97df8676b7
@ -582,9 +582,17 @@ impl DefPathData {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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);
|
||||
( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));
|
||||
() => (0usize);
|
||||
($one:tt) => (1usize);
|
||||
($($pairs:tt $_p:tt)*) => (count!($($pairs)*) << 1usize);
|
||||
($odd:tt $($rest:tt)*) => (count!($($rest)*) | 1usize);
|
||||
}
|
||||
|
||||
// We define the GlobalMetaDataKind enum with this macro because we want to
|
||||
|
@ -723,10 +723,17 @@ macro_rules! peel {
|
||||
($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 {
|
||||
@ -735,7 +742,7 @@ macro_rules! tuple {
|
||||
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,)*);
|
||||
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> {
|
||||
|
Loading…
Reference in New Issue
Block a user