various questions

bearophile bearophileHUGS at lycos.com
Wed Jul 28 18:40:40 PDT 2010


Last version for now, it can be improved further in various ways:


import std.typetuple: TypeTuple;
import std.metastrings: Format;

template Iota(int stop) {
    static if (stop <= 0)
        alias TypeTuple!() Iota;
    else
        alias TypeTuple!(Iota!(stop-1), stop-1) Iota;
}

enum string[] str_types = ["int", "float", "short"];
mixin(Format!("alias TypeTuple!(%s, %s, %s) types;", str_types[0], str_types[1], str_types[2]));
static assert(str_types.length == types.length); // safety

enum string[] str_sizes = ["100", "200", "250"];
mixin(Format!("enum int[] sizes = [%s, %s, %s];", str_sizes[0], str_sizes[1], str_sizes[2]));
static assert(str_sizes.length == sizes.length); // safety

void staticDispatch3(alias templ)(string run_t, string run_n, string run_m) {
    foreach (t; Iota!(str_types.length))
        foreach (n; Iota!(str_sizes.length))
            foreach (m; Iota!(str_sizes.length))
                if (run_t == str_types[t] && run_n == str_sizes[n] && run_m == str_sizes[m]) {
                    templ!(types[t], sizes[n], sizes[m])();
                    goto END;
                }
    assert(0); // safety

    END: {}
}

// ----------------------------

import std.stdio: writeln;

void foo(T, int N, int M)() {
    writeln(typeid(T), " ", N, " ", M);
}

void main() {
    staticDispatch3!(foo)("int", "200", "100");
}


A more generic staticDispatch3 like this doesn't work because items1 is a tuple, so it gets flattened...

void staticDispatch3(alias func, alias str_items1, alias items1,
                                 alias str_items2, alias items2,
                                 alias str_items3, alias items3)
                    (string run_i1, string run_i2, string run_i3) {
    static assert(str_items1.length == items1.length);
    static assert(str_items2.length == items2.length);
    static assert(str_items3.length == items3.length);

    foreach (i1; Iota!(items1.length))
        foreach (i2; Iota!(items2.length))
            foreach (i3; Iota!(items3.length))
                if (run_i1 == str_types[i1] &&
                    run_i2 == str_types[i2] &&
                    run_i3 == str_types[i3]) {
                    func!(items1[i1], items2[i2], items3[i3])();
                    goto END;
                }
    assert(0); // safety

    END: {}
}

Bye,
bearophile


More information about the Digitalmars-d-learn mailing list