Comment #0 by andrej.mitrovich — 2011-08-29T19:15:23Z
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))
Comment #1 by andrej.mitrovich — 2011-08-29T20:16:51Z
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.
Comment #2 by bearophile_hugs — 2011-08-30T01:51:23Z
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.
}
}
Comment #4 by peter.alexander.au — 2014-01-26T09:19:55Z
You can also use staticIndexOf
template isOneOf(X, T...)
{
enum isOneOf = staticIndexOf(X, TypeTuple!T) != -1;
}
Comment #5 by andrej.mitrovich — 2014-01-26T11:53:05Z
(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/[email protected]
Comment #6 by andrej.mitrovich — 2016-08-27T22:21:38Z
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));
}
-----