Macros and repetitions: flexible identifier access, concat_idents?


#1

I want abstract over the following alogorithm reducing the repetitve code

fn next<K: Ord, A, B, C>(t: (&mut Iterator<Item = (K, A)>,
                             &mut Iterator<Item = (K, B)>,
                             &mut Iterator<Item = (K, C)>))
                         -> Option<(K, A, B, C)> {
    if let (Some(mut a), Some(mut b), Some(mut c)) = (t.0.next(), t.1.next(), t.2.next()) {
        while a.0 != b.0 && b.0 != c.0 {
            while a.0 < b.0 {
                if let Some(next) = t.0.next() {
                    a = next;
                } else {
                    return None;
                }
            }
            while b.0 < c.0 {
                if let Some(next) = t.1.next() {
                    b = next;
                } else {
                    return None;
                }
            }
            while c.0 < a.0 {
                if let Some(next) = t.2.next() {
                    c = next;
                } else {
                    return None;
                }
            }
        }
        return Some((a.0, a.1, b.1, c.1));
    }
    None
}

and produce some impls with a macro like so

macro_rules! impl_next {
    ($($V:ident),+) => {
        fn next<K: Ord, $($V),*>(t: ($(&mut Iterator<Item=(K,$V)>,)*))
                                 -> Option<(K, $($V),*)> {
            // ???
        }
    };
}

impl_next!(A, B);
impl_next!(A, B, C);
// ...

Is it possible to express the algorithm within the macro-language concerning flexible identifier access, concat_idents and stuff like that?


Iterators: shorten call to map
#2

By making some changes to the algorithm and beeing more general:

  • Introduce enough identifiers to face shadowing (2 instead of 1 for each type line 136)
  • Replace calls to tuplemembers with destructuring (line 101)
  • Change the algorithm behavior slightly for avoiding individual identifier access (see the max!() macro part on line 105)

I finally came up with some working code: