I think Steven Schveighoffer came up with this originally: template isOneOf(X, T...) { static if (!T.length) enum bool isOneOf = false; else static if (is (X == T[0])) enum bool isOneOf = true; else enum bool isOneOf = isOneOf!(X, T[1..$]); } It's very useful as a replacement for multiple checks on a single type parameter, e.g.: void foo(T)(T t) if (is(T == Type1) || is(T == Type2) || is(T == Type3)) turns into: void foo(T)(T t) if (isOneOf!(T, Type1, Type2, Type3))
However the code will have to be slightly improved. If you accidentally pass a tuple followed by a single type things can get weird. E.g.: template isOneOf(X, T...) { static if (!T.length) enum bool isOneOf = false; else static if (is (X == T[0])) enum bool isOneOf = true; else enum bool isOneOf = isOneOf!(X, T[1..$]); } void test(T...)(T t) { static assert (isOneOf!(T, double)); // passes by mistake static assert (isOneOf!(double, T)); // ok, fails properly } void main() { test(1, 2, 3); } So that's something to improve.
Something like this? (A different recursion base): template SameTypes(X, T...) { static if (T.length) enum bool SameTypes = is(X == T[0]) && SameTypes!(X, T[1 .. $]); else enum bool SameTypes = true; } void main() { static assert (!SameTypes!(int, int, int, double)); static assert (!SameTypes!(double, int, int, int)); static assert (SameTypes!(double)); static assert (SameTypes!(int)); static assert (SameTypes!(int, typeof(1))); static assert (SameTypes!(int, typeof(1), typeof(2))); }
I think this should be in std.typetuple, and also can be implemented using anySatisfy. template isOneOf(X, T...) { enum isOneOf = anySatisfy!(staticEqualsTo!X, T); } private template staticEqualsTo(X) { template staticEqualsTo(Y) { enum staticEqualsTo = isSame!(X, Y); // ^ isSame is a private template in std.typetuple. } }
You can also use staticIndexOf template isOneOf(X, T...) { enum isOneOf = staticIndexOf(X, TypeTuple!T) != -1; }
(In reply to comment #4) > You can also use staticIndexOf > > template isOneOf(X, T...) > { > enum isOneOf = staticIndexOf(X, TypeTuple!T) != -1; > } Unfortunately staticIndexOf slows down compilation on more demanding template metaprogramming: http://forum.dlang.org/thread/mailman.1418.1346015010.31962.digitalmars-d@puremagic.com
We have anySatisfy for this now: ----- import std.meta; void main() { enum isInt ( T ) = is(T == int); static assert(anySatisfy!(isInt, float, char, int)); static assert(!anySatisfy!(isInt, float, char)); } -----