Bug 6573 – Add isOneOf to std.traits

Status
RESOLVED
Resolution
WORKSFORME
Severity
enhancement
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
Other
OS
Windows
Creation time
2011-08-29T19:15:00Z
Last change time
2016-08-27T22:21:38Z
Assigned to
nobody
Creator
andrej.mitrovich

Comments

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
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))); }
Comment #3 by kennytm — 2011-08-30T04:39:01Z
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)); } -----