Map Range Higher Order Macro


#1

I wrote a higher order macro to apply another macro to a range of values 0..n where n is an octal number with digits separated by spaces. It’s primarily useful for generating impls on arrays.

The macro:

macro_rules! map_range {
    /* The actual macro */
    (%# apply $tmpl:ident, $shift:expr, $offset:expr, $by:expr, (0 $($rest:tt)*)) => {
        map_range!(%# apply $tmpl, $shift, $offset, $by*2, ($($rest)*));
        map_range!(%# apply $tmpl, $shift, $offset + $by, $by*2, ($($rest)*));
    };
    (%# apply $tmpl:ident, $shift:expr, $offset:expr, $by:expr, (1 $($rest:tt)*)) => {
        map_range!(%# apply $tmpl, $shift-$by, $offset, $by, (0 $($rest)*));
        $tmpl!((($offset) - ($shift)));
    };
    (%# apply $tmpl:ident, $shift:expr, $offset:expr, $by:expr, ()) => { };

    /* Convert from little endien octal to big endian binary */
    (%# convert $tmpl:ident, (0 $($octal:tt)*), ($($binary:tt)*)) => {
        map_range!(%# convert $tmpl, ($($octal)*), (0 0 0 $($binary)*));
    };
    (%# convert $tmpl:ident, (1 $($octal:tt)*), ($($binary:tt)*)) => {
        map_range!(%# convert $tmpl, ($($octal)*), (1 0 0 $($binary)*));
    };
    (%# convert $tmpl:ident, (2 $($octal:tt)*), ($($binary:tt)*)) => {
        map_range!(%# convert $tmpl, ($($octal)*), (0 1 0 $($binary)*));
    };
    (%# convert $tmpl:ident, (3 $($octal:tt)*), ($($binary:tt)*)) => {
        map_range!(%# convert $tmpl, ($($octal)*), (1 1 0 $($binary)*));
    };
    (%# convert $tmpl:ident, (4 $($octal:tt)*), ($($binary:tt)*)) => {
        map_range!(%# convert $tmpl, ($($octal)*), (0 0 1 $($binary)*));
    };
    (%# convert $tmpl:ident, (5 $($octal:tt)*), ($($binary:tt)*)) => {
        map_range!(%# convert $tmpl, ($($octal)*), (1 0 1 $($binary)*));
    };
    (%# convert $tmpl:ident, (6 $($octal:tt)*), ($($binary:tt)*)) => {
        map_range!(%# convert $tmpl, ($($octal)*), (0 1 1 $($binary)*));
    };
    (%# convert $tmpl:ident, (7 $($octal:tt)*), ($($binary:tt)*)) => {
        map_range!(%# convert $tmpl, ($($octal)*), (1 1 1 $($binary)*));
    };
    (%# convert $tmpl:ident, (), $binary:tt) => {
        map_range!(%# apply $tmpl, 0, 0, 1, $binary);
    };

    /* Public API */
    ($tmpl:ident @ $($num:tt)*) => {
        map_range!(%# convert $tmpl, ($($num)*), ());
    };
}

Example:

use std::mem;

trait AsArray<T> {
    fn as_array(&self) -> &T;
}

macro_rules! array_impl {
    ($value:expr) => {
        impl<T> AsArray<[T; $value]> for [T] {
            fn as_array(&self) -> &[T; $value] {
                const LEN: usize = $value;

                if self.len() == LEN {
                    unsafe { mem::transmute(self.as_ptr()) }
                } else {
                    panic!();
                }
            }
        }
    };
}

map_range!(array_impl @ 4 0 0); // Call array_impl!(i) for i in 0..256

So, before I create an entirely new crate for this macro, are there any macro collection crates where this might belong?