How do I test if an alias is a template in D 2.0?
template isTemplate(alias T)
{
enum bool isTemplate = ???;
}
Update:
It should work like:
struct S(T)
{
int opCall() { return 0; }
int opUnary(string s)() if (s == "-") { return 0; }
}
pragma(msg, isTemplate!(S)); //Should print true
pragma(msg, isTemplate!(S!(int))); //Should print false
pragma(msg, isTemplate!((S!(int)).opCall)); //Should print false
pragma(msg, isTemplate!((S!(int)).opUnary)); //Should print true
For reference, things that don't work:
You can't use any expression like T!(...)
because you don't know what to put in place of the ellipses.
You can't say &T
because that also doesn't work if you're just given a plain old type name.
This passes all except 2 tests I have listed in the other answer
import std.algorithm : startsWith, canFind;
template isTemplate(alias B) {
enum isTemplate = !__traits(compiles, {auto x=B;}) // excludes values
&& !__traits(compiles, {B x;}) // excludes types
&& __traits(compiles, {alias B x;}) // excludes instance members
&& !B.stringof.startsWith("module ", "package ") // excludes modules
&& !B.stringof.canFind("!("); // excludes instantiated templates
}
The 2 tests that have failed like:
struct Inner2(string U="!(") {}
static assert(isTemplate(Inner2));
If you are sure the template won't have a default argument containing "...!(..."
I think it is safe to use.
template isTemplate(alias T, Args...)
{
enum bool isTemplate = __traits(compiles, T!(Args));
}
this also puts additional constraint - it must be template which can be instantiated with given arguments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With