Suppose I need to do something similar to this:
mixin(some_template!("x", "foo"));
mixin(some_template!("x", "bar"));
mixin(some_template!("x", "baz"));
mixin(some_template!("y", "foo"));
mixin(some_template!("y", "bar"));
mixin(some_template!("z", "baz"));
Is it somehow possible to create another_template
which is a variadic version of some_template
, where you can give anywhere from 2 to however-many arguments? What I mean is that I would like to be able to say:
mixin(another_template!("x", "foo", "bar", "baz"));
mixin(another_template!("y", "foo", "bar"));
mixin(another_template!("z", "baz"));
and have it expand to equivalent code to what the first example would expand to.
Yes, using the regular variadic template syntax (Something...
collects the rest of the template arguments given and they can be of mixed types. see: http://dlang.org/template#TemplateTupleParameter):
string some_template(strings...)() {
string a;
foreach(f; strings)
a ~= f;
return a;
}
void main() {
mixin(some_template!("int ", "giggle", ";"));
}
You can restrict the type with a constraint like this:
// this condition will only compile if it is passed a string
import std.typetuple;
enum check_if_string(string s) = true;
// then we check that they all compile with the check_if_string check
string some_template(strings...)() if(allSatisfy!(check_if_string, strings)) {
string a;
foreach(f; strings)
a ~= f;
return a;
}
The error message will be ugly though, and non-strings won't compile even without this check so it isn't really important. But you can also use the if check in there for like if(strings.length >= 2)
as well.
This is called a template constraint: http://dlang.org/template#Constraint
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