On Wednesday, 12 October 2016 at 16:29:22 UTC, Basile B. wrote:
On Tuesday, 11 October 2016 at 20:17:19 UTC, Straivers wrote:
I have a class T with a templated function foo(string name)(int, int, float) that will be mixed in via template, and I want to determine if that class has mixed it in such that foo(name = "bar"). How could I go about this? Thanks.


eg:

mixin template A(string name, Args...) {
    void foo(string fooName)(Args args)
        if (fooName == name) {}
}

template hasFoo(string name, A) {
    enum hasFoo = ???
}

class B {
    mixin A!("mash", int, int, string);
}

For this particular example the following solution works:

template A(string name, Args...)
{
    void foo(string fooName)(Args args)
        if (fooName == name) {}
}

template hasFoo(string name, T, V...)
{
    enum hasFoo = __traits(hasMember, T, "foo") &&
        is(typeof(T.foo!name) == typeof(A!(name,V).foo!name));
}

class B
{
    mixin A!("mash", int, int, string);
}

unittest
{
    static assert( hasFoo!("mash", B, int, int , string));
    static assert( !hasFoo!("rash", B, int, uint , string));
}


Now I can't say that I's generic enough to validate any members that's injected.
Note well that it wouldn't work with a regular mixin template.

You can also take a look at "std.traits.TemplateOf"

There is also isTemplate (https://dlang.org/spec/traits.html#isTemplate). You can check first that the member exists and then check if it's a template (though this will pick up more than just template functions). There's also a *very* ugly hack you can do:

//A template function's .stringof is of the format <function name>(<template args>)(<function args>) //so match on the number of brackets to determine whether it's a template function or not
enum isTemplateFunction = __traits(isTemplate, f)
                              && fstr.balancedParens('(', ')')
                              && (fstr.canFind("if")
                                  || fstr.count!(c =>
cast(bool)c.among!('(', ')')) == 4);

Reply via email to